"""FlowDeck — Pydantic request models for API validation.""" from __future__ import annotations from pydantic import BaseModel, Field, model_validator from app.middleware.security import ALLOWED_EXTENSIONS, _ext # ── File Save ──────────────────────────────────────────────── class FileSaveRequest(BaseModel): """Request model for saving/updating a file via Gitea.""" path: str = Field(..., min_length=1, description="File path in the repository") content: str = Field(..., description="File content (UTF-8 encoded)") message: str = Field(default="Update via FlowDeck", description="Commit message") sha: str | None = Field(default=None, description="SHA of the file being updated (required for updates)") @model_validator(mode="after") def validate_path_extension(self): ext = _ext(self.path) if ext and ext not in ALLOWED_EXTENSIONS: raise ValueError(f"File extension '{ext}' is not allowed") return self # ── Upload ─────────────────────────────────────────────────── class UploadValidationResult(BaseModel): """Result of validating an upload.""" filename: str size: int extension: str valid: bool error: str | None = None class IssueCreateRequest(BaseModel): """Request model for creating a Gitea issue.""" title: str = Field(..., min_length=1, max_length=500) body: str = Field(default="") labels: str = Field(default="", description="Comma-separated label IDs") milestone: str = Field(default="", description="Milestone ID") assignee: str = Field(default="") class IssueUpdateRequest(BaseModel): """Request model for updating a Gitea issue (partial update).""" title: str | None = Field(default=None, max_length=500) body: str | None = Field(default=None) state: str | None = Field(default=None, pattern=r"^(open|closed)$") labels: str | None = Field(default=None, description="Comma-separated label IDs") milestone: str | None = Field(default=None) assignee: str | None = Field(default=None) # ── Card Move ──────────────────────────────────────────────── class CardMoveRequest(BaseModel): """Request model for moving a card between columns.""" owner: str = Field(..., min_length=1) repo: str = Field(..., min_length=1) issue_id: int = Field(..., gt=0) column: str = Field(..., min_length=1) # ── Column Mapping ─────────────────────────────────────────── class ColMappingRequest(BaseModel): """Request model for column-to-label mapping.""" owner: str = Field(..., min_length=1) repo: str = Field(..., min_length=1) column: str = Field(..., min_length=1) gitea_label: str = Field(..., min_length=1) close_issue: bool = Field(default=False)