fix(growth): harden deterministic report evidence
This commit is contained in:
@@ -12,26 +12,46 @@ func AnalyzeEventEffect(history []DailyPoint, event Event, catalog []Event) Even
|
||||
byDate := pointsByDate(history)
|
||||
eventDays := daysInclusive(event.StartDate, event.EndDate)
|
||||
var baselineSessions, baselinePaid, baselineAmount int64
|
||||
actualComplete := true
|
||||
for _, eventDay := range eventDays {
|
||||
if point, ok := byDate[dayKey(eventDay)]; ok {
|
||||
effect.ActualSessionCount += point.SessionCount
|
||||
effect.ActualPaidSessions += point.PaidSessionCount
|
||||
effect.ActualAmountRial += point.PaidAmountRial
|
||||
point, ok := byDate[dayKey(eventDay)]
|
||||
if !ok {
|
||||
actualComplete = false
|
||||
break
|
||||
}
|
||||
for week := 1; week <= 8; week++ {
|
||||
effect.ActualSessionCount += point.SessionCount
|
||||
effect.ActualPaidSessions += point.PaidSessionCount
|
||||
effect.ActualAmountRial += point.PaidAmountRial
|
||||
}
|
||||
if !actualComplete {
|
||||
effect.SuppressionReason = SuppressionIncompleteEventWindow
|
||||
return effect
|
||||
}
|
||||
for week := 1; week <= 8; week++ {
|
||||
var windowSessions, windowPaid, windowAmount int64
|
||||
complete := true
|
||||
for _, eventDay := range eventDays {
|
||||
candidate := eventDay.AddDate(0, 0, -7*week)
|
||||
if eventDates[dayKey(candidate)] {
|
||||
continue
|
||||
complete = false
|
||||
break
|
||||
}
|
||||
point, ok := byDate[dayKey(candidate)]
|
||||
if !ok {
|
||||
continue
|
||||
complete = false
|
||||
break
|
||||
}
|
||||
effect.ObservationCount++
|
||||
baselineSessions += point.SessionCount
|
||||
baselinePaid += point.PaidSessionCount
|
||||
baselineAmount += point.PaidAmountRial
|
||||
windowSessions += point.SessionCount
|
||||
windowPaid += point.PaidSessionCount
|
||||
windowAmount += point.PaidAmountRial
|
||||
}
|
||||
if !complete {
|
||||
continue
|
||||
}
|
||||
effect.ObservationCount++
|
||||
baselineSessions += windowSessions
|
||||
baselinePaid += windowPaid
|
||||
baselineAmount += windowAmount
|
||||
}
|
||||
if effect.ObservationCount < MinBaselineObservations {
|
||||
effect.SuppressionReason = SuppressionInsufficientObservations
|
||||
@@ -45,9 +65,9 @@ func AnalyzeEventEffect(history []DailyPoint, event Event, catalog []Event) Even
|
||||
return effect
|
||||
}
|
||||
effect.Eligible = true
|
||||
effect.SessionUpliftBPS = changeBPS(effect.ActualSessionCount/int64(len(eventDays)), effect.BaselineSessionCount)
|
||||
effect.PaidSessionUpliftBPS = changeBPS(effect.ActualPaidSessions/int64(len(eventDays)), effect.BaselinePaidSessions)
|
||||
effect.AmountUpliftBPS = changeBPS(effect.ActualAmountRial/int64(len(eventDays)), effect.BaselineAmountRial)
|
||||
effect.SessionUpliftBPS = changeBPS(effect.ActualSessionCount, effect.BaselineSessionCount)
|
||||
effect.PaidSessionUpliftBPS = changeBPS(effect.ActualPaidSessions, effect.BaselinePaidSessions)
|
||||
effect.AmountUpliftBPS = changeBPS(effect.ActualAmountRial, effect.BaselineAmountRial)
|
||||
effect.MaterialWin = effect.PaidSessionUpliftBPS >= MaterialChangeBPS || effect.AmountUpliftBPS >= MaterialChangeBPS
|
||||
effect.MaterialDecline = effect.PaidSessionUpliftBPS <= -MaterialChangeBPS || effect.AmountUpliftBPS <= -MaterialChangeBPS
|
||||
return effect
|
||||
@@ -140,6 +160,9 @@ func normalizeDate(value time.Time) time.Time {
|
||||
|
||||
func dayKey(value time.Time) string { return normalizeDate(value).Format(time.DateOnly) }
|
||||
|
||||
func dateBefore(a, b time.Time) bool { return dayKey(a) < dayKey(b) }
|
||||
func dateAfter(a, b time.Time) bool { return dayKey(a) > dayKey(b) }
|
||||
|
||||
func changeBPS(actual, baseline int64) int64 {
|
||||
if baseline <= 0 {
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user