from pydantic import BaseModel, Field from typing import Optional, List, Dict from datetime import datetime from models.shot import ShotStatus from models.task import TaskType, TaskStatus class ShotBase(BaseModel): name: str = Field(..., min_length=1, max_length=255) description: Optional[str] = None frame_start: int = Field(default=1001, ge=1) frame_end: int = Field(default=1001, ge=1) status: ShotStatus = ShotStatus.NOT_STARTED project_id: Optional[int] = Field(None, description="Project ID - auto-populated from episode if not provided") class ShotCreate(ShotBase): pass class ShotUpdate(BaseModel): name: Optional[str] = Field(None, min_length=1, max_length=255) description: Optional[str] = None frame_start: Optional[int] = Field(None, ge=1) frame_end: Optional[int] = Field(None, ge=1) status: Optional[ShotStatus] = None project_id: Optional[int] = Field(None, description="Project ID - must match episode's project") class ShotResponse(ShotBase): id: int project_id: int # Make required in response episode_id: int created_at: datetime updated_at: datetime # Summary information task_count: int = 0 # Optional computed field for display project_name: Optional[str] = Field(None, description="Project name for display purposes") class Config: from_attributes = True class TaskStatusInfo(BaseModel): """Task status information for table display""" task_type: str # String to support custom task types status: str # Changed from TaskStatus enum to str to support custom statuses task_id: Optional[int] = None assigned_user_id: Optional[int] = None class ShotListResponse(BaseModel): id: int name: str description: Optional[str] = None frame_start: int frame_end: int status: ShotStatus project_id: int episode_id: int created_at: datetime updated_at: datetime # Summary information task_count: int = 0 # Optional computed field for display project_name: Optional[str] = Field(None, description="Project name for display purposes") # Task status information for table display task_status: Dict[str, Optional[str]] = Field(default_factory=dict, description="Task status by task type") task_details: List[TaskStatusInfo] = Field(default_factory=list, description="Detailed task information") class Config: from_attributes = True class BulkShotCreate(BaseModel): """Schema for bulk shot creation with naming patterns""" name_prefix: str = Field(..., min_length=1, max_length=100) shot_count: int = Field(..., ge=1, le=1000) start_number: int = Field(default=10, ge=1) number_padding: int = Field(default=3, ge=1, le=6) frame_start: int = Field(default=1001, ge=1) frame_end: int = Field(default=1001, ge=1) description_template: Optional[str] = None create_default_tasks: bool = Field(default=True) task_types: Optional[List[str]] = None # If None, use default shot task types (changed from TaskType to str) class BulkShotResponse(BaseModel): """Response for bulk shot creation""" created_shots: List[ShotResponse] created_tasks_count: int = 0 message: str