"""Add server_default to boolean and string-enum columns. Every non-nullable column with a Python-side default should also have a server_default so that raw SQL inserts (migrations, scripts, bulk loads) produce a valid row without having to specify the value explicitly. This migration covers two categories: - Booleans: SET DEFAULT false / true - String enums / sentinel strings: SET DEFAULT 'value' Revision ID: 0025 Revises: 0024 """ from __future__ import annotations from alembic import op import sqlalchemy as sa revision = "0025" down_revision = "0024" branch_labels = None depends_on = None # (table, column, default_value) _BOOL_FALSE: list[tuple[str, str]] = [ ("musehub_repos", "training_opt_out"), ("musehub_identities", "is_verified"), ("musehub_issue_comments", "is_deleted"), ("musehub_releases", "is_draft"), ("musehub_webhook_deliveries", "success"), ("musehub_sessions", "is_active"), ("musehub_intel_entangle", "structurally_linked"), ("musehub_intel_stable", "since_start"), ("musehub_intel_type", "return_is_any"), ("musehub_bridge_mirrors", "auto_export"), ("musehub_profile_snapshots", "is_stale"), ("musehub_domains", "is_verified"), ("musehub_domains", "is_deprecated"), ] _BOOL_TRUE: list[tuple[str, str]] = [ ("musehub_webhooks", "active"), ] _STR_DEFAULTS: list[tuple[str, str, str]] = [ ("musehub_repos", "visibility", "public"), ("musehub_identities", "identity_type", "human"), ("musehub_issues", "state", "open"), ("musehub_proposals", "state", "open"), ("musehub_proposal_reviews", "state", "pending"), ("musehub_releases", "channel", "stable"), ("musehub_sessions", "schema_version", "1"), ("musehub_background_jobs", "status", "pending"), ("musehub_intel_api_surface", "visibility", "public"), ("musehub_mists", "visibility", "public"), ("musehub_intel_breakage_issues", "severity", "warning"), ("musehub_bridge_mirrors", "git_branch", "muse-mirror"), ("musehub_collaborators", "permission", "write"), ("musehub_coord_tasks", "queue", "default"), ("musehub_coord_tasks", "status", "pending"), ("musehub_domains", "version", "1.0.0"), ("musehub_domains", "viewer_type", "generic"), ] def upgrade() -> None: conn = op.get_bind() for table, col in _BOOL_FALSE: conn.execute(sa.text(f"ALTER TABLE {table} ALTER COLUMN {col} SET DEFAULT false")) for table, col in _BOOL_TRUE: conn.execute(sa.text(f"ALTER TABLE {table} ALTER COLUMN {col} SET DEFAULT true")) for table, col, val in _STR_DEFAULTS: conn.execute(sa.text(f"ALTER TABLE {table} ALTER COLUMN {col} SET DEFAULT '{val}'")) def downgrade() -> None: conn = op.get_bind() for table, col in _BOOL_FALSE + _BOOL_TRUE: conn.execute(sa.text(f"ALTER TABLE {table} ALTER COLUMN {col} DROP DEFAULT")) for table, col, _ in _STR_DEFAULTS: conn.execute(sa.text(f"ALTER TABLE {table} ALTER COLUMN {col} DROP DEFAULT"))