from __future__ import annotations from datetime import datetime, timezone from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String, Text, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column, relationship from app.core.db.common import CommonBase class DomainMapping(CommonBase): """Maps an incoming domain/host to marketplace, tenant, branch, or consultant context. Phase 7T.1 only stores and manages the mappings. Runtime domain resolution is added in Phase 7T.2, so this table is intentionally safe and independent. """ __tablename__ = "domain_mappings" __table_args__ = ( UniqueConstraint("domain_name", name="uq_domain_mappings_domain_name"), ) id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) domain_name: Mapped[str] = mapped_column(String(255), nullable=False, index=True) domain_type: Mapped[str] = mapped_column(String(60), nullable=False, index=True) tenant_id: Mapped[int | None] = mapped_column(ForeignKey("tenants.id", ondelete="SET NULL"), nullable=True, index=True) branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True) consultant_id: Mapped[int | None] = mapped_column(ForeignKey("consultant_profiles.id", ondelete="SET NULL"), nullable=True, index=True) parent_tenant_id: Mapped[int | None] = mapped_column(ForeignKey("tenants.id", ondelete="SET NULL"), nullable=True, index=True) is_primary: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True) is_verified: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True) status: Mapped[str] = mapped_column(String(30), nullable=False, default="draft", index=True) verification_token: Mapped[str | None] = mapped_column(String(120), nullable=True, index=True) dns_txt_name: Mapped[str | None] = mapped_column(String(255), nullable=True) dns_txt_value: Mapped[str | None] = mapped_column(String(255), nullable=True) ssl_mode: Mapped[str] = mapped_column(String(30), nullable=False, default="manual") ssl_status: Mapped[str] = mapped_column(String(30), nullable=False, default="not_checked", index=True) ssl_provider: Mapped[str | None] = mapped_column(String(60), nullable=True) ssl_last_checked_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) ssl_not_after_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) ssl_issuer: Mapped[str | None] = mapped_column(String(255), nullable=True) ssl_subject: Mapped[str | None] = mapped_column(String(255), nullable=True) ssl_last_error: Mapped[str | None] = mapped_column(Text, nullable=True) notes: Mapped[str | None] = mapped_column(Text, nullable=True) created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True) updated_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True) created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False) updated_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), nullable=False) tenant = relationship("Tenant", foreign_keys=[tenant_id]) branch = relationship("Branch", foreign_keys=[branch_id]) consultant = relationship("ConsultantProfile", foreign_keys=[consultant_id]) parent_tenant = relationship("Tenant", foreign_keys=[parent_tenant_id])