"""add Fabric graph read model Revision ID: y2t3u4v5w6x7 Revises: x1s2t3u4v5w6 Create Date: 2026-05-23 """ from alembic import op import sqlalchemy as sa from sqlalchemy.dialects.postgresql import JSONB, UUID revision = "y2t3u4v5w6x7" down_revision = "x1s2t3u4v5w6" branch_labels = None depends_on = None def upgrade() -> None: op.create_table( "fabric_graph_imports", sa.Column("id", UUID(as_uuid=True), primary_key=True, nullable=False), sa.Column("source_repo_slug", sa.String(length=100), nullable=False), sa.Column("source_url", sa.Text(), nullable=True), sa.Column("source_commit", sa.String(length=80), nullable=True), sa.Column("source_path", sa.Text(), nullable=True), sa.Column("api_version", sa.String(length=100), nullable=True), sa.Column("export_kind", sa.String(length=100), nullable=True), sa.Column("exported_at", sa.DateTime(timezone=True), nullable=True), sa.Column("content_hash", sa.String(length=64), nullable=False), sa.Column("node_count", sa.Integer(), nullable=False, server_default="0"), sa.Column("edge_count", sa.Integer(), nullable=False, server_default="0"), sa.Column("validation_status", sa.String(length=20), nullable=False, server_default="valid"), sa.Column("error_details", JSONB(), nullable=True), sa.Column("graph_json", JSONB(), nullable=False, server_default="{}"), sa.Column("is_latest", sa.Boolean(), nullable=False, server_default="false"), sa.Column("last_seen_at", sa.DateTime(timezone=True), nullable=True), sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()), sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()), sa.UniqueConstraint("source_repo_slug", "content_hash", name="uq_fabric_graph_imports_source_hash"), ) op.create_index("ix_fabric_graph_imports_source_repo_slug", "fabric_graph_imports", ["source_repo_slug"]) op.create_index("ix_fabric_graph_imports_source_commit", "fabric_graph_imports", ["source_commit"]) op.create_index("ix_fabric_graph_imports_export_kind", "fabric_graph_imports", ["export_kind"]) op.create_index("ix_fabric_graph_imports_exported_at", "fabric_graph_imports", ["exported_at"]) op.create_index("ix_fabric_graph_imports_content_hash", "fabric_graph_imports", ["content_hash"]) op.create_index("ix_fabric_graph_imports_validation_status", "fabric_graph_imports", ["validation_status"]) op.create_index("ix_fabric_graph_imports_is_latest", "fabric_graph_imports", ["is_latest"]) op.create_table( "fabric_graph_nodes", sa.Column("id", UUID(as_uuid=True), primary_key=True, nullable=False), sa.Column("import_id", UUID(as_uuid=True), nullable=False), sa.Column("source_repo_slug", sa.String(length=100), nullable=False), sa.Column("graph_id", sa.Text(), nullable=False), sa.Column("kind", sa.String(length=100), nullable=False), sa.Column("name", sa.Text(), nullable=False), sa.Column("repo_slug", sa.String(length=100), nullable=False), sa.Column("domain_slug", sa.String(length=100), nullable=False), sa.Column("lifecycle", sa.String(length=50), nullable=False), sa.Column("canonical_type", sa.String(length=100), nullable=True), sa.Column("canon_category", sa.String(length=100), nullable=True), sa.Column("canon_anchor", sa.Text(), nullable=True), sa.Column("mapping_fit", sa.String(length=20), nullable=True), sa.Column("evidence_state", sa.String(length=20), nullable=True), sa.Column("display_only", sa.Boolean(), nullable=False, server_default="false"), sa.Column("attributes", JSONB(), nullable=False, server_default="{}"), sa.Column("raw_json", JSONB(), nullable=False, server_default="{}"), sa.ForeignKeyConstraint(["import_id"], ["fabric_graph_imports.id"], ondelete="CASCADE"), sa.UniqueConstraint("import_id", "graph_id", name="uq_fabric_graph_nodes_import_graph_id"), ) op.create_index("ix_fabric_graph_nodes_import_id", "fabric_graph_nodes", ["import_id"]) op.create_index("ix_fabric_graph_nodes_source_repo_slug", "fabric_graph_nodes", ["source_repo_slug"]) op.create_index("ix_fabric_graph_nodes_kind", "fabric_graph_nodes", ["kind"]) op.create_index("ix_fabric_graph_nodes_repo_slug", "fabric_graph_nodes", ["repo_slug"]) op.create_index("ix_fabric_graph_nodes_domain_slug", "fabric_graph_nodes", ["domain_slug"]) op.create_index("ix_fabric_graph_nodes_lifecycle", "fabric_graph_nodes", ["lifecycle"]) op.create_index("ix_fabric_graph_nodes_canonical_type", "fabric_graph_nodes", ["canonical_type"]) op.create_index("ix_fabric_graph_nodes_canon_category", "fabric_graph_nodes", ["canon_category"]) op.create_index("ix_fabric_graph_nodes_mapping_fit", "fabric_graph_nodes", ["mapping_fit"]) op.create_index("ix_fabric_graph_nodes_evidence_state", "fabric_graph_nodes", ["evidence_state"]) op.create_index("ix_fabric_graph_nodes_display_only", "fabric_graph_nodes", ["display_only"]) op.create_table( "fabric_graph_edges", sa.Column("id", UUID(as_uuid=True), primary_key=True, nullable=False), sa.Column("import_id", UUID(as_uuid=True), nullable=False), sa.Column("source_repo_slug", sa.String(length=100), nullable=False), sa.Column("edge_key", sa.String(length=64), nullable=False), sa.Column("from_graph_id", sa.Text(), nullable=False), sa.Column("to_graph_id", sa.Text(), nullable=False), sa.Column("edge_type", sa.String(length=100), nullable=False), sa.Column("canonical_type", sa.String(length=100), nullable=True), sa.Column("canon_anchor", sa.Text(), nullable=True), sa.Column("mapping_fit", sa.String(length=20), nullable=True), sa.Column("evidence_state", sa.String(length=20), nullable=True), sa.Column("display_only", sa.Boolean(), nullable=False, server_default="false"), sa.Column("attributes", JSONB(), nullable=False, server_default="{}"), sa.Column("raw_json", JSONB(), nullable=False, server_default="{}"), sa.ForeignKeyConstraint(["import_id"], ["fabric_graph_imports.id"], ondelete="CASCADE"), sa.UniqueConstraint("import_id", "edge_key", name="uq_fabric_graph_edges_import_edge_key"), ) op.create_index("ix_fabric_graph_edges_import_id", "fabric_graph_edges", ["import_id"]) op.create_index("ix_fabric_graph_edges_source_repo_slug", "fabric_graph_edges", ["source_repo_slug"]) op.create_index("ix_fabric_graph_edges_edge_key", "fabric_graph_edges", ["edge_key"]) op.create_index("ix_fabric_graph_edges_edge_type", "fabric_graph_edges", ["edge_type"]) op.create_index("ix_fabric_graph_edges_canonical_type", "fabric_graph_edges", ["canonical_type"]) op.create_index("ix_fabric_graph_edges_mapping_fit", "fabric_graph_edges", ["mapping_fit"]) op.create_index("ix_fabric_graph_edges_evidence_state", "fabric_graph_edges", ["evidence_state"]) op.create_index("ix_fabric_graph_edges_display_only", "fabric_graph_edges", ["display_only"]) def downgrade() -> None: op.drop_index("ix_fabric_graph_edges_display_only", table_name="fabric_graph_edges") op.drop_index("ix_fabric_graph_edges_evidence_state", table_name="fabric_graph_edges") op.drop_index("ix_fabric_graph_edges_mapping_fit", table_name="fabric_graph_edges") op.drop_index("ix_fabric_graph_edges_canonical_type", table_name="fabric_graph_edges") op.drop_index("ix_fabric_graph_edges_edge_type", table_name="fabric_graph_edges") op.drop_index("ix_fabric_graph_edges_edge_key", table_name="fabric_graph_edges") op.drop_index("ix_fabric_graph_edges_source_repo_slug", table_name="fabric_graph_edges") op.drop_index("ix_fabric_graph_edges_import_id", table_name="fabric_graph_edges") op.drop_table("fabric_graph_edges") op.drop_index("ix_fabric_graph_nodes_display_only", table_name="fabric_graph_nodes") op.drop_index("ix_fabric_graph_nodes_evidence_state", table_name="fabric_graph_nodes") op.drop_index("ix_fabric_graph_nodes_mapping_fit", table_name="fabric_graph_nodes") op.drop_index("ix_fabric_graph_nodes_canon_category", table_name="fabric_graph_nodes") op.drop_index("ix_fabric_graph_nodes_canonical_type", table_name="fabric_graph_nodes") op.drop_index("ix_fabric_graph_nodes_lifecycle", table_name="fabric_graph_nodes") op.drop_index("ix_fabric_graph_nodes_domain_slug", table_name="fabric_graph_nodes") op.drop_index("ix_fabric_graph_nodes_repo_slug", table_name="fabric_graph_nodes") op.drop_index("ix_fabric_graph_nodes_kind", table_name="fabric_graph_nodes") op.drop_index("ix_fabric_graph_nodes_source_repo_slug", table_name="fabric_graph_nodes") op.drop_index("ix_fabric_graph_nodes_import_id", table_name="fabric_graph_nodes") op.drop_table("fabric_graph_nodes") op.drop_index("ix_fabric_graph_imports_is_latest", table_name="fabric_graph_imports") op.drop_index("ix_fabric_graph_imports_validation_status", table_name="fabric_graph_imports") op.drop_index("ix_fabric_graph_imports_content_hash", table_name="fabric_graph_imports") op.drop_index("ix_fabric_graph_imports_exported_at", table_name="fabric_graph_imports") op.drop_index("ix_fabric_graph_imports_export_kind", table_name="fabric_graph_imports") op.drop_index("ix_fabric_graph_imports_source_commit", table_name="fabric_graph_imports") op.drop_index("ix_fabric_graph_imports_source_repo_slug", table_name="fabric_graph_imports") op.drop_table("fabric_graph_imports")