Define the terms used in the process
The word customer may describe a legal buyer, a billing account, a user, or an organization under contract. These concepts overlap but are not interchangeable. Begin with a vocabulary workshop around actual decisions and source records. Capture each term, its owner, its lifecycle, and the questions it can answer.
Choose one process, such as invoice approval, and model the concepts it uses. Expand the glossary as other domains are added. If teams use customer to mean different things, preserve those definitions instead of combining them in an object full of optional fields.
Preserve identity and the grain of a record
State what one record represents. An invoice header is different from an invoice line, a payment allocation, and an approval decision. Joins between those grains can repeat values, so make the cardinality explicit and aggregate at the intended grain. A stable identifier should survive a display name change and distinguish records from different source namespaces.
Use source identifiers as provenance and establish a separate canonical identity only when its matching rules are understood. For invoice inv_1042, keep the originating system and local key alongside the canonical reference. A merger or correction should leave an inspectable history instead of rewriting every trace of the original record.
| Concept | Identity | Business meaning |
|---|---|---|
| Invoice | Source namespace plus invoice key | A request for payment |
| Invoice line | Parent invoice identity plus stable line key | A billed item or charge |
| Approval | Decision identifier | An authorized assessment of a specific version |
Joining invoice headers and lines
The header amount repeats for each joined line.
At invoice grain
| Invoice | Header amount |
|---|---|
| inv_1042 | 12,400 GBP |
12,400 GBP belongs to one invoice. At this grain, the header total appears once.
After joining the line records
| Invoice | Line | Header amount | Line amount |
|---|---|---|---|
| inv_1042 | line_01 | 12,400 GBP | 9,800 GBP |
| inv_1042 | line_02 | 12,400 GBP | 2,600 GBP |
Duplicates the invoice value.
Preserves the invoice value.
Sum the line amounts, or aggregate the lines to invoice grain before joining to the header.
Model state and time explicitly
A status field is useful only when its transitions and ownership are defined. Specify whether an invoice can move from approved back to review, who permits that transition, and what happens to an action already queued. Distinguish a recorded state change from an inferred business condition.
Record event time and observation time when delayed information matters. A supplier may have been suspended yesterday while the integration learned about it this morning. Keeping both times allows an investigation to reconstruct what was true and what the decision maker could reasonably have known at the time.
Test the model against business cases
Use representative examples including partial invoices, reopened contracts, duplicate supplier names, and cancelled approvals. Ask domain specialists to explain the expected result before encoding transformation rules. This exposes ambiguous assumptions earlier than a large schema review and provides useful acceptance cases for later testing.
Assign an owner to each definition and a review process for semantic changes. Record terms using stable concept identifiers and useful labels. Standards such as SKOS can express labels and broader relationships, but adopting a vocabulary format does not replace agreement about the business meaning or accountability for its maintenance.