Close the 037 pipeline-automation and read-API gaps found in the audit:
deploy/release hooks did not create VerificationRun, and GET endpoints for
history/detail were absent even though 039 UI and client call them.
T080 - _release_routes.py: create_release now fires best-effort
_trigger_release_verification -> VerificationRun with trigger=release_create
(metric+structure); verification scheduling failures never roll back the
release transaction.
T081 - verification.py: add GET /verification/history (dashboard_id +
environment_id filters, newest-first) and GET /verification/{run_id}
(404 RUN_NOT_FOUND); reuse _record_to_response.
- verification_run.py + alembic migration p2q3r4s5t6u7: nullable indexed
dashboard_id populated from structure/visual/metric category_params.
- verification_service.py: _derive_dashboard_id helper.
Verification: release routes (32) + verification API (8) + persistence (21)
= 53 passed; ruff clean for changed code (pre-existing RUF012/UP017 on old
lines left untouched).
45 lines
1.9 KiB
Python
45 lines
1.9 KiB
Python
# #region Alembic.VerificationRunDashboardId [C:2] [TYPE Module] [SEMANTICS alembic,verification,dashboard,history]
|
|
# @ingroup Alembic
|
|
# @BRIEF Add nullable verification_runs.dashboard_id for 037 T081 history filtering by dashboard.
|
|
# @LAYER Database
|
|
# @RELATION DEPENDS_ON -> [Models.VerificationRun]
|
|
# @INVARIANT The column is nullable and indexed — existing runs remain valid and history
|
|
# filtering by dashboard is a soft filter (runs without dashboard_id excluded only
|
|
# when the caller filters on dashboard_id).
|
|
# @RATIONALE VerificationRunRecord previously carried repository/release/environment but no
|
|
# dashboard identity; frontend getVerificationHistory(dashboardId, envId) needs a
|
|
# dashboard-scoped query. dashboard_id is populated from category_params at persist.
|
|
# @REJECTED Encoding dashboard identity into environment_id or release_id was rejected — it is
|
|
# a distinct dimension and would corrupt existing environment/release semantics.
|
|
"""add verification_runs.dashboard_id
|
|
|
|
Revision ID: p2q3r4s5t6u7
|
|
Revises: o1p2q3r4s5t6
|
|
Create Date: 2026-08-07 14:00:00.000000
|
|
"""
|
|
|
|
from collections.abc import Sequence
|
|
|
|
import sqlalchemy as sa
|
|
|
|
from alembic import op
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = "p2q3r4s5t6u7"
|
|
down_revision: str | Sequence[str] | None = "o1p2q3r4s5t6"
|
|
branch_labels: str | Sequence[str] | None = None
|
|
depends_on: str | Sequence[str] | None = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
"""Add nullable, indexed verification_runs.dashboard_id."""
|
|
op.add_column("verification_runs", sa.Column("dashboard_id", sa.Integer(), nullable=True))
|
|
op.create_index("ix_verification_runs_dashboard", "verification_runs", ["dashboard_id"])
|
|
|
|
|
|
def downgrade() -> None:
|
|
"""Drop the dashboard_id index and column."""
|
|
op.drop_index("ix_verification_runs_dashboard", table_name="verification_runs")
|
|
op.drop_column("verification_runs", "dashboard_id")
|
|
# #endregion Alembic.VerificationRunDashboardId
|