- Documentation
- /
- Rehab
- /
- System Diagram
System Diagram
The Progressive Rehabilitation and Mine Closure data model, mapped — 47 models, 161 relationships
🔍 For serious exploration, open the Interactive Diagram Viewer — pan, mouse-wheel zoom, fit-to-screen, full-screen, per-module tabs, the full 161-relationship ERD, and a focus mode that draws one model and its neighbours at a chosen depth.
Person(43 links),MineSite(22) andEvidence(19) are role/site/attachment columns that fan out to nearly everything, so the viewer hides those links by default — a toggle brings them back. The diagrams below are the readable, static summary of the principal links only.
Architecture Overview
Eleven areas mirror the sidebar menu. Every arrow means "one row of the left model is referenced by many rows of the right model".
flowchart LR
subgraph PLAN["📋 Plans & obligations"]
SourceAuthority --> SourceDocument --> Requirement
ClosurePlan --> PlanRequirementLink
ClosurePlan --> ClosureAssumption
ClosurePlan --> ClosureObjective
end
subgraph DOM["🗺️ Domains & land use"]
ClosureDomain --> DomainLandUse
PostMiningLandUse --> DomainLandUse
ClosureDomain --> DomainObjective
ClosureDomain --> LandAvailabilityEvent
end
subgraph CRIT["✅ Completion criteria"]
CompletionCriterion --> DomainCriterion --> CriterionAssessment
end
subgraph REHAB["🌱 Rehabilitation delivery"]
DisturbanceEvent
RehabilitationPrescription --> RehabilitationWork
RehabilitationCampaign --> RehabilitationWork
RehabilitationWork --> WorkMaterial
RehabilitationWork --> WorkInspection
end
subgraph MON["📈 Monitoring & results"]
MonitoringProgram --> MonitoringSchedule
MonitoringLocation --> MonitoringSchedule
MonitoringSchedule --> MonitoringEvent --> MonitoringResult
end
subgraph DONE["🏁 Certification & relinquishment"]
CertificationApplication --> CertificationCriterion
RelinquishmentApplication --> RelinquishmentDomain
ClosureReview
end
subgraph RISK["⚠️ Risk, findings & actions"]
ClosureRisk
Finding --> CorrectiveAction
end
subgraph STK["🤝 Stakeholders & commitments"]
Stakeholder --> EngagementEvent
Stakeholder --> ClosureCommitment
end
subgraph COST["💰 Closure cost"]
ClosureCostEstimate --> ClosureCostItem
ActualClosureCost
end
subgraph SITE["⛏️ Sites, areas & people"]
Organisation --> Person
MineSite --> SpatialArea
end
subgraph EVD["📚 Evidence & governance"]
Document --> Evidence
Approval
end
Requirement --> PlanRequirementLink
MineSite --> ClosurePlan
ClosurePlan --> ClosureDomain
SpatialArea --> ClosureDomain
ClosurePlan --> CompletionCriterion
ClosureObjective --> DomainObjective
ClosureDomain --> DomainCriterion
ClosureDomain --> DisturbanceEvent
ClosureDomain --> RehabilitationPrescription
ClosureDomain --> RehabilitationWork
CompletionCriterion --> MonitoringSchedule
MonitoringEvent --> Finding
CriterionAssessment --> Finding
ClosureRisk --> CorrectiveAction
ClosureCommitment --> CorrectiveAction
DomainCriterion --> CertificationCriterion
CriterionAssessment --> CertificationCriterion
ClosureDomain --> CertificationApplication
CertificationApplication --> RelinquishmentDomain
ClosureDomain --> RelinquishmentDomain
ClosureDomain --> ClosureCostItem
RehabilitationWork --> ActualClosureCost
ClosurePlan --> ClosureReview
(ClosureDomain is the hub of the model — 20 relationships touch it. It is
where the plan, the land, the criteria, the work, the monitoring, the cost and
the certification all meet, which is exactly the pack's design intent: the
domain, not the site and not the plan, is the operational unit of closure.)
Obligations to Plan
Where a requirement came from, and how the plan answers it. The
PlanRequirementLink join is the audit surface a regulator reads first.
erDiagram
SourceAuthority ||--o{ SourceDocument : "source_authority_id"
SourceDocument ||--o{ SourceDocument : "superseded_by_id"
Document ||--o{ SourceDocument : "local_document_id"
SourceDocument ||--o{ Requirement : "source_document_id"
MineSite ||--o{ ClosurePlan : "mine_site_id"
ClosurePlan ||--o{ ClosurePlan : "supersedes_plan_id"
Document ||--o{ ClosurePlan : "document_id"
ClosurePlan ||--o{ PlanRequirementLink : "closure_plan_id"
Requirement ||--o{ PlanRequirementLink : "requirement_id"
ClosurePlan ||--o{ ClosureAssumption : "closure_plan_id"
ClosurePlan ||--o{ ClosureObjective : "closure_plan_id"
Domains, Land Use and Area State
The spatial and operational spine. Spatial areas and closure domains each
self-nest; the four area-state columns live on ClosureDomain and
LandAvailabilityEvent is the audit trail between them.
erDiagram
MineSite ||--o{ SpatialArea : "mine_site_id"
SpatialArea ||--o{ SpatialArea : "parent_area_id"
MineSite ||--o{ ClosureDomain : "mine_site_id"
SpatialArea ||--o{ ClosureDomain : "spatial_area_id"
ClosurePlan ||--o{ ClosureDomain : "closure_plan_id"
ClosureDomain ||--o{ ClosureDomain : "parent_domain_id"
MineSite ||--o{ PostMiningLandUse : "mine_site_id"
ClosureDomain ||--o{ DomainLandUse : "closure_domain_id"
PostMiningLandUse ||--o{ DomainLandUse : "post_mining_land_use_id"
ClosureObjective ||--o{ DomainObjective : "closure_objective_id"
ClosureDomain ||--o{ DomainObjective : "closure_domain_id"
ClosureDomain ||--o{ DisturbanceEvent : "closure_domain_id"
ClosureDomain ||--o{ LandAvailabilityEvent : "closure_domain_id"
Completion Criteria
A criterion is defined once at plan level, localised per domain, and judged by dated assessments. A criterion revision supersedes its predecessor rather than overwriting it.
erDiagram
ClosurePlan ||--o{ CompletionCriterion : "closure_plan_id"
CompletionCriterion ||--o{ CompletionCriterion : "supersedes_criterion_id"
ClosureDomain ||--o{ DomainCriterion : "closure_domain_id"
CompletionCriterion ||--o{ DomainCriterion : "completion_criterion_id"
DomainCriterion ||--o{ CriterionAssessment : "domain_criterion_id"
Evidence ||--o{ CriterionAssessment : "evidence_id"
The one FK dropped in translation. The pack also carried
DomainCriterion.currentAssessmentId → CriterionAssessment, which forms a true 2-cycle withCriterionAssessment.domainCriterionId. The child side is load-bearing — an assessment must know what it judged — so the pointer back was dropped. The latest assessment is reachable by ordering a criterion's assessments byassessment_date.
Rehabilitation Delivery
The approved treatment, what was actually delivered against it, and the hold-point inspections that prove it. A prescription revision supersedes its predecessor.
erDiagram
ClosureDomain ||--o{ RehabilitationPrescription : "closure_domain_id"
RehabilitationPrescription ||--o{ RehabilitationPrescription : "supersedes_prescription_id"
Document ||--o{ RehabilitationPrescription : "document_id"
MineSite ||--o{ RehabilitationCampaign : "mine_site_id"
RehabilitationCampaign ||--o{ RehabilitationWork : "rehabilitation_campaign_id"
RehabilitationPrescription ||--o{ RehabilitationWork : "rehabilitation_prescription_id"
ClosureDomain ||--o{ RehabilitationWork : "closure_domain_id"
Organisation ||--o{ RehabilitationWork : "contractor_organisation_id"
RehabilitationWork ||--o{ WorkMaterial : "rehabilitation_work_id"
RehabilitationWork ||--o{ WorkInspection : "rehabilitation_work_id"
SpatialArea ||--o{ WorkMaterial : "source_spatial_area_id"
Monitoring
Programs define what is measured and why; a schedule pins a parameter to a location and, critically, to the completion criterion it serves; events and results are the evidence.
erDiagram
MineSite ||--o{ MonitoringProgram : "mine_site_id"
MineSite ||--o{ MonitoringLocation : "mine_site_id"
ClosureDomain ||--o{ MonitoringLocation : "closure_domain_id"
SpatialArea ||--o{ MonitoringLocation : "spatial_area_id"
MonitoringProgram ||--o{ MonitoringSchedule : "monitoring_program_id"
MonitoringLocation ||--o{ MonitoringSchedule : "monitoring_location_id"
CompletionCriterion ||--o{ MonitoringSchedule : "completion_criterion_id"
MonitoringSchedule ||--o{ MonitoringEvent : "monitoring_schedule_id"
MonitoringProgram ||--o{ MonitoringEvent : "monitoring_program_id"
MonitoringLocation ||--o{ MonitoringEvent : "monitoring_location_id"
MonitoringEvent ||--o{ MonitoringResult : "monitoring_event_id"
(MonitoringSchedule.completion_criterion_id is the link that makes the
criteria testable. Without it a monitoring program is data collection; with it,
every criterion can be traced to the measurements that will decide it.)
Risk, Findings and Corrective Actions
The improvement loop. Findings come from exceedances and failed assessments; actions come from findings, risks and commitments alike.
erDiagram
MineSite ||--o{ ClosureRisk : "mine_site_id"
ClosureDomain ||--o{ ClosureRisk : "closure_domain_id"
ClosurePlan ||--o{ ClosureRisk : "closure_plan_id"
MonitoringEvent ||--o{ Finding : "monitoring_event_id"
CriterionAssessment ||--o{ Finding : "criterion_assessment_id"
ClosureDomain ||--o{ Finding : "closure_domain_id"
Finding ||--o{ CorrectiveAction : "finding_id"
ClosureRisk ||--o{ CorrectiveAction : "closure_risk_id"
ClosureCommitment ||--o{ CorrectiveAction : "commitment_id"
Stakeholders, Commitments and Cost
What was promised and to whom, and what it costs. Both chains close back onto delivery evidence.
erDiagram
MineSite ||--o{ Stakeholder : "mine_site_id"
Organisation ||--o{ Stakeholder : "organisation_id"
Stakeholder ||--o{ EngagementEvent : "stakeholder_id"
Stakeholder ||--o{ ClosureCommitment : "stakeholder_id"
Requirement ||--o{ ClosureCommitment : "requirement_id"
MineSite ||--o{ ClosureCostEstimate : "mine_site_id"
ClosureCostEstimate ||--o{ ClosureCostEstimate : "supersedes_estimate_id"
ClosureCostEstimate ||--o{ ClosureCostItem : "closure_cost_estimate_id"
ClosureDomain ||--o{ ClosureCostItem : "closure_domain_id"
RehabilitationWork ||--o{ ClosureCostItem : "rehabilitation_work_id"
ClosureDomain ||--o{ ActualClosureCost : "closure_domain_id"
RehabilitationWork ||--o{ ActualClosureCost : "rehabilitation_work_id"
Certification and Relinquishment
Progressive certification is per domain and carries each criterion with its assessment. Relinquishment is whole-of-site and carries a readiness row per domain.
erDiagram
ClosureDomain ||--o{ CertificationApplication : "closure_domain_id"
Document ||--o{ CertificationApplication : "application_document_id"
CertificationApplication ||--o{ CertificationCriterion : "certification_application_id"
DomainCriterion ||--o{ CertificationCriterion : "domain_criterion_id"
CriterionAssessment ||--o{ CertificationCriterion : "criterion_assessment_id"
ClosurePlan ||--o{ RelinquishmentApplication : "closure_plan_id"
RelinquishmentApplication ||--o{ RelinquishmentDomain : "relinquishment_application_id"
ClosureDomain ||--o{ RelinquishmentDomain : "closure_domain_id"
CertificationApplication ||--o{ RelinquishmentDomain : "certification_application_id"
ClosurePlan ||--o{ ClosureReview : "closure_plan_id"
Application Flow — Disturbance to Certification
The order in which the system is actually used, and what gates each step.
flowchart TD
A["⛏️ Disturbance event<br/><i>area, volume, topsoil stripped</i>"] --> B["🗺️ Closure domain<br/><i>disturbed hectares</i>"]
B --> C{"Mining finished<br/>with this ground?"}
C -->|no| C2["Stays NOT_AVAILABLE<br/><i>milestone date recorded</i>"]
C2 --> C
C -->|yes| D["📗 Land availability event<br/>→ AVAILABLE"]
D --> E["📐 Rehabilitation prescription<br/><i>approved before work starts</i>"]
E --> F["🌱 Rehabilitation work<br/><i>campaign, contractor, quantities</i>"]
F --> G{"Hold point inspection<br/>passes?"}
G -->|no| G2["🔁 Rework — stage returns<br/>to REWORK_REQUIRED"]
G2 --> F
G -->|yes| H["📗 → REHABILITATED → MONITORING"]
H --> I["📈 Monitoring schedule<br/><i>tied to a completion criterion</i>"]
I --> J["📊 Events + results<br/><i>over the assessment period</i>"]
J --> K{"Enough events?<br/><i>minimum_monitoring_events</i>"}
K -->|no| J
K -->|yes| L["⚖️ Criterion assessment<br/><i>assessed · reviewed · approved</i>"]
L --> M{"All applicable criteria<br/>MET or disclosed?"}
M -->|no| N["🚩 Finding → corrective action<br/><i>criterion stays AT_RISK / NOT_MET</i>"]
N --> I
M -->|yes| O["🏁 Certification application<br/><i>each criterion + its assessment</i>"]
O --> P{"Decision"}
P -->|"APPROVED with conditions"| Q["📗 → CERTIFIED<br/>conditions become commitments"]
P -->|"INFORMATION_REQUEST"| I
Q --> R["🤝 Relinquishment readiness<br/><i>one row per domain</i>"]
Application Flow — Why a Criterion Cannot Just Be Marked Met
The single most important rule in the domain, drawn out.
flowchart TD
S(["DomainCriterion at NOT_ASSESSED"]) --> R["📊 Monitoring results accumulate"]
R --> Q{"Values inside the<br/>target range?"}
Q -->|"yes — but that's not enough"| K1["Still NOT_ASSESSED"]
K1 --> K2["⚖️ CriterionAssessment written<br/><i>period, evidence, confidence, limitations</i>"]
K2 --> K3{"Reviewed by a second person?"}
K3 -->|no| K2
K3 -->|yes| K4{"Approved?"}
K4 -->|no| K2
K4 -->|yes| K5["✅ result recorded<br/>MET · PARTIALLY_MET · NOT_MET · AT_RISK"]
K5 --> K6["DomainCriterion.status follows<br/><i>the assessment, not the raw data</i>"]
Q -->|no| N["🚩 Finding raised<br/>→ corrective action"]
N --> R
K5 -.->|"PARTIALLY_MET"| D["📄 Disclosed in the application —<br/>a conditional decision, not a deferral"]
Reading the Diagrams
A ||--o{ Bmeans one row of A is referenced by many rows of B (the label is the foreign-key column on B).- These static diagrams show principal links only — the role columns that
appear on nearly every model (
*_person_id,mine_site_id,evidence_id) are omitted for readability. The interactive viewer's Full ERD shows all 161, with the person/site/evidence noise toggleable. ClosureDomainis the hub of the model — the viewer's Focus mode is the fastest way to see its 20 links.Personhas the most (43) because every closure act records who did it: owned, accountable, responsible, prepared, reviewed, approved, assessed, inspected, authorised, detected, assigned, verified, submitted, captured, accepted.- One FK was dropped in translation:
DomainCriterion.current_assessment_id, which formed a true 2-cycle withCriterionAssessment.domain_criterion_id. See the Completion Criteria section above. Everything else in the source model is present. Seven self-references are kept:SpatialArea.parent_area_id,ClosureDomain.parent_domain_id,ClosurePlan.supersedes_plan_id,CompletionCriterion.supersedes_criterion_id,RehabilitationPrescription.supersedes_prescription_id,ClosureCostEstimate.supersedes_estimate_idandSourceDocument.superseded_by_id. - One pointer is deliberately not a foreign key:
Approval.entity_type+entity_idis a polymorphic reference — an approval can hang off a plan, a prescription, an assessment, a certification application, a cost estimate or a relinquishment application — so it is a type/id pair, not an edge.
Diagrams are derived from the generated schema metadata
(apps/rehab/generated/json/rehab_relationship_metadata.json). If the DSL schema
changes, regenerate the metadata (python -m codegen.cli all rehab), rebuild the
viewer (python apps/rehab/scripts/build_diagram_viewer.py) and update this
page.