44 lines
2.7 KiB
PL/PgSQL
44 lines
2.7 KiB
PL/PgSQL
-- Keep the live charge and intent fences in sync with recovery action v8.
|
|
-- Existing authenticated v6/v7 history remains unchanged.
|
|
BEGIN;
|
|
CREATE OR REPLACE FUNCTION public.mcp_routing_manual_inverse_charge_source() RETURNS trigger LANGUAGE plpgsql AS $$
|
|
BEGIN
|
|
IF NOT EXISTS(
|
|
SELECT 1 FROM public.mcp_operations o
|
|
JOIN public.mcp_plans p ON p.id=o.plan_id AND p.connection_id=o.connection_id
|
|
JOIN public.mcp_routing_profiles r ON r.id=NEW.profile_id AND r.connection_id=o.connection_id
|
|
JOIN public.mcp_operations source ON source.id=NEW.source_operation_id AND source.connection_id=o.connection_id
|
|
JOIN public.mcp_plans sp ON sp.id=source.plan_id AND sp.connection_id=source.connection_id
|
|
JOIN public.mcp_connections c ON c.id=o.connection_id
|
|
WHERE o.id=NEW.recovery_operation_id AND p.id=NEW.recovery_plan_id
|
|
AND o.connection_id=NEW.connection_id AND c.owner_id=NEW.owner_id
|
|
AND r.version=NEW.profile_version AND o.state='pending' AND p.state='executing'
|
|
AND p.operation_id='operations.recover' AND p.operation_version=8
|
|
AND sp.id=NEW.source_plan_id AND sp.operation_id='routing.community.switch' AND sp.operation_version=7
|
|
AND source.state IN('applied','partial')
|
|
) THEN RAISE EXCEPTION 'manual inverse charge differs from pending admission'; END IF;
|
|
RETURN NEW;
|
|
END $$;
|
|
CREATE OR REPLACE FUNCTION public.mcp_scoped_recovery_manual_version() RETURNS trigger LANGUAGE plpgsql AS $$
|
|
BEGIN
|
|
IF NEW.mode='manual' AND NOT pg_try_advisory_xact_lock(hashtextextended('mcp-runner-admission',0))
|
|
THEN RAISE EXCEPTION 'manual intent admission snapshot busy'; END IF;
|
|
IF NEW.mode='manual' AND NOT EXISTS(
|
|
SELECT 1 FROM public.mcp_operations o
|
|
JOIN public.mcp_plans p ON p.id=o.plan_id AND p.connection_id=o.connection_id
|
|
JOIN public.mcp_operation_steps s ON s.operation_id=o.id AND s.step_index=0
|
|
JOIN public.mcp_operations source ON source.id=NEW.source_operation_id AND source.connection_id=o.connection_id
|
|
WHERE o.id=NEW.recovery_operation_id AND o.state='running'
|
|
AND p.state='executing' AND p.operation_id='operations.recover' AND p.operation_version=8
|
|
AND NEW.source_step_index=0 AND s.state='intent'
|
|
AND s.intended_state->>'kind'='service'
|
|
AND s.intended_state->>'service'='routing.community.scoped.recover'
|
|
AND s.intended_state->'input'->>'mode'='manual'
|
|
AND s.intended_state->'input'->>'sourceOperationId'=NEW.source_operation_id::text
|
|
AND s.intended_state->'input'->>'receiptId'=NEW.recovery_receipt_id::text
|
|
) THEN RAISE EXCEPTION 'manual inverse requires current exact running recovery'; END IF;
|
|
RETURN NEW;
|
|
END $$;
|
|
INSERT INTO public.schema_migrations(id) VALUES('0056_mcp_manual_inverse_recovery_v8') ON CONFLICT(id) DO NOTHING;
|
|
COMMIT;
|