From 7abc71ed95973285094569fa33ddc3436614c152 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Tue, 7 Jul 2026 14:16:55 +0000 Subject: [PATCH] Drop property-table wiring for certificate_number MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On reflection the certificate number only needs to travel through the address2uprn pipeline (result CSV, S3 output) as an internal value — not persisted to property. Reverts the PropertyIdentityInsert / property_table.py / property_postgres_repository.py changes; keeps certificate_number flowing through get_epc_data_with_postcode, get_uprn_with_epc_df, get_uprn_from_historic_epc, and the address2uprn_certificate_number result column. Co-Authored-By: Claude Sonnet 5 --- infrastructure/postgres/property_table.py | 1 - orchestration/bulk_upload_finaliser_orchestrator.py | 7 ------- repositories/property/property_postgres_repository.py | 1 - repositories/property/property_repository.py | 7 ++----- .../test_bulk_upload_finaliser_orchestrator.py | 4 ---- 5 files changed, 2 insertions(+), 18 deletions(-) diff --git a/infrastructure/postgres/property_table.py b/infrastructure/postgres/property_table.py index 9664b7885..56d0b2fa7 100644 --- a/infrastructure/postgres/property_table.py +++ b/infrastructure/postgres/property_table.py @@ -49,7 +49,6 @@ class PropertyRow(SQLModel, table=True): user_inputted_address: Optional[str] = Field(default=None) user_inputted_postcode: Optional[str] = Field(default=None) lexiscore: Optional[float] = Field(default=None) - certificate_number: Optional[str] = Field(default=None) # FE-owned columns the modelling pipeline now WRITES to record a run: the old # engine set `has_recommendations` (engine.py); we mirror that, and bump diff --git a/orchestration/bulk_upload_finaliser_orchestrator.py b/orchestration/bulk_upload_finaliser_orchestrator.py index 534835e20..1d707a8d7 100644 --- a/orchestration/bulk_upload_finaliser_orchestrator.py +++ b/orchestration/bulk_upload_finaliser_orchestrator.py @@ -41,7 +41,6 @@ INTERNAL_REF_COL = "Internal Reference" UPRN_COL = "address2uprn_uprn" MATCHED_ADDRESS_COL = "address2uprn_address" LEXISCORE_COL = "address2uprn_lexiscore" -CERTIFICATE_NUMBER_COL = "address2uprn_certificate_number" MISSING_SENTINEL = "invalid postcode" UK_POSTCODE_RE = re.compile(r"[A-Z]{1,2}\d[A-Z\d]?\s*\d[A-Z]{2}", re.IGNORECASE) @@ -363,11 +362,6 @@ class BulkUploadFinaliserOrchestrator: internal_ref = _normalize(raw.get(INTERNAL_REF_COL)) or None lexiscore = _parse_lexiscore(raw.get(LEXISCORE_COL)) - certificate_number_raw = _normalize(raw.get(CERTIFICATE_NUMBER_COL)) - certificate_number = ( - None if _is_missing(certificate_number_raw) else certificate_number_raw - ) - return PropertyIdentityInsert( portfolio_id=portfolio_id, uprn=uprn, @@ -377,6 +371,5 @@ class BulkUploadFinaliserOrchestrator: user_inputted_address=user_inputted_address, user_inputted_postcode=user_inputted_postcode, lexiscore=lexiscore, - certificate_number=certificate_number, creation_status="READY", ) diff --git a/repositories/property/property_postgres_repository.py b/repositories/property/property_postgres_repository.py index 57fb9ef54..1072c18d8 100644 --- a/repositories/property/property_postgres_repository.py +++ b/repositories/property/property_postgres_repository.py @@ -162,7 +162,6 @@ class PropertyPostgresRepository(PropertyRepository): "user_inputted_address": r.user_inputted_address, "user_inputted_postcode": r.user_inputted_postcode, "lexiscore": r.lexiscore, - "certificate_number": r.certificate_number, } for r in rows ] diff --git a/repositories/property/property_repository.py b/repositories/property/property_repository.py index 3911ab3ca..e2f8284ae 100644 --- a/repositories/property/property_repository.py +++ b/repositories/property/property_repository.py @@ -13,10 +13,8 @@ class PropertyIdentityInsert: """One row inserted into the FE-owned ``property`` table at Finalise (ADR-0013). Mirrors the exact column set today's Next.js ``/finalize`` writes: nine fields - plus ``creation_status='READY'``, plus ``certificate_number`` (the EPC - certificate the address2uprn lookup matched, not written by the old - Next.js route). ``address``/``postcode`` are the resolved (matched ?? - user-inputted) values and may be ``None``. + plus ``creation_status='READY'``. ``address``/``postcode`` are the resolved + (matched ?? user-inputted) values and may be ``None``. """ portfolio_id: int @@ -27,7 +25,6 @@ class PropertyIdentityInsert: user_inputted_address: Optional[str] user_inputted_postcode: Optional[str] lexiscore: Optional[float] - certificate_number: Optional[str] = None creation_status: str = "READY" diff --git a/tests/orchestration/test_bulk_upload_finaliser_orchestrator.py b/tests/orchestration/test_bulk_upload_finaliser_orchestrator.py index 0462e9792..335a3e919 100644 --- a/tests/orchestration/test_bulk_upload_finaliser_orchestrator.py +++ b/tests/orchestration/test_bulk_upload_finaliser_orchestrator.py @@ -100,7 +100,6 @@ def test_finalise_inserts_resolved_rows_and_marks_complete() -> None: "address2uprn_uprn": "100023", "address2uprn_address": "1 SOME STREET, TOWN, SW1A 1AA", "address2uprn_lexiscore": "0.95", - "address2uprn_certificate_number": "1234-5678-9012-3456-7890", }, ] @@ -115,7 +114,6 @@ def test_finalise_inserts_resolved_rows_and_marks_complete() -> None: assert row.postcode == "SW1A 1AA" # extracted from the matched address assert row.user_inputted_address == "1 Some Street" assert row.lexiscore == 0.95 - assert row.certificate_number == "1234-5678-9012-3456-7890" assert row.creation_status == "READY" # The upload is marked complete via the injected status writer. assert status.calls == [(task_id, "complete")] @@ -130,7 +128,6 @@ def test_finalise_falls_back_to_user_input_when_unmatched() -> None: "address2uprn_uprn": "invalid postcode", "address2uprn_address": "invalid postcode", "address2uprn_lexiscore": "", - "address2uprn_certificate_number": "invalid postcode", }, ] @@ -141,7 +138,6 @@ def test_finalise_falls_back_to_user_input_when_unmatched() -> None: assert row.address == "2 Other Road" # falls back to user input assert row.postcode == "B1 1BB" # falls back to user-inputted postcode assert row.lexiscore is None - assert row.certificate_number is None # missing sentinel -> None def test_finalise_parses_pandas_float_uprn() -> None: