diff --git a/README.md b/README.md index f49c5a2..10ad8a8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ZarinPal Merchant Analytics — Backend -Go backend for merchant identity, dataset ingestion, deterministic analytics, authenticated APIs, and later AvalAI integration. +Go backend for merchant identity, dataset ingestion, deterministic analytics, authenticated APIs, and the bounded AvalAI-assisted growth analyst. Current state: the local MVP implements database migration, streaming dataset import, secure demo identity, deterministic dashboard analytics, merchant-scoped details/CSV, diff --git a/docs/ANALYTICS-SPEC.md b/docs/ANALYTICS-SPEC.md index 9551972..1380701 100644 --- a/docs/ANALYTICS-SPEC.md +++ b/docs/ANALYTICS-SPEC.md @@ -15,7 +15,7 @@ Turn normalized ZarinPal payment facts into trustworthy, merchant-scoped analyti - Merchant API: requests versioned analytics sections and exposes typed results/events. - Dashboard: renders sections independently as they become ready. - Analytics worker: calculates idempotent section results from PostgreSQL and caches approved aggregates in Redis. -- Future AI adapter: post-MVP consumer of minimized, approved aggregate facts only. +- AI growth analyst: separately approved consumer of minimized, approved aggregate facts only; see ADR 0015 and `GROWTH-ANALYST-SPEC.md`. ## In scope @@ -36,9 +36,11 @@ Turn normalized ZarinPal payment facts into trustworthy, merchant-scoped analyti ## Out of scope for MVP -- Holiday or named-event reporting -- AI-generated recommendations or free-form LLM analysis -- Forecasting, causal claims, or automated campaign execution +The exclusions in this section describe the original four-section analytics MVP. The later, separately approved AI growth analyst adds bounded event analytics and forecasting without changing the canonical MVP period or metric contracts. + +- Holiday or named-event reporting inside the original four analytics sections +- Unbounded or free-form LLM analysis +- Causal claims or automated campaign execution - Arbitrary merchant-created formulas or cross-merchant filters - Real-time streaming payment ingestion owned by this service - Persisting calculated analytics as PostgreSQL business facts @@ -64,7 +66,7 @@ Every section uses a versioned typed contract and has independent `queued`, `cal - Timing percentiles exclude null values and expose sample size and non-null coverage; missing time never becomes zero. - `NoAttempt` markers create zero-attempt sessions and never count as attempts or retries. `InBank` is an observed attempt stage, not proof of rejection. - Every result states the exact Tehran-local half-open period, Jalali label, unit, sample/denominator, dataset snapshot, metric-definition version, and calculation timestamp. -- Approved period types are one Tehran-local day, one Saturday–Friday week, one Jalali month, or one Persian season. Holiday/event dimensions do not exist in the MVP contract. +- Approved interactive reporting-period types remain one Tehran-local day, one Saturday–Friday week, one Jalali month, or one Persian season. The separately versioned growth-event catalog is evidence for growth reports, not a new interactive reporting-period type. ## Peer comparison contract diff --git a/docs/DATA-FOUNDATION-SPEC.md b/docs/DATA-FOUNDATION-SPEC.md index 1d560dc..baa3f2f 100644 --- a/docs/DATA-FOUNDATION-SPEC.md +++ b/docs/DATA-FOUNDATION-SPEC.md @@ -216,7 +216,7 @@ Resolved: use normalized PostgreSQL source-of-truth entities plus a reporting-da Resolved: the MVP reads one immutable completed-import snapshot and performs no payment-fact mutations. An idempotent `POST` starts four sections through Asynq `v0.26.0` (explicitly pre-1.0) in a separate Go worker, limited to 4 concurrent jobs/merchant and 16 globally. Redis caches results for 30 days; authenticated SSE uses 15-second heartbeats and one-hour replay. Sections have a 60-second attempt timeout and two transient exponential-backoff retries. Start, SSE, and manual-retry operations are rate-limited. No PostgreSQL cache-invalidation trigger exists in the MVP. See ADR 0011. -Resolved: holiday and named-event reporting are removed from scope. MVP reporting periods are limited to daily, weekly, Jalali-month, and Persian-season views. See ADR 0010. +Resolved: holiday and named-event reporting were removed from the original analytics MVP, whose interactive reporting periods remain daily, weekly, Jalali-month, and Persian-season views. The later growth analyst adds a separate reviewed event-evidence catalog under ADR 0015 without changing those reporting-period contracts. See ADRs 0010 and 0015. Resolved: reporting weeks follow the Iranian week: Saturday through Friday in `Asia/Tehran`, represented as half-open API/database ranges. See ADR 0012. diff --git a/docs/METRIC-CATALOGUE.md b/docs/METRIC-CATALOGUE.md index 976042f..609ddc0 100644 --- a/docs/METRIC-CATALOGUE.md +++ b/docs/METRIC-CATALOGUE.md @@ -13,7 +13,7 @@ Every merchant-facing number identifies its grain, formula, source fields, filte - Money uses `payment_sessions.amount_rial` and `payment_sessions.fee_amount_rial` exactly once per session. - Terminal filters join the session's `terminal_id`; peer cohorts join the merchant's `category_id` and exclude the active merchant. - The sole completed `import_runs` row identifies the immutable MVP dataset snapshot included in cache/result metadata. -- `calendar_dates` defines Saturday–Friday weeks, Jalali months, and Persian seasons; no holiday dimension exists. +- `calendar_dates` defines Saturday–Friday weeks, Jalali months, and Persian seasons; it intentionally has no holiday dimension. Growth reports use their own reviewed, versioned event-evidence catalog under ADR 0015. ## Bank-paid sessions diff --git a/docs/PHYSICAL-SCHEMA-PROPOSAL.md b/docs/PHYSICAL-SCHEMA-PROPOSAL.md index 0d1caf1..c56a8cd 100644 --- a/docs/PHYSICAL-SCHEMA-PROPOSAL.md +++ b/docs/PHYSICAL-SCHEMA-PROPOSAL.md @@ -98,7 +98,7 @@ Unique `(import_run_id, severity, rule_code)` keeps one aggregate record per rul | `reporting_week_end_exclusive` | `date` required | following Saturday; equals start + 7 days | | `persian_season` | `smallint` required | `1..4` | -Unique `(jalali_year, jalali_month, jalali_day)` prevents duplicate calendar mappings. Indexes on `(jalali_year, jalali_month, gregorian_date)`, `(jalali_year, persian_season, gregorian_date)`, and `(reporting_week_start, gregorian_date)` support approved periods. Holiday/named-event columns do not exist. +Unique `(jalali_year, jalali_month, jalali_day)` prevents duplicate calendar mappings. Indexes on `(jalali_year, jalali_month, gregorian_date)`, `(jalali_year, persian_season, gregorian_date)`, and `(reporting_week_start, gregorian_date)` support approved periods. Holiday/named-event columns do not exist here; the later growth capability owns a separate reviewed event-evidence catalog. ### Merchant and demo identity