""" Pydantic schemas for department management """ from pydantic import BaseModel, Field, validator from typing import List, Literal import re DEPARTMENT_NAME_PATTERN = r'^[a-z0-9_]{2,50}$' class CustomDepartmentCreate(BaseModel): """Schema for creating a new custom department""" department: str = Field(..., min_length=2, max_length=50, description="Department name") department_type: Literal["shot", "asset"] = Field(..., description="Whether this department applies to shots or assets") task_types: List[str] = Field(default_factory=list, description="Task types owned by this department") @validator('department') def validate_department_name(cls, v): """Validate department name format""" if not re.match(DEPARTMENT_NAME_PATTERN, v): raise ValueError( 'Department name must be 2-50 characters, lowercase alphanumeric with underscores only' ) return v @validator('task_types', each_item=True) def validate_task_type_name(cls, v): if not re.match(DEPARTMENT_NAME_PATTERN, v): raise ValueError( 'Task type name must be 2-50 characters, lowercase alphanumeric with underscores only' ) return v class CustomDepartmentUpdate(BaseModel): """Schema for updating a custom department name""" old_name: str = Field(..., description="Current department name") new_name: str = Field(..., min_length=2, max_length=50, description="New department name") @validator('new_name') def validate_department_name(cls, v): """Validate department name format""" if not re.match(DEPARTMENT_NAME_PATTERN, v): raise ValueError( 'Department name must be 2-50 characters, lowercase alphanumeric with underscores only' ) return v class DepartmentTaskTypeCreate(BaseModel): """Schema for adding a task type to a custom department""" task_type: str = Field(..., min_length=2, max_length=50, description="Task type name") @validator('task_type') def validate_task_type_name(cls, v): if not re.match(DEPARTMENT_NAME_PATTERN, v): raise ValueError( 'Task type name must be 2-50 characters, lowercase alphanumeric with underscores only' ) return v class DepartmentTaskTypeUpdate(BaseModel): """Schema for renaming a task type within a custom department""" old_name: str = Field(..., description="Current task type name") new_name: str = Field(..., min_length=2, max_length=50, description="New task type name") @validator('new_name') def validate_task_type_name(cls, v): if not re.match(DEPARTMENT_NAME_PATTERN, v): raise ValueError( 'Task type name must be 2-50 characters, lowercase alphanumeric with underscores only' ) return v class DepartmentInfo(BaseModel): """A single department: its name, whether it applies to shots or assets, and its owned task types""" name: str type: Literal["shot", "asset"] task_types: List[str] class AllDepartmentsResponse(BaseModel): """Schema for response containing all departments (standard + custom)""" departments: List[DepartmentInfo] = Field(..., description="All departments") standard_departments: List[DepartmentInfo] = Field(..., description="Standard departments (read-only)") custom_departments: List[DepartmentInfo] = Field(..., description="Custom departments") class DepartmentInUseError(BaseModel): """Schema for error when trying to delete a department in use""" error: str = Field(..., description="Error message") department: str = Field(..., description="Department that is in use") member_count: int = Field(..., description="Number of project members using this department") task_count: int = Field(..., description="Number of tasks using this department") class DepartmentTaskTypeInUseError(BaseModel): """Schema for error when trying to delete a department task type in use""" error: str = Field(..., description="Error message") department: str = Field(..., description="Department the task type belongs to") task_type: str = Field(..., description="Task type that is in use") task_count: int = Field(..., description="Number of tasks using this task type")