mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
56 lines
1.9 KiB
Python
56 lines
1.9 KiB
Python
from __future__ import annotations
|
|
|
|
from abc import ABC, abstractmethod
|
|
from dataclasses import dataclass
|
|
|
|
from domain.modelling.plan import Plan
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class PlanSaveRequest:
|
|
"""Bundles the five fields the plan repository needs to persist one Plan.
|
|
|
|
Mirrors ``EpcSaveRequest`` in shape — used by ``PlanRepository.save_batch()``
|
|
to accumulate write intent before the batch is flushed in one Unit of Work."""
|
|
|
|
plan: Plan
|
|
property_id: int
|
|
scenario_id: int
|
|
portfolio_id: int
|
|
is_default: bool
|
|
|
|
|
|
class PlanRepository(ABC):
|
|
"""Persists a Plan (and its Plan Measures) for a Property + Scenario.
|
|
|
|
A re-run INSERTs a fresh Plan and keeps the prior one as history rather than
|
|
deleting it. When the new Plan is the default, prior default Plans for the
|
|
same (Property, Scenario) are demoted to `is_default=False`, so the current
|
|
Plan is the one with `is_default=True` (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. Keeps prior Plans for
|
|
``(property_id, scenario_id)`` as history; when ``is_default`` is True,
|
|
demotes those prior Plans to ``is_default=False``."""
|
|
...
|
|
|
|
@abstractmethod
|
|
def save_batch(self, requests: list[PlanSaveRequest]) -> list[int]:
|
|
"""Persist a batch of Plans in three statements regardless of batch size.
|
|
|
|
Returns one plan id per request in input order. Fires a single demote
|
|
UPDATE only when at least one request has ``is_default=True``. Keeps
|
|
prior Plans as history (ADR-0017)."""
|
|
...
|