"""Adopt the App queue contract and migrate legacy mappings. Revision ID: 0002_app_queue_contract Revises: 0001_bitrix_sync_full Create Date: 2026-08-06 """ from collections.abc import Sequence from alembic import op revision: str = "0002_app_queue_contract" down_revision: str | None = "0001_bitrix_sync_full" branch_labels: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None def upgrade() -> None: op.execute( """ DO $$ BEGIN IF to_regclass('han_app.entity_external_mapping') IS NOT NULL THEN EXECUTE $copy$ INSERT INTO bitrix_sync.entity_external_mapping (id,entity_type,entity_id,external_system,external_entity_type, external_id,status,opened_at,closed_at,close_reason,created_at,updated_at) SELECT id,entity_type,entity_id,'bitrix24','contact', external_id,'active',coalesce(created_at,now()),NULL,NULL, coalesce(created_at,now()),coalesce(created_at,now()) FROM han_app.entity_external_mapping ON CONFLICT DO NOTHING $copy$; IF EXISTS ( SELECT 1 FROM han_app.entity_external_mapping old LEFT JOIN bitrix_sync.entity_external_mapping new ON new.id=old.id WHERE new.id IS NULL ) THEN RAISE EXCEPTION 'legacy mapping migration verification failed'; END IF; END IF; END $$; """ ) op.execute( """ INSERT INTO bitrix_sync.settings_versions (id,version,validation_status,active,created_by,created_at,activated_at) VALUES ('00000000-0000-0000-0000-000000000001',1,'valid',true,'migration',now(),now()) ON CONFLICT DO NOTHING """ ) op.execute( """ INSERT INTO bitrix_sync.settings (id,version_id,key,value_type,value_json,validation_status,active,created_at,updated_at) VALUES (gen_random_uuid(),'00000000-0000-0000-0000-000000000001','worker','object', jsonb_build_object( 'batch_size',20,'batch_wait_ms',200,'claim_size',20,'lease_seconds',60, 'limiter_refill_per_sec',2,'limiter_burst',2,'max_in_flight',2, 'retry_base_seconds',1,'retry_max_seconds',900,'retry_horizon_seconds',86400 ), 'valid',true,now(),now()), (gen_random_uuid(),'00000000-0000-0000-0000-000000000001','reconciliation','object', jsonb_build_object( 'contact_interval_seconds',900,'alert_interval_seconds',3600, 'overlap_seconds',300,'recovered_spike_threshold',20 ), 'valid',true,now(),now()), (gen_random_uuid(),'00000000-0000-0000-0000-000000000001','business_alerts','object', jsonb_build_object( 'entity_type_id',NULL,'category_id',NULL,'stage_new',NULL, 'stage_in_progress',NULL,'stage_resolved',NULL, 'stage_closed_without_resolution',NULL,'sla_business_hours',8 ), 'valid',true,now(),now()) ON CONFLICT DO NOTHING; """ ) def downgrade() -> None: raise RuntimeError("App queue contract migration is forward-only")