From 87d0cc41abce0bc88d4e8521c453fde7f9ea9dfe Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Wed, 1 Jul 2026 09:36:28 +0000 Subject: [PATCH] =?UTF-8?q?Resolve=20a=20party-ceiling=20roof=20marker=20t?= =?UTF-8?q?o=20the=20party-ceiling=20member=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- .../roof_party_ceiling_guard.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/domain/epc/property_overrides/roof_party_ceiling_guard.py b/domain/epc/property_overrides/roof_party_ceiling_guard.py index 97cdb09b1..c4b446c3e 100644 --- a/domain/epc/property_overrides/roof_party_ceiling_guard.py +++ b/domain/epc/property_overrides/roof_party_ceiling_guard.py @@ -1,9 +1,23 @@ from __future__ import annotations +import re from typing import Optional from domain.epc.property_overrides.roof_type import RoofType +# The roof-type token (before any ``: `` suffix), normalised to lower +# alphanumerics, → its party-ceiling RoofType member. Normalising strips spacing +# and case so both ``"another dwelling above"`` and ``"anotherdwellingabove"`` +# match the same marker. +_PARTY_CEILING_MARKERS: dict[str, RoofType] = { + "anotherdwellingabove": RoofType.ADJACENT_ANOTHER_DWELLING_ABOVE, +} + + +def _normalise_roof_token(description: str) -> str: + token = description.split(":", 1)[0] + return re.sub(r"[^a-z0-9]", "", token.lower()) + def roof_party_ceiling_guard(description: str) -> Optional[RoofType]: """Deterministically resolve a party-ceiling roof description to its RoofType. @@ -20,4 +34,4 @@ def roof_party_ceiling_guard(description: str) -> Optional[RoofType]: that is not a party-ceiling marker so the LLM classifier still handles it (#1376). """ - raise NotImplementedError + return _PARTY_CEILING_MARKERS.get(_normalise_roof_token(description))