fix: deliver validated AI insight responses
This commit is contained in:
@@ -8,6 +8,8 @@ import (
|
||||
|
||||
type Module string
|
||||
|
||||
type Section string
|
||||
|
||||
const (
|
||||
ModuleOverview Module = "overview"
|
||||
ModulePayments Module = "payments"
|
||||
@@ -17,10 +19,28 @@ const (
|
||||
ModuleGrowth Module = "growth"
|
||||
)
|
||||
|
||||
const (
|
||||
SectionFull Section = "full"
|
||||
SectionPast Section = "past"
|
||||
SectionLatestObserved Section = "latest-observed"
|
||||
SectionFuture7Days Section = "future-7-days"
|
||||
SectionFuture30Days Section = "future-30-days"
|
||||
SectionFuture90Days Section = "future-90-days"
|
||||
SectionFindings Section = "findings"
|
||||
SectionOptions Section = "options"
|
||||
)
|
||||
|
||||
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 ErrRefreshCooldown = errors.New("ai insight: refresh cooldown")
|
||||
var ErrIdempotencyConflict = errors.New("ai insight: idempotency conflict")
|
||||
var ErrOnboardingRequired = errors.New("ai insight: onboarding required")
|
||||
|
||||
type RefreshCooldownError struct{ NextRefreshAt time.Time }
|
||||
|
||||
func (e *RefreshCooldownError) Error() string { return "ai insight: refresh cooldown" }
|
||||
func (e *RefreshCooldownError) Unwrap() error { return ErrRefreshCooldown }
|
||||
|
||||
func ParseModule(value string) (Module, bool) {
|
||||
module := Module(value)
|
||||
@@ -32,6 +52,18 @@ func ParseModule(value string) (Module, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func ParseSection(module Module, value string) (Section, bool) {
|
||||
section := Section(value)
|
||||
switch section {
|
||||
case SectionPast, SectionLatestObserved, SectionFuture7Days, SectionFuture30Days, SectionFindings, SectionOptions:
|
||||
return section, true
|
||||
case SectionFuture90Days:
|
||||
return section, module == ModuleGrowth
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
type Confidence string
|
||||
|
||||
const (
|
||||
@@ -83,8 +115,44 @@ type Copy struct {
|
||||
Options []Option `json:"options"`
|
||||
}
|
||||
|
||||
func MergeSection(base, generated Copy, section Section) (Copy, error) {
|
||||
switch section {
|
||||
case SectionFull:
|
||||
return generated, nil
|
||||
case SectionPast:
|
||||
base.Past = generated.Past
|
||||
case SectionLatestObserved:
|
||||
base.LatestObserved = generated.LatestObserved
|
||||
case SectionFuture7Days:
|
||||
base.Future7Days = generated.Future7Days
|
||||
case SectionFuture30Days:
|
||||
base.Future30Days = generated.Future30Days
|
||||
case SectionFuture90Days:
|
||||
if generated.Future90Days == nil {
|
||||
return Copy{}, errors.New("ai insight: future 90 day section unavailable")
|
||||
}
|
||||
base.Future90Days = generated.Future90Days
|
||||
case SectionFindings:
|
||||
base.Findings = generated.Findings
|
||||
case SectionOptions:
|
||||
base.Options = generated.Options
|
||||
default:
|
||||
return Copy{}, errors.New("ai insight: invalid section")
|
||||
}
|
||||
return base, nil
|
||||
}
|
||||
|
||||
type Scope struct {
|
||||
TerminalID *string `json:"terminalId"`
|
||||
PeriodID *string `json:"periodId,omitempty"`
|
||||
}
|
||||
|
||||
type PeriodScope struct {
|
||||
PeriodID string
|
||||
PeriodType string
|
||||
StartAt time.Time
|
||||
EndAt time.Time
|
||||
JalaliLabelFA string
|
||||
}
|
||||
|
||||
type RefreshState struct {
|
||||
@@ -95,27 +163,30 @@ type RefreshState struct {
|
||||
}
|
||||
|
||||
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"`
|
||||
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"`
|
||||
SectionRefresh map[Section]RefreshState `json:"sectionRefreshState"`
|
||||
GeneratedAt time.Time `json:"generatedAt"`
|
||||
}
|
||||
|
||||
type Job struct {
|
||||
JobID string `json:"jobId"`
|
||||
SnapshotID string `json:"snapshotId"`
|
||||
Module Module `json:"module"`
|
||||
Section Section `json:"sectionId"`
|
||||
State string `json:"state"`
|
||||
EventsURL string `json:"eventsUrl"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
@@ -133,6 +204,7 @@ type CreateRequest struct {
|
||||
MerchantID int64
|
||||
TerminalID string
|
||||
Module Module
|
||||
Section Section
|
||||
TriggerReason string
|
||||
ManualRefresh bool
|
||||
IdempotencyKey string
|
||||
@@ -142,4 +214,23 @@ type CreateRequest struct {
|
||||
Confidence Confidence
|
||||
CatalogVersion string
|
||||
Evidence json.RawMessage
|
||||
Period PeriodScope
|
||||
}
|
||||
|
||||
type ProviderUsage struct {
|
||||
InputTokens int64
|
||||
OutputTokens int64
|
||||
ProviderRequests int64
|
||||
LatencyMS int64
|
||||
ProviderRequestID string
|
||||
EstimatedCost string
|
||||
}
|
||||
|
||||
type Completion struct {
|
||||
Analysis Analysis
|
||||
AICopy *Copy
|
||||
Status string
|
||||
FailureCode string
|
||||
Model string
|
||||
Usage ProviderUsage
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user