Skip to content

ADR-0002: Matched-rule provenance

  • Status: Accepted
  • Date: 2026-08-11
  • Deciders: maintainers
  • Related: ADR-0004

Context

Transactions come from a specific parse rule. Knowing which rule matched is useful for debugging parse quality, auditing, and future per-rule stats.

Decision

TransactionEntity.ruleId is a real foreign key to rules(id), populated from the matched rule's DB id via ParserRule.dbId.

  • Static rules (BankRuleSets) carry dbId = null; once seeded into the DB and loaded back, RuleEntity.toParserRule() sets dbId = id.
  • The FK is ON DELETE SET NULL — deleting a rule nulls the link instead of destroying history.
  • Embedded-JSON candidates have no rule → ruleId = null.

Consequences

  • Provenance is a first-class column, queryable and joinable.
  • Rule edits (pattern change) do not rewrite historical transactions' links — provenance points at the rule version that produced the row.
  • The rules table must exist before transactions insert; seeding happens at app start (RuleRepository.seedDefaults).

Alternatives considered

  • Storing the rule id/label as free text on the transaction — rejected: no referential integrity, duplicates labels, joins harder.