package insight import ( "encoding/json" "errors" "time" ) type Module string const ( ModuleOverview Module = "overview" ModulePayments Module = "payments" ModuleFees Module = "fees" ModulePeers Module = "peers" ModuleTransactions Module = "transactions" ModuleGrowth Module = "growth" ) var ErrNotFound = errors.New("ai insight: not found") var ErrUnknownTerminal = errors.New("ai insight: unknown terminal") var ErrRefreshLimited = errors.New("ai insight: refresh limited") var ErrIdempotencyConflict = errors.New("ai insight: idempotency conflict") func ParseModule(value string) (Module, bool) { module := Module(value) switch module { case ModuleOverview, ModulePayments, ModuleFees, ModulePeers, ModuleTransactions, ModuleGrowth: return module, true default: return "", false } } type Confidence string const ( ConfidenceHigh Confidence = "HIGH" ConfidenceMedium Confidence = "MEDIUM" ConfidenceLow Confidence = "LOW" ConfidenceInsufficientData Confidence = "INSUFFICIENT_DATA" ) type Narrative struct { Headline string `json:"headline"` Body string `json:"body"` EvidenceID []string `json:"evidenceIds"` } type Finding struct { EvidenceID string `json:"evidenceId"` Title string `json:"title"` Summary string `json:"summary"` ScoreBPS int `json:"scoreBps"` Confidence Confidence `json:"confidence"` } type Option struct { Title string `json:"title"` Description string `json:"description"` EvidenceID []string `json:"evidenceIds"` } type CalendarContext struct { EventKey string `json:"eventKey"` TitleFA string `json:"titleFa"` StartDate string `json:"startDate"` EndDate string `json:"endDate"` Tone string `json:"tone"` CommercialPosture string `json:"commercialPosture"` OfficialHoliday bool `json:"officialHoliday"` EvidenceSupported bool `json:"evidenceSupported"` OverlapConfounded bool `json:"overlapConfounded"` } type Copy struct { Past Narrative `json:"past"` LatestObserved Narrative `json:"latestObserved"` Future7Days Narrative `json:"future7Days"` Future30Days Narrative `json:"future30Days"` Future90Days *Narrative `json:"future90Days,omitempty"` Findings []Finding `json:"findings"` Options []Option `json:"options"` } type Scope struct { TerminalID *string `json:"terminalId"` } type RefreshState struct { State string `json:"state"` JobID string `json:"jobId,omitempty"` EventsURL string `json:"eventsUrl,omitempty"` NextRefreshAt *time.Time `json:"nextRefreshAt,omitempty"` } type Snapshot struct { InsightID string `json:"insightId"` Module Module `json:"module"` Revision int `json:"revision"` Status string `json:"status"` Scope Scope `json:"scope"` AsOfDate string `json:"asOfDate"` DataThroughDate string `json:"dataThroughDate"` ForecastStart string `json:"forecastStartDate"` Freshness Freshness `json:"freshness"` DataLagDays int `json:"dataLagDays"` Confidence Confidence `json:"confidence"` Copy Copy `json:"copy"` Evidence json.RawMessage `json:"evidence"` CalendarContext []CalendarContext `json:"calendarContext"` RefreshState RefreshState `json:"refreshState"` GeneratedAt time.Time `json:"generatedAt"` } type Job struct { JobID string `json:"jobId"` SnapshotID string `json:"snapshotId"` State string `json:"state"` EventsURL string `json:"eventsUrl"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } type Event struct { ID int64 `json:"eventId"` Type string `json:"type"` Payload json.RawMessage `json:"payload"` OccurredAt time.Time `json:"occurredAt"` } type CreateRequest struct { MerchantID int64 TerminalID string Module Module TriggerReason string ManualRefresh bool IdempotencyKey string RequestHash string Fingerprint string Time TimeContext Confidence Confidence CatalogVersion string Evidence json.RawMessage }