mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
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>
55 lines
1.8 KiB
Python
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
|