"""Pydantic schemas for Project, SubProject, ProjectFunctionGroup, ProjectFunction.""" from datetime import datetime from pydantic import BaseModel, Field # ===== Project Schemas ===== class ProjectCreateRequest(BaseModel): """Request body for creating a new project.""" name: str = Field(..., max_length=255) description: str | None = None status: str = Field("draft", max_length=20) start_date: datetime | None = None end_date: datetime | None = None budget: float | None = None total_costs: float = 0.0 notes: str | None = None custom_fields: str | None = None custom_field_defs: str | None = None class ProjectUpdateRequest(BaseModel): """Request body for updating an existing project.""" name: str | None = Field(None, max_length=255) description: str | None = None status: str | None = Field(None, max_length=20) start_date: datetime | None = None end_date: datetime | None = None budget: float | None = None total_costs: float | None = None notes: str | None = None custom_fields: str | None = None custom_field_defs: str | None = None class ProjectResponse(BaseModel): """Public project representation.""" id: str account_id: str name: str description: str | None = None status: str start_date: datetime | None = None end_date: datetime | None = None budget: float | None = None total_costs: float = 0.0 notes: str | None = None custom_fields: str | None = None custom_field_defs: str | None = None created_at: datetime updated_at: datetime model_config = {"from_attributes": True} class ProjectListResponse(BaseModel): """Paginated list of projects.""" items: list[ProjectResponse] total: int page: int size: int # ===== SubProject Schemas ===== class SubProjectCreateRequest(BaseModel): """Request body for creating a subproject.""" name: str = Field(..., max_length=255) parent_id: str | None = None sort_order: int = 0 class SubProjectUpdateRequest(BaseModel): """Request body for updating a subproject.""" name: str | None = Field(None, max_length=255) parent_id: str | None = None sort_order: int | None = None class SubProjectResponse(BaseModel): """Public subproject representation.""" id: str name: str project_id: str parent_id: str | None = None sort_order: int = 0 model_config = {"from_attributes": True} class SubProjectListResponse(BaseModel): """Paginated list of subprojects.""" items: list[SubProjectResponse] total: int page: int size: int # ===== ProjectFunctionGroup Schemas ===== class ProjectFunctionGroupCreateRequest(BaseModel): """Request body for creating a function group.""" name: str = Field(..., max_length=255) sort_order: int = 0 class ProjectFunctionGroupUpdateRequest(BaseModel): """Request body for updating a function group.""" name: str | None = Field(None, max_length=255) sort_order: int | None = None class ProjectFunctionGroupResponse(BaseModel): """Public function group representation.""" id: str name: str project_id: str sort_order: int = 0 model_config = {"from_attributes": True} class ProjectFunctionGroupListResponse(BaseModel): """Paginated list of function groups.""" items: list[ProjectFunctionGroupResponse] total: int page: int size: int # ===== ProjectFunction Schemas ===== class ProjectFunctionCreateRequest(BaseModel): """Request body for creating a project function.""" name: str = Field(..., max_length=255) quantity: float = 1.0 daily_costs: float = 0.0 total_costs: float = 0.0 sort_order: int = 0 class ProjectFunctionUpdateRequest(BaseModel): """Request body for updating a project function.""" name: str | None = Field(None, max_length=255) quantity: float | None = None daily_costs: float | None = None total_costs: float | None = None sort_order: int | None = None class ProjectFunctionResponse(BaseModel): """Public project function representation.""" id: str name: str function_group_id: str quantity: float = 1.0 daily_costs: float = 0.0 total_costs: float = 0.0 sort_order: int = 0 model_config = {"from_attributes": True} class ProjectFunctionListResponse(BaseModel): """Paginated list of project functions.""" items: list[ProjectFunctionResponse] total: int page: int size: int