feat(scoring): composite recency decay and severity weights persisted in DB [FASE-5.1]
This commit is contained in:
117
backend/alembic/versions/b030_phase5_scoring_and_snapshots.py
Normal file
117
backend/alembic/versions/b030_phase5_scoring_and_snapshots.py
Normal file
@@ -0,0 +1,117 @@
|
||||
"""Phase 5: scoring recency/severity columns and snapshot breakdown fields.
|
||||
|
||||
Revision ID: b030phase5
|
||||
Revises: b029phase3
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
revision: str = "b030phase5"
|
||||
down_revision: Union[str, None] = "b029phase3"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def _column_names(table: str) -> set[str]:
|
||||
bind = op.get_bind()
|
||||
insp = sa.inspect(bind)
|
||||
return {c["name"] for c in insp.get_columns(table)}
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
snap_cols = _column_names("coverage_snapshots")
|
||||
if "by_tactic" not in snap_cols:
|
||||
op.add_column(
|
||||
"coverage_snapshots",
|
||||
sa.Column("by_tactic", postgresql.JSONB(), nullable=False, server_default="{}"),
|
||||
)
|
||||
if "by_status" not in snap_cols:
|
||||
op.add_column(
|
||||
"coverage_snapshots",
|
||||
sa.Column("by_status", postgresql.JSONB(), nullable=False, server_default="{}"),
|
||||
)
|
||||
if "stale_count" not in snap_cols:
|
||||
op.add_column(
|
||||
"coverage_snapshots",
|
||||
sa.Column("stale_count", sa.Integer(), nullable=False, server_default="0"),
|
||||
)
|
||||
if "never_tested_count" not in snap_cols:
|
||||
op.add_column(
|
||||
"coverage_snapshots",
|
||||
sa.Column("never_tested_count", sa.Integer(), nullable=False, server_default="0"),
|
||||
)
|
||||
if "coverage_percentage" not in snap_cols:
|
||||
op.add_column(
|
||||
"coverage_snapshots",
|
||||
sa.Column("coverage_percentage", sa.Float(), nullable=False, server_default="0"),
|
||||
)
|
||||
|
||||
cfg_cols = _column_names("scoring_config")
|
||||
if "weight_recency" not in cfg_cols and "weight_freshness" in cfg_cols:
|
||||
op.alter_column(
|
||||
"scoring_config",
|
||||
"weight_freshness",
|
||||
new_column_name="weight_recency",
|
||||
)
|
||||
cfg_cols.remove("weight_freshness")
|
||||
cfg_cols.add("weight_recency")
|
||||
elif "weight_recency" not in cfg_cols:
|
||||
op.add_column(
|
||||
"scoring_config",
|
||||
sa.Column("weight_recency", sa.Float(), nullable=False, server_default="10.0"),
|
||||
)
|
||||
|
||||
if "weight_severity" not in cfg_cols and "weight_platform_diversity" in cfg_cols:
|
||||
op.alter_column(
|
||||
"scoring_config",
|
||||
"weight_platform_diversity",
|
||||
new_column_name="weight_severity",
|
||||
)
|
||||
elif "weight_severity" not in cfg_cols:
|
||||
op.add_column(
|
||||
"scoring_config",
|
||||
sa.Column("weight_severity", sa.Float(), nullable=False, server_default="10.0"),
|
||||
)
|
||||
|
||||
if "updated_by" not in cfg_cols:
|
||||
op.add_column(
|
||||
"scoring_config",
|
||||
sa.Column(
|
||||
"updated_by",
|
||||
postgresql.UUID(as_uuid=True),
|
||||
sa.ForeignKey("users.id", ondelete="SET NULL"),
|
||||
nullable=True,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
cfg_cols = _column_names("scoring_config")
|
||||
if "updated_by" in cfg_cols:
|
||||
op.drop_column("scoring_config", "updated_by")
|
||||
if "weight_severity" in cfg_cols:
|
||||
op.alter_column(
|
||||
"scoring_config",
|
||||
"weight_severity",
|
||||
new_column_name="weight_platform_diversity",
|
||||
)
|
||||
if "weight_recency" in cfg_cols:
|
||||
op.alter_column(
|
||||
"scoring_config",
|
||||
"weight_recency",
|
||||
new_column_name="weight_freshness",
|
||||
)
|
||||
|
||||
for col in (
|
||||
"coverage_percentage",
|
||||
"never_tested_count",
|
||||
"stale_count",
|
||||
"by_status",
|
||||
"by_tactic",
|
||||
):
|
||||
if col in _column_names("coverage_snapshots"):
|
||||
op.drop_column("coverage_snapshots", col)
|
||||
Reference in New Issue
Block a user