Commit graph

7452 commits

Author SHA1 Message Date
Daniel Roth
60146f0c30 Abri survey amendment trigger defers first-time survey dates to the creation trigger 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:52:49 +00:00
Daniel Roth
1529544c19 Abri survey amendment trigger defers first-time survey dates to the creation trigger 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:52:26 +00:00
Daniel Roth
597cd1c83f Abri survey amendment trigger fires when the confirmed survey time changes on an Abri condition deal 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:52:00 +00:00
Daniel Roth
8c5d1a27ff Abri survey amendment trigger fires when the confirmed survey time changes on an Abri condition deal 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:50:53 +00:00
Daniel Roth
bf344e1b58 Abri survey amendment trigger stays quiet when the survey date and time are unchanged 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:49:19 +00:00
Daniel Roth
fce9d30589 Abri survey amendment trigger stays quiet when the survey date and time are unchanged 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:48:53 +00:00
Daniel Roth
7bfd26476e Abri survey amendment trigger ignores deals that are not Abri condition deals 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:48:26 +00:00
Daniel Roth
16b25c4b54 Abri survey amendment trigger ignores deals that are not Abri condition deals 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:47:51 +00:00
Daniel Roth
dbbb12fa54 Abri survey amendment trigger fires when the confirmed survey date changes on an Abri condition deal 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:47:29 +00:00
Daniel Roth
1c75b44630 Abri survey amendment trigger fires when the confirmed survey date changes on an Abri condition deal 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:47:07 +00:00
Daniel Roth
5df78cf9ba Merge branch 'main' into feature/abri-api-integration 2026-07-02 16:41:46 +00:00
Daniel Roth
ffb0f8cc66
Merge pull request #1434 from Hestia-Homes/feature/abri-api-integration
Abri API: hubspot deal differ for CreateJob
2026-07-02 17:41:18 +01:00
Daniel Roth
fdeb15501f Abri survey creation trigger falls back to project code only when no project is associated 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:29:11 +00:00
Daniel Roth
911e77d7cf Abri survey creation trigger falls back to project code only when no project is associated 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:28:13 +00:00
Daniel Roth
cf5a272d7e Abri survey creation trigger recognises deals by their associated Abri project id 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:27:29 +00:00
Daniel Roth
cc682e3e74 Abri survey creation trigger recognises deals by their associated Abri project id 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:27:05 +00:00
Daniel Roth
592173e1e5 Abri Condition project gate is a reusable helper for future Abri triggers 🟪
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:03:34 +00:00
Daniel Roth
7aabfdfa5b Abri survey creation trigger ignores syncs with no parseable confirmed_survey_date 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:02:36 +00:00
Daniel Roth
c059771af5 Abri survey creation trigger ignores syncs with no parseable confirmed_survey_date 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:02:08 +00:00
Daniel Roth
fb2b7e164c Abri survey creation trigger matches the Abri Condition project code case-insensitively 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:01:43 +00:00
Daniel Roth
5b9038ab61 Abri survey creation trigger matches the Abri Condition project code case-insensitively 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:01:25 +00:00
Daniel Roth
bd0c45aa57 Abri Condition project code lives in a reusable class constant 🟪
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 16:00:09 +00:00
Daniel Roth
97bf001fbf Abri survey creation trigger ignores deals outside the Abri Condition project 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 15:59:38 +00:00
Daniel Roth
882eb1eff9 Abri survey creation trigger ignores deals outside the Abri Condition project 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 15:59:05 +00:00
Daniel Roth
fc2ba88759 Abri survey creation trigger ignores deals that already have a confirmed_survey_date 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 15:58:41 +00:00
Daniel Roth
697df8ade3 Abri survey creation trigger ignores deals that already have a confirmed_survey_date 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 15:58:09 +00:00
Daniel Roth
51ac5e2f5e Abri survey creation trigger fires when confirmed_survey_date is first set on an Abri Condition deal 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 15:57:26 +00:00
Daniel Roth
bd3c45d81c Abri survey creation trigger fires when confirmed_survey_date is first set on an Abri Condition deal 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 15:56:49 +00:00
Jun-te Kim
cf50c53cad
Merge pull request #1431 from Hestia-Homes/fix/refetch-solar-reuse-stored
Fix refetch_solar=False dropping solar from re-modelled plans (reuse stored Solar instead)
2026-07-02 15:27:44 +01:00
Jun-te Kim
100949073f refetch_solar=False models with stored Solar insights and never calls Google 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 14:21:46 +00:00
Jun-te Kim
c1a558d2b5 refetch_solar=False models with stored Solar insights and never calls Google 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 14:19:31 +00:00
Jun-te Kim
e08048244a
Merge pull request #1429 from Hestia-Homes/fix/property-overlay-storage-category
Set electric-storage category (7) on storage property overlays
2026-07-02 12:51:58 +01:00
Jun-te Kim
12e8e52eaa
Merge pull request #1428 from Hestia-Homes/test/booth-close-sap-accuracy-corpus
Add UPRN 100020942571 (8 Booth Close) to the SAP accuracy corpus
2026-07-02 12:51:38 +01:00
Jun-te Kim
4ca3491eb2
Merge pull request #1426 from Hestia-Homes/fix/hhrsh-storage-offpeak-pricing
Fix HHRSH storage heaters priced at peak rate (engine 48 vs accredited Elmhurst 71)
2026-07-02 12:50:32 +01:00
KhalimCK
61321d0d47
Merge pull request #1422 from Hestia-Homes/fix/roof-vaulted-nd-sentinel-eligibility
Roof eligibility resolves sentinel thickness by age band (vaulted joins sloping)
2026-07-02 12:45:51 +01:00
Jun-te Kim
e27ecf4a26 Set electric-storage category (7) on storage property overlays
`_category_for` mapped room heaters / heat pumps / heat networks but
returned None for electric-storage-heater codes (401-409), so a storage
system override emitted `sap_main_heating_code=409` +
`main_heating_category=None` while `_control_for` right beside it correctly
set the storage charge control — an asymmetry. Map storage codes to
category 7 so the overlaid cert is internally consistent (code 401-409 <->
category 7), matching the control/fuel/meter companions the overlay drags.

Consistency follow-up to the modelling HHRSH off-peak-pricing fix (#1426):
that PR's Table 12a resolver already prices any storage-coded system
off-peak regardless of category, so this is NOT a live mispricing — it
removes a latent code<->category inconsistency that other category-keyed
logic (responsiveness, pumps/fans) could trip on.

Tests: storage/HHRSH overlay tests now also assert `main_heating_category==7`.
tests/domain/epc (347) + prediction/override/reclassify (118) green; source
pyright-clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 11:45:49 +00:00
Jun-te Kim
e79e83bbbe Add UPRN 100020942571 (8 Booth Close) to the SAP accuracy corpus
Pins the engine's baseline SAP (54) for this electric-room-heater +
gas-multipoint end-terrace ground-floor maisonette (portfolio 814 pid
742121) against accredited Elmhurst RdSAP-10 (worksheet SAP 53, within
1 point), with the Elmhurst Input Summary + SAP Worksheet PDFs saved as
evidence alongside the cert's epc.json.

Companion to the HHRSH storage-heater off-peak-pricing fix PR: this
baseline pin confirms the calculator is faithful on the as-lodged
dwelling; that PR fixes the HHRSH recommendation overlay (engine 48->73
vs Elmhurst 71).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 11:31:28 +00:00
Jun-te Kim
f5fbeb8e7e Fix HHRSH storage heaters priced at peak rate (engine 48 vs Elmhurst 71)
The high-heat-retention storage-heater (HHRSH) recommendation was computed
as LOWERING SAP and wrongly rejected by the Optimiser, leaving electric-
room-heater flats/maisonettes stuck at band E with no sensible plan.

Root cause: `_HHR_STORAGE_OVERLAY` sets `sap_main_heating_code=409` (HHR
storage) + `meter_type="Dual"` but left `main_heating_category` at the
pre-existing value (10 = electric room heaters). The SAP 10.2 Table 12a
space-heating high-rate-fraction resolver classifies by category, so it
misread the off-peak storage heating as direct-acting electric (1.00
high-rate) and priced 100% at the 7-hour peak rate (15.29p) instead of the
storage off-peak split (0.00, ~5.5p).

Verified against accredited Elmhurst RdSAP-10 on UPRN 100020942571
(8 Booth Close, SE28 8BW): engine HHRSH SAP 48 (peak-priced, cost £1087)
vs Elmhurst 71 (cost ~£611); with the fix the engine gives 73 / £576.

Two-part fix (defence in depth, so no future overlay/mapper can
reintroduce it):
- `_HHR_STORAGE_OVERLAY` now sets `main_heating_category=7`, keeping the
  overlaid EPC internally consistent.
- `_table_12a_system_for_main` now classifies electric storage heaters by
  their Table 4a SAP code (401-409) as well as `category==7`, checked
  before the room-heater branch, so a specific storage code is
  authoritative over a stale/inconsistent category.

Tests: new regression `test_storage_heater_classified_by_sap_code_over_stale_category`;
updated the HHRSH overlay pin. Full accuracy corpus still passes (no regressions).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 11:24:03 +00:00
Jun-te Kim
ca3d4ce84b
Merge pull request #1423 from Hestia-Homes/feat/glazing-secondary-member
Add SECONDARY glazing: GlazingType member, overlay code 5, guard support + 796 backfill
2026-07-02 12:22:58 +01:00
Khalim Conn-Kowlessar
6d812d99c5 An unlodged roof type with ND thickness gets no roof recommendation 🟩
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 11:20:55 +00:00
Khalim Conn-Kowlessar
0efae77fd2 An unlodged roof type with ND thickness gets no roof recommendation 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 11:18:55 +00:00
Jun-te Kim
7baab9376c Backfill uniform secondary-glazing overrides misfiled as Single glazing
39 Hyde-796 property_overrides rows ('100% secondary glazing (sap 9.94)')
plus the classifier-cache row; the cache phase self-gates on the
'Secondary glazing' pgEnum label landing (assessment-model#345).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 11:12:25 +00:00
Jun-te Kim
248e230d37 Dominant secondary-glazing split resolves deterministically to SECONDARY 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 11:10:40 +00:00
Jun-te Kim
787f0066c8 Dominant secondary-glazing split resolves deterministically to SECONDARY 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 11:09:47 +00:00
Khalim Conn-Kowlessar
63c889bd02 Roof dispatcher docstring and constants reflect the sentinel-aware pitched trigger 🟪
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 11:09:07 +00:00
Jun-te Kim
f873d5cad3 Landlord 'Secondary glazing' override overlays SAP10 glazing code 5 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 11:08:16 +00:00
Khalim Conn-Kowlessar
1d13dee38e ND loft roof on a pre-1950 dwelling gets loft insulation 🟩
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 11:05:47 +00:00
Khalim Conn-Kowlessar
989cd61574 ND loft roof on a pre-1950 dwelling gets loft insulation 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 11:04:40 +00:00
Khalim Conn-Kowlessar
b33735ef30 NI (insulation present) and measured depths keep a vaulted roof ineligible 🟩
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 11:03:38 +00:00
Khalim Conn-Kowlessar
1dd2d19f78 ND on a limited-insulation age band yields no roof recommendation 🟩
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 11:03:01 +00:00