fix: keep growth analysis available per terminal
This commit is contained in:
@@ -13,7 +13,7 @@ Give an authenticated merchant a trustworthy 90-day Persian growth outlook: hist
|
||||
|
||||
- Aggregate session count and paid Rial amount by Tehran-local day for the authenticated merchant and optional owned terminal. `Paid` and `Verified` are successful; money remains integer Rial at session grain.
|
||||
- Forecast begins the day after the latest complete imported dataset date and covers 90 days. Count and amount are modeled independently from weekday-aware rolling baselines, bounded trend adjustment, catalogued event uplift, and empirical residual P10/P50/P90 values.
|
||||
- Rolling-origin backtests classify usable output as `HIGH` or `MEDIUM`; other results return `INSUFFICIENT_DATA` and do not call AvalAI.
|
||||
- Rolling-origin backtests classify output as `HIGH`, `MEDIUM`, or `LOW`. Limited-history and poorly validated forecasts remain visible as `LOW` with wider uncertainty; only a scope with no historical observations returns `INSUFFICIENT_DATA`.
|
||||
- Historical event effect compares matching weekdays from the preceding eight non-event weeks. At least four observations and 100 baseline sessions are required. A material win/decline is at least 20%.
|
||||
- Upcoming similarity prefers an exact event family, then catalog tag similarity of at least 0.60. Return at most five opportunities and three risks. A risk requires a forecast at least 20% below a baseline with at least 100 sessions.
|
||||
- Merchant scope may include peer context only under the existing threshold of 10 other same-category merchants and 1,000 combined peer sessions, with one equally weighted value per merchant. Terminal scope always suppresses peers.
|
||||
@@ -25,7 +25,7 @@ Give an authenticated merchant a trustworthy 90-day Persian growth outlook: hist
|
||||
- The consumer-owned `GrowthAnalyticsTools` boundary exposes only `get_growth_context`, `get_event_evidence`, `get_peer_context`, and `get_campaign_playbook`. Scope is injected from the authenticated job, not accepted from model arguments.
|
||||
- Use `POST /v1/responses`, `store:false`, strict function schemas, strict structured output, `parallel_tool_calls:false`, no more than four tool calls and two model turns, 1,600 output tokens, a 30-second deadline, and one transient retry.
|
||||
- Treat model output as untrusted. Accept only known evidence ids and qualitative Persian fields. Reject numeric claims, unsafe language, unknown references, refusal/incomplete output, or schema drift and use deterministic Persian fallback copy.
|
||||
- Skip AvalAI when no material opportunity/risk exists or confidence is insufficient. AI failure produces `PARTIAL`, never an empty report.
|
||||
- Skip AvalAI when no material opportunity/risk exists or there are no historical observations. Low-confidence evidence may be interpreted, but the response must preserve its limitation. AI failure produces `PARTIAL`, never an empty report.
|
||||
|
||||
## Persistence, caching, jobs, and limits
|
||||
|
||||
@@ -33,7 +33,7 @@ Give an authenticated merchant a trustworthy 90-day Persian growth outlook: hist
|
||||
- A fingerprint includes merchant/terminal scope, import watermark, forecast date/horizon, catalog, analytics, prompt/schema, and model versions. A matching successful report is reused without an AI call.
|
||||
- Keep the current matching report indefinitely and superseded/manual-refresh revisions for 90 days. Concurrent identical requests collapse to one job.
|
||||
- States are `QUEUED`, `ANALYZING`, `GENERATING`, `READY`, `PARTIAL`, and `FAILED`. Preserve the previous successful report during refresh/failure.
|
||||
- Defaults: create 10/user/minute; five uncached scopes/merchant/Tehran day; one merchant-wide manual refresh/Tehran day; four concurrent generations globally; explicit production daily request/token budgets; one active generation per fingerprint.
|
||||
- Defaults: create 10/user/minute; five uncached scopes/merchant/Tehran day; four concurrent generations globally; explicit production daily request/token budgets; one active generation per fingerprint. Manual retries remain available for a scope until it has a persisted `READY` AI summary; after that, one manual refresh per terminal scope is available per Tehran day. The all-terminals selection is a separate scope.
|
||||
- Budget exhaustion returns deterministic `PARTIAL` output. Only an unavailable manual refresh returns `429` with `nextRefreshAt`/`Retry-After`.
|
||||
- Structured logs include safe report/version/status/cache/usage/latency fields without prompts, transaction values, usernames, or sensitive identifiers.
|
||||
|
||||
|
||||
@@ -1010,7 +1010,7 @@ components:
|
||||
terminalId: {type: string, minLength: 1, maxLength: 128}
|
||||
refresh:
|
||||
type: boolean
|
||||
description: When omitted, the request reuses the current matching report.
|
||||
description: When omitted, the request reuses the current matching report. Manual retries remain available until the requested scope has persisted AI copy.
|
||||
GrowthRange:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
@@ -1037,7 +1037,7 @@ components:
|
||||
properties:
|
||||
startDate: {type: string, format: date-time}
|
||||
horizonDays: {type: integer, enum: [90]}
|
||||
confidence: {type: string, enum: [HIGH, MEDIUM, INSUFFICIENT_DATA]}
|
||||
confidence: {type: string, enum: [HIGH, MEDIUM, LOW, INSUFFICIENT_DATA]}
|
||||
suppressionReason: {type: string}
|
||||
points: {type: array, maxItems: 90, items: {$ref: '#/components/schemas/GrowthForecastPoint'}}
|
||||
backtest:
|
||||
@@ -1167,7 +1167,10 @@ components:
|
||||
failureCode: {type: string}
|
||||
cached: {type: boolean}
|
||||
stale: {type: boolean}
|
||||
nextRefreshAt: {type: string, format: date-time}
|
||||
nextRefreshAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Current time while no AI summary exists for the scope; otherwise the next refresh boundary for that terminal scope in the Tehran day. The all-terminals selection is a separate scope.
|
||||
createdAt: {type: string, format: date-time}
|
||||
updatedAt: {type: string, format: date-time}
|
||||
eventsUrl: {type: string, format: uri-reference}
|
||||
|
||||
Reference in New Issue
Block a user