from datetime import datetime from uuid import UUID from pydantic import BaseModel, ConfigDict, Field class InitializeRequest(BaseModel): username: str = Field(min_length=3, max_length=64, pattern=r"^[A-Za-z0-9_.-]+$") password: str = Field(min_length=12, max_length=256) class LoginRequest(BaseModel): username: str password: str class UserOut(BaseModel): model_config = ConfigDict(from_attributes=True) id: UUID username: str class FolderCreate(BaseModel): name: str = Field(min_length=1, max_length=120) class FolderOut(BaseModel): model_config = ConfigDict(from_attributes=True) id: UUID name: str class ListCreate(BaseModel): name: str = Field(min_length=1, max_length=120) folder_id: UUID | None = None class ListOut(BaseModel): model_config = ConfigDict(from_attributes=True) id: UUID folder_id: UUID | None name: str is_inbox: bool class TaskCreate(BaseModel): title: str = Field(min_length=1, max_length=500) list_id: UUID description: str = "" priority: int = Field(default=0, ge=0, le=3) due_at: datetime | None = None parent_id: UUID | None = None class TaskUpdate(BaseModel): title: str = Field(default=None, min_length=1, max_length=500) description: str = Field(default=None) priority: int | None = Field(default=None, ge=0, le=3) due_at: datetime | None = None completed: bool | None = None version: int = Field(ge=1) class TaskOut(BaseModel): model_config = ConfigDict(from_attributes=True) id: UUID list_id: UUID parent_id: UUID | None title: str description: str priority: int completed: bool due_at: datetime | None version: int class TaskPage(BaseModel): items: list[TaskOut] next_cursor: str | None = None