mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-07-19 08:53:01 +00:00
3.6 KiB
3.6 KiB
Handover: Add properties by postcode search
Branch: feature/add-properties-by-postcode (2 commits pushed, tree clean).
Context date: 2026-07-06. Goal journey: add properties → create scenarios (done, PR #353) → trigger modelling (soon).
State
Done and verified (npx tsc --noEmit clean, 329 tests pass):
- Domain core
src/lib/postcodeSearch/model.ts+model.test.ts(9 tests):normalisePostcode,classifyOsCode,isCacheFresh(30-day),toAddressCandidates(DPA>LPI, UPRN-dedup, postcode-stripped title-case address),buildWritePlan(property row + 0–2 override facts). - ADR-0007 (
docs/adr/) — all decisions + rationale.docs/adr/**gitignore rule removed (it had eaten ADRs 0004–0006; ask team if recoverable). - CONTEXT.md — "Postcode search" entry; VocabularyMapping now has two producers.
os_placesadded toOverrideSourceValues(schema only — migration not yet generated).- Approved design mockup (build the page to this): https://claude.ai/code/artifact/d05a3ab0-48ed-41c3-94b4-b13106b7f372
Remaining work (in order)
- Enum migration: run
./generate_migration.shforoverride_source+os_places(no.sqlmigrations live in-repo; script is repo-root). - Routes under
src/app/api/portfolio/[portfolioId]/properties/:search/route.tsGET?postcode=: normalise →postcode_searchcache read (isCacheFresh; row has uniquepostcode+ jsonbresultData) → on miss/stale calllookupPostcode(src/app/api/postcode/LookupPostcode.ts; addparliamentary_constituencyto its result type) + OS pages fetch (LookupOsPlaces.ts) → upsert cache → returntoAddressCandidates+ geo +alreadyInPortfolioflags (one query: uprns in portfolio) + cache age.route.tsPOST submit{candidates, geo}(re-validate server-side): transaction overbuildWritePlanrows — insertpropertyON CONFLICT DO NOTHING(partial uniqueuq_property_portfolio_uprn), upsertlandlord_property_type_overrides/landlord_built_form_type_overrides((portfolio_id, description)unique, description = OS code, sourceos_places), insertproperty_overridessnapshots (building_part=0,original_spreadsheet_description= OS code). Return{added, skipped}. Next-15 rules:await params,{ error }shape.
- Page
/portfolio/[slug]/properties/add+ "Add properties" dropdown beside Export insrc/app/portfolio/[slug]/components/PropertyTable.tsx("Search by postcode" + "Bulk excel import — Soon"). Then retire toolbarAddNewdropdown. TanStack Query v4 mutations; no useEffect/useMemo (CLAUDE.md).
How to verify (patterns proven this session)
- DB:
.env.localcreds; NODE_PATH node scripts withpg(ssl:{rejectUnauthorized:false}). - Live app:
./node_modules/.bin/next dev -p 3111; mint a session cookie withnext-auth/jwtencode+NEXTAUTH_SECRETfrom.env.local, email@domna.homes, cookienext-auth.session-token. Server-rendered data is greppable in the RSC payload. - Test portfolio: 814 (new-approach). Searched-in properties will render blank/awaiting modelling — that's by design (ADR-0007), not a bug.
OS_API_KEYenv var powers OS Places.
Gotchas
- Properties inserted now are "new approach" (
updated_at >= 2026-06-01,epcSources.ts) — every read path expects an EPC graph that won't exist until modelling. Expected. - Never per-scenario/per-property probe loops on
plan(1.6M rows) — grouped/scoped queries only (seedocs/wip/new-modelling-ui-handover.mdperf notes). - PR #353 (Scenarios tab) is separate, open; its ADR is numbered 0003.