docs: record paid and fee invariants

This commit is contained in:
2026-08-20 16:54:21 +03:30
parent 23d75fc63c
commit fc4b998cf4

View File

@@ -35,7 +35,7 @@ Build sequence: data foundation → identity and analytics → API → dashboard
- Observed volume: 2,213,289 attempts, 2,062,839 sessions, 343 merchants, 348 terminals, 5 categories. - Observed volume: 2,213,289 attempts, 2,062,839 sessions, 343 merchants, 348 terminals, 5 categories.
- Observed period: 2026-01-01 through 2026-07-01. - Observed period: 2026-01-01 through 2026-07-01.
- Nullability is material: response, PSP, issuer/card, verification timing, and settlement fields are incomplete. - Nullability is material: response, PSP, issuer/card, verification timing, and settlement fields are incomplete.
- `adjusted_fee` is obfuscated and supports relative analysis only. - Source `adjusted_fee` is the merchant-fee field for this product and is normalized once per session as a real Rial amount; the challenge source name/value was confidentiality-adjusted.
- Raw CSV/database state is local operational input, not versioned source. - Raw CSV/database state is local operational input, not versioned source.
## Cross-cutting invariants ## Cross-cutting invariants
@@ -48,13 +48,14 @@ Build sequence: data foundation → identity and analytics → API → dashboard
6. AI is post-MVP, receives only minimized/sanitized aggregates, and cannot become the source of record. 6. AI is post-MVP, receives only minimized/sanitized aggregates, and cannot become the source of record.
7. External calls have timeouts and bounded retries; jobs are idempotent and observable. 7. External calls have timeouts and bounded retries; jobs are idempotent and observable.
8. Production changes are reversible and backed by documented health checks and rollback steps. 8. Production changes are reversible and backed by documented health checks and rollback steps.
9. Only `Verified` is a confirmed successful session; `Paid` remains a separately reported state until an approved metric-catalogue revision says otherwise. 9. `Paid` and `Verified` are both successful bank payments; `Paid` still requires merchant verification and `Verified` is finalized. Paid-volume and recovery metrics include both while verification metrics keep them separate.
10. MVP reporting periods are limited to daily, Saturday–Friday weekly, Jalali-month, and Persian-season views with consistent `Asia/Tehran` boundaries across database, API, and frontend. 10. Merchant fees are real Rial amounts stored/summed once per session; repeated attempt rows never multiply a fee.
11. An idempotent start request enqueues overview, payment-performance, fees, and peer-comparison sections for bounded parallel calculation by a separate Go worker; Redis caches each typed section for 30 days under merchant/cohort and metric-definition revisions. 11. MVP reporting periods are limited to daily, Saturday–Friday weekly, Jalali-month, and Persian-season views with consistent `Asia/Tehran` boundaries across database, API, and frontend.
12. A separate authenticated SSE request exposes each section as it becomes ready. Redis and the on-demand worker remain private, and Redis is never a source of truth or backup target. 12. An idempotent start request enqueues overview, payment-performance, fees, and peer-comparison sections for bounded parallel calculation by a separate Go worker; Redis caches each typed section for 30 days under merchant/cohort and metric-definition revisions.
13. Each section attempt is limited to 60 seconds and at most two transient retries with exponential backoff/jitter; deterministic errors fail immediately. 13. A separate authenticated SSE request exposes each section as it becomes ready. Redis and the on-demand worker remain private, and Redis is never a source of truth or backup target.
14. The worker pins pre-1.0 Asynq `v0.26.0`, runs at 16 jobs globally and 4/merchant by default, and changes require reviewed dependency/load evidence. 14. Each section attempt is limited to 60 seconds and at most two transient retries with exponential backoff/jitter; deterministic errors fail immediately.
15. Start, manual-retry, and SSE limits use independent authenticated-user/merchant buckets and return `429` with `Retry-After` before work is queued. SSE heartbeats run every 15 seconds and authorized run-event replay lasts one hour. 15. The worker pins pre-1.0 Asynq `v0.26.0`, runs at 16 jobs globally and 4/merchant by default, and changes require reviewed dependency/load evidence.
16. Start, manual-retry, and SSE limits use independent authenticated-user/merchant buckets and return `429` with `Retry-After` before work is queued. SSE heartbeats run every 15 seconds and authorized run-event replay lasts one hour.
## Required capability specs ## Required capability specs