import uuid import enum from datetime import datetime, timezone from sqlalchemy import String, Boolean, DateTime, Enum as SAEnum, Text, Numeric, Integer from sqlalchemy.orm import Mapped, mapped_column, relationship from app.database import Base class SchoolStatus(str, enum.Enum): active = "active" suspended = "suspended" expired = "expired" pending = "pending" class LicenseTier(str, enum.Enum): basic = "basic" standard = "standard" premium = "premium" class School(Base): __tablename__ = "schools" id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) name: Mapped[str] = mapped_column(String(255), nullable=False) slug: Mapped[str] = mapped_column(String(100), unique=True, nullable=False, index=True) address: Mapped[str | None] = mapped_column(Text, nullable=True) city: Mapped[str | None] = mapped_column(String(100), nullable=True) contact_name: Mapped[str | None] = mapped_column(String(255), nullable=True) contact_email: Mapped[str | None] = mapped_column(String(255), nullable=True) contact_phone: Mapped[str | None] = mapped_column(String(50), nullable=True) billing_email: Mapped[str | None] = mapped_column(String(255), nullable=True) status: Mapped[SchoolStatus] = mapped_column(SAEnum(SchoolStatus), default=SchoolStatus.pending, nullable=False) tier: Mapped[LicenseTier] = mapped_column(SAEnum(LicenseTier), default=LicenseTier.standard, nullable=False) student_limit: Mapped[int] = mapped_column(Integer, default=500, nullable=False) sms_sender_name: Mapped[str] = mapped_column(String(11), default="SCHOOL", nullable=False) sms_credits: Mapped[float] = mapped_column(Numeric(12, 2), default=0.0, nullable=False) sms_credit_low_threshold: Mapped[int] = mapped_column(Integer, default=50, nullable=False) hub_base_url: Mapped[str | None] = mapped_column(String(500), nullable=True) feature_overrides: Mapped[dict | None] = mapped_column(Text, nullable=True) # JSON string onboarding_completed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) notes: Mapped[str | None] = mapped_column(Text, nullable=True) admins: Mapped[list["HubUser"]] = relationship("HubUser", back_populates="school") license: Mapped["License | None"] = relationship("License", back_populates="school", uselist=False) sms_jobs: Mapped[list["SmsJob"]] = relationship("SmsJob", back_populates="school") invoices: Mapped[list["Invoice"]] = relationship("Invoice", back_populates="school") tickets: Mapped[list["SupportTicket"]] = relationship("SupportTicket", back_populates="school") audit_logs: Mapped[list["AuditLog"]] = relationship("AuditLog", back_populates="school")