www_site/services/api/app/schemas.py

70 lines
1.7 KiB
Python

from datetime import datetime
from typing import Any, Literal
from uuid import UUID
from pydantic import BaseModel, EmailStr, Field, field_validator
class RegisterRequest(BaseModel):
email: EmailStr
password: str = Field(min_length=8, max_length=128)
class LoginRequest(BaseModel):
email: EmailStr
password: str = Field(min_length=1, max_length=128)
class PasswordChangeRequest(BaseModel):
current_password: str = Field(min_length=1, max_length=128)
new_password: str = Field(min_length=8, max_length=128)
class UserPublic(BaseModel):
id: UUID
email: str | None
phone: str | None
role: Literal["user", "admin"]
plan: Literal["free", "vip"]
status: Literal["active", "disabled"]
email_verified: bool
phone_verified: bool
created_at: datetime
last_login_at: datetime | None
class AuthResponse(BaseModel):
user: UserPublic
class MembershipRequest(BaseModel):
plan: Literal["free", "vip"]
starts_at: datetime | None = None
expires_at: datetime | None = None
reason: str = Field(min_length=1, max_length=500)
class StatusRequest(BaseModel):
status: Literal["active", "disabled"]
reason: str = Field(min_length=1, max_length=500)
class QuotaAdjustmentRequest(BaseModel):
amount: int
reason: str = Field(min_length=1, max_length=500)
idempotency_key: str = Field(min_length=8, max_length=120)
class VerificationConfirmRequest(BaseModel):
challenge_id: UUID
code: str = Field(min_length=4, max_length=12)
class VerificationSendRequest(BaseModel):
channel: Literal["email", "phone"]
purpose: Literal["registration", "contact_binding", "contact_change", "password_reset"]
def normalize_email(value: str) -> str:
return value.strip().lower()