docs: adopt lazy analytics caching

This commit is contained in:
2026-08-20 16:17:27 +03:30
parent 7c8afeaa4b
commit 680596fe73
10 changed files with 80 additions and 45 deletions

View File

@@ -49,7 +49,7 @@ Synthetic profile fields carry an explicit `profile_is_synthetic` marker. Creden
`adjusted_fee` uses fixed precision and is labeled as an obfuscated relative value. The physical precision is finalized from exact decimal profiling before migration approval.
Both fact tables distinguish `bootstrap` from `zarinpal_live` origin. Bootstrap rows reference an import run; live rows do not invent one. Live creation/update metadata forms the incremental analytics watermark contract, including status changes to an existing session.
Both fact tables distinguish `bootstrap` from `zarinpal_live` origin. Bootstrap rows reference an import run; live rows do not invent one. Payment facts are append-only for the MVP; inserts advance database-managed analytics revisions.
### Rebuildable analytics projections
@@ -59,10 +59,12 @@ Both fact tables distinguish `bootstrap` from `zarinpal_live` origin. Bootstrap
| `merchant_day_*_breakdowns` | merchant + date + approved dimension | Only metric-catalogue breakdowns proven useful, such as PSP/failure groups |
| `merchant_period_*` | merchant + approved day/week/month/season period | Non-additive or measured expensive metrics only |
| `cohort_period_*` | approved cohort + period | Suppressed peer benchmark inputs/outputs with provenance and freshness |
| `merchant_analytics_state` | one row per merchant | current source revision, cached revision, metric-definition version, calculation status/time |
| `cohort_analytics_state` | one row per benchmark cohort/category | current source revision and cached revision for peer projections |
Projection names/columns are finalized by the analytics metric catalogue. Avoid a generic key/value metrics table because it weakens types, constraints, and discoverability.
Projection metadata records source watermark, calculation version, calculated time, and status. An incremental refresh runs at least every 15 minutes; a nightly reconciliation checks/rebuilds an authoritative window and advances freshness only after successful atomic publication.
Projection rows record merchant/cohort source revision, metric-definition version, calculated time, and publication status. Inserts atomically increment the affected revision through schema-owned database logic so direct upstream writes cannot bypass invalidation. A dashboard cache miss or revision mismatch acquires a PostgreSQL advisory/row lock, builds typed projections, and advances the cached revision only after atomic publication. No generic JSON metric cache, Redis, scheduled refresh, or time-to-live expiry is required.
## Initial index policy
@@ -77,9 +79,10 @@ Projection metadata records source watermark, calculation version, calculated ti
- Payment/import provenance uses restrictive foreign keys; no cascading deletion of analytical facts from merchant/profile operations.
- Imported source facts are immutable after a completed import. Corrections create a new versioned recovery/import decision.
- Production payment facts are append-only in the MVP. Update/delete semantics require a future ADR and corresponding cache-invalidation rules.
- Synthetic display profiles and credentials can change independently from source facts.
- Derived projections may be rebuilt and atomically replaced; freshness/provenance prevents stale data from appearing current.
- Derived projections may be rebuilt and atomically replaced; source and metric-definition revisions prevent stale data from appearing current.
## Production population boundary
After the one-time CSV bootstrap, ZarinPal—not this project—writes future production payment records directly to the normalized PostgreSQL session/attempt tables. This project owns the schema/migration and analytics contract but not ZarinPal's write workflow. Compatibility, required fields, source origin, and creation/update watermarks are versioned interfaces; recurring CSV ETL is prohibited.
After the one-time CSV bootstrap, ZarinPal—not this project—writes future production payment records directly to the normalized PostgreSQL session/attempt tables. This project owns the schema/migration, insert-triggered analytics-revision, and read contract but not ZarinPal's write workflow. Compatibility, required fields, source origin, and append-only insertion semantics are versioned interfaces; recurring CSV ETL is prohibited.