Model/repositories/plan/plan_postgres_repository.py
Khalim Conn-Kowlessar 01c2c3910e refactor(modelling): rename the cluster SQLModel classes …Row → …Model
Standardise the modelling persistence classes on the …Model suffix (PlanModel,
RecommendationModel, RecommendationMaterialModel) — matching the epc_property
precedent and the legacy names the rest of backend/ already imports, so the
shim's plan re-export becomes literal (no alias) and the eventual shim deletion
needs zero renames. The …Row→…Model sweep for the non-cluster tables
(Property/Task/Material/…) waits until their live legacy …Model counterparts
are retired, to avoid reintroducing dual-definition collisions. No behaviour
change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 22:42:21 +00:00

55 lines
1.8 KiB
Python

from __future__ import annotations
from sqlmodel import Session, col, delete
from domain.modelling.plan import Plan
from infrastructure.postgres.modelling import PlanModel, RecommendationModel
from repositories.plan.plan_repository import PlanRepository
class PlanPostgresRepository(PlanRepository):
"""Maps a Plan and its Plan Measures onto the live ``plan`` /
``recommendation`` tables (ADR-0017). Does not commit — the Unit of Work
owns the transaction (ADR-0012)."""
def __init__(self, session: Session) -> None:
self._session = session
def save(
self,
plan: Plan,
*,
property_id: int,
scenario_id: int,
portfolio_id: int,
is_default: bool,
) -> int:
# Idempotent replace for (property_id, scenario_id): deleting the Plan
# cascades to its recommendation rows via the plan_id FK (ON DELETE
# CASCADE), so a re-run overwrites rather than duplicating (ADR-0012).
self._session.exec( # type: ignore[call-overload]
delete(PlanModel).where(
col(PlanModel.property_id) == property_id,
col(PlanModel.scenario_id) == scenario_id,
)
)
plan_row = PlanModel.from_domain(
plan,
property_id=property_id,
scenario_id=scenario_id,
portfolio_id=portfolio_id,
is_default=is_default,
)
self._session.add(plan_row)
self._session.flush()
if plan_row.id is None:
raise ValueError("plan row did not receive an id")
for measure in plan.measures:
self._session.add(
RecommendationModel.from_domain(
measure, property_id=property_id, plan_id=plan_row.id
)
)
return plan_row.id