"""phases 11-15: monthly_reports, school_monthly_stats, school new columns Revision ID: 003_phases11_15 Revises: 002_phase9 Create Date: 2026-03-16 """ from alembic import op import sqlalchemy as sa revision = "003_phases11_15" down_revision = "002_phase9" branch_labels = None depends_on = None def upgrade() -> None: # Schools: new columns op.add_column("schools", sa.Column("hub_base_url", sa.String(500), nullable=True)) op.add_column("schools", sa.Column("feature_overrides", sa.Text, nullable=True)) op.add_column("schools", sa.Column("onboarding_completed_at", sa.DateTime(timezone=True), nullable=True)) # monthly_reports table op.create_table( "monthly_reports", sa.Column("id", sa.String(36), primary_key=True), sa.Column("school_id", sa.String(36), sa.ForeignKey("schools.id", ondelete="CASCADE"), nullable=False), sa.Column("report_month", sa.String(7), nullable=False), sa.Column("email_sent_at", sa.DateTime(timezone=True), nullable=True), sa.Column("report_data", sa.JSON, nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), ) op.create_index("ix_monthly_reports_school_id", "monthly_reports", ["school_id"]) # school_monthly_stats table op.create_table( "school_monthly_stats", sa.Column("id", sa.String(36), primary_key=True), sa.Column("school_id", sa.String(36), sa.ForeignKey("schools.id", ondelete="CASCADE"), nullable=False), sa.Column("report_month", sa.String(7), nullable=False), sa.Column("total_students", sa.Integer, nullable=True), sa.Column("school_days", sa.Integer, nullable=True), sa.Column("present_days_total", sa.Integer, nullable=True), sa.Column("absent_days_total", sa.Integer, nullable=True), sa.Column("late_days_total", sa.Integer, nullable=True), sa.Column("avg_attendance_rate", sa.Numeric(5, 2), nullable=True), sa.Column("sms_sent", sa.Integer, nullable=True), sa.Column("pull_status", sa.String(20), nullable=False, server_default="unavailable"), sa.Column("pulled_at", sa.DateTime(timezone=True), nullable=True), sa.Column("hub_base_url", sa.String(500), nullable=True), ) op.create_index("ix_school_monthly_stats_school_id", "school_monthly_stats", ["school_id"]) def downgrade() -> None: op.drop_table("school_monthly_stats") op.drop_table("monthly_reports") op.drop_column("schools", "onboarding_completed_at") op.drop_column("schools", "feature_overrides") op.drop_column("schools", "hub_base_url")