"""Backfill software owners onto historical offboarding revoke tasks. Revision ID: 524 Revises: 523 """ import sqlalchemy as sa from alembic import op revision = "524" down_revision = "523" branch_labels = None depends_on = None def upgrade() -> None: # Idempotent: only fills genuinely unassigned software seat/permission # revoke tasks. Explicit transfers and tasks without a catalog owner are # intentionally left unchanged. op.get_bind().execute( sa.text( """ UPDATE provisioning_tasks AS task INNER JOIN asset_software_catalog AS software ON software.id = task.software_id SET task.assignee_id = software.owner_person_id WHERE task.source = 'offboarding' AND task.action = 'revoke' AND task.target_type IN ('seat', 'permission') AND task.assignee_id IS NULL AND task.software_id IS NOT NULL AND software.owner_person_id IS NOT NULL """ ) ) def downgrade() -> None: # Do not erase assignees on downgrade: the migration cannot distinguish # rows backfilled here from rows deliberately assigned before it ran. pass