import uuid from datetime import datetime from pydantic import BaseModel, ConfigDict, model_validator from api.models.decision import DecisionStatus, DecisionType from api.schemas.compat import OptionalWorkplanIdCompatMixin from pydantic import AliasChoices, Field class DecisionCreate(BaseModel): topic_id: uuid.UUID | None = None workplan_id: uuid.UUID | None = Field( default=None, validation_alias=AliasChoices("workplan_id", "workstream_id"), ) title: str description: str | None = None decision_type: DecisionType = DecisionType.pending status: DecisionStatus = DecisionStatus.open rationale: str | None = None decided_by: str | None = None decided_at: datetime | None = None deadline: datetime | None = None escalation_note: str | None = None @model_validator(mode="after") def topic_or_workplan_required(self) -> "DecisionCreate": if self.topic_id is None and self.workplan_id is None: raise ValueError("At least one of topic_id or workplan_id must be set") return self class DecisionResolve(BaseModel): rationale: str decided_by: str write_log: bool = True # append to DECISIONS.md in the registered project directory class DecisionUpdate(BaseModel): title: str | None = None description: str | None = None decision_type: DecisionType | None = None status: DecisionStatus | None = None rationale: str | None = None decided_by: str | None = None decided_at: datetime | None = None deadline: datetime | None = None escalation_note: str | None = None superseded_by: uuid.UUID | None = None class DecisionRead(OptionalWorkplanIdCompatMixin, BaseModel): model_config = ConfigDict(from_attributes=True) id: uuid.UUID topic_id: uuid.UUID | None = None title: str description: str | None = None decision_type: DecisionType status: DecisionStatus rationale: str | None = None decided_by: str | None = None decided_at: datetime | None = None deadline: datetime | None = None escalation_note: str | None = None superseded_by: uuid.UUID | None = None created_at: datetime updated_at: datetime