"""add_architecture_quality_tracking_tables Revision ID: 7a7ce92593d5 Revises: a2064e1dfcd4 Create Date: 2025-11-28 09:21:16.545203 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa from sqlalchemy.dialects import postgresql # revision identifiers, used by Alembic. revision: str = '7a7ce92593d5' down_revision: Union[str, None] = 'a2064e1dfcd4' branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # Create architecture_scans table op.create_table( 'architecture_scans', sa.Column('id', sa.Integer(), nullable=False), sa.Column('timestamp', sa.DateTime(timezone=True), server_default=sa.text("(datetime('now'))"), nullable=False), sa.Column('total_files', sa.Integer(), nullable=True), sa.Column('total_violations', sa.Integer(), nullable=True), sa.Column('errors', sa.Integer(), nullable=True), sa.Column('warnings', sa.Integer(), nullable=True), sa.Column('duration_seconds', sa.Float(), nullable=True), sa.Column('triggered_by', sa.String(length=100), nullable=True), sa.Column('git_commit_hash', sa.String(length=40), nullable=True), sa.PrimaryKeyConstraint('id') ) op.create_index(op.f('ix_architecture_scans_id'), 'architecture_scans', ['id'], unique=False) op.create_index(op.f('ix_architecture_scans_timestamp'), 'architecture_scans', ['timestamp'], unique=False) # Create architecture_rules table op.create_table( 'architecture_rules', sa.Column('id', sa.Integer(), nullable=False), sa.Column('rule_id', sa.String(length=20), nullable=False), sa.Column('category', sa.String(length=50), nullable=False), sa.Column('name', sa.String(length=200), nullable=False), sa.Column('description', sa.Text(), nullable=True), sa.Column('severity', sa.String(length=10), nullable=False), sa.Column('enabled', sa.Boolean(), nullable=False, server_default='1'), sa.Column('custom_config', sa.JSON(), nullable=True), sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text("(datetime('now'))"), nullable=False), sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text("(datetime('now'))"), nullable=False), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('rule_id') ) op.create_index(op.f('ix_architecture_rules_id'), 'architecture_rules', ['id'], unique=False) op.create_index(op.f('ix_architecture_rules_rule_id'), 'architecture_rules', ['rule_id'], unique=True) # Create architecture_violations table op.create_table( 'architecture_violations', sa.Column('id', sa.Integer(), nullable=False), sa.Column('scan_id', sa.Integer(), nullable=False), sa.Column('rule_id', sa.String(length=20), nullable=False), sa.Column('rule_name', sa.String(length=200), nullable=False), sa.Column('severity', sa.String(length=10), nullable=False), sa.Column('file_path', sa.String(length=500), nullable=False), sa.Column('line_number', sa.Integer(), nullable=False), sa.Column('message', sa.Text(), nullable=False), sa.Column('context', sa.Text(), nullable=True), sa.Column('suggestion', sa.Text(), nullable=True), sa.Column('status', sa.String(length=20), server_default='open', nullable=True), sa.Column('assigned_to', sa.Integer(), nullable=True), sa.Column('resolved_at', sa.DateTime(timezone=True), nullable=True), sa.Column('resolved_by', sa.Integer(), nullable=True), sa.Column('resolution_note', sa.Text(), nullable=True), sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text("(datetime('now'))"), nullable=False), sa.ForeignKeyConstraint(['assigned_to'], ['users.id'], ), sa.ForeignKeyConstraint(['resolved_by'], ['users.id'], ), sa.ForeignKeyConstraint(['scan_id'], ['architecture_scans.id'], ), sa.PrimaryKeyConstraint('id') ) op.create_index(op.f('ix_architecture_violations_file_path'), 'architecture_violations', ['file_path'], unique=False) op.create_index(op.f('ix_architecture_violations_id'), 'architecture_violations', ['id'], unique=False) op.create_index(op.f('ix_architecture_violations_rule_id'), 'architecture_violations', ['rule_id'], unique=False) op.create_index(op.f('ix_architecture_violations_scan_id'), 'architecture_violations', ['scan_id'], unique=False) op.create_index(op.f('ix_architecture_violations_severity'), 'architecture_violations', ['severity'], unique=False) op.create_index(op.f('ix_architecture_violations_status'), 'architecture_violations', ['status'], unique=False) # Create violation_assignments table op.create_table( 'violation_assignments', sa.Column('id', sa.Integer(), nullable=False), sa.Column('violation_id', sa.Integer(), nullable=False), sa.Column('user_id', sa.Integer(), nullable=False), sa.Column('assigned_at', sa.DateTime(timezone=True), server_default=sa.text("(datetime('now'))"), nullable=False), sa.Column('assigned_by', sa.Integer(), nullable=True), sa.Column('due_date', sa.DateTime(timezone=True), nullable=True), sa.Column('priority', sa.String(length=10), server_default='medium', nullable=True), sa.ForeignKeyConstraint(['assigned_by'], ['users.id'], ), sa.ForeignKeyConstraint(['user_id'], ['users.id'], ), sa.ForeignKeyConstraint(['violation_id'], ['architecture_violations.id'], ), sa.PrimaryKeyConstraint('id') ) op.create_index(op.f('ix_violation_assignments_id'), 'violation_assignments', ['id'], unique=False) op.create_index(op.f('ix_violation_assignments_violation_id'), 'violation_assignments', ['violation_id'], unique=False) # Create violation_comments table op.create_table( 'violation_comments', sa.Column('id', sa.Integer(), nullable=False), sa.Column('violation_id', sa.Integer(), nullable=False), sa.Column('user_id', sa.Integer(), nullable=False), sa.Column('comment', sa.Text(), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text("(datetime('now'))"), nullable=False), sa.ForeignKeyConstraint(['user_id'], ['users.id'], ), sa.ForeignKeyConstraint(['violation_id'], ['architecture_violations.id'], ), sa.PrimaryKeyConstraint('id') ) op.create_index(op.f('ix_violation_comments_id'), 'violation_comments', ['id'], unique=False) op.create_index(op.f('ix_violation_comments_violation_id'), 'violation_comments', ['violation_id'], unique=False) def downgrade() -> None: # Drop tables in reverse order (to respect foreign key constraints) op.drop_index(op.f('ix_violation_comments_violation_id'), table_name='violation_comments') op.drop_index(op.f('ix_violation_comments_id'), table_name='violation_comments') op.drop_table('violation_comments') op.drop_index(op.f('ix_violation_assignments_violation_id'), table_name='violation_assignments') op.drop_index(op.f('ix_violation_assignments_id'), table_name='violation_assignments') op.drop_table('violation_assignments') op.drop_index(op.f('ix_architecture_violations_status'), table_name='architecture_violations') op.drop_index(op.f('ix_architecture_violations_severity'), table_name='architecture_violations') op.drop_index(op.f('ix_architecture_violations_scan_id'), table_name='architecture_violations') op.drop_index(op.f('ix_architecture_violations_rule_id'), table_name='architecture_violations') op.drop_index(op.f('ix_architecture_violations_id'), table_name='architecture_violations') op.drop_index(op.f('ix_architecture_violations_file_path'), table_name='architecture_violations') op.drop_table('architecture_violations') op.drop_index(op.f('ix_architecture_rules_rule_id'), table_name='architecture_rules') op.drop_index(op.f('ix_architecture_rules_id'), table_name='architecture_rules') op.drop_table('architecture_rules') op.drop_index(op.f('ix_architecture_scans_timestamp'), table_name='architecture_scans') op.drop_index(op.f('ix_architecture_scans_id'), table_name='architecture_scans') op.drop_table('architecture_scans')