mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Stage 2 of First Run. Establishes each Property's Baseline Performance from persisted source data and writes it back — reads only from repos, never a Fetcher or HTTP (ADR-0003), so it is byte-identical whether Ingestion ran milliseconds ago or last week. Domain (`domain/baseline/`): - `Performance` VO — the four rated quantities: SAP / EPC Band / CO2 / Primary Energy Intensity. `lodged_performance(epc)` reads them off the EPC's recorded fields (PEUI = `energy_consumption_current`). - `BaselinePerformance` (ADR-0004) — the paired `lodged` + `effective` Performance + `rebaseline_reason`, plus the no-derivation part of the energy block (`space_heating_kwh` / `water_heating_kwh`, off the RHI, deterministic per ADR-0006). Both halves always populated. - `Rebaseliner` port + `StubRebaseliner`: the re-score-on-override seam (ADR-0011). SAP10 certs pass through (effective == lodged, reason "none"); a pre-SAP10 cert raises `RebaselineNotImplemented` rather than fabricating a plausible-but-wrong "none" — ML rebaselining is not wired yet. Mirrors the repo's strict-raise culture. Persistence: new `BaselineRepository` port + `BaselinePostgresRepository` + flat-column `baseline_performance` SQLModel (one row per Property). Per ADR-0004's amendment this is a standalone table, NOT columns on the retiring `property_details_epc`. Production migration is FE-owned (Drizzle) — docs/migrations/baseline-performance-table.md. Docs (grill-with-docs): corrected CONTEXT.md Lodged/Effective Performance to Primary Energy Intensity (the term collided with its own _Avoid_ entry under "heat demand") + fixed stale RHI field names; amended ADR-0004 Consequences for the standalone-table decision. Fuel split + bills (rest of EPC Energy Derivation) deferred to a follow-up — they need a Fuel Rates source (Ofgem-cap ETL) that does not exist yet. TDD, one test -> one impl: 7 tests (lodged read, rebaseliner pass-through + raise, orchestrator establish-and-persist + pre-SAP10 raise, Postgres round-trip + absent). pyright strict clean; AAA layout. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
43 lines
2.5 KiB
Markdown
43 lines
2.5 KiB
Markdown
# `baseline_performance` table — FE-owned migration
|
|
|
|
**Context:** Slice 6 (Hestia-Homes/Model#1135) of the `ara_first_run` rebuild. The
|
|
`BaselineOrchestrator` establishes a Property's **Baseline Performance** (ADR-0004) and persists it
|
|
via a new `BaselineRepository` port. This is a brand-new table — no predecessor.
|
|
|
|
Per ADR-0004's amendment, the lodged/effective pair does **not** land on `property_details_epc`
|
|
(which is being retired as too coupled to the legacy EPC-API schema). It lands here, as its own
|
|
aggregate's table.
|
|
|
|
The SQLModel row is defined in `infrastructure/postgres/` so the ephemeral-Postgres tests build it
|
|
via `SQLModel.metadata.create_all`. The **production migration is FE-owned (Drizzle ORM)** — a
|
|
straight lift-and-shift of the columns below.
|
|
|
|
## `baseline_performance` — one row per Property
|
|
|
|
| Column | Type | Notes |
|
|
|---|---|---|
|
|
| `id` | serial PK | |
|
|
| `property_id` | int, FK → `property.id`, **unique** | one Baseline Performance per Property |
|
|
| `lodged_sap_score` | int | Lodged Performance — gov register, off the Effective EPC |
|
|
| `lodged_epc_band` | text | the `Epc` enum, stored as its string value (e.g. `"C"`) |
|
|
| `lodged_co2_emissions` | float | |
|
|
| `lodged_primary_energy_intensity` | int | PEUI (kWh/m²/yr); **not** "heat demand" — see CONTEXT.md |
|
|
| `effective_sap_score` | int | Effective Performance — what modelling scored against |
|
|
| `effective_epc_band` | text | |
|
|
| `effective_co2_emissions` | float | |
|
|
| `effective_primary_energy_intensity` | int | |
|
|
| `rebaseline_reason` | text | `none` \| `pre_sap10` \| `physical_state_changed` \| `both` |
|
|
| `space_heating_kwh` | float | off `renewable_heat_incentive`; deterministic (ADR-0006) |
|
|
| `water_heating_kwh` | float | off `renewable_heat_incentive` |
|
|
|
|
This slice has no ML rebaselining, so `effective_* == lodged_*` and `rebaseline_reason = 'none'`
|
|
for every row written (a pre-SAP10 cert raises rather than persisting a wrong-but-plausible row —
|
|
see #1135). The `effective_*` columns exist now so the table shape is stable when ML lands.
|
|
|
|
## Deferred (follow-up — EPC Energy Derivation + Fuel Rates)
|
|
|
|
`fuel_split` and `bills` are **not** in this table yet. They are produced by
|
|
`EpcEnergyDerivationService`, which needs a current **Fuel Rates** source (Ofgem-cap ETL) that does
|
|
not exist yet. They land together in the follow-up so this table is not migrated twice. Likely
|
|
shape: a `bills`-style block (per-fuel kWh + standing charge + SEG) — to be specified in that
|
|
slice's migration note.
|