"""Monthly report and school stats models.""" import uuid from datetime import datetime, timezone, date from sqlalchemy import String, DateTime, Date, Text, JSON, Numeric, Integer, ForeignKey from sqlalchemy.orm import Mapped, mapped_column from app.database import Base class MonthlyReport(Base): """Record of each monthly report sent to a school.""" __tablename__ = "monthly_reports" id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) school_id: Mapped[str] = mapped_column(String(36), ForeignKey("schools.id", ondelete="CASCADE"), nullable=False, index=True) report_month: Mapped[str] = mapped_column(String(7), nullable=False) # YYYY-MM email_sent_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) report_data: Mapped[dict | None] = mapped_column(JSON, nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) class SchoolMonthlyStats(Base): """Attendance + SMS stats pulled from on-prem each month.""" __tablename__ = "school_monthly_stats" id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) school_id: Mapped[str] = mapped_column(String(36), ForeignKey("schools.id", ondelete="CASCADE"), nullable=False, index=True) report_month: Mapped[str] = mapped_column(String(7), nullable=False) # YYYY-MM total_students: Mapped[int | None] = mapped_column(Integer, nullable=True) school_days: Mapped[int | None] = mapped_column(Integer, nullable=True) present_days_total: Mapped[int | None] = mapped_column(Integer, nullable=True) absent_days_total: Mapped[int | None] = mapped_column(Integer, nullable=True) late_days_total: Mapped[int | None] = mapped_column(Integer, nullable=True) avg_attendance_rate: Mapped[float | None] = mapped_column(Numeric(5, 2), nullable=True) sms_sent: Mapped[int | None] = mapped_column(Integer, nullable=True) pull_status: Mapped[str] = mapped_column(String(20), default="unavailable", nullable=False) # success|failed|unavailable pulled_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) hub_base_url: Mapped[str | None] = mapped_column(String(500), nullable=True)