""" Pydantic models for request/response validation """ from datetime import datetime from typing import Optional, List from pydantic import BaseModel, EmailStr, Field from bson import ObjectId class PyObjectId(str): """Custom ObjectId type for Pydantic""" @classmethod def __get_validators__(cls): yield cls.validate @classmethod def validate(cls, v): if not ObjectId.is_valid(v): raise ValueError("Invalid ObjectId") return str(v) # Auth models class SendCodeRequest(BaseModel): email: EmailStr class RegisterRequest(BaseModel): email: EmailStr code: str password: str username: str class LoginRequest(BaseModel): email: EmailStr password: str class TelegramWidgetAuth(BaseModel): id: int first_name: Optional[str] = None last_name: Optional[str] = None username: Optional[str] = None photo_url: Optional[str] = None auth_date: Optional[int] = None hash: Optional[str] = None # User models class UserBase(BaseModel): id: Optional[str] = Field(None, alias='_id') username: str firstName: Optional[str] = None lastName: Optional[str] = None photoUrl: Optional[str] = None role: str = 'user' telegramId: Optional[str] = None class Config: populate_by_name = True class UserResponse(UserBase): email: Optional[str] = None banned: bool = False createdAt: datetime lastActiveAt: Optional[datetime] = None # Post models class PostBase(BaseModel): id: Optional[str] = Field(None, alias='_id') content: Optional[str] = None images: List[str] = [] tags: List[str] = [] hashtags: List[str] = [] isNSFW: bool = False isHomo: bool = False isArt: bool = False createdAt: datetime class Config: populate_by_name = True class PostResponse(PostBase): author: Optional[UserBase] = None likesCount: int = 0 commentsCount: int = 0 publishedToChannel: bool = False adminNumber: Optional[int] = None # Report models class ReportBase(BaseModel): id: Optional[str] = Field(None, alias='_id') postId: str reason: str status: str = 'pending' createdAt: datetime class Config: populate_by_name = True class ReportResponse(ReportBase): reporter: Optional[UserBase] = None post: Optional[PostResponse] = None reviewedBy: Optional[UserBase] = None # Admin models class AdminBase(BaseModel): id: Optional[str] = Field(None, alias='_id') telegramId: str username: str firstName: Optional[str] = None lastName: Optional[str] = None adminNumber: int class Config: populate_by_name = True class AdminResponse(AdminBase): addedBy: Optional[str] = None createdAt: datetime # Request models class UpdatePostRequest(BaseModel): content: Optional[str] = None tags: Optional[List[str]] = None isNSFW: Optional[bool] = None isHomo: Optional[bool] = None isArt: Optional[bool] = None class UpdateReportRequest(BaseModel): status: str = 'reviewed' class BanUserRequest(BaseModel): banned: bool days: Optional[int] = None class AddAdminRequest(BaseModel): userId: str adminNumber: int class ConfirmAdminRequest(BaseModel): userId: str code: str