from datetime import datetime, timezone from sqlalchemy import JSON, Boolean, DateTime, Integer, String, Text from sqlalchemy.orm import Mapped, mapped_column from .database import Base def utcnow() -> datetime: return datetime.now(timezone.utc) class AdminUser(Base): __tablename__ = "admin_users" id: Mapped[int] = mapped_column(primary_key=True) username: Mapped[str] = mapped_column(String(64), unique=True, index=True) password_hash: Mapped[str] = mapped_column(String(255)) class Brand(Base): __tablename__ = "brand" id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String(128), default="") logo: Mapped[str] = mapped_column(Text, default="") hero: Mapped[str] = mapped_column(Text, default="") contact_bg: Mapped[str] = mapped_column(Text, default="") phone: Mapped[str] = mapped_column(String(64), default="") phone_href: Mapped[str] = mapped_column(String(128), default="") email: Mapped[str] = mapped_column(String(128), default="") address: Mapped[str] = mapped_column(Text, default="") class Service(Base): __tablename__ = "services" id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(256)) desc: Mapped[str] = mapped_column(Text, default="") icon: Mapped[str] = mapped_column(String(32), default="draft") class Project(Base): __tablename__ = "projects" id: Mapped[int] = mapped_column(primary_key=True) slug: Mapped[str] = mapped_column(String(128), unique=True, index=True) title: Mapped[str] = mapped_column(String(256)) location: Mapped[str] = mapped_column(String(128), default="") year: Mapped[str] = mapped_column(String(64), default="") status: Mapped[str] = mapped_column(String(16), default="done") # done | progress image: Mapped[str] = mapped_column(Text, default="") gallery: Mapped[list] = mapped_column(JSON, default=list) area: Mapped[str] = mapped_column(String(64), default="") floors: Mapped[str] = mapped_column(String(64), default="") units: Mapped[str] = mapped_column(String(64), default="") client: Mapped[str] = mapped_column(String(128), default="") summary: Mapped[str] = mapped_column(Text, default="") body: Mapped[list] = mapped_column(JSON, default=list) class Article(Base): __tablename__ = "articles" id: Mapped[int] = mapped_column(primary_key=True) slug: Mapped[str] = mapped_column(String(128), unique=True, index=True) title: Mapped[str] = mapped_column(String(256)) date: Mapped[str] = mapped_column(String(64), default="") category: Mapped[str] = mapped_column(String(64), default="") image: Mapped[str] = mapped_column(Text, default="") read: Mapped[str] = mapped_column(String(32), default="") excerpt: Mapped[str] = mapped_column(Text, default="") body: Mapped[list] = mapped_column(JSON, default=list) class Testimonial(Base): __tablename__ = "testimonials" id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String(128)) role: Mapped[str] = mapped_column(String(128), default="") quote: Mapped[str] = mapped_column(Text, default="") class Faq(Base): __tablename__ = "faqs" id: Mapped[int] = mapped_column(primary_key=True) question: Mapped[str] = mapped_column(Text) answer: Mapped[str] = mapped_column(Text, default="") class TeamMember(Base): __tablename__ = "team" id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String(128)) role: Mapped[str] = mapped_column(String(128), default="") bio: Mapped[str] = mapped_column(Text, default="") class TimelineItem(Base): __tablename__ = "timeline" id: Mapped[int] = mapped_column(primary_key=True) year: Mapped[str] = mapped_column(String(32)) title: Mapped[str] = mapped_column(String(256)) desc: Mapped[str] = mapped_column(Text, default="") image: Mapped[str] = mapped_column(Text, default="") class Stat(Base): __tablename__ = "stats" id: Mapped[int] = mapped_column(primary_key=True) value: Mapped[int] = mapped_column(Integer) suffix: Mapped[str] = mapped_column(String(16), default="") label: Mapped[str] = mapped_column(String(128)) class WhyUsItem(Base): __tablename__ = "why_us" id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(256)) desc: Mapped[str] = mapped_column(Text, default="") class BeforeAfter(Base): __tablename__ = "before_after" id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(256), default="") lead: Mapped[str] = mapped_column(Text, default="") before: Mapped[str] = mapped_column(Text, default="") after: Mapped[str] = mapped_column(Text, default="") before_label: Mapped[str] = mapped_column(String(128), default="") after_label: Mapped[str] = mapped_column(String(128), default="") class NavItem(Base): __tablename__ = "nav_items" id: Mapped[int] = mapped_column(primary_key=True) label: Mapped[str] = mapped_column(String(64)) href: Mapped[str] = mapped_column(String(128)) class Hero(Base): """محتوای هیرو صفحه اصلی — رکورد یگانه.""" __tablename__ = "hero" id: Mapped[int] = mapped_column(primary_key=True) kicker: Mapped[str] = mapped_column(Text, default="") title: Mapped[str] = mapped_column(Text, default="") title_highlight: Mapped[str] = mapped_column(String(128), default="") subtitle: Mapped[str] = mapped_column(Text, default="") badge_value: Mapped[str] = mapped_column(String(32), default="") badge_label: Mapped[str] = mapped_column(Text, default="") cta_primary_label: Mapped[str] = mapped_column(String(128), default="") cta_primary_href: Mapped[str] = mapped_column(String(128), default="") cta_secondary_label: Mapped[str] = mapped_column(String(128), default="") cta_secondary_href: Mapped[str] = mapped_column(String(128), default="") scroll_label: Mapped[str] = mapped_column(String(64), default="") class StorySection(Base): """بخش «درباره ما» در خانه و صفحه درباره — رکورد یگانه.""" __tablename__ = "story" id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(256), default="") paragraphs: Mapped[list] = mapped_column(JSON, default=list) quote: Mapped[str] = mapped_column(Text, default="") quote_author: Mapped[str] = mapped_column(Text, default="") stat1_value: Mapped[str] = mapped_column(String(32), default="") stat1_label: Mapped[str] = mapped_column(String(128), default="") stat2_value: Mapped[str] = mapped_column(String(32), default="") stat2_label: Mapped[str] = mapped_column(String(128), default="") link_label: Mapped[str] = mapped_column(String(128), default="") link_href: Mapped[str] = mapped_column(String(128), default="") bento: Mapped[list] = mapped_column(JSON, default=list) # [{src, alt}] class SectionHeadingContent(Base): """تیتر و توضیح بخش‌ها — فرانت‌اند بر اساس key آن را پیدا می‌کند.""" __tablename__ = "section_headings" id: Mapped[int] = mapped_column(primary_key=True) key: Mapped[str] = mapped_column(String(64), unique=True, index=True) label: Mapped[str] = mapped_column(String(64), default="") title: Mapped[str] = mapped_column(String(256), default="") lead: Mapped[str] = mapped_column(Text, default="") image: Mapped[str] = mapped_column(Text, default="") cta_label: Mapped[str] = mapped_column(String(128), default="") cta_href: Mapped[str] = mapped_column(String(128), default="") class PageHeroContent(Base): """هیرو بالای هر صفحه — key: about | services | projects | investment | blog | faq | contact.""" __tablename__ = "page_heroes" id: Mapped[int] = mapped_column(primary_key=True) key: Mapped[str] = mapped_column(String(32), unique=True, index=True) title: Mapped[str] = mapped_column(String(256), default="") lead: Mapped[str] = mapped_column(Text, default="") image: Mapped[str] = mapped_column(Text, default="") class InvestmentModel(Base): __tablename__ = "investment_models" id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(256)) desc: Mapped[str] = mapped_column(Text, default="") points: Mapped[list] = mapped_column(JSON, default=list) class ProcessStep(Base): __tablename__ = "process_steps" id: Mapped[int] = mapped_column(primary_key=True) step: Mapped[str] = mapped_column(String(16), default="") title: Mapped[str] = mapped_column(String(256)) desc: Mapped[str] = mapped_column(Text, default="") class Office(Base): __tablename__ = "offices" id: Mapped[int] = mapped_column(primary_key=True) city: Mapped[str] = mapped_column(String(64)) address: Mapped[str] = mapped_column(Text, default="") hours: Mapped[str] = mapped_column(String(128), default="") class GalleryImage(Base): __tablename__ = "gallery_images" id: Mapped[int] = mapped_column(primary_key=True) src: Mapped[str] = mapped_column(Text, default="") alt: Mapped[str] = mapped_column(Text, default="") class StatusLabel(Base): """برچسب فارسی وضعیت پروژه — key: done | progress.""" __tablename__ = "status_labels" id: Mapped[int] = mapped_column(primary_key=True) key: Mapped[str] = mapped_column(String(16), unique=True, index=True) label: Mapped[str] = mapped_column(String(64)) class ContactSectionContent(Base): """بخش فرم تماس — رکورد یگانه.""" __tablename__ = "contact_section" id: Mapped[int] = mapped_column(primary_key=True) label: Mapped[str] = mapped_column(String(64), default="") title: Mapped[str] = mapped_column(String(256), default="") lead: Mapped[str] = mapped_column(Text, default="") address_label: Mapped[str] = mapped_column(String(64), default="") phone_label: Mapped[str] = mapped_column(String(64), default="") email_label: Mapped[str] = mapped_column(String(64), default="") name_label: Mapped[str] = mapped_column(String(64), default="") name_placeholder: Mapped[str] = mapped_column(String(128), default="") phone_field_label: Mapped[str] = mapped_column(String(64), default="") phone_placeholder: Mapped[str] = mapped_column(String(64), default="") note_label: Mapped[str] = mapped_column(String(64), default="") note_optional_label: Mapped[str] = mapped_column(String(64), default="") note_placeholder: Mapped[str] = mapped_column(String(256), default="") submit_label: Mapped[str] = mapped_column(String(128), default="") sending_label: Mapped[str] = mapped_column(String(64), default="") success_title: Mapped[str] = mapped_column(String(256), default="") success_text: Mapped[str] = mapped_column(Text, default="") success_button_label: Mapped[str] = mapped_column(String(128), default="") class NewsletterSectionContent(Base): """بخش خبرنامه — رکورد یگانه.""" __tablename__ = "newsletter" id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(256), default="") lead: Mapped[str] = mapped_column(Text, default="") placeholder: Mapped[str] = mapped_column(String(128), default="") button_label: Mapped[str] = mapped_column(String(64), default="") sending_label: Mapped[str] = mapped_column(String(64), default="") success_text: Mapped[str] = mapped_column(String(256), default="") class FooterContent(Base): """متن‌های فوتر — رکورد یگانه.""" __tablename__ = "footer" id: Mapped[int] = mapped_column(primary_key=True) about_text: Mapped[str] = mapped_column(Text, default="") pages_heading: Mapped[str] = mapped_column(String(64), default="") services_heading: Mapped[str] = mapped_column(String(64), default="") contact_heading: Mapped[str] = mapped_column(String(64), default="") copyright: Mapped[str] = mapped_column(String(256), default="") tagline: Mapped[str] = mapped_column(String(256), default="") socials: Mapped[list] = mapped_column(JSON, default=list) # [{label, href, icon}] class ContactMessage(Base): __tablename__ = "contact_messages" id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String(128)) phone: Mapped[str] = mapped_column(String(32)) note: Mapped[str] = mapped_column(Text, default="") is_read: Mapped[bool] = mapped_column(Boolean, default=False) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow) class Subscriber(Base): __tablename__ = "subscribers" id: Mapped[int] = mapped_column(primary_key=True) email: Mapped[str] = mapped_column(String(256), unique=True, index=True) is_active: Mapped[bool] = mapped_column(Boolean, default=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow)