package growthreport import ( "encoding/json" "fmt" "time" ) type Status string const ( StatusQueued Status = "QUEUED" StatusAnalyzing Status = "ANALYZING" StatusGenerating Status = "GENERATING" StatusReady Status = "READY" StatusPartial Status = "PARTIAL" StatusFailed Status = "FAILED" ) func (s Status) Terminal() bool { return s == StatusReady || s == StatusPartial || s == StatusFailed } type Scope struct { TerminalID *string `json:"terminalId"` } type CampaignBrief struct { Headline string `json:"headline"` Interpretation string `json:"interpretation"` OfferSuggestion string `json:"offerSuggestion"` MessageSuggestion string `json:"messageSuggestion"` PreparationAction string `json:"preparationAction"` Limitation string `json:"limitation"` EvidenceIDs []string `json:"evidenceIds"` } type AICopy struct { Briefs []CampaignBrief `json:"briefs"` } type Usage struct { InputTokens int64 `json:"inputTokens"` OutputTokens int64 `json:"outputTokens"` LatencyMS int64 `json:"latencyMs"` ProviderRequests int64 `json:"providerRequests"` ReservedTokens int64 `json:"reservedTokens"` ProviderRequestID string `json:"providerRequestId,omitempty"` EstimatedCost string `json:"estimatedCost,omitempty"` } type Report struct { ReportID string `json:"reportId"` Revision int `json:"revision"` Status Status `json:"status"` Scope Scope `json:"scope"` HorizonDays int `json:"horizonDays"` ForecastStartDate *time.Time `json:"forecastStartDate,omitempty"` DeterministicEvidence json.RawMessage `json:"deterministicEvidence,omitempty"` AICopy *AICopy `json:"aiCopy,omitempty"` FailureCode *string `json:"failureCode,omitempty"` Cached bool `json:"cached"` Stale bool `json:"stale"` NextRefreshAt time.Time `json:"nextRefreshAt"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` EventsURL string `json:"eventsUrl"` } type Record struct { Report MerchantID int64 TerminalDBID *int64 Fingerprint string DatasetWatermark string CatalogVersion string AnalyticsVersion string PromptVersion string SchemaVersion string Model string Usage Usage ManualRefresh bool TehranRefreshDay *time.Time ClaimToken string } type CreateRequest struct { TerminalID string `json:"terminalId"` Refresh bool `json:"refresh"` } type RefreshLimitError struct{ NextRefreshAt time.Time } func (e *RefreshLimitError) Error() string { return fmt.Sprintf("%s: next refresh at %s", ErrRefreshLimited, e.NextRefreshAt.Format(time.RFC3339)) } func (e *RefreshLimitError) Unwrap() error { return ErrRefreshLimited }