from __future__ import annotations from datetime import datetime from uuid import UUID from pydantic import BaseModel, ConfigDict, Field # ── Vote Session ───────────────────────────────────────────────── class VoteSessionCreate(BaseModel): """Payload for opening a new vote session.""" decision_id: UUID | None = None item_version_id: UUID | None = None voting_protocol_id: UUID = Field(..., description="ID of the voting protocol to apply") class VoteSessionOut(BaseModel): """Full vote session representation including tallies.""" model_config = ConfigDict(from_attributes=True) id: UUID decision_id: UUID | None = None item_version_id: UUID | None = None voting_protocol_id: UUID # Snapshot at session start wot_size: int smith_size: int techcomm_size: int # Dates starts_at: datetime ends_at: datetime # Status status: str # Tallies votes_for: int votes_against: int votes_total: int smith_votes_for: int techcomm_votes_for: int threshold_required: float result: str | None = None # Chain recording chain_recorded: bool chain_tx_hash: str | None = None created_at: datetime # ── Vote ───────────────────────────────────────────────────────── class VoteCreate(BaseModel): """Payload for casting a vote (with cryptographic proof).""" session_id: UUID vote_value: str = Field(..., max_length=32, description="for, against, or nuanced level") nuanced_level: int | None = Field(default=None, ge=0, le=5, description="0-5 for nuanced votes") comment: str | None = None signature: str = Field(..., description="Ed25519 signature of signed_payload") signed_payload: str = Field(..., description="The exact payload that was signed") class VoteOut(BaseModel): """Full vote representation.""" model_config = ConfigDict(from_attributes=True) id: UUID session_id: UUID voter_id: UUID vote_value: str nuanced_level: int | None = None comment: str | None = None signature: str signed_payload: str voter_wot_status: str voter_is_smith: bool voter_is_techcomm: bool is_active: bool created_at: datetime