"""Simulation plan model.""" import json from datetime import datetime from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey from sqlalchemy.orm import relationship, backref from ..database import Base class SimulationPlan(Base): """A simulation plan (simulation_plan.json format, compatible with local executor).""" __tablename__ = "simulation_plans" id = Column(Integer, primary_key=True, index=True) project_id = Column(Integer, ForeignKey("projects.id"), nullable=False, index=True) name = Column(String(200), nullable=False) plan_id = Column(String(100), unique=True, index=True) # e.g. SP-20260827-001 status = Column(String(20), default="draft") # draft / confirmed / executing / completed / failed plan_json = Column(Text, nullable=False) # Full simulation_plan.json content variables_summary = Column(Text, default="") # JSON: variable names and ranges for display estimated_points = Column(Integer, default=0) estimated_time_min = Column(Integer, default=0) notes = Column(Text, default="") created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # F2 fix: cascade delete from project -> plans -> results project = relationship("Project", backref=backref("plans", cascade="all, delete-orphan")) results = relationship("SimulationResult", backref="plan", cascade="all, delete-orphan") def get_plan_dict(self) -> dict: try: return json.loads(self.plan_json) if self.plan_json else {} except (json.JSONDecodeError, TypeError): return {} def set_plan_dict(self, data: dict) -> None: self.plan_json = json.dumps(data, ensure_ascii=False, indent=2)