From dcf0b2ccb95d2e4e90128de3793c06bd9791e37b Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Tue, 9 Jun 2026 12:17:57 +0000 Subject: [PATCH 1/4] use task_handler rather subtask_handler for magicplan --- applications/magic_plan/handler.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/applications/magic_plan/handler.py b/applications/magic_plan/handler.py index 13bb59c4..cf861908 100644 --- a/applications/magic_plan/handler.py +++ b/applications/magic_plan/handler.py @@ -1,21 +1,21 @@ import os +import boto3 from typing import Any, Optional -import boto3 - +from applications.magic_plan.magic_plan_trigger_request import MagicPlanTriggerRequest from infrastructure.magic_plan.config import MagicPlanConfig from infrastructure.magic_plan.magic_plan_client import MagicPlanClient from infrastructure.s3.s3_client import S3Client from orchestration.magic_plan_orchestrator import MagicPlanOrchestrator -from applications.magic_plan.magic_plan_trigger_request import MagicPlanTriggerRequest from domain.magicplan.models import Plan -from utilities.aws_lambda.subtask_handler import subtask_handler +from domain.tasks.tasks import Source +from utilities.aws_lambda.task_handler import task_handler from utilities.logger import setup_logger logger = setup_logger() -@subtask_handler() +@task_handler(task_source="magic_plan", source=Source.HUBSPOT_DEAL) def handler(body: dict[str, Any], context: Any) -> Optional[str]: config = MagicPlanConfig.from_env(os.environ) payload = MagicPlanTriggerRequest.model_validate(body) From 31c2e07a021d6e1f17e3daafbf7b6dee3a6e34e4 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Tue, 9 Jun 2026 12:19:39 +0000 Subject: [PATCH 2/4] revert accidental changes to magicplan repo --- .../magic_plan_postgres_repository.py | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/repositories/magic_plan/magic_plan_postgres_repository.py b/repositories/magic_plan/magic_plan_postgres_repository.py index c2df041e..fbf9203a 100644 --- a/repositories/magic_plan/magic_plan_postgres_repository.py +++ b/repositories/magic_plan/magic_plan_postgres_repository.py @@ -32,11 +32,15 @@ class MagicPlanPostgresRepository(MagicPlanRepository): self._session = session def get_plan_by_uploaded_file_id(self, uploaded_file_id: int) -> Optional[Plan]: - plan_row = self._session.execute( # pyright: ignore[reportDeprecated] - select(MagicPlanPlanModel).where( - col(MagicPlanPlanModel.uploaded_file_id) == uploaded_file_id + plan_row = ( + self._session.execute( # pyright: ignore[reportDeprecated] + select(MagicPlanPlanModel).where( + col(MagicPlanPlanModel.uploaded_file_id) == uploaded_file_id + ) ) - ).scalars().one_or_none() + .scalars() + .one_or_none() + ) if plan_row is None: return None @@ -47,7 +51,9 @@ class MagicPlanPostgresRepository(MagicPlanRepository): select(MagicPlanFloorModel).where( col(MagicPlanFloorModel.magic_plan_plan_id) == plan_id ) - ).scalars().all() + ) + .scalars() + .all() ) floor_ids = [cast(int, f.id) for f in floor_rows] @@ -56,7 +62,9 @@ class MagicPlanPostgresRepository(MagicPlanRepository): select(MagicPlanRoomModel).where( col(MagicPlanRoomModel.magic_plan_floor_id).in_(floor_ids) ) - ).scalars().all() + ) + .scalars() + .all() ) room_ids = [cast(int, r.id) for r in room_rows] @@ -65,7 +73,9 @@ class MagicPlanPostgresRepository(MagicPlanRepository): select(MagicPlanWindowModel).where( col(MagicPlanWindowModel.magic_plan_room_id).in_(room_ids) ) - ).scalars().all() + ) + .scalars() + .all() ) window_ids = [cast(int, w.id) for w in window_rows] @@ -74,7 +84,9 @@ class MagicPlanPostgresRepository(MagicPlanRepository): select(MagicPlanDoorModel).where( col(MagicPlanDoorModel.magic_plan_room_id).in_(room_ids) ) - ).scalars().all() + ) + .scalars() + .all() ) door_ids = [cast(int, d.id) for d in door_rows] @@ -86,7 +98,9 @@ class MagicPlanPostgresRepository(MagicPlanRepository): window_ids ) ) - ).scalars().all() + ) + .scalars() + .all() } door_vent_by_door_id = { cast(int, dv.magic_plan_door_id): dv @@ -94,7 +108,9 @@ class MagicPlanPostgresRepository(MagicPlanRepository): select(MagicPlanDoorVentilationModel).where( col(MagicPlanDoorVentilationModel.magic_plan_door_id).in_(door_ids) ) - ).scalars().all() + ) + .scalars() + .all() } windows_by_room_id: dict[int, list[Window]] = {} From ade6891ff0ffcb709d51eabba09570e09065cfe8 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Tue, 9 Jun 2026 12:24:12 +0000 Subject: [PATCH 3/4] revert accidental changes --- .../magic_plan_postgres_repository.py | 36 ++++++------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/repositories/magic_plan/magic_plan_postgres_repository.py b/repositories/magic_plan/magic_plan_postgres_repository.py index fbf9203a..c2df041e 100644 --- a/repositories/magic_plan/magic_plan_postgres_repository.py +++ b/repositories/magic_plan/magic_plan_postgres_repository.py @@ -32,15 +32,11 @@ class MagicPlanPostgresRepository(MagicPlanRepository): self._session = session def get_plan_by_uploaded_file_id(self, uploaded_file_id: int) -> Optional[Plan]: - plan_row = ( - self._session.execute( # pyright: ignore[reportDeprecated] - select(MagicPlanPlanModel).where( - col(MagicPlanPlanModel.uploaded_file_id) == uploaded_file_id - ) + plan_row = self._session.execute( # pyright: ignore[reportDeprecated] + select(MagicPlanPlanModel).where( + col(MagicPlanPlanModel.uploaded_file_id) == uploaded_file_id ) - .scalars() - .one_or_none() - ) + ).scalars().one_or_none() if plan_row is None: return None @@ -51,9 +47,7 @@ class MagicPlanPostgresRepository(MagicPlanRepository): select(MagicPlanFloorModel).where( col(MagicPlanFloorModel.magic_plan_plan_id) == plan_id ) - ) - .scalars() - .all() + ).scalars().all() ) floor_ids = [cast(int, f.id) for f in floor_rows] @@ -62,9 +56,7 @@ class MagicPlanPostgresRepository(MagicPlanRepository): select(MagicPlanRoomModel).where( col(MagicPlanRoomModel.magic_plan_floor_id).in_(floor_ids) ) - ) - .scalars() - .all() + ).scalars().all() ) room_ids = [cast(int, r.id) for r in room_rows] @@ -73,9 +65,7 @@ class MagicPlanPostgresRepository(MagicPlanRepository): select(MagicPlanWindowModel).where( col(MagicPlanWindowModel.magic_plan_room_id).in_(room_ids) ) - ) - .scalars() - .all() + ).scalars().all() ) window_ids = [cast(int, w.id) for w in window_rows] @@ -84,9 +74,7 @@ class MagicPlanPostgresRepository(MagicPlanRepository): select(MagicPlanDoorModel).where( col(MagicPlanDoorModel.magic_plan_room_id).in_(room_ids) ) - ) - .scalars() - .all() + ).scalars().all() ) door_ids = [cast(int, d.id) for d in door_rows] @@ -98,9 +86,7 @@ class MagicPlanPostgresRepository(MagicPlanRepository): window_ids ) ) - ) - .scalars() - .all() + ).scalars().all() } door_vent_by_door_id = { cast(int, dv.magic_plan_door_id): dv @@ -108,9 +94,7 @@ class MagicPlanPostgresRepository(MagicPlanRepository): select(MagicPlanDoorVentilationModel).where( col(MagicPlanDoorVentilationModel.magic_plan_door_id).in_(door_ids) ) - ) - .scalars() - .all() + ).scalars().all() } windows_by_room_id: dict[int, list[Window]] = {} From ea899fe0ab31d59d7f0c94f330ddfebe8b1092b9 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Tue, 9 Jun 2026 12:27:57 +0000 Subject: [PATCH 4/4] actually revert changes --- .../magic_plan_postgres_repository.py | 150 +----------------- .../magic_plan/magic_plan_repository.py | 4 - .../test_magic_plan_postgres_repository.py | 57 ------- 3 files changed, 2 insertions(+), 209 deletions(-) diff --git a/repositories/magic_plan/magic_plan_postgres_repository.py b/repositories/magic_plan/magic_plan_postgres_repository.py index c2df041e..baf15e56 100644 --- a/repositories/magic_plan/magic_plan_postgres_repository.py +++ b/repositories/magic_plan/magic_plan_postgres_repository.py @@ -1,20 +1,12 @@ from __future__ import annotations -from typing import Any, Optional, cast +from typing import Any, cast from sqlalchemy import delete, select from sqlalchemy.dialects.postgresql import insert as pg_insert from sqlmodel import Session, col -from domain.magicplan.models import ( - Door, - DoorVentilation, - Floor, - Plan, - Room, - Window, - WindowVentilation, -) +from domain.magicplan.models import Floor, Plan from infrastructure.postgres.magic_plan_tables import ( MagicPlanDoorModel, MagicPlanDoorVentilationModel, @@ -31,144 +23,6 @@ class MagicPlanPostgresRepository(MagicPlanRepository): def __init__(self, session: Session) -> None: self._session = session - def get_plan_by_uploaded_file_id(self, uploaded_file_id: int) -> Optional[Plan]: - plan_row = self._session.execute( # pyright: ignore[reportDeprecated] - select(MagicPlanPlanModel).where( - col(MagicPlanPlanModel.uploaded_file_id) == uploaded_file_id - ) - ).scalars().one_or_none() - if plan_row is None: - return None - - plan_id = cast(int, plan_row.id) - - floor_rows = list( - self._session.execute( # pyright: ignore[reportDeprecated] - select(MagicPlanFloorModel).where( - col(MagicPlanFloorModel.magic_plan_plan_id) == plan_id - ) - ).scalars().all() - ) - floor_ids = [cast(int, f.id) for f in floor_rows] - - room_rows = list( - self._session.execute( # pyright: ignore[reportDeprecated] - select(MagicPlanRoomModel).where( - col(MagicPlanRoomModel.magic_plan_floor_id).in_(floor_ids) - ) - ).scalars().all() - ) - room_ids = [cast(int, r.id) for r in room_rows] - - window_rows = list( - self._session.execute( # pyright: ignore[reportDeprecated] - select(MagicPlanWindowModel).where( - col(MagicPlanWindowModel.magic_plan_room_id).in_(room_ids) - ) - ).scalars().all() - ) - window_ids = [cast(int, w.id) for w in window_rows] - - door_rows = list( - self._session.execute( # pyright: ignore[reportDeprecated] - select(MagicPlanDoorModel).where( - col(MagicPlanDoorModel.magic_plan_room_id).in_(room_ids) - ) - ).scalars().all() - ) - door_ids = [cast(int, d.id) for d in door_rows] - - window_vent_by_window_id = { - cast(int, wv.magic_plan_window_id): wv - for wv in self._session.execute( # pyright: ignore[reportDeprecated] - select(MagicPlanWindowVentilationModel).where( - col(MagicPlanWindowVentilationModel.magic_plan_window_id).in_( - window_ids - ) - ) - ).scalars().all() - } - door_vent_by_door_id = { - cast(int, dv.magic_plan_door_id): dv - for dv in self._session.execute( # pyright: ignore[reportDeprecated] - select(MagicPlanDoorVentilationModel).where( - col(MagicPlanDoorVentilationModel.magic_plan_door_id).in_(door_ids) - ) - ).scalars().all() - } - - windows_by_room_id: dict[int, list[Window]] = {} - for w_row, w_id in zip(window_rows, window_ids): - room_id = cast(int, w_row.magic_plan_room_id) - wv_row = window_vent_by_window_id.get(w_id) - ventilation = ( - WindowVentilation( - opening_type=wv_row.opening_type, - num_openings=wv_row.num_openings, - pct_openable=wv_row.pct_openable, - trickle_vent_area_mm2=wv_row.trickle_vent_area_mm2, - num_trickle_vents=wv_row.num_trickle_vents, - ) - if wv_row is not None - else None - ) - windows_by_room_id.setdefault(room_id, []).append( - Window( - width_m=cast(float, w_row.width_m), - height_m=cast(float, w_row.height_m), - area_m2=cast(float, w_row.area_m2), - ventilation=ventilation, - ) - ) - - doors_by_room_id: dict[int, list[Door]] = {} - for d_row, d_id in zip(door_rows, door_ids): - room_id = cast(int, d_row.magic_plan_room_id) - dv_row = door_vent_by_door_id.get(d_id) - ventilation = ( - DoorVentilation(undercut_mm=dv_row.undercut_mm) - if dv_row is not None - else None - ) - doors_by_room_id.setdefault(room_id, []).append( - Door( - width_mm=cast(float, d_row.width_mm), - height_mm=cast(float, d_row.height_mm), - ventilation=ventilation, - ) - ) - - rooms_by_floor_id: dict[int, list[Room]] = {} - for r_row, r_id in zip(room_rows, room_ids): - floor_id = cast(int, r_row.magic_plan_floor_id) - rooms_by_floor_id.setdefault(floor_id, []).append( - Room( - name=cast(str, r_row.name), - width_m=cast(float, r_row.width_m), - length_m=cast(float, r_row.length_m), - area_m2=cast(float, r_row.area_m2), - windows=windows_by_room_id.get(r_id, []), - doors=doors_by_room_id.get(r_id, []), - ) - ) - - floors = [ - Floor( - level=f_row.level, - name=None, - rooms=rooms_by_floor_id.get(cast(int, f_row.id), []), - ) - for f_row in floor_rows - ] - - return Plan( - uid=cast(str, plan_row.magic_plan_uid), - name=plan_row.name, - address=plan_row.address, - postcode=plan_row.postcode, - floors=floors, - ) - def save(self, plan: Plan, uploaded_file_id: int) -> None: plan_id = self._upsert_plan(plan, uploaded_file_id) self._delete_children(plan_id) diff --git a/repositories/magic_plan/magic_plan_repository.py b/repositories/magic_plan/magic_plan_repository.py index 0e26cfdf..e404fad1 100644 --- a/repositories/magic_plan/magic_plan_repository.py +++ b/repositories/magic_plan/magic_plan_repository.py @@ -1,7 +1,6 @@ from __future__ import annotations from abc import ABC, abstractmethod -from typing import Optional from domain.magicplan.models import Plan @@ -17,6 +16,3 @@ class MagicPlanRepository(ABC): @abstractmethod def save(self, plan: Plan, uploaded_file_id: int) -> None: ... - - @abstractmethod - def get_plan_by_uploaded_file_id(self, uploaded_file_id: int) -> Optional[Plan]: ... diff --git a/tests/repositories/magic_plan/test_magic_plan_postgres_repository.py b/tests/repositories/magic_plan/test_magic_plan_postgres_repository.py index c064feee..4aaca0bf 100644 --- a/tests/repositories/magic_plan/test_magic_plan_postgres_repository.py +++ b/tests/repositories/magic_plan/test_magic_plan_postgres_repository.py @@ -91,63 +91,6 @@ def test_save_writes_ventilation_rows(db_engine: Engine) -> None: assert len(session.exec(select(MagicPlanDoorVentilationModel)).all()) == 1 -def test_get_plan_by_uploaded_file_id_returns_plan(db_engine: Engine) -> None: - # Arrange - plan = _plan() - - with Session(db_engine) as session: - MagicPlanPostgresRepository(session).save(plan, uploaded_file_id=42) - session.commit() - - # Act - with Session(db_engine) as session: - result = MagicPlanPostgresRepository(session).get_plan_by_uploaded_file_id(42) - - # Assert — full aggregate reconstructed; floor.name is not persisted (accepted data gap) - assert result is not None - assert result.uid == plan.uid - assert result.name == plan.name - assert result.address == plan.address - assert result.postcode == plan.postcode - assert len(result.floors) == 1 - result_floor = result.floors[0] - assert result_floor.level == plan.floors[0].level - assert result_floor.name is None # floor.name is not persisted per PRD - assert len(result_floor.rooms) == 1 - result_room = result_floor.rooms[0] - source_room = plan.floors[0].rooms[0] - assert result_room.name == source_room.name - assert result_room.width_m == source_room.width_m - assert result_room.length_m == source_room.length_m - assert result_room.area_m2 == source_room.area_m2 - assert len(result_room.windows) == 1 - result_window = result_room.windows[0] - source_window = source_room.windows[0] - assert result_window.width_m == source_window.width_m - assert result_window.height_m == source_window.height_m - assert result_window.area_m2 == source_window.area_m2 - assert result_window.ventilation is not None - assert result_window.ventilation == source_window.ventilation - assert len(result_room.doors) == 1 - result_door = result_room.doors[0] - source_door = source_room.doors[0] - assert result_door.width_mm == source_door.width_mm - assert result_door.height_mm == source_door.height_mm - assert result_door.ventilation is not None - assert result_door.ventilation == source_door.ventilation - - -def test_get_plan_by_uploaded_file_id_returns_none_when_not_found(db_engine: Engine) -> None: - # Arrange — nothing saved for uploaded_file_id=999 - - # Act - with Session(db_engine) as session: - result = MagicPlanPostgresRepository(session).get_plan_by_uploaded_file_id(999) - - # Assert - assert result is None - - def test_save_is_idempotent(db_engine: Engine) -> None: # Arrange plan = _plan()