Files
han-app/codebase/backend/api-backend/alembic/versions/0012_safety_v2_checkpoint.py
T

75 lines
3.0 KiB
Python

"""Persist Message Safety v2 evidence and recovery locations.
Revision ID: 0012_safety_v2_checkpoint
Revises: 0011_module07_contract
Create Date: 2026-08-06
"""
from collections.abc import Sequence
from alembic import op
revision: str = "0012_safety_v2_checkpoint"
down_revision: str | None = "0011_module07_contract"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
op.execute(
"""
ALTER TABLE han_app.messages
ADD COLUMN IF NOT EXISTS safety_processing_mode varchar(16),
ADD COLUMN IF NOT EXISTS safety_config_version bigint,
ADD COLUMN IF NOT EXISTS safety_rules_version varchar(128);
ALTER TABLE han_app.message_attachments
ADD COLUMN IF NOT EXISTS quarantine_version_id varchar(1024),
ADD COLUMN IF NOT EXISTS quarantine_etag varchar(1024);
ALTER TABLE han_app.message_attachments
DROP CONSTRAINT IF EXISTS message_attachments_scan_status_check;
ALTER TABLE han_app.message_attachments
ADD CONSTRAINT message_attachments_scan_status_check
CHECK (scan_status IN ('pending','clean','bypassed','infected','failed')) NOT VALID;
ALTER TABLE han_app.message_attachments
VALIDATE CONSTRAINT message_attachments_scan_status_check;
ALTER TABLE han_app.safety_tasks
ADD COLUMN IF NOT EXISTS poll_location varchar(1024),
ADD COLUMN IF NOT EXISTS processing_mode varchar(16),
ADD COLUMN IF NOT EXISTS config_version bigint,
ADD COLUMN IF NOT EXISTS rules_version varchar(128),
ADD COLUMN IF NOT EXISTS expires_at timestamptz;
UPDATE han_app.safety_tasks
SET poll_location = '/internal/safety/v2/messages/tasks/' || task_id,
expires_at = deadline_at
WHERE poll_location IS NULL OR expires_at IS NULL;
ALTER TABLE han_app.safety_tasks
ALTER COLUMN poll_location SET NOT NULL,
ALTER COLUMN expires_at SET NOT NULL;
"""
)
# Notification uploads use the same safety contract.
op.execute(
"""
ALTER TABLE han_app.client_upload_drafts
ADD COLUMN IF NOT EXISTS quarantine_version_id varchar(1024),
ADD COLUMN IF NOT EXISTS quarantine_etag varchar(1024),
ADD COLUMN IF NOT EXISTS safety_processing_mode varchar(16),
ADD COLUMN IF NOT EXISTS safety_config_version bigint,
ADD COLUMN IF NOT EXISTS safety_rules_version varchar(128);
ALTER TABLE han_app.client_upload_drafts
DROP CONSTRAINT IF EXISTS client_upload_drafts_scan_status_check;
ALTER TABLE han_app.client_upload_drafts
ADD CONSTRAINT client_upload_drafts_scan_status_check
CHECK (scan_status IN ('pending','clean','bypassed','infected','failed')) NOT VALID;
ALTER TABLE han_app.client_upload_drafts
VALIDATE CONSTRAINT client_upload_drafts_scan_status_check;
"""
)
def downgrade() -> None:
raise RuntimeError("Safety v2 checkpoint migration is forward-only")