from datetime import datetime from typing import Literal from pydantic import BaseModel, ConfigDict, EmailStr, Field # ---------- پایه ---------- class ORMModel(BaseModel): model_config = ConfigDict(from_attributes=True) # ---------- خروجی‌ها ---------- class BrandOut(ORMModel): id: int name: str logo: str hero: str contact_bg: str phone: str phone_href: str email: str address: str class ServiceOut(ORMModel): id: int title: str desc: str icon: str class ProjectOut(ORMModel): id: int slug: str title: str location: str year: str status: str image: str gallery: list[str] area: str floors: str units: str client: str summary: str body: list[str] class ArticleOut(ORMModel): id: int slug: str title: str date: str category: str image: str read: str excerpt: str body: list[str] class TestimonialOut(ORMModel): id: int name: str role: str quote: str class FaqOut(ORMModel): id: int question: str answer: str class TeamMemberOut(ORMModel): id: int name: str role: str bio: str class TimelineItemOut(ORMModel): id: int year: str title: str desc: str image: str class StatOut(ORMModel): id: int value: int suffix: str label: str class WhyUsItemOut(ORMModel): id: int title: str desc: str class BeforeAfterOut(ORMModel): id: int title: str lead: str before: str after: str before_label: str after_label: str class ContactMessageOut(ORMModel): id: int name: str phone: str note: str is_read: bool created_at: datetime class SubscriberOut(ORMModel): id: int email: str is_active: bool created_at: datetime # ---------- ورودی فرم‌ها ---------- class ContactIn(BaseModel): name: str = Field(min_length=3, max_length=128) phone: str = Field(pattern=r"^[\d۰-۹+\-\s]{8,15}$") note: str = Field(default="", max_length=2000) class NewsletterIn(BaseModel): email: EmailStr # ---------- ورودی‌های پنل مدیریت ---------- class LoginIn(BaseModel): username: str password: str class TokenOut(BaseModel): access_token: str token_type: str = "bearer" class BrandIn(BaseModel): name: str = "" logo: str = "" hero: str = "" contact_bg: str = "" phone: str = "" phone_href: str = "" email: str = "" address: str = "" class ServiceIn(BaseModel): title: str = Field(min_length=1, max_length=256) desc: str = "" icon: str = "draft" class ProjectIn(BaseModel): slug: str = Field(min_length=1, max_length=128) title: str = Field(min_length=1, max_length=256) location: str = "" year: str = "" status: Literal["done", "progress"] = "done" image: str = "" gallery: list[str] = [] area: str = "" floors: str = "" units: str = "" client: str = "" summary: str = "" body: list[str] = [] class ArticleIn(BaseModel): slug: str = Field(min_length=1, max_length=128) title: str = Field(min_length=1, max_length=256) date: str = "" category: str = "" image: str = "" read: str = "" excerpt: str = "" body: list[str] = [] class TestimonialIn(BaseModel): name: str = Field(min_length=1, max_length=128) role: str = "" quote: str = "" class FaqIn(BaseModel): question: str = Field(min_length=1) answer: str = "" class TeamMemberIn(BaseModel): name: str = Field(min_length=1, max_length=128) role: str = "" bio: str = "" class TimelineItemIn(BaseModel): year: str = Field(min_length=1, max_length=32) title: str = Field(min_length=1, max_length=256) desc: str = "" image: str = "" class StatIn(BaseModel): value: int suffix: str = "" label: str = Field(min_length=1, max_length=128) class WhyUsItemIn(BaseModel): title: str = Field(min_length=1, max_length=256) desc: str = "" class BeforeAfterIn(BaseModel): title: str = "" lead: str = "" before: str = "" after: str = "" before_label: str = "" after_label: str = "" class MessageReadIn(BaseModel): is_read: bool = True