from pydantic import BaseModel, ConfigDict, Field from datetime import datetime, date from typing import Optional, List, Literal from app.schemas.project_task import ProjectTaskResponse ProjectStatus = Literal["not_started", "in_progress", "completed", "blocked", "review", "on_hold"] class ProjectCreate(BaseModel): model_config = ConfigDict(extra="forbid") name: str = Field(min_length=1, max_length=255) description: Optional[str] = Field(None, max_length=5000) status: ProjectStatus = "not_started" color: Optional[str] = Field(None, max_length=20) due_date: Optional[date] = None is_tracked: bool = False class ProjectUpdate(BaseModel): model_config = ConfigDict(extra="forbid") name: Optional[str] = Field(None, min_length=1, max_length=255) description: Optional[str] = Field(None, max_length=5000) status: Optional[ProjectStatus] = None color: Optional[str] = Field(None, max_length=20) due_date: Optional[date] = None is_tracked: Optional[bool] = None class ProjectResponse(BaseModel): id: int user_id: int = 0 name: str description: Optional[str] status: str color: Optional[str] due_date: Optional[date] is_tracked: bool created_at: datetime updated_at: datetime tasks: List[ProjectTaskResponse] = [] model_config = ConfigDict(from_attributes=True) class TrackedTaskResponse(BaseModel): id: int title: str status: str priority: str due_date: date project_name: str project_id: int parent_task_title: Optional[str] = None