mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 20:15:23 +02:00
fix(experiments): include full 24h of end_date in DiD overlap bounds
This commit is contained in:
@@ -264,21 +264,21 @@ export function computeDiD(
|
|||||||
salesData: CombinedKPIs[]
|
salesData: CombinedKPIs[]
|
||||||
): DifferenceInDifferencesResult {
|
): DifferenceInDifferencesResult {
|
||||||
const startDate = parseLocalDate(experiment.start_date);
|
const startDate = parseLocalDate(experiment.start_date);
|
||||||
const endDate = experiment.end_date ? parseLocalDate(experiment.end_date) : new Date();
|
const endDate = experiment.end_date ? parseLocalDate(experiment.end_date) : new Date(new Date().setHours(0, 0, 0, 0));
|
||||||
|
|
||||||
// Seasonal Baseline override logic
|
const startTs = startDate.getTime();
|
||||||
let beforeStart: Date;
|
const endTs = endDate.getTime() + 86400000; // Add 24h so end bound is midnight of next day
|
||||||
let beforeEnd = startDate; // By default, before period goes up to the exact start date
|
|
||||||
|
let beforeStartTs: number;
|
||||||
|
let beforeEndTs: number;
|
||||||
|
|
||||||
if (experiment.baseline_start_date && experiment.baseline_end_date) {
|
if (experiment.baseline_start_date && experiment.baseline_end_date) {
|
||||||
beforeStart = parseLocalDate(experiment.baseline_start_date);
|
beforeStartTs = parseLocalDate(experiment.baseline_start_date).getTime();
|
||||||
beforeEnd = parseLocalDate(experiment.baseline_end_date);
|
beforeEndTs = parseLocalDate(experiment.baseline_end_date).getTime() + 86400000;
|
||||||
// Explicit end + 1 day so `< beforeEnd` logic includes the last day
|
|
||||||
beforeEnd = new Date(beforeEnd.getTime() + 86400000);
|
|
||||||
} else {
|
} else {
|
||||||
// Legacy auto-deduction (shifts the exact timeframe to the left)
|
const durationMs = endTs - startTs;
|
||||||
const durationMs = endDate.getTime() - startDate.getTime();
|
beforeEndTs = startTs; // Adjacent: baseline ends right at the moment experiment starts
|
||||||
beforeStart = new Date(startDate.getTime() - durationMs);
|
beforeStartTs = beforeEndTs - durationMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
const treatmentAsinSet = getExperimentAsins(experiment.asins || [], salesData);
|
const treatmentAsinSet = getExperimentAsins(experiment.asins || [], salesData);
|
||||||
@@ -291,11 +291,6 @@ export function computeDiD(
|
|||||||
controlWeekly = aggregateWeeklyMetrics(controlAsinSet, salesData, experiment.marketplace);
|
controlWeekly = aggregateWeeklyMetrics(controlAsinSet, salesData, experiment.marketplace);
|
||||||
}
|
}
|
||||||
|
|
||||||
const startTs = startDate.getTime();
|
|
||||||
const endTs = endDate.getTime();
|
|
||||||
const beforeStartTs = beforeStart.getTime();
|
|
||||||
const beforeEndTs = beforeEnd.getTime();
|
|
||||||
|
|
||||||
const tSplit = splitPeriods(treatmentWeekly, startTs, endTs, beforeStartTs, beforeEndTs);
|
const tSplit = splitPeriods(treatmentWeekly, startTs, endTs, beforeStartTs, beforeEndTs);
|
||||||
const cSplit = hasControlGroup
|
const cSplit = hasControlGroup
|
||||||
? splitPeriods(controlWeekly, startTs, endTs, beforeStartTs, beforeEndTs)
|
? splitPeriods(controlWeekly, startTs, endTs, beforeStartTs, beforeEndTs)
|
||||||
@@ -347,19 +342,21 @@ export function buildCounterfactualSeries(
|
|||||||
metric: string
|
metric: string
|
||||||
): TrendDataPoint[] {
|
): TrendDataPoint[] {
|
||||||
const startDate = parseLocalDate(experiment.start_date);
|
const startDate = parseLocalDate(experiment.start_date);
|
||||||
const endDate = experiment.end_date ? parseLocalDate(experiment.end_date) : new Date();
|
const endDate = experiment.end_date ? parseLocalDate(experiment.end_date) : new Date(new Date().setHours(0, 0, 0, 0));
|
||||||
|
|
||||||
// Seasonal Baseline override logic
|
const startTs = startDate.getTime();
|
||||||
let beforeStart: Date;
|
const endTs = endDate.getTime() + 86400000; // Add 24h
|
||||||
let beforeEnd = startDate;
|
|
||||||
|
let beforeStartTs: number;
|
||||||
|
let beforeEndTs: number;
|
||||||
|
|
||||||
if (experiment.baseline_start_date && experiment.baseline_end_date) {
|
if (experiment.baseline_start_date && experiment.baseline_end_date) {
|
||||||
beforeStart = parseLocalDate(experiment.baseline_start_date);
|
beforeStartTs = parseLocalDate(experiment.baseline_start_date).getTime();
|
||||||
beforeEnd = parseLocalDate(experiment.baseline_end_date);
|
beforeEndTs = parseLocalDate(experiment.baseline_end_date).getTime() + 86400000;
|
||||||
beforeEnd = new Date(beforeEnd.getTime() + 86400000);
|
|
||||||
} else {
|
} else {
|
||||||
const durationMs = endDate.getTime() - startDate.getTime();
|
const durationMs = endTs - startTs;
|
||||||
beforeStart = new Date(startDate.getTime() - durationMs);
|
beforeEndTs = startTs;
|
||||||
|
beforeStartTs = beforeEndTs - durationMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
const treatmentAsinSet = getExperimentAsins(experiment.asins || [], salesData);
|
const treatmentAsinSet = getExperimentAsins(experiment.asins || [], salesData);
|
||||||
@@ -368,15 +365,7 @@ export function buildCounterfactualSeries(
|
|||||||
const hasControlGroup = (experiment.control_asins || []).length > 0;
|
const hasControlGroup = (experiment.control_asins || []).length > 0;
|
||||||
|
|
||||||
if (!hasControlGroup) {
|
if (!hasControlGroup) {
|
||||||
// Without control group, counterfactual = flat line at pre-treatment average
|
const { before: beforeData } = splitPeriods(treatmentWeekly, startTs, endTs, beforeStartTs, beforeEndTs);
|
||||||
const startTs = startDate.getTime();
|
|
||||||
const endTs = endDate.getTime();
|
|
||||||
const beforeStartTs = beforeStart.getTime();
|
|
||||||
const beforeEndTs = beforeEnd.getTime();
|
|
||||||
|
|
||||||
// To calculate counterfactual, we need the "before" average.
|
|
||||||
// Treatment before period:
|
|
||||||
const { before: beforeData } = splitPeriods(treatmentWeekly, startTs, endTs, beforeStartTs, beforeEndTs); // Use splitPeriods to match exactly
|
|
||||||
const preAvg = avgMetric(beforeData, metric);
|
const preAvg = avgMetric(beforeData, metric);
|
||||||
|
|
||||||
return treatmentWeekly.map(w => ({
|
return treatmentWeekly.map(w => ({
|
||||||
@@ -390,11 +379,6 @@ export function buildCounterfactualSeries(
|
|||||||
const controlAsinSet = getExperimentAsins(experiment.control_asins, salesData);
|
const controlAsinSet = getExperimentAsins(experiment.control_asins, salesData);
|
||||||
const controlWeekly = aggregateWeeklyMetrics(controlAsinSet, salesData, experiment.marketplace);
|
const controlWeekly = aggregateWeeklyMetrics(controlAsinSet, salesData, experiment.marketplace);
|
||||||
|
|
||||||
const startTs = startDate.getTime();
|
|
||||||
const endTs = endDate.getTime();
|
|
||||||
const beforeStartTs = beforeStart.getTime();
|
|
||||||
const beforeEndTs = beforeEnd.getTime();
|
|
||||||
|
|
||||||
const { before: tBeforeData } = splitPeriods(treatmentWeekly, startTs, endTs, beforeStartTs, beforeEndTs);
|
const { before: tBeforeData } = splitPeriods(treatmentWeekly, startTs, endTs, beforeStartTs, beforeEndTs);
|
||||||
const { before: cBeforeData } = splitPeriods(controlWeekly, startTs, endTs, beforeStartTs, beforeEndTs);
|
const { before: cBeforeData } = splitPeriods(controlWeekly, startTs, endTs, beforeStartTs, beforeEndTs);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user