Schema Page 36 Generated 2026-05-17 DAMA · Data Modeling & Design
Chain, milestones & contracts 38 leaves 100.0% Declaration 0.0% Evidence 0.0% Derivation 0 in overlays 0 with worked example
The process artefacts of a transaction — its lifecycle state machine, the linked transactions ahead and behind it in a chain, and the contract documents that settle it. Everything here happens at the transaction level, not the property level.
The claim
Chain, milestones, contracts — three sides of the same fact: this transaction is moving through time.
Why this aggregate exists
A property doesn't have a chain; a transaction does. A property doesn't sign contracts; participants in a transaction do. A property persists across many transactions; milestones are scoped to one. Putting process on a separate page keeps the propertyPack pages focused on attributes of the asset, not progress through the sale.
Entity relationships
---
config:
layout: elk
elk:
direction: DOWN
nodePlacementStrategy: BRANDES_KOEPF
mergeEdges: false
---
erDiagram
Transaction ||--o{ Contract : "contracts"
Transaction ||--o| Chain : "chain"
Transaction ||--o| Milestones : "milestones"
Chain ||--o{ OnwardPurchase : "onwardPurchase"
OnwardPurchase ||--o| Address : "address"
Contract ||--o| Contract : "contract"
Contract ||--o{ Signature : "signatures"
Contract ||--o| Template : "template"
Template ||--o{ RequiredSignatorie : "requiredSignatories"
Milestones ||--o| Listed : "listed"
Milestones ||--o| LegalForms : "legalForms"
Milestones ||--o| SoldSubjectToContract : "soldSubjectToContract"
Milestones ||--o| Searches : "searches"
Milestones ||--o| Enquiries : "enquiries"
Milestones ||--o| ExchangeOfContracts : "exchangeOfContracts"
Milestones ||--o| Completion : "completion"
Transaction {
}
Chain {
}
OnwardPurchase {
object externalIds "externalIds"
string sellingAgent "Estate Agent selling the property"
string transactionId "UUID for an onward transaction"
integer uprn "Unique Property Reference Number"
}
Address {
string buildingName "Building name"
string buildingNumber "Building number"
string homeNation "Home nation"
string line_3 "Address 3"
string line1 "Address 1"
string line2 "Address 2"
string postcode "Postcode"
string street "Street"
string subBuilding "Sub building name"
string town "Town"
}
Contract {
object terms "terms"
}
Template {
string name "name"
string url "url"
object externalIds "externalIds"
}
RequiredSignatorie {
boolean requiresAll "requiresAll"
string role "role"
}
Signature {
string name "name"
string signedOn "signedOn"
object externalIds "externalIds"
}
Milestones {
}
Completion {
string completed "completed"
string expected "expected"
string started "started"
}
Enquiries {
string completed "completed"
string started "started"
}
ExchangeOfContracts {
string completed "completed"
string expected "expected"
}
LegalForms {
string completed "completed"
string started "started"
}
Listed {
string completed "completed"
string expected "expected"
}
Searches {
string completed "completed"
string expected "expected"
string started "started"
}
SoldSubjectToContract {
string completed "completed"
}
Physical model — every JSON object owned by this page is a node, every scalar field a row. 17 objects, 38 scalar fields. Generated from the schema walk; click any node to jump to its table. Lifecycle state machine
stateDiagram-v2
[*] --> Listed
Listed --> OfferAccepted: "offer received & accepted"
OfferAccepted --> Searches: "conveyancing starts"
Searches --> Enquiries: "searches returned"
Enquiries --> ContractDrafted: "enquiries resolved"
ContractDrafted --> Exchanged: "contracts exchanged"
Exchanged --> Completed: "completion day"
Completed --> [*]
OfferAccepted --> Withdrawn: "fall-through"
Searches --> Withdrawn
Enquiries --> Withdrawn
Withdrawn --> [*]
Milestone state machine, implicit in the schema today. Valid
transitions are documented here in prose but not enforced by SHACL
— the schema permits a Completed milestone before an Exchanged one,
which is a real defect this diagram makes visible. Timeline
gantt
title Typical UK residential transaction timeline (12 weeks)
dateFormat YYYY-MM-DD
axisFormat %b %d
section Listing
Listed :done, a1, 2026-01-06, 14d
section Offer & memo
Offer accepted :active, a2, 2026-01-20, 5d
Memorandum of sale : a3, after a2, 3d
section Conveyancing
Searches ordered : a4, after a3, 21d
Mortgage offer : a5, after a3, 28d
Enquiries raised & answered : a6, after a4, 14d
section Contract
Contract drafted : a7, after a6, 7d
Exchange :crit, a8, after a7, 1d
Completion :crit, a9, after a8, 14d
Indicative timeline. The schema records dates per milestone
(`expected` vs `actual`) but does not encode dependencies. This
Gantt shows the typical 12-week shape — exchange and completion
are the critical path. Chain No scalar fields on this object — pure container.
No scalar fields on this object — pure container.
Title Description Type Kind Field Required Overlays Affordance externalIds — object Declaration externalIds — — — Estate Agent selling the property Estate Agent selling the property string Declaration sellingAgent — — — UUID for an onward transaction — string Declaration transactionId — — — Unique Property Reference Number — integer Declaration uprn — — —
Title Description Type Kind Field Required Overlays Affordance Building name — string Declaration buildingName — — — Building number — string Declaration buildingNumber — — — Home nation — string Declaration homeNation — — — Address 3 — string Declaration line 3 — — — Address 1 — string Declaration line1 — — — Address 2 — string Declaration line2 — — — Postcode — string Declaration postcode — — — Street — string Declaration street — — — Sub building name — string Declaration subBuilding — — — Town — string Declaration town — — —
Milestones No scalar fields on this object — pure container.
Title Description Type Kind Field Required Overlays Affordance completed — string Declaration completed — — — expected — string Declaration expected — — — started — string Declaration started — — —
Title Description Type Kind Field Required Overlays Affordance completed — string Declaration completed — — — started — string Declaration started — — —
Title Description Type Kind Field Required Overlays Affordance completed — string Declaration completed — — — expected — string Declaration expected — — —
Title Description Type Kind Field Required Overlays Affordance completed Actual date of first public listing for sale string Declaration completed — — — expected Planned date of listing, for example when scheduled in advance around e.g. Boxing Day activity string Declaration expected — — —
Title Description Type Kind Field Required Overlays Affordance completed — string Declaration completed — — — expected — string Declaration expected — — — started The date the legal form were shared with the vendor for completion string Declaration started — — —
Title Description Type Kind Field Required Overlays Affordance completed — string Declaration completed — — —
Contracts No scalar fields on this object — pure container.
Title Description Type Kind Field Required Overlays Affordance terms Data group capturing term information. object Declaration terms* yes — —
Title Description Type Kind Field Required Overlays Affordance name — string Declaration name* yes — — signedOn Date and time of signature in ISO 8601 format string Declaration signedOn* yes — — externalIds — object Declaration externalIds — — —
Title Description Type Kind Field Required Overlays Affordance name — string Declaration name* yes — — url A Uniform Resource Locator is the unique web address of a resource on the internet, such as an API, webpage, image, or file. It tells your web browser how and where to access that resource, functioning like a street address for the web. Link to application on council planning portal string Declaration url* yes — — externalIds — object Declaration externalIds — — —
Title Description Type Kind Field Required Overlays Affordance requiresAll Boolean flag: require all. boolean Declaration requiresAll — — — role — string Declaration role — — —
Gap notes
Milestone ordering is implicit in the schema (listed → offerAccepted → exchange → completion) but isn't expressed as a state machine. A future revision should encode valid transitions explicitly — today, a completion milestone can appear before an exchange milestone without schema-level objection.
Comments