Course · ← 0006 Choosing the Stack · capstone
Lesson 0007 · capstone · ~20 minutes
Everything from lessons 0001–0006, collapsed into one schema you could defend in a design review. Do the sketch before you scroll — that is the whole exercise.
A donor-funded project will systematically register roughly 40,000 parcels in three rural districts. Boundaries are traced from 30 cm imagery with community teams. Customary group holdings are common. The register must show current rights, answer historical questions, and survive handover to district staff in year four.
Sketch the tables. Ten minutes, on paper. Then read on.
Not the only right answer — but every deviation from it should be a decision you can name.
-- everything below carries the temporal columns (lesson 0004)
-- begin_lifespan, end_lifespan system time: when we believed it
-- begin_real_world, end_real_world real-world time: when it was true
-- current state = WHERE end_lifespan IS NULL
party -- LA_Party
id, type(natural|group|state), name, id_document, ...
party_member -- LA_PartyMember: who is in a group party
group_party_id, party_id, share
spatial_unit -- LA_SpatialUnit
id, label, geom(geometry, national grid CRS),
capture_method(imagery|gnss|survey|sketch), -- FFP: lesson 0002
accuracy_class,
boundary_type(general|fixed),
predecessor_ids[] -- mutation lineage: lesson 0004
ba_unit -- LA_BAUnit: the seam (lesson 0001)
id, label, type
ba_unit_spatial_unit -- one BAUnit may bind several parcels
ba_unit_id, spatial_unit_id
rrr -- LA_RRR: right | restriction | responsibility
id, ba_unit_id, party_id, kind, type, share, status
source -- LA_AdministrativeSource / LA_SpatialSource
id, kind(deed|court_order|survey_plan|photo|affidavit|testimony),
document_ref, captured_at, submitted_by
rrr_source, spatial_unit_source -- evidence links, many-to-many
-- systematic campaign machinery (lesson 0003)
adjudication_area id, name, declared_on, display_from, display_to, status
claim id, area_id, spatial_unit_id, party_id, asserted_rrr,
status(claimed|displayed|objected|adjudicated|registered|rejected)
objection id, claim_id, objector_party_id, grounds, decided_on,
decision, decided_by
Rights never touch geometry. rrr points at ba_unit, never at spatial_unit. That one indirection is what lets a boundary be recorrected from better imagery without disturbing ownership, and lets one right cover three parcels — the payoff from lesson 0001 and 0004.
Claims are not rights. claim is a separate table with its own lifecycle, not a status flag on rrr. The authoritative register stays clean while 40,000 claims churn through display and objection — lesson 0003. Rows cross into rrr only on adjudication.
Geometry knows how it was made. capture_method, accuracy_class and boundary_type are what make incremental improvement possible and stop anyone treating an imagery trace as a survey — lesson 0002.
Evidence is a table, not an attachment. source is first-class and shared by both halves, because in a dispute the question is never just what does the register say but on what basis.
Group parties exist from day one. Customary holdings are the norm, not an edge case. Retrofitting party_member after launch means rewriting every ownership query you have.
Storage CRS: the national projected grid, so areas and distances are meaningful. Reproject at the service edge for web clients — lesson 0005.
Nine or more, unprompted, and you can hold your own in a design review on this material. Fewer than six and the gap is worth a lesson of its own — say which boxes you missed.
You now have the domain layer the mission asked for. The natural continuations, in order of usefulness to a build: