LinkDesk/backend/schemas/shot.py

99 lines
3.2 KiB
Python

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