""" Schools API - Pydantic Models. Data models for school and school staff endpoints. """ from typing import Optional, List from datetime import datetime from pydantic import BaseModel, Field # ============================================================================= # School Type Models # ============================================================================= class SchoolTypeResponse(BaseModel): """School type response model.""" id: str name: str name_short: Optional[str] = None category: Optional[str] = None description: Optional[str] = None # ============================================================================= # School Models # ============================================================================= class SchoolBase(BaseModel): """Base school model for creation/update.""" name: str = Field(..., max_length=255) school_number: Optional[str] = Field(None, max_length=20) school_type_id: Optional[str] = None school_type_raw: Optional[str] = None state: str = Field(..., max_length=10) district: Optional[str] = None city: Optional[str] = None postal_code: Optional[str] = None street: Optional[str] = None address_full: Optional[str] = None latitude: Optional[float] = None longitude: Optional[float] = None website: Optional[str] = None email: Optional[str] = None phone: Optional[str] = None fax: Optional[str] = None principal_name: Optional[str] = None principal_title: Optional[str] = None principal_email: Optional[str] = None principal_phone: Optional[str] = None secretary_name: Optional[str] = None secretary_email: Optional[str] = None secretary_phone: Optional[str] = None student_count: Optional[int] = None teacher_count: Optional[int] = None class_count: Optional[int] = None founded_year: Optional[int] = None is_public: bool = True is_all_day: Optional[bool] = None has_inclusion: Optional[bool] = None languages: Optional[List[str]] = None specializations: Optional[List[str]] = None source: Optional[str] = None source_url: Optional[str] = None class SchoolCreate(SchoolBase): """School creation model.""" pass class SchoolUpdate(BaseModel): """School update model (all fields optional).""" name: Optional[str] = Field(None, max_length=255) school_number: Optional[str] = None school_type_id: Optional[str] = None state: Optional[str] = None district: Optional[str] = None city: Optional[str] = None postal_code: Optional[str] = None street: Optional[str] = None website: Optional[str] = None email: Optional[str] = None phone: Optional[str] = None principal_name: Optional[str] = None student_count: Optional[int] = None teacher_count: Optional[int] = None is_active: Optional[bool] = None class SchoolResponse(BaseModel): """School response model.""" id: str name: str school_number: Optional[str] = None school_type: Optional[str] = None school_type_short: Optional[str] = None school_category: Optional[str] = None state: str district: Optional[str] = None city: Optional[str] = None postal_code: Optional[str] = None street: Optional[str] = None address_full: Optional[str] = None latitude: Optional[float] = None longitude: Optional[float] = None website: Optional[str] = None email: Optional[str] = None phone: Optional[str] = None fax: Optional[str] = None principal_name: Optional[str] = None principal_email: Optional[str] = None student_count: Optional[int] = None teacher_count: Optional[int] = None is_public: bool = True is_all_day: Optional[bool] = None staff_count: int = 0 source: Optional[str] = None crawled_at: Optional[datetime] = None is_active: bool = True created_at: datetime updated_at: datetime class SchoolsListResponse(BaseModel): """List response with pagination info.""" schools: List[SchoolResponse] total: int page: int page_size: int class SchoolStatsResponse(BaseModel): """School statistics response.""" total_schools: int total_staff: int schools_by_state: dict schools_by_type: dict schools_with_website: int schools_with_email: int schools_with_principal: int total_students: int total_teachers: int last_crawl_time: Optional[datetime] = None class BulkImportRequest(BaseModel): """Bulk import request.""" schools: List[SchoolCreate] class BulkImportResponse(BaseModel): """Bulk import response.""" imported: int updated: int skipped: int errors: List[str] # ============================================================================= # School Staff Models # ============================================================================= class SchoolStaffBase(BaseModel): """Base school staff model.""" first_name: Optional[str] = None last_name: str full_name: Optional[str] = None title: Optional[str] = None position: Optional[str] = None position_type: Optional[str] = None subjects: Optional[List[str]] = None email: Optional[str] = None phone: Optional[str] = None class SchoolStaffCreate(SchoolStaffBase): """School staff creation model.""" school_id: str class SchoolStaffResponse(SchoolStaffBase): """School staff response model.""" id: str school_id: str school_name: Optional[str] = None profile_url: Optional[str] = None photo_url: Optional[str] = None is_active: bool = True created_at: datetime class SchoolStaffListResponse(BaseModel): """Staff list response.""" staff: List[SchoolStaffResponse] total: int