Commit graph

1247 commits

Author SHA1 Message Date
Daniel Roth
54cf807f2b correct comment following previous commit 2026-06-30 11:10:19 +00:00
Daniel Roth
7c9faba215 sort dupe files based on upload timestamp rather than id 2026-06-30 11:06:58 +00:00
Daniel Roth
ac6983ae68 only get most recent version of each uploaded file per s3 key 2026-06-30 11:02:49 +00:00
Jun-te Kim
f51fdca3d8 Add partial index on material(is_active) for the catalogue read
The modelling_e2e Lambda reads the active catalogue once per invocation
(SELECT * FROM material WHERE is_active ORDER BY id). Without an index this
was a full seq scan every time (~23ms), paid by all 32 concurrent Lambdas at
startup. Partial index on id WHERE is_active returns the active rows already
id-ordered — no sort, no filter.

Verified on dev: seq scan 23.2ms -> index scan 4.2ms.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 11:53:19 +00:00
Khalim Conn-Kowlessar
e4960db2c1 feat(epc): persist 7 calculator-read fields dropped on save
A recursive persistence-fidelity guard surfaced 7 fields the SAP calculator
reads but the epc_property projection had no column for, so they were silently
lost on save->reload (same bug class as the PV arrays / floor flags). All
additive, nullable except the PV-diverter bool; no backfill (defaults match
the domain defaults).

- epc_main_heating_detail: community_heating_boiler_fuel_type,
  community_heating_chp_fraction (community-heated CHP).
- epc_building_part: alt_wall_1_is_sheltered, alt_wall_2_is_sheltered, and
  wall_insulation_thermal_conductivity (jsonb to preserve Union[int,str]).
- epc_property: energy_pv_diverter_present (NOT NULL DEFAULT false),
  heating_cylinder_volume_measured_l, ventilation_air_permeability_ap50_m3_h_m2.

Includes generated migration 0246_minor_lady_bullseye.sql + snapshot/journal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 18:34:45 +00:00
Khalim Conn-Kowlessar
a1548ca3a9 feat(epc): persist PV arrays and floor heat-loss flags
Add EPC persistence schema for two round-trip-fidelity gaps so the Model
backend can store the full EpcPropertyData faithfully:

- New child table epc_photovoltaic_array (one row per PV array), mirroring
  the epc_window child-table pattern.
- epc_floor_dimension: add is_exposed_floor and is_above_partially_heated_space
  boolean flags (NOT NULL DEFAULT false; additive, no backfill).

Includes generated migration 0245_magenta_nomad.sql + snapshot/journal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 16:38:36 +00:00
Jun-te Kim
163412506c Show UPRN on selected address in remote assessment
Display the UPRN beneath the selected address on the remote assessment
page so it's available for quicker debugging. The value is already on
the selected address object from the postcode lookup; it just wasn't
rendered.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 14:50:36 +00:00
Jun-te Kim
752ffe1935 feat(db): add property.marked_for_deletion soft-delete flag
Add a NOT NULL DEFAULT false `marked_for_deletion` boolean to the
`property` table. Hard deletes are expensive (cascading child rows,
indexes), so a row is flagged here and a separate cron job performs the
physical delete later; reads can filter on the flag in the interim.

A constant default makes this a metadata-only ALTER on Postgres 11+ (no
table rewrite); existing rows backfill to false.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 12:18:32 +00:00
Daniel Roth
1b7d314fdd SQL correction 2026-06-24 15:06:43 +00:00
Daniel Roth
e3a58e7e9c migration files 2026-06-24 15:02:21 +00:00
Daniel Roth
fb431a1a25 wall insulation thickness is jsonb 2026-06-24 15:01:11 +00:00
Daniel Roth
4f6537bf7e migration files 2026-06-24 13:52:46 +00:00
Daniel Roth
d0b39ecdcb add new columns to table 2026-06-24 13:52:06 +00:00
Daniel Roth
f3c03b0ba5 migration files 2026-06-22 13:03:20 +00:00
Daniel Roth
e32bcf0d4e add property_id task source 2026-06-22 13:02:36 +00:00
Jun-te Kim
1ac4e20c4c db changes 2026-06-19 15:04:43 +00:00
Jun-te Kim
ae74133575 feat(db): add epc_property.source for predicted-EPC slot (ADR-0031)
Adds a `source` discriminator to `epc_property` so a property can hold a
lodged and a predicted EPC at the same time, per the EPC Prediction
production-wiring branch in the Model repo (docs/MIGRATION_NOTE_predicted_epc_source.md).

- `source` text NOT NULL default 'lodged' — backfills every existing row as
  a real lodged EPC.
- Unique index becomes (property_id, portfolio_id, source) so lodged +
  predicted rows can coexist for the same property/portfolio.
- New (property_id, source) index — lodged/predicted reads filter on both.

Allowed values: 'lodged' | 'predicted'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 13:46:19 +00:00
Daniel Roth
e3ee1480aa dont hardcode expected file count in tests 2026-06-15 13:42:03 +00:00
Daniel Roth
8e9e093def fix brokn unit tests 2026-06-15 13:38:01 +00:00
Daniel Roth
86642de2a2 Don't include PAR photopack in MIssing Documents list 2026-06-15 13:06:28 +00:00
Daniel Roth
2a9da6765b Switch EPC SAP (Potential) data source from epcSapScorePotential to potentialPostSapScoreDropdown 2026-06-15 11:57:39 +00:00
Daniel Roth
5ad99df044 correct typo 2026-06-15 09:54:15 +00:00
Daniel Roth
32bb2e39ef Merge branch 'main' into feature/new-cols-in-property-export 2026-06-15 09:50:16 +00:00
Daniel Roth
c72b7c1625 Add coordination comments, damp/mould, and Domna survey columns to property table and CSV export
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 09:48:41 +00:00
Daniel Roth
10f7d4c188 migration 2026-06-15 08:59:46 +00:00
Daniel Roth
db0b3670f4 delete col 2026-06-15 08:59:24 +00:00
Daniel Roth
954fb5b16e migration 2026-06-15 08:52:41 +00:00
Daniel Roth
a3ee12a418 osmosis_survey_required column 2026-06-15 08:50:41 +00:00
Daniel Roth
3425dae3cc migration files 2026-06-10 14:25:37 +00:00
Daniel Roth
a5e07ffa1c add last_submission_date to hs deal table 2026-06-10 14:23:55 +00:00
Daniel Roth
2e9ec32c48 migration files 2026-06-09 13:57:31 +00:00
Daniel Roth
de963bbc39 add file type and file source 2026-06-09 13:56:52 +00:00
Jun-te Kim
d0d5ec0366
Merge pull request #310 from Hestia-Homes/feature/frontend_landlord_overrides
Feature/frontend landlord overrides
2026-06-08 16:23:21 +01:00
Jun-te Kim
c2b7e00075 new table for new deal proeprties we want 2026-06-08 14:42:50 +00:00
Jun-te Kim
cc134f8ce9
Merge branch 'main' into feature/frontend_landlord_overrides 2026-06-08 14:00:20 +01:00
Daniel Roth
7e2be3efbd Merge branch 'main' into feature/magicplan-ventilation-tables 2026-06-08 12:21:22 +00:00
Jun-te Kim
30d3e727d1 route of the address2uprn problem of float value 2026-06-08 09:38:48 +00:00
Jun-te Kim
f6545c2fa0 property override 2026-06-08 09:38:48 +00:00
Jun-te Kim
b9bbd916b5 Render finalising status on the bulk-upload page and auto-advance to complete
The async finaliser (ADR-0005) introduced the `finalising` status, but the
server page's STATUS_CONFIG had no entry for it, so it fell through to the
`ready_for_processing` fallback ("Awaiting column mapping") and never mounted the
live poller — the page looked stuck even though the Lambda had inserted the
properties and written `complete`.

- Add the `finalising` card ("Uploading to ARA") to STATUS_CONFIG.
- Render OnboardingProgress during `finalising` so it polls live.
- Refresh the server page once when the poll first sees a terminal status
  (guarded by a new `serverStatus` prop to avoid a loop; uses react-query v4
  onSuccess, no useEffect) so it advances to the "Processing complete" card.
- Add a `finalising` → "Uploading to ARA" badge on the uploads list.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 09:38:48 +00:00
Jun-te Kim
87aca96dfa bulk upload finaliser 2026-06-08 09:38:48 +00:00
Jun-te Kim
dff86b1ec2 save current progress 2026-06-08 09:38:48 +00:00
Jun-te Kim
22375e1746 Add Step 1 "Verify classification" to bulk-upload review (ADR-0004)
For uploads with classifier columns, surface the classifier's
description→enum assumptions on the awaiting_review screen so the user can
correct any (written source='user') and acknowledge before Finalise.
Previously only the multi-entry order step existed, so non-multi-entry
uploads got no classification review at all and the assumptions were
applied silently.

- detectMultiEntry: capture a sample whenever classifier columns are
  mapped (largest-count row if multi-entry, else first classified row);
  the sample now carries all classifier columns. "sample != null" means
  "there is something to verify"; largestCount >= 2 stays the multi-entry
  signal.
- setVerifyAck + verify-classification PATCH route + useConfirmVerification.
- VerifyClassificationPanel (Step 1); MultiEntryOrderingPanel slimmed to
  order-only with read-only classification annotation; canFinalize gated
  on both steps where each applies.
- Unit tests for detectMultiEntry + ordering helpers.

The verify_ack column + 0219 migration landed separately via #303.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 09:38:48 +00:00
Jun-te Kim
c9b7d71843 Show + edit sample classifications on awaiting_review (#298, #299)
#298: read the classifier's resolved enums for the multi-entry sample's
entries (joined from landlord_*_overrides by normalized description) and show
each beside the raw text, or "not classified" when absent.

#299: make each classification editable — a dropdown of the category's valid
enum values whose selection upserts the override by (portfolio, description)
with source='user', so the classifier never re-clobbers it. UI notes the
portfolio-wide blast radius. Verification ack is folded into the existing
order-confirm (no separate flag/migration); editing is optional review.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 09:38:48 +00:00
Jun-te Kim
65a5f57321 Confirm building-part ordering on awaiting_review (#297)
Adds the multiEntryOrdering jsonb column + interactive order picker: the
largest-count multi-entry sample is shown with a building-part dropdown per
file position (one Main building + Extensions), validated as a permutation.
A PATCH route persists { count: permutation } + confirmed, and Finalise is
disabled until the ordering is confirmed when the upload is multi-entry.

Migration for the new column is intentionally not included here — generated
after origin/main is merged (its multi_entry_summary migration lands first).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 09:38:48 +00:00
Jun-te Kim
9cb0cb19f3 lanlord exetension application 2026-06-08 09:38:21 +00:00
Jun-te Kim
052ab446e0 merged from main 2026-06-08 09:36:26 +00:00
Daniel Roth
b16e0f7d3d new tables for magicplan ventilation. move opening type from window table to window ventilation table 2026-06-08 09:25:16 +00:00
Khalim Conn-Kowlessar
6f38677da3 Make recommendation denormalisation backfill safe and online
The 0222-0225 batch backfilled plan_id/material_* onto recommendation
inside drizzle's single migration transaction. On the production table
(~26M rows) that held an AccessExclusiveLock for hours, blocked unrelated
migrations, exhausted EBS throughput credits, and could not report
progress or resume.

Split schema DDL from data backfill:
- 0222/0224: keep only instant metadata-only DDL (ADD COLUMN + FK
  NOT VALID); drop the inline CREATE INDEX.
- 0223/0225: backfills removed (now no-ops pointing to the script).
- New src/app/db/backfill-recommendation-denormalization.ts: idempotent,
  resumable, batched (committed per batch) backfill that then builds the
  indexes CONCURRENTLY and validates the FKs online.
- CONTEXT.md: document recommendation->plan (1:1) and recommendation->
  material (now at most 1; legacy multi-material rows reconciled).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 08:36:39 +00:00
Daniel Roth
d2c9c0696a add guard clause when backfilling plan_id to recommendation 2026-06-05 10:13:49 +00:00
Daniel Roth
694bac47e1 backfill materials columns for recommendation table 2026-06-05 10:13:31 +00:00