Skip to content
Ritesh FirodiyaGet in touch

Work / Chitragupt / Wiki / Decisions

2026-07-12-per-txn-ay-bucketing-for-expense-ledger

Decisioncanonicalverified 2026-07-12

DECISION.2026-07-12.PER-TXN-AY-BUCKETING-FOR-EXPENSE-LEDGER

Decision

Ledger entries derive ay from their per-transaction date (txn_date), not from the enclosing document's ctx.ay. Envelope rows without a transaction date (Form 16, 26AS, AIS) keep ctx.ay.

Why

The recompute audit surfaced a silent data-corruption bug: a bank statement spanning February–May 2026 filed every row under one AY. The March rows should sit in AY 2026-27; the April/May rows in AY 2027-28. Both the expense pillar (per-AY KPI hero) and the tax pillar (Chapter VI-A caps, HRA, §80D) read where("ay","==",args.ay) — so half the user's transactions silently vanished from whichever AY the mapper picked for the document.

The pre-fix behaviour was equivalent to trusting whoever named the statement (e.g. "January to December 2026 statement") over the statute. Indian FY runs 1 Apr → 31 Mar, so any statement whose window crosses Mar/Apr is at risk; the frequency of long-span statements makes this common.

Impact

  • _lib.ts::makeEntry calls deriveAyFromDate(txnDate) and uses the derived AY on the ledger row. ctx.ay remains the fallback for envelope rows (no txnDate).
  • Bank-statement mapper is the primary beneficiary; MF CAS SIP rows and broker trade logs follow the same path when they carry txnDate.
  • Tests updated: expense-pipeline.test.ts now expects the correct statute-derived AY (12 May 2026 → AY 2027-28) instead of the document's ctx.ay.
  • Downstream engines (pillar-expense, pillar-tax, pillar-portfolio) automatically pick up the correct AY because their queries filter where("ay","==",args.ay) — no engine change required.

Status

Active. Landed as part of the Phase 3 recompute-correctness sweep.

Sources

  • Phase 3 recompute-correctness commit (Phase 3 sweep).
  • apps/functions/src/triggers/firestore/ledger-mappers/_lib.ts::makeEntry.
  • Related concept: user-identity-entry.

Every project of mine is written down like this.

Read the résumé