0004_phase1_intel_tables.py
python
sha256:0997d6250ae6476362f6fe2025af7789f46d03df3e9f34356d5e8ee79b201923
fix(issues): use issue number as pagination cursor, not cre…
Sonnet 4.6
patch
8 days ago
| 1 | """phase1_intel_tables |
| 2 | |
| 3 | Adds 11 new normalized intel tables and extends musehub_symbol_intel with |
| 4 | two new columns (last_commit_id, op) for Phase 1 of issue #8. |
| 5 | |
| 6 | New tables: |
| 7 | musehub_intel_coupling — co-changing file pairs |
| 8 | musehub_intel_entangle — symbol entanglement pairs |
| 9 | musehub_intel_dead — dead-code candidates |
| 10 | musehub_intel_blast_risk — composite pre-release risk per symbol |
| 11 | musehub_intel_stable — long-stable symbols |
| 12 | musehub_intel_velocity — module growth velocity |
| 13 | musehub_intel_clones — duplicate code clusters |
| 14 | musehub_intel_type — per-symbol type health |
| 15 | musehub_intel_api_surface — public API surface entries |
| 16 | musehub_intel_languages — language breakdown per push |
| 17 | musehub_intel_refactor_events — detected refactoring events |
| 18 | |
| 19 | Extended columns on musehub_symbol_intel: |
| 20 | last_commit_id VARCHAR(128) — most recent commit that touched this symbol |
| 21 | op VARCHAR(16) — latest op (add/modify/delete) |
| 22 | |
| 23 | Revision ID: 0004 |
| 24 | Revises: 0003 |
| 25 | Create Date: 2026-05-02 00:00:00.000000+00:00 |
| 26 | """ |
| 27 | from __future__ import annotations |
| 28 | |
| 29 | from typing import Sequence, Union |
| 30 | |
| 31 | import sqlalchemy as sa |
| 32 | from alembic import op |
| 33 | |
| 34 | revision: str = '0004' |
| 35 | down_revision: Union[str, None] = '0003' |
| 36 | branch_labels: Union[str, Sequence[str], None] = None |
| 37 | depends_on: Union[str, Sequence[str], None] = None |
| 38 | |
| 39 | |
| 40 | def upgrade() -> None: |
| 41 | # Extend musehub_symbol_intel |
| 42 | op.add_column('musehub_symbol_intel', sa.Column('last_commit_id', sa.String(128), nullable=True)) |
| 43 | op.add_column('musehub_symbol_intel', sa.Column('op', sa.String(16), nullable=True)) |
| 44 | |
| 45 | op.create_table( |
| 46 | 'musehub_intel_coupling', |
| 47 | sa.Column('repo_id', sa.String(128), sa.ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), primary_key=True, nullable=False), |
| 48 | sa.Column('file_a', sa.String(512), primary_key=True, nullable=False), |
| 49 | sa.Column('file_b', sa.String(512), primary_key=True, nullable=False), |
| 50 | sa.Column('co_changes', sa.Integer, nullable=False, server_default='0'), |
| 51 | sa.Column('ref', sa.String(128), nullable=False), |
| 52 | ) |
| 53 | op.create_index('ix_intel_coupling_repo', 'musehub_intel_coupling', ['repo_id']) |
| 54 | |
| 55 | op.create_table( |
| 56 | 'musehub_intel_entangle', |
| 57 | sa.Column('repo_id', sa.String(128), sa.ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), primary_key=True, nullable=False), |
| 58 | sa.Column('symbol_a', sa.String(512), primary_key=True, nullable=False), |
| 59 | sa.Column('symbol_b', sa.String(512), primary_key=True, nullable=False), |
| 60 | sa.Column('co_change_rate', sa.Float, nullable=False, server_default='0.0'), |
| 61 | sa.Column('co_changes', sa.Integer, nullable=False, server_default='0'), |
| 62 | sa.Column('structurally_linked', sa.Boolean, nullable=False, server_default='false'), |
| 63 | sa.Column('ref', sa.String(128), nullable=False), |
| 64 | ) |
| 65 | op.create_index('ix_intel_entangle_repo', 'musehub_intel_entangle', ['repo_id']) |
| 66 | |
| 67 | op.create_table( |
| 68 | 'musehub_intel_dead', |
| 69 | sa.Column('repo_id', sa.String(128), sa.ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), primary_key=True, nullable=False), |
| 70 | sa.Column('address', sa.String(512), primary_key=True, nullable=False), |
| 71 | sa.Column('kind', sa.String(64), nullable=False), |
| 72 | sa.Column('confidence', sa.String(16), nullable=False, server_default='medium'), |
| 73 | sa.Column('reason', sa.Text, nullable=True), |
| 74 | sa.Column('ref', sa.String(128), nullable=False), |
| 75 | ) |
| 76 | op.create_index('ix_intel_dead_repo', 'musehub_intel_dead', ['repo_id']) |
| 77 | |
| 78 | op.create_table( |
| 79 | 'musehub_intel_blast_risk', |
| 80 | sa.Column('repo_id', sa.String(128), sa.ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), primary_key=True, nullable=False), |
| 81 | sa.Column('address', sa.String(512), primary_key=True, nullable=False), |
| 82 | sa.Column('kind', sa.String(64), nullable=False), |
| 83 | sa.Column('risk', sa.String(16), nullable=False, server_default='low'), |
| 84 | sa.Column('risk_score', sa.Integer, nullable=False, server_default='0'), |
| 85 | sa.Column('impact_score', sa.Float, nullable=False, server_default='0.0'), |
| 86 | sa.Column('churn_score', sa.Float, nullable=False, server_default='0.0'), |
| 87 | sa.Column('test_gap_score', sa.Float, nullable=False, server_default='0.0'), |
| 88 | sa.Column('coupling_score', sa.Float, nullable=False, server_default='0.0'), |
| 89 | sa.Column('ref', sa.String(128), nullable=False), |
| 90 | ) |
| 91 | op.create_index('ix_intel_blast_risk_repo', 'musehub_intel_blast_risk', ['repo_id']) |
| 92 | |
| 93 | op.create_table( |
| 94 | 'musehub_intel_stable', |
| 95 | sa.Column('repo_id', sa.String(128), sa.ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), primary_key=True, nullable=False), |
| 96 | sa.Column('address', sa.String(512), primary_key=True, nullable=False), |
| 97 | sa.Column('days_stable', sa.Integer, nullable=False, server_default='0'), |
| 98 | sa.Column('since_start', sa.Boolean, nullable=False, server_default='false'), |
| 99 | sa.Column('ref', sa.String(128), nullable=False), |
| 100 | ) |
| 101 | op.create_index('ix_intel_stable_repo', 'musehub_intel_stable', ['repo_id']) |
| 102 | |
| 103 | op.create_table( |
| 104 | 'musehub_intel_velocity', |
| 105 | sa.Column('repo_id', sa.String(128), sa.ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), primary_key=True, nullable=False), |
| 106 | sa.Column('module', sa.String(512), primary_key=True, nullable=False), |
| 107 | sa.Column('added', sa.Integer, nullable=False, server_default='0'), |
| 108 | sa.Column('removed', sa.Integer, nullable=False, server_default='0'), |
| 109 | sa.Column('net', sa.Integer, nullable=False, server_default='0'), |
| 110 | sa.Column('modified', sa.Integer, nullable=False, server_default='0'), |
| 111 | sa.Column('active_commits', sa.Integer, nullable=False, server_default='0'), |
| 112 | sa.Column('prior_added', sa.Integer, nullable=False, server_default='0'), |
| 113 | sa.Column('prior_net', sa.Integer, nullable=False, server_default='0'), |
| 114 | sa.Column('acceleration', sa.Float, nullable=False, server_default='0.0'), |
| 115 | sa.Column('stagnant_commits', sa.Integer, nullable=False, server_default='0'), |
| 116 | sa.Column('ref', sa.String(128), nullable=False), |
| 117 | ) |
| 118 | op.create_index('ix_intel_velocity_repo', 'musehub_intel_velocity', ['repo_id']) |
| 119 | |
| 120 | op.create_table( |
| 121 | 'musehub_intel_clones', |
| 122 | sa.Column('repo_id', sa.String(128), sa.ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), primary_key=True, nullable=False), |
| 123 | sa.Column('cluster_hash', sa.String(128), primary_key=True, nullable=False), |
| 124 | sa.Column('tier', sa.String(32), nullable=False), |
| 125 | sa.Column('member_count', sa.Integer, nullable=False, server_default='0'), |
| 126 | sa.Column('members_json', sa.Text, nullable=False, server_default='[]'), |
| 127 | sa.Column('ref', sa.String(128), nullable=False), |
| 128 | ) |
| 129 | op.create_index('ix_intel_clones_repo', 'musehub_intel_clones', ['repo_id']) |
| 130 | |
| 131 | op.create_table( |
| 132 | 'musehub_intel_type', |
| 133 | sa.Column('repo_id', sa.String(128), sa.ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), primary_key=True, nullable=False), |
| 134 | sa.Column('address', sa.String(512), primary_key=True, nullable=False), |
| 135 | sa.Column('kind', sa.String(64), nullable=False), |
| 136 | sa.Column('return_is_any', sa.Boolean, nullable=False, server_default='false'), |
| 137 | sa.Column('params_total', sa.Integer, nullable=False, server_default='0'), |
| 138 | sa.Column('params_annotated', sa.Integer, nullable=False, server_default='0'), |
| 139 | sa.Column('params_with_any', sa.Integer, nullable=False, server_default='0'), |
| 140 | sa.Column('type_score', sa.Float, nullable=False, server_default='0.0'), |
| 141 | sa.Column('ref', sa.String(128), nullable=False), |
| 142 | ) |
| 143 | op.create_index('ix_intel_type_repo', 'musehub_intel_type', ['repo_id']) |
| 144 | |
| 145 | op.create_table( |
| 146 | 'musehub_intel_api_surface', |
| 147 | sa.Column('repo_id', sa.String(128), sa.ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), primary_key=True, nullable=False), |
| 148 | sa.Column('address', sa.String(512), primary_key=True, nullable=False), |
| 149 | sa.Column('kind', sa.String(64), nullable=False), |
| 150 | sa.Column('signature_id', sa.String(128), nullable=True), |
| 151 | sa.Column('visibility', sa.String(32), nullable=False, server_default='public'), |
| 152 | sa.Column('ref', sa.String(128), nullable=False), |
| 153 | ) |
| 154 | op.create_index('ix_intel_api_surface_repo', 'musehub_intel_api_surface', ['repo_id']) |
| 155 | |
| 156 | op.create_table( |
| 157 | 'musehub_intel_languages', |
| 158 | sa.Column('repo_id', sa.String(128), sa.ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), primary_key=True, nullable=False), |
| 159 | sa.Column('language', sa.String(128), primary_key=True, nullable=False), |
| 160 | sa.Column('symbol_count', sa.Integer, nullable=False, server_default='0'), |
| 161 | sa.Column('file_count', sa.Integer, nullable=False, server_default='0'), |
| 162 | sa.Column('pct', sa.Float, nullable=False, server_default='0.0'), |
| 163 | sa.Column('ref', sa.String(128), nullable=False), |
| 164 | ) |
| 165 | op.create_index('ix_intel_languages_repo', 'musehub_intel_languages', ['repo_id']) |
| 166 | |
| 167 | op.create_table( |
| 168 | 'musehub_intel_refactor_events', |
| 169 | sa.Column('event_id', sa.String(128), primary_key=True, nullable=False), |
| 170 | sa.Column('repo_id', sa.String(128), sa.ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False), |
| 171 | sa.Column('kind', sa.String(64), nullable=False), |
| 172 | sa.Column('address', sa.String(512), nullable=False), |
| 173 | sa.Column('detail', sa.Text, nullable=True), |
| 174 | sa.Column('commit_id', sa.String(128), nullable=False), |
| 175 | sa.Column('committed_at', sa.DateTime(timezone=True), nullable=False), |
| 176 | ) |
| 177 | op.create_index('ix_intel_refactor_events_repo', 'musehub_intel_refactor_events', ['repo_id']) |
| 178 | op.create_index('ix_intel_refactor_events_commit', 'musehub_intel_refactor_events', ['commit_id']) |
| 179 | |
| 180 | |
| 181 | def downgrade() -> None: |
| 182 | op.drop_table('musehub_intel_refactor_events') |
| 183 | op.drop_table('musehub_intel_languages') |
| 184 | op.drop_table('musehub_intel_api_surface') |
| 185 | op.drop_table('musehub_intel_type') |
| 186 | op.drop_table('musehub_intel_clones') |
| 187 | op.drop_table('musehub_intel_velocity') |
| 188 | op.drop_table('musehub_intel_stable') |
| 189 | op.drop_table('musehub_intel_blast_risk') |
| 190 | op.drop_table('musehub_intel_dead') |
| 191 | op.drop_table('musehub_intel_entangle') |
| 192 | op.drop_table('musehub_intel_coupling') |
| 193 | op.drop_column('musehub_symbol_intel', 'op') |
| 194 | op.drop_column('musehub_symbol_intel', 'last_commit_id') |
File History
1 commit
sha256:0997d6250ae6476362f6fe2025af7789f46d03df3e9f34356d5e8ee79b201923
fix(issues): use issue number as pagination cursor, not cre…
Sonnet 4.6
patch
8 days ago