feat(growth): add deterministic forecasting engine
This commit is contained in:
148
internal/growth/types.go
Normal file
148
internal/growth/types.go
Normal file
@@ -0,0 +1,148 @@
|
||||
package growth
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
CatalogVersion = "1405.1"
|
||||
AnalyticsVersion = "1.0.0"
|
||||
|
||||
MinBaselineObservations = 4
|
||||
MinBaselineSessions = 100
|
||||
MaterialChangeBPS = 2_000
|
||||
MinSimilarityBPS = 6_000
|
||||
)
|
||||
|
||||
type Confidence string
|
||||
|
||||
const (
|
||||
ConfidenceHigh Confidence = "HIGH"
|
||||
ConfidenceMedium Confidence = "MEDIUM"
|
||||
ConfidenceInsufficientData Confidence = "INSUFFICIENT_DATA"
|
||||
)
|
||||
|
||||
type SuppressionReason string
|
||||
|
||||
const (
|
||||
SuppressionInsufficientObservations SuppressionReason = "INSUFFICIENT_BASELINE_OBSERVATIONS"
|
||||
SuppressionInsufficientBaselineSessions SuppressionReason = "INSUFFICIENT_BASELINE_SESSIONS"
|
||||
SuppressionInsufficientHistory SuppressionReason = "INSUFFICIENT_HISTORY"
|
||||
SuppressionInsufficientCohort SuppressionReason = "INSUFFICIENT_COHORT"
|
||||
SuppressionTerminalScope SuppressionReason = "TERMINAL_SCOPE_UNSUPPORTED"
|
||||
)
|
||||
|
||||
type DailyPoint struct {
|
||||
Date time.Time `json:"date"`
|
||||
SessionCount int64 `json:"sessionCount"`
|
||||
PaidSessionCount int64 `json:"paidSessionCount"`
|
||||
PaidAmountRial int64 `json:"paidAmountRial"`
|
||||
EventIDs []string `json:"eventIds,omitempty"`
|
||||
}
|
||||
|
||||
type EventKind string
|
||||
|
||||
const (
|
||||
EventOfficial EventKind = "OFFICIAL"
|
||||
EventCommercial EventKind = "COMMERCIAL"
|
||||
)
|
||||
|
||||
type Event struct {
|
||||
ID string `json:"id"`
|
||||
TitleFA string `json:"titleFa"`
|
||||
StartDate time.Time `json:"startDate"`
|
||||
EndDate time.Time `json:"endDate"`
|
||||
Family string `json:"family"`
|
||||
Tags []string `json:"tags"`
|
||||
Source string `json:"source"`
|
||||
Categories []string `json:"categories"`
|
||||
Kind EventKind `json:"kind"`
|
||||
}
|
||||
|
||||
type EventEffect struct {
|
||||
EvidenceID string `json:"evidenceId"`
|
||||
EventID string `json:"eventId"`
|
||||
Eligible bool `json:"eligible"`
|
||||
SuppressionReason SuppressionReason `json:"suppressionReason,omitempty"`
|
||||
ObservationCount int `json:"observationCount"`
|
||||
BaselineSessionCount int64 `json:"baselineSessionCount"`
|
||||
BaselinePaidSessions int64 `json:"baselinePaidSessions"`
|
||||
BaselineAmountRial int64 `json:"baselineAmountRial"`
|
||||
ActualSessionCount int64 `json:"actualSessionCount"`
|
||||
ActualPaidSessions int64 `json:"actualPaidSessions"`
|
||||
ActualAmountRial int64 `json:"actualAmountRial"`
|
||||
SessionUpliftBPS int64 `json:"sessionUpliftBps"`
|
||||
PaidSessionUpliftBPS int64 `json:"paidSessionUpliftBps"`
|
||||
AmountUpliftBPS int64 `json:"amountUpliftBps"`
|
||||
MaterialWin bool `json:"materialWin"`
|
||||
MaterialDecline bool `json:"materialDecline"`
|
||||
}
|
||||
|
||||
type EventMatch struct {
|
||||
Event Event `json:"event"`
|
||||
ScoreBPS int64 `json:"scoreBps"`
|
||||
MatchBasis string `json:"matchBasis"`
|
||||
}
|
||||
|
||||
type Range struct {
|
||||
P10 int64 `json:"p10"`
|
||||
P50 int64 `json:"p50"`
|
||||
P90 int64 `json:"p90"`
|
||||
}
|
||||
|
||||
type ForecastPoint struct {
|
||||
Date time.Time `json:"date"`
|
||||
BaselineSessions int64 `json:"baselineSessions"`
|
||||
BaselineAmountRial int64 `json:"baselineAmountRial"`
|
||||
PaidSessions Range `json:"paidSessions"`
|
||||
PaidAmountRial Range `json:"paidAmountRial"`
|
||||
EventIDs []string `json:"eventIds,omitempty"`
|
||||
}
|
||||
|
||||
type BacktestResult struct {
|
||||
Origins int `json:"origins"`
|
||||
SessionMAPEBPS int64 `json:"sessionMapeBps"`
|
||||
AmountMAPEBPS int64 `json:"amountMapeBps"`
|
||||
IntervalCoverageBPS int64 `json:"intervalCoverageBps"`
|
||||
}
|
||||
|
||||
type Forecast struct {
|
||||
StartDate time.Time `json:"startDate"`
|
||||
HorizonDays int `json:"horizonDays"`
|
||||
Confidence Confidence `json:"confidence"`
|
||||
SuppressionReason SuppressionReason `json:"suppressionReason,omitempty"`
|
||||
Points []ForecastPoint `json:"points"`
|
||||
Backtest BacktestResult `json:"backtest"`
|
||||
}
|
||||
|
||||
type Opportunity struct {
|
||||
EvidenceID string `json:"evidenceId"`
|
||||
EventID string `json:"eventId"`
|
||||
EventTitleFA string `json:"eventTitleFa"`
|
||||
Date time.Time `json:"date"`
|
||||
SimilarityBPS int64 `json:"similarityBps"`
|
||||
ExpectedSessions Range `json:"expectedSessions"`
|
||||
ExpectedAmountRial Range `json:"expectedAmountRial"`
|
||||
HistoricalEvidenceID string `json:"historicalEvidenceId"`
|
||||
}
|
||||
|
||||
type Risk struct {
|
||||
EvidenceID string `json:"evidenceId"`
|
||||
Date time.Time `json:"date"`
|
||||
SessionDeclineBPS int64 `json:"sessionDeclineBps"`
|
||||
AmountDeclineBPS int64 `json:"amountDeclineBps"`
|
||||
ExpectedSessions Range `json:"expectedSessions"`
|
||||
ExpectedAmountRial Range `json:"expectedAmountRial"`
|
||||
}
|
||||
|
||||
type EvidenceBundle struct {
|
||||
Opportunities []Opportunity `json:"opportunities"`
|
||||
Risks []Risk `json:"risks"`
|
||||
}
|
||||
|
||||
type CampaignBrief struct {
|
||||
HeadlineFA string `json:"headlineFa"`
|
||||
GuidanceFA string `json:"guidanceFa"`
|
||||
OfferFA string `json:"offerFa"`
|
||||
PreparationFA string `json:"preparationFa"`
|
||||
LimitationFA string `json:"limitationFa"`
|
||||
EvidenceIDs []string `json:"evidenceIds"`
|
||||
}
|
||||
Reference in New Issue
Block a user