ADR-0002. DiscriminationType as authoritative tax classification (dual-write taxTypeId)
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2026-04-15 |
| Deciders | taxation-team |
| Supersedes | — |
Context
- The system has a generic
DiscriminationTypeclassifier (scopes for inventory, finance, license, andtax_classification). - The legacy
TaxTypeentity in thepricingschema also classified taxes (000_VAT,400_PIT, ...), duplicating that concept. TaxGroupItemandTaxneed one classification source; existing pricing/calculation code still readsTax.taxTypeId.- We want a single, scope-partitioned catalogue without breaking pricing immediately.
Decision
TaxGroupItem.discriminationTypeId and Tax.discriminationTypeId (both notNull) are the authoritative tax classification. During provisioning we dual-write: each Tax keeps the new discriminationTypeId and the legacy taxTypeId (nullable) so existing pricing reads continue to work. Discrimination types under scope tax_classification are seeded by taxation-0001-seed-discrimination-types.ts.
Consequences
| Pros | Cons |
|---|---|
| Single classifier catalogue across domains | Two columns to keep aligned during the transition |
Tax.taxTypeId stays nullable — no hard break for pricing | Reconciliation logic needed to map DiscriminationType → TaxType |
| New tax classes added via discrimination seeds, not schema | TaxType table lingers until pricing migrates fully |
Alternatives Considered
| Option | Pros | Cons | Why rejected |
|---|---|---|---|
Keep TaxType only | No migration | Duplicate classifier concept; no cross-domain reuse | Diverges from DiscriminationType strategy |
Drop taxTypeId immediately | Clean schema | Breaks pricing reads in-flight | Too risky without coordinated pricing change |
| Separate tax-only classifier table | Focused | Yet another classifier; same duplication problem | Reuse beats new table |
References
packages/core/src/models/schemas/tax/tax-group-item/schema.ts(discriminationTypeId)packages/core/src/models/schemas/pricing/tax/schema.ts(taxTypeIdnullable +discriminationTypeId)packages/core/src/models/schemas/public/discrimination-type/constants.ts:DiscriminationTypeScopes.TAX_CLASSIFICATIONpackages/taxation/src/services/tax-provisioning.service.ts(dual-write loop)packages/taxation/src/migrations/processes/taxation-0001-seed-discrimination-types.ts