31 lines
2.8 KiB
Markdown
31 lines
2.8 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 daily base projections 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 by grouping these components through the reporting-date model and recompute ratios from their numerators and denominators.
|
|
|
|
Create separate metric-specific period projections only for non-additive metrics or query paths proven expensive—for example, exact unique payer-token counts cannot be obtained by summing daily distinct counts. Projection rows record source import/version and freshness.
|
|
|
|
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 read smaller, purpose-built projections.
|
|
- Daily components support many calendar groupings without precomputing every possible period.
|
|
- Explicit reporting-period definitions and metric provenance make future AI observations traceable.
|
|
- Projection refresh, failure, stale-state visibility, and reconciliation tests become required operational behavior.
|
|
- Schema/index/projection details remain subject to data profiling and approved metric/API requirements.
|