from datetime import datetime, timedelta from enum import Enum from typing import Optional, List from pydantic import BaseModel, EmailStr, Field class UserRole(str, Enum): user = "user" admin = "admin" class Token(BaseModel): access_token: str token_type: str = "bearer" expires_in: int = Field(..., description="Seconds until token expiration") class UserBase(BaseModel): email: EmailStr class UserCreate(UserBase): password: str class UserLogin(UserBase): password: str class UserOut(UserBase): id: int role: UserRole created_at: datetime class Config: from_attributes = True class CemeteryBase(BaseModel): name: str description: Optional[str] = None region: Optional[str] = None center_lat: float center_lon: float zoom: int = 15 class CemeteryCreate(CemeteryBase): pass class CemeteryUpdate(BaseModel): name: Optional[str] = None description: Optional[str] = None region: Optional[str] = None center_lat: Optional[float] = None center_lon: Optional[float] = None zoom: Optional[int] = None class CemeteryOut(CemeteryBase): id: int created_at: datetime class Config: from_attributes = True class GraveStatus(str, Enum): pending = "pending" approved = "approved" rejected = "rejected" class GraveBase(BaseModel): cemetery_id: int lat: float lon: float full_name: str birth_date: Optional[str] = None death_date: Optional[str] = None class GraveCreate(GraveBase): pass class GraveUpdate(BaseModel): lat: Optional[float] = None lon: Optional[float] = None full_name: Optional[str] = None birth_date: Optional[str] = None death_date: Optional[str] = None status: Optional[GraveStatus] = None class GraveOut(GraveBase): id: int status: GraveStatus photo_url: Optional[str] = None created_by: Optional[int] created_at: datetime updated_at: datetime class Config: from_attributes = True class FavoriteBase(BaseModel): grave_id: int class FavoriteCreate(FavoriteBase): pass class FavoriteOut(FavoriteBase): id: int user_id: int created_at: datetime class Config: from_attributes = True class SearchQuery(BaseModel): cemetery_id: int q: str = Field(..., description="Full name query") class ApproveRequest(BaseModel): approved: bool comment: Optional[str] = None class RejectRequest(BaseModel): comment: str