"""Backend-neutral simulation result and preparation error contracts.""" from __future__ import annotations from dataclasses import dataclass from typing import Literal from app.simulation.core.metadata import ResultVariableMetadata SimulationRunStatus = Literal["completed", "cancelled", "failed"] @dataclass(frozen=True) class SimulationPreparationIssue: code: str message: str def as_dict(self) -> dict[str, str]: return {"code": self.code, "message": self.message} class SimulationPreparationError(ValueError): def __init__(self, issues: tuple[SimulationPreparationIssue, ...]) -> None: super().__init__("The compiled model is not ready for simulation.") self.issues = issues @dataclass(frozen=True) class GenericSimulationResult: success: bool status: SimulationRunStatus message: str simulated_until: float requested_stop_time: float variables: tuple[ResultVariableMetadata, ...] series: dict[str, list[float]] final: dict[str, float] diagnostics: dict[str, object] def as_dict(self) -> dict[str, object]: return { "success": self.success, "status": self.status, "partial": self.status != "completed", "message": self.message, "simulatedUntil": self.simulated_until, "requestedStopTime": self.requested_stop_time, "variables": [variable.as_dict() for variable in self.variables], "series": self.series, "final": self.final, "diagnostics": self.diagnostics, }