mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
Slice 3 of #1157. Persists a Plan and its Plan Measures to the live plan / recommendation tables via SQLModel mirrors (ADR-0017). - infrastructure/postgres/plan_table.py: PlanRow (`plan`) + RecommendationRow (`recommendation`) mirrors. RecommendationRow adds the new `plan_id` FK (ON DELETE CASCADE) linking each Plan Measure to its Plan, replacing the plan_recommendations m2m for new writes. from_domain mappers convert CO2 kg → tonnes to match the live column contract and derive post_epc_rating from the rounded SAP. Only the impact + cost + identity columns the tracer fills are declared; energy/bill, U-value, valuation, labour, plan_type are left to later slices. - PlanRepository port + PlanPostgresRepository.save(plan, *, property_id, scenario_id, portfolio_id, is_default) -> plan id. Idempotent replace: deleting the Plan cascades to its recommendation rows via plan_id, so a re-run overwrites (ADR-0012). No commit — the UoW owns the transaction. 2 tests (persist + idempotent re-run); pyright strict clean; 73 pass across repositories/modelling/orchestration with no regressions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
29 lines
865 B
Python
29 lines
865 B
Python
from __future__ import annotations
|
|
|
|
from abc import ABC, abstractmethod
|
|
|
|
from domain.modelling.plan import Plan
|
|
|
|
|
|
class PlanRepository(ABC):
|
|
"""Persists a Plan (and its Plan Measures) for a Property + Scenario.
|
|
|
|
One Plan per (Property, Scenario). The write is idempotent on re-run: it
|
|
replaces the existing Plan for that pair rather than duplicating (ADR-0012
|
|
/ ADR-0017). `portfolio_id` and `is_default` are supplied by the
|
|
orchestrator (the former from the trigger, the latter from the Scenario).
|
|
"""
|
|
|
|
@abstractmethod
|
|
def save(
|
|
self,
|
|
plan: Plan,
|
|
*,
|
|
property_id: int,
|
|
scenario_id: int,
|
|
portfolio_id: int,
|
|
is_default: bool,
|
|
) -> int:
|
|
"""Persist ``plan`` and return its Plan id, replacing any existing Plan
|
|
for ``(property_id, scenario_id)``."""
|
|
...
|