31 lines
2.7 KiB
Markdown
31 lines
2.7 KiB
Markdown
# ADR 0007: Calendar-aware analytics projections without initial table partitioning
|
|
|
|
- Status: Accepted
|
|
- Date: 2026-08-20
|
|
|
|
## Context
|
|
|
|
The source contains approximately 2.2 million payment-attempt rows, but attempts are only one domain entity. Merchant, terminal, session, attempt, import, identity, and reporting-date concepts require separate normalized relations connected by constraints. The product needs daily, weekly, Jalali-month, and Persian-season analysis.
|
|
|
|
Calculating every dashboard result from normalized attempt rows on every request creates avoidable latency. Conversely, splitting attempts into unrelated tables by month/category or adding PostgreSQL partitions before measuring query and maintenance behavior introduces complexity without evidence. Some metrics are additive across days, while distinct payer-token counts and percentiles are not.
|
|
|
|
## Decision
|
|
|
|
Keep normalized business/source-of-truth relations: categories, merchants, merchant users, terminals, payment sessions, payment attempts, and import provenance. The attempt relation retains one row per source attempt; normalization does not arbitrarily distribute a single entity's rows across category/month tables.
|
|
|
|
Add a reporting-date model containing Gregorian and Jalali date attributes, explicit reporting-week boundaries, Persian months/seasons, and weekdays.
|
|
|
|
Build idempotent, rebuildable analytics-section queries containing additive components such as session count, attempt count, successful count, amount sum, and fee sum as approved by the metric catalogue. Derive week/month/season totals through the reporting-date model and recompute ratios from their numerators and denominators.
|
|
|
|
Calculate non-additive metrics such as exact unique payer-token counts directly at their requested grain; never obtain them by summing daily distinct counts. Cache each typed section in Redis under source/cohort and metric-definition revisions.
|
|
|
|
Keep normalized fact tables unpartitioned initially. Add targeted indexes from approved API access paths and verified query plans. Introduce PostgreSQL partitioning only through a future ADR supported by measured table growth, query latency, vacuum/maintenance behavior, or retention operations.
|
|
|
|
## Consequences
|
|
|
|
- The normalized ERD remains semantically correct while dashboards reuse disposable Redis results.
|
|
- Section calculations support approved period groupings without storing calculated facts as PostgreSQL business truth.
|
|
- Explicit reporting-period definitions and metric provenance make future AI observations traceable.
|
|
- Lazy parallel calculation, Redis revision keys, job deduplication, partial failure, and SSE visibility tests become required behavior.
|
|
- Schema/index/cache details remain subject to data profiling and approved metric/API requirements.
|