D-09
Transportation
An outbound transport pattern over shipment and leg commitments, versioned promised arrival dates, milestone events carrying both event time and capture time, and freight charge components with their currency, valuation basis and recognition date — with the current operating picture and the historical cohort kept on separate controls.
There is a reference build of this pattern: the Transportation dashboard in the showcase renders it over frozen, simulated data — not a live client system.
See the working synthetic reference build. The OTIF & service pattern answers the customer-facing side of the same question at order-line grain; this one sits at shipment and leg grain and adds carrier, mode and freight. Neither replaces the other, and this pattern claims no ERP source mapping until a named product, version and extraction path have been verified.
What it answers
Two people read this pattern. A transport planner asks which shipments are open right now, which are already past the date promised, and which have arrived but are not yet confirmed. A logistics manager asks how each carrier and lane performed against the promise as it was originally frozen, how long the movements actually took, and what the freight cost on a stated basis.
Those are different questions about different populations, so they get different time controls. The planner’s view is pinned to a business as-of date with its own knowledge cutoff; the manager’s view is pinned to an authored cohort of committed arrival dates. Neither control moves the other, and both stay in the URL.
The distinction that decides whether the numbers are trustworthy is between shipped, departed, arrived and delivery-confirmed. Only a declared delivery confirmation closes a shipment. A current ETA is a prediction; it is published beside the frozen promise and never substituted for a delivery.
The wireframe
Transportation dashboard with separate as-of, due-window and cohort controls, four measures, an exception worklist, a pooled transit distribution and freight by mode
Layout basis
- L-04 Tabbed Views — keeps the planner's open exception queue and the manager's historical cohort review on separate time controls rather than one shared filter
- L-03 Master-Detail / Drill-Down — keeps each open shipment's legs, promise revisions and last known milestone attached to the row that raised the exception
- Control row — the as-of date and the knowledge cutoff are two pins, not one; the due window belongs to the current picture and the cohort to the historical one.
- Measure row — open work and completed work never share a tile; each rate carries its own numerator and denominator.
- Worklist — original and current promise sit side by side, so a shipment that is late only because the promise moved is visible as exactly that.
- Distribution — raw durations pool at the displayed scope; open shipments are counted as censored rather than imputed or dropped.
- Freight — the charge basis and currency are on the face of every figure, and a charge that belongs to no single leg keeps its own bucket.
The transport model
The milestone fact is an accumulating line: one row per observed event, carrying the instant it happened AND the instant it was captured. Those two columns are what let the same shipment read as open at one as-of date and as an on-time delivery at a later one, with no restatement of history.
Commitments are versioned rather than updated. Revision 1 is the frozen original promise; later revisions are appended with their own capture instant, so “the promise as it was known then” has exactly one answer at any cutoff. Carrier, mode and equipment capacity live at leg grain, which is why utilisation is a leg measure while freight per shipment is not. Order allocations are the bridge that lets one order split across shipments and many orders consolidate onto one without duplicating either the order or its units.
Grain one milestone event of one shipment, optionally attributed to one leg
Stored components
- event_type
- occurred_at
- captured_at
- source_system
- corrects_event_id
- shipment_id
- leg_id
Foreign keys
- → dim_shipment
- → dim_shipment_leg
- → dim_arrival_commitment
- → dim_carrier
- → dim_lane
- → dim_transport_mode
- → dim_order_allocation
- → dim_freight_charge
- shipment_id
- lane_id
- shipment_type
- gross_weight
- tender_date
- expected_leg_count
- expected_allocation_count
One commercial movement. Consolidation is expressed by several order allocations pointing at one shipment, never by duplicating the shipment. The expected counts are declared with the shipment row, which is what makes a partly captured route or payload detectable without reading the rows a cutoff cannot yet see.
- revision_number
- commitment_basis
- committed_arrival_date
- change_reason
- captured_at
Revision 1 is the frozen original promise. Later revisions are appended, so the original is always retrievable and a current ETA never overwrites it.
- lane_id
- origin_facility
- destination_facility
Origin-to-destination corridor; a lane whose endpoints change is a new identity.
- business_as_of
- knowledge_cutoff_at
The business as-of date and the knowledge cutoff are separate pins; a delivery that has happened but not been captured leaves the shipment open. Supporting facts are captured on their own clocks, so a known shipment may be missing its route, its frozen promise or its allocations — reported as outstanding evidence rather than removed from the population.
- charge_type
- valuation_basis
- document_type
- currency_code
- recognized_on
- leg_id
A charge that cannot be attributed to one leg keeps a null leg reference and its own bucket, so no mode total is manufactured.
- leg_id
- leg_sequence
- origin_facility
- destination_facility
- carrier_id
- mode_id
- capacity_weight
Carrier, mode and equipment capacity live at leg grain, which is why utilisation is a leg measure and freight per shipment is not. The legs form one ordered, continuous route between the endpoints the lane declares, so no leg can start where the goods never arrived.
- carrier_id
- carrier_label
- carrier_arrangement
Reviewed on the carrier of the delivering leg, which the view states rather than assumes.
- mode_id
- capacity_basis
Capacity basis is declared, so a weight utilisation and a volume utilisation can never be mixed into one figure.
- order_id
- shipment_id
- allocated_quantity
The bridge that lets one order split across shipments and many orders consolidate onto one, without duplicating an order or its units.
Measures and states
| Measure | Formula | Additivity | Note |
|---|---|---|---|
| On-time delivery vs original commitment | count(confirmed deliveries on or before revision-1 committed arrival) / count(confirmed deliveries) | Non-additive | Requires a declared delivery-confirmation event and a frozen commitment. A current ETA is a prediction and is never substituted; an open shipment is censored, not counted as a miss or a success. |
| Confirmed-delivery coverage | count(confirmed deliveries) / count(eligible cohort shipments) | Non-additive | Publishes how much of the cohort has an outcome at all. Cancelled shipments leave the denominator; open shipments stay in it as censored. |
| Transit duration percentile | PERCENTILE_CONT(p) over pooled ship-confirm-to-delivery durations | Non-additive | Pools raw observations at the displayed scope; never averages group percentiles. Open shipments contribute no duration and are disclosed as censored. |
| Invoiced freight | sum(signed charge amount where valuation basis = invoiced and currency = selected) | Additive | Exact minor-unit components including credits. Accruals are a separate population; amounts in different currencies are never added and no rate is applied. |
| Freight per shipment / per unit mass | invoiced total / count(shipments carrying an eligible charge); invoiced total / sum(captured gross weight of those shipments) | Non-additive | Each denominator is an explicitly eligible population. A shipment with no captured weight leaves both components of the mass rate and is counted as excluded. |
| Weight utilisation | sum(mass moved on eligible legs) / sum(declared capacity of those legs) | Non-additive | Leg grain: a multi-leg shipment's mass counts once per leg it moved on. Legs with no declared capacity are excluded — utilisation is never inferred from shipment weight alone. |
Every rate here is a ratio of sums over an explicitly eligible population, and both sums travel with it. A zero denominator is unavailable, not zero: a lane with one confirmed delivery that missed reads 0.0%, and a lane with no confirmed delivery at all reads as unavailable. Those are different answers.
Service and cost are published side by side and never blended. A composite rank would need a weighting nobody has authored, and it would hide the carrier that is cheapest and least reliable behind a mid-table score. Environmental measures are out of scope for this pattern: an emissions figure needs activity data, emission factors, a declared boundary and provenance for each, and stating a mode is not a substitute for any of them.
Implementation notes
- Keep shipped, departed, arrived and delivery-confirmed as four distinct event types, and declare the grain each is recorded at. A departure and an arrival happen to one leg and must name it; a ship confirm, a delivery confirmation and a cancellation are about the whole consignment and must not. A shipment-grain departure reports a shipment in transit while every one of its legs still reads as never departed.
- Declare how many EFFECTIVE rows of each type the profile models, and reject the extras rather than reading only the earliest. One departure and one arrival per leg, one ship confirm and one delivery confirmation per shipment; only a logged exception, which carries no state, repeats. A second uncorrected departure recorded after its own leg has arrived is a contradiction in the history, and a validator that inspects only the first row of a type will accept it and then quietly disagree with itself. Restate a milestone with a correction; model a genuine re-departure as another leg.
- Order the lifecycle explicitly. A cancellation stops a movement that has not been delivered; a row cancelling an already-confirmed delivery is a post-delivery reversal and belongs to a return profile, so refuse it rather than letting a delivered shipment lose its outcome. When a cancellation is legitimate, say whether it landed before or after the ship confirm — only the first leaves the allocated quantity unshipped.
- Require the legs to form one ordered, continuous route between the endpoints the lane declares, and reject a leg that starts and ends in the same place. Every duration and utilisation figure is built on that route.
- Declare which supporting facts every shipment must eventually carry, and treat their capture as a separate question. Two of them are POPULATIONS — every leg of the route, every order allocation — so declare how many of each to expect ON the shipment row, where the expectation is captured at the same instant as the shipment itself. Asking whether at least one row arrived cannot tell one leg of two from one leg of one; only a captured count reaching a declared count establishes completeness, and an expectation that was never declared stays unknown however many rows exist. Validate the whole published dataset against those declarations, so the counts can be trusted at a cutoff where the rows are not yet visible.
- A shipment whose supporting rows have not all landed keeps its identity and reports what is outstanding as captured-of-declared; deleting it shrinks every denominator without saying so. Never infer a missing fact from a row the cutoff cannot see. Which leg is FINAL is a property of the whole route, so a part-captured route supplies neither a delivering carrier nor a final arrival — otherwise an arrival at an intermediate cross-dock reads as the shipment having arrived, and the last visible leg names the wrong carrier. Unassignable shipments get their own disclosed bucket, and under a named carrier the figures are stated as a lower bound.
- A partly captured payload yields a real but partial order count and quantity. Publish them as lower bounds with their coverage beside them — never as an exact total, and never as a zero.
- Keep static reference dimensions apart from captured transaction facts. Only the latter carry a capture instant, and only they can be partially captured; a carrier or a lane is the same at every cutoff and is never missing evidence.
- Store both event time and capture time on every milestone, and compare them as instants including offset — never as text. Pin the business as-of date and the knowledge cutoff separately.
- Append commitment revisions; never update in place. Reject a shipment with two rows at the same revision number, or with revisions whose capture instants do not strictly increase.
- Model order-to-shipment allocation as its own bridge, and reject an allocation total above the ordered quantity. A split may not create quantity, and a consolidation may not count an order twice.
- Hold money and mass as exact decimal components at a declared scale and format text surfaces from the decimal string rather than converting. Converting a quantity through a floating-point number alters identities above roughly nine quadrillion minor units. Where a surface genuinely needs a number — a chart geometry — check the conversion and give it an explicit unplottable state instead of a rounded length. Never add two currencies, and never add an invoiced amount to an accrual.
- Publish an absent measurement and a measured zero differently, on every surface at once. No observed charge row is unavailable; signed rows that genuinely cancel out are a measured zero. A tile calling a figure unavailable while a total row beside it prints 0.00 is the failure this rule exists to prevent.
- Declare the capacity basis on the mode. Utilisation needs a declared capacity on the leg; shipment weight alone does not imply one, and a leg that never departed committed no capacity.
- Keep a charge that belongs to no single leg in its own bucket rather than spreading it across legs, so the mode split still sums exactly to the total.