import re from datetime import date from typing import Optional from pydantic import BaseModel, Field, field_validator class AiUserCreate(BaseModel): r"""Schema for creating a new AI user. Validates user data for the POST /ai/admin/users endpoint. Attributes: id (str, optional): User UUID. Auto-generated if not provided. name (str): User's full name. Required, 1-128 characters. email (str): User's email address. Required, max 256 characters. Must be a valid email format. dob (date, optional): Date of birth in YYYY-MM-DD format. gender (str, optional): User's gender, max 10 characters. Example:: >>> user = AiUserCreate( ... name="John Doe", ... email="john@example.com", ... dob="1990-01-15", ... gender="male" ... ) """ id: Optional[str] = None name: str = Field(min_length=1, max_length=128) email: str = Field(..., max_length=256) dob: Optional[date] = None gender: Optional[str] = Field(default=None, max_length=10) @field_validator("email") def validate_email(cls, v): if not re.match(r"^[^@\s]+@[^@\s]+\.[^@\s]+$", v): raise ValueError("invalid email") return v class AiUserUpdate(BaseModel): r"""Schema for updating an existing AI user. Validates user data for the PUT /ai/admin/users/{UserID} endpoint. All fields are optional for partial updates. Attributes: name (str, optional): User's full name, 1-128 characters. email (str, optional): User's email address, max 256 characters. Must be a valid email format if provided. dob (date, optional): Date of birth in YYYY-MM-DD format. gender (str, optional): User's gender, max 10 characters. Example:: >>> # Partial update - only change name >>> update = AiUserUpdate(name="Jane Doe") >>> # Full update >>> update = AiUserUpdate( ... name="Jane Doe", ... email="jane@example.com", ... gender="female" ... ) """ name: Optional[str] = Field(default=None, min_length=1, max_length=128) email: Optional[str] = Field(default=None, max_length=256) dob: Optional[date] = None gender: Optional[str] = Field(default=None, max_length=10) @field_validator("email") def validate_email(cls, v): if not re.match(r"^[^@\s]+@[^@\s]+\.[^@\s]+$", v): raise ValueError("invalid email") return v class AiUserFilter(BaseModel): r"""Schema for filtering and paginating AI users. Used for parsing query parameters in the GET /ai/admin/users endpoint. Attributes: q (str, optional): Search keyword for name and email fields. name (str, optional): Filter by name (partial match). email (str, optional): Filter by email (partial match). gender (str, optional): Filter by gender (exact match). dob_from (date, optional): Filter users with DOB on or after this date. dob_to (date, optional): Filter users with DOB on or before this date. created_from (str, optional): Filter users created on or after this datetime. created_to (str, optional): Filter users created on or before this datetime. page (int): Page number (0-indexed). Default: ``0`` size (int): Records per page, 1-200. Default: ``20`` sortby (str): Field to sort by. Default: ``"modified"`` asc (bool): Sort ascending if ``True``. Default: ``False`` Example:: >>> # Parse from query string >>> filter = AiUserFilter( ... q="john", ... page=0, ... size=10, ... sortby="created", ... asc=True ... ) """ q: Optional[str] = None name: Optional[str] = None email: Optional[str] = None gender: Optional[str] = None dob_from: Optional[date] = None dob_to: Optional[date] = None created_from: Optional[str] = None created_to: Optional[str] = None page: int = Field(default=0, ge=0) size: int = Field(default=20, ge=1, le=200) sortby: str = "modified" asc: bool = False