CREATE TRIGGER `provisioning_queue_guard` BEFORE INSERT ON `provisioning_operations` WHEN NEW.`status` = 'requested' BEGIN SELECT CASE WHEN NOT EXISTS ( SELECT 1 FROM `tenant_instances` WHERE `id` = NEW.`tenant_id` AND `desired_generation` + 1 = NEW.`target_generation` AND `credential_revision` = NEW.`credential_revision` AND `tombstoned_at` IS NULL AND ( (NEW.`operation` = 'ensure' AND `lifecycle` IN ('requested', 'failed', 'degraded')) OR (NEW.`operation` = 'suspend' AND `lifecycle` IN ('ready', 'degraded')) OR (NEW.`operation` = 'resume' AND `lifecycle` IN ('suspended', 'failed')) OR (NEW.`operation` = 'deprovision' AND `lifecycle` IN ('requested', 'ready', 'suspended', 'failed', 'degraded')) ) ) THEN RAISE(ABORT, 'invalid_provisioning_transition') END; END;--> statement-breakpoint CREATE TRIGGER `provisioning_queue_tenant_update` AFTER INSERT ON `provisioning_operations` WHEN NEW.`status` = 'requested' BEGIN UPDATE `tenant_instances` SET `lifecycle` = CASE NEW.`operation` WHEN 'suspend' THEN 'suspending' WHEN 'deprovision' THEN 'deprovisioning' ELSE 'provisioning' END, `desired_state` = CASE NEW.`operation` WHEN 'suspend' THEN 'suspended' WHEN 'deprovision' THEN 'deleted' ELSE 'running' END, `desired_generation` = NEW.`target_generation`, `relay_ready` = 0, `updated_at` = NEW.`created_at` WHERE `id` = NEW.`tenant_id`; END;--> statement-breakpoint CREATE TRIGGER `provisioning_completion_guard` BEFORE UPDATE OF `status` ON `provisioning_operations` WHEN OLD.`status` IN ('requested', 'leased') AND NEW.`status` IN ('succeeded', 'failed') BEGIN SELECT CASE WHEN NOT EXISTS ( SELECT 1 FROM `tenant_instances` WHERE `id` = OLD.`tenant_id` AND `desired_generation` = OLD.`target_generation` AND ( NEW.`status` = 'failed' OR `credential_revision` = OLD.`credential_revision` ) ) THEN RAISE(ABORT, 'stale_provisioning_generation') END; END;--> statement-breakpoint CREATE TRIGGER `provisioning_completion_tenant_update` AFTER UPDATE OF `status` ON `provisioning_operations` WHEN OLD.`status` IN ('requested', 'leased') AND NEW.`status` IN ('succeeded', 'failed') BEGIN UPDATE `tenant_instances` SET `lifecycle` = CASE WHEN NEW.`status` = 'failed' AND NEW.`operation` IN ('ensure', 'resume') THEN 'failed' WHEN NEW.`status` = 'failed' THEN 'degraded' WHEN NEW.`operation` IN ('ensure', 'resume') THEN 'ready' WHEN NEW.`operation` = 'suspend' THEN 'suspended' ELSE 'deleted' END, `observed_state` = CASE WHEN NEW.`status` = 'failed' THEN `observed_state` WHEN NEW.`operation` IN ('ensure', 'resume') THEN 'running' WHEN NEW.`operation` = 'suspend' THEN 'suspended' ELSE 'absent' END, `active_generation` = CASE WHEN NEW.`status` = 'succeeded' THEN NEW.`target_generation` ELSE `active_generation` END, `runtime_version` = CASE WHEN NEW.`status` = 'succeeded' AND NEW.`operation` IN ('ensure', 'resume') THEN NEW.`result_runtime_version` WHEN NEW.`status` = 'succeeded' AND NEW.`operation` = 'deprovision' THEN NULL ELSE `runtime_version` END, `runtime_ref` = CASE WHEN NEW.`status` = 'succeeded' AND NEW.`operation` IN ('ensure', 'resume') THEN NEW.`result_runtime_ref` WHEN NEW.`status` = 'succeeded' AND NEW.`operation` = 'deprovision' THEN NULL ELSE `runtime_ref` END, `relay_origin` = CASE WHEN NEW.`status` = 'succeeded' AND NEW.`operation` IN ('ensure', 'resume') THEN NEW.`result_relay_origin` WHEN NEW.`status` = 'succeeded' AND NEW.`operation` = 'deprovision' THEN NULL ELSE `relay_origin` END, `secret_bundle_ref` = CASE WHEN NEW.`status` = 'succeeded' AND NEW.`operation` IN ('ensure', 'resume') THEN NEW.`result_secret_bundle_ref` WHEN NEW.`status` = 'succeeded' AND NEW.`operation` = 'deprovision' THEN NULL ELSE `secret_bundle_ref` END, `last_health_at` = CASE WHEN NEW.`status` = 'succeeded' THEN NEW.`health_checked_at` ELSE `last_health_at` END, `tombstoned_at` = CASE WHEN NEW.`status` = 'succeeded' AND NEW.`operation` = 'deprovision' THEN NEW.`completed_at` ELSE `tombstoned_at` END, `relay_ready` = 0, `updated_at` = NEW.`completed_at` WHERE `id` = NEW.`tenant_id`; END;