mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
`heat_transmission_from_cert` hardcoded all window + door area to the first sap_building_part (Main) via the `if i == 0` branch. That's heat-loss-invariant for cohort certs whose per-bp wall U is uniform (cohort 6 all share wall_construction + wall_insulation_type across bps) but wrong for cert 001479 where Ext1's wall U=0.26 (filled cavity, age M) differs sharply from Main's U=0.70 (uninsulated cavity, age C). Worksheet §3: External walls Main 47.13 net × 0.70 = 32.99 (29a) External walls Ext1 10.17 net × 0.26 = 2.64 (29a) External walls Ext2 5.90 × 0.70 = 4.13 (29a) Σ walls 39.77 Pre-slice the cascade attributed all 9 windows to Main, leaving Ext1's 6.37 m² window NOT deducted from Ext1's wall — Ext1 wall area inflated to 16.54 (gross) instead of 10.17 (net), then multiplied by the lower U=0.26 → cascade understated walls_w_per_k by ~2.8 W/K. Add `_window_bp_index` mapping `SapWindow.window_location` (int from API mapper, "Main"/"Nth Extension" string from Elmhurst) to a sap_building_parts index. Pre-compute per-bp window areas and use that in the loop's `net_wall_area` calculation. Backwards-compat preserved for direct callers passing `window_total_area_m2` kwarg with an empty `epc.sap_windows` (legacy single-bp test path): the kwarg total still apportions to Main. Cohort hand-built fixtures default `window_location=0` so all windows route to Main — same as the old i==0 logic for those tests. Cascade behaviour changes for 3 golden certs with non-Main windows (all 3 in the right direction — residuals tighten toward zero): 6035-7729: SAP -5 → -4, PE +36.15 → +34.02, CO2 +0.81 → +0.76 7536-3827: SAP +4 (same), PE -27.17 → -24.73, CO2 -0.72 → -0.66 8135-1728: SAP +1 (same), PE -16.98 → -16.51, CO2 -0.30 → -0.29 Pins tightened; notes annotated with slice attribution. Cert 001479 chain pin closes from delta 1.63 → 1.37 (cascade SAP 70.64 → 70.38, target 69.0094) — remaining ~4.4 W/K HLC gap lives in floor U defaults (Ext1 insulated "As Built") and Ext2 roof area derivation. 70 of 71 chain+golden+heat-transmission tests green; only the cert 001479 chain pin remains RED (load-bearing forcing function). Pyright net-zero (13-error baseline on heat_transmission.py preserved). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| domain | ||
| fetchers | ||
| repos | ||
| utils | ||
| README.md | ||
Shared packages
Workspace packages consumed by services/*. Each package is its own Python distribution with its own pyproject.toml; services import via the workspace dependency mechanism ({ workspace = true }).
| Package | Purpose |
|---|---|
domain/ |
Shared domain types — Property, BaselinePerformance, Plan, Scenario, EpcPropertyData, etc. No persistence, no IO, no business logic. |
repos/ |
Persistence layer — one repo per aggregate. Owns the SQL. Depends on domain. |
fetchers/ |
External API clients (gov EPC, Ofgem, Google Solar, etc.). Depend on domain for response shapes. |
utils/ |
Cross-cutting infra — logging, S3, CloudWatch URL builders, SQS task helpers. |
Adding a new shared package
Only when a real second consumer materialises. Don't pre-shatter (repos-epc, repos-property, ...) — split when a deployment needs to drop a dep, not before.
See ../ara_backend_design.md §11 for the broader monorepo layout and ../CONTEXT.md for the domain glossary that names the types living in domain/.