Three operational aggregates — Contract Management, Chain of Custody, Case Workflow — sitting over a two-layer substrate of durable Person identity and operational Case state.
Make the three-capability mental model that we already use in pitches and PRDs architecturally explicit, and introduce a Person identity layer beneath the case so that pre-need contracts — newly in MVP scope — have a place to live.
Person identity exists before any case. Case substrate is built on top at need-time. Three aggregates operate over this substrate, each owning its own tables. Scheduling sits beside them as a shared service.
Identity lives at the base; case state sits above it. Workflow, contracts, and custody all read and write through these layers but never own them.
The base layer. People exist before any case — pre-need clients, repeat-customer families, multi-generational relationships. The substrate is the only writer of identity facts; all aggregates that need to update a Person call substrate services. Identity verification follows a supersession pattern (corrections do not overwrite history).
Materialized when a death occurs (or a first-call is received). The umbrella record for one active case: who is the deceased, which family members are involved, which branch, which jurisdiction, what status. Case-scoped facts about the deceased (time, place, cause of death) live here — not on the Person record.
Each owns a distinct source of authority. Cross-aggregate writes go through service interfaces; the database does not enforce this, code review does.
Sole writer of pricing catalogs, contracts, line items, amendments, signed documents. Pre-need contracts reference a Person directly; at-need contracts reference a Case. At-need conversion is internal to this aggregate — not a cross-aggregate handoff.
The aggregate with the strongest regulatory and legal-discovery requirements. Custody events are immutable, append-only, with supersession for corrections. CoC scan modules in Workflow trigger writes through a service interface — never direct inserts. Asset terminal-state checks block case closure.
The largest aggregate by table count and the most active at runtime. Owns module execution state and the context envelope. Reads extensively from substrate, contract, and CoC — writes back only through service interfaces. The module engine produces activity-event and services-rendered writes automatically on module completion.
Scheduling is a service, not an aggregate. It owns calendars, resources, and availability — written to by Workflow (most often), Contract Management (arrangement conferences), and CoC (transport). Scheduled events show up on cases as Layer 3 activity events when relevant.
A scope discovery on 2026-05-12 added pre-arrangement contracts to MVP. Pre-need agreements predate any case — they reference a living person, with locked-in pricing that activates at need-time. Without a Person identity layer, the data model traps deceased records inside cases and cannot represent a future-deceased who has no case yet.
The regulatory grouping (FTC Funeral Rule, BC's Cremation, Interment and Funeral Services Act) treats pre-need and at-need as a single contractual continuum. Pricing structure, GPL catalogs, packages, and amendment patterns are the same.
What differs is the relationship target: pre-need points at a Person, at-need points at a Case. Same aggregate, different reference.
In MVP: pre-need agreement structure, line items, locked-in pricing. Out of MVP: trust accounting, payment schedules, escrow tracking.
Code-organization and review rules, not database constraints. They prevent the aggregate boundaries from drifting as the system grows and turn ambiguous design questions into decided ones.
Each aggregate is the only writer of its tables. Cross-aggregate writes happen through published service interfaces.
Person fields (name, DOB, identity_verified) are updated only by substrate services. Identity verification supersession is enforced here.
At-need conversion of a pre-need contract is a Contract Management operation. The trigger is a substrate event Contracts subscribes to.
Neither aggregate has a pre-need analog. A pre-need Person has no custody history and no workflow execution. Structural fact, not a constraint.
services_rendered (Workflow) is read by Contract Management during reconciliation. The most prominent cross-aggregate read; result lands as a contract amendment.
Multiple aggregates write scheduled events through the scheduling service. The service enforces resource availability; aggregates trust it.