"""Request/response models for the auth endpoints. These are the ONLY thing standing between the database and the HTTP response — FastAPI serialises a SQLAlchemy/dataclass object through whichever `response_model` a route declares, so a field simply not being listed here is what keeps password_hash/token_hash out of every response. When adding a new field, ask whether it belongs in a response before adding it, not after. """ from typing import Annotated from uuid import UUID from pydantic import BaseModel, EmailStr, Field # Named aliases rather than inline constraints, because these two rules are also applied outside # the HTTP layer: `velodrome.cli` validates `create-admin`'s input against exactly the same ones, # so an account created from the CLI can't hold a password the register endpoint would have # rejected. Defined once here so the two can't drift apart. Password = Annotated[str, Field(min_length=8, max_length=200)] DisplayName = Annotated[str, Field(min_length=1, max_length=200)] class RegisterRequest(BaseModel): email: EmailStr password: Password display_name: DisplayName invite_code: str = Field(min_length=1, max_length=200) class LoginRequest(BaseModel): email: EmailStr password: str = Field(min_length=1, max_length=200) class UserOut(BaseModel): id: UUID email: str display_name: str