-- D09 DRAFT ONLY. Never run this file against production as part of application startup. -- Quiesce handling, transfer, return, restart and advance workers before an audited legacy backfill. -- Apply additive columns first, then deploy ALL D09 writers together; mixed old/new writers are unsafe. -- The root task is an identity, not a completion-order comparison. Never backfill MAX(task_id). ALTER TABLE flw_advance_intent ADD COLUMN activation_task_id BIGINT NULL, ADD COLUMN activation_task_ids LONGTEXT NULL, ADD COLUMN handled_task_ids LONGTEXT NULL, ADD COLUMN trigger_task_id BIGINT NULL, ADD COLUMN activation_def_id BIGINT NULL, ADD COLUMN activation_def_version INT NULL, ADD COLUMN activation_apply_round INT NULL, ADD COLUMN revision BIGINT NOT NULL DEFAULT 0, ADD UNIQUE KEY uk_flw_advance_activation (activation_task_id); -- Inventory is a rollout gate, not an automatic guess of the historical cohort/last handler: -- SELECT instance_id,node_id,id,status FROM flw_advance_intent WHERE activation_task_id IS NULL AND status IN ('PENDING','EXHAUSTED'); -- NULL work without a registered successor is held EXHAUSTED, never executed or silently marked DONE. -- For a still-active legacy node, an operator supplies the EXACT audited current task cohort. -- If pending tasks remain, p_trigger must be NULL: their future real handling re-arms the new head. -- If all tasks are already handled, p_trigger requires independent evidence of the LAST handler; -- equal handle_time/ID order is NOT evidence. Ambiguous history stays held for an explicit audited resolution. -- p_audit_ref identifies that evidence. A successor is inserted BEFORE NULL work is retired, atomically. -- Test harness extracts the procedure below as ONE JDBC statement; mysql clients need DELIMITER $$ ... $$. DELIMITER $$ -- D09_BACKFILL_BEGIN CREATE PROCEDURE d09_backfill_activation(IN p_instance BIGINT, IN p_node VARCHAR(64), IN p_tasks JSON, IN p_trigger BIGINT, IN p_audit_ref VARCHAR(128)) BEGIN DECLARE v_root BIGINT; DECLARE v_def BIGINT; DECLARE v_version INT; DECLARE v_round INT; DECLARE v_status INT; DECLARE v_nodes TEXT; DECLARE v_pending INT; DECLARE v_count INT; DECLARE v_head BIGINT; DECLARE v_members LONGTEXT; DECLARE v_handled JSON; DECLARE v_edge VARCHAR(128); DECLARE v_user INT; DECLARE v_name VARCHAR(64); DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; RESIGNAL; END; IF p_audit_ref IS NULL OR LENGTH(TRIM(p_audit_ref))=0 OR p_tasks IS NULL OR JSON_TYPE(p_tasks)<>'ARRAY' OR JSON_LENGTH(p_tasks)=0 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='D09 audited cohort input is required'; END IF; IF EXISTS (SELECT 1 FROM JSON_TABLE(p_tasks,'$[*]' COLUMNS(ord FOR ORDINALITY,task_id BIGINT PATH '$')) j WHERE JSON_TYPE(JSON_EXTRACT(p_tasks,CONCAT('$[',j.ord-1,']')))<>'INTEGER' OR j.task_id<=0) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='D09 task identities must be positive integers'; END IF; START TRANSACTION; SELECT def_id,def_version,apply_round,status,current_nodes INTO v_def,v_version,v_round,v_status,v_nodes FROM flw_instance WHERE id=p_instance FOR UPDATE; IF v_status IS NULL OR v_status<>10 OR FIND_IN_SET(p_node,COALESCE(v_nodes,''))=0 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='D09 legacy node is not currently active'; END IF; IF EXISTS (SELECT 1 FROM flw_advance_intent WHERE instance_id=p_instance AND node_id=p_node AND activation_task_id IS NOT NULL) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='D09 registered successor exists; do not overwrite it'; END IF; SELECT COUNT(DISTINCT t.id),MIN(t.id) INTO v_count,v_root FROM flw_task t JOIN JSON_TABLE(p_tasks,'$[*]' COLUMNS(task_id BIGINT PATH '$')) j ON j.task_id=t.id WHERE t.instance_id=p_instance AND t.node_id=p_node AND t.status IN (0,1,3,5); IF v_count<>JSON_LENGTH(p_tasks) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='D09 cohort has duplicates, foreign or invalid tasks'; END IF; SET v_members=CONCAT(',',REPLACE(REPLACE(REPLACE(CAST(p_tasks AS CHAR),'[',''),']',''),' ',''),','); IF EXISTS (SELECT 1 FROM flw_task WHERE instance_id=p_instance AND node_id=p_node AND status=0 AND LOCATE(CONCAT(',',id,','),v_members)=0) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='D09 cohort omits current pending tasks'; END IF; SELECT COUNT(*) INTO v_pending FROM flw_task WHERE instance_id=p_instance AND node_id=p_node AND status=0; IF (v_pending=0 AND p_trigger IS NULL) OR (v_pending>0 AND p_trigger IS NOT NULL) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='D09 pending cohort waits; completed cohort needs proven last handler'; END IF; IF p_trigger IS NOT NULL THEN IF LOCATE(CONCAT(',',p_trigger,','),v_members)=0 OR NOT EXISTS (SELECT 1 FROM flw_task WHERE id=p_trigger AND status=1) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='D09 last handler is not an approved cohort member'; END IF; SELECT edge_name,assignee_id,assignee_name INTO v_edge,v_user,v_name FROM flw_task WHERE id=p_trigger; END IF; SELECT JSON_ARRAYAGG(id) INTO v_handled FROM flw_task WHERE instance_id=p_instance AND node_id=p_node AND status<>0 AND LOCATE(CONCAT(',',id,','),v_members)>0; INSERT INTO flw_advance_intent(instance_id,node_id,activation_task_id,activation_task_ids,handled_task_ids, trigger_task_id,activation_def_id,activation_def_version,activation_apply_round,revision, edge_name,assignee_id,assignee_name,status,attempts,next_retry_at,last_error,create_time,update_time,create_by) VALUES(p_instance,p_node,v_root,v_members, IF(v_handled IS NULL,NULL,CONCAT(',',REPLACE(REPLACE(REPLACE(CAST(v_handled AS CHAR),'[',''),']',''),' ',''),',')), p_trigger,v_def,v_version,v_round,0,v_edge,v_user,v_name,IF(p_trigger IS NULL,'DONE','PENDING'),0,NOW(), LEFT(CONCAT('D09_AUDITED_BACKFILL: ',p_audit_ref),255),NOW(),NOW(),LEFT(p_audit_ref,64)); SET v_head=LAST_INSERT_ID(); UPDATE flw_advance_intent SET status='DONE',revision=revision+1,update_time=NOW(), last_error=LEFT(CONCAT('D09_HANDOFF: successor=',v_head,' audit=',p_audit_ref),255) WHERE instance_id=p_instance AND node_id=p_node AND activation_task_id IS NULL AND status IN ('PENDING','EXHAUSTED'); COMMIT; END -- D09_BACKFILL_END $$ DELIMITER ; -- No CALL is executed by this draft. Audit the cohort before an explicitly approved maintenance invocation.