# 开发 / 测试环境 V4 旧任务数据清理说明 ## 1. 使用边界 本说明只适用于开发 / 测试环境,用于 M002 V4 主线停止双写旧 `workflow_reservation_task` 后,清理历史 smoke、fixture 或调试过程中遗留的旧任务数据。 项目当前决策: - V4 后新业务主线只写 V4 模型:`workflow_reservation_v4_order_task`、`workflow_reservation_v4_task_card`、`workflow_reservation_v4_source_notification`。 - 开发阶段不维护 V2/V3 旧任务兼容,测试数据可重建。 - 本清理策略不代表生产迁移方案;生产数据迁移必须在上线前单独设计、评审和演练。 ## 2. 不清理的数据 以下数据不要通过本脚本清理: - `platform_source_message_inbox` - `workflow_reservation_v4_order_task` - `workflow_reservation_v4_task_card` - `workflow_reservation_v4_source_notification` - `workflow_reservation_catalog_account` - `workflow_reservation_catalog_code` - 用户、角色、权限、菜单和酒店配置表 - `platform_superagent_dispatch_run` - SourceMessage 原始链路和 SuperAgent dispatch 运行记录 ## 3. 清理范围 清理目标为旧任务主模型和直接依赖旧 task 的开发测试数据: - `workflow_reservation_opera_operation_attempt` - `workflow_reservation_opera_operation` - `workflow_reservation_audit_log` 中 `task_id` 指向旧任务的审计行 - `workflow_reservation_invoice_generation.task_id` 指向旧任务时置空,不删除生成记录 - `workflow_reservation_task_card` - `workflow_reservation_task` - `workflow_reservation_order.created_from_task_id` 指向旧任务时置空,不删除订单 `workflow_reservation_invoice_generation` 可能带可选 `task_id`。第一版只解除旧 task 引用,不默认删除催款单生成记录;如某次测试明确需要删除旧任务关联的催款单记录,应另行确认后按测试数据范围处理。 ## 4. 执行前检查 先确认当前环境是开发或测试环境,并备份数据库或保留可重建脚本。 ```sql SELECT COUNT(*) AS legacy_task_count FROM workflow_reservation_task; SELECT hotel_id, task_status, COUNT(*) AS task_count FROM workflow_reservation_task GROUP BY hotel_id, task_status ORDER BY hotel_id, task_status; ``` 如只清理单酒店测试数据,先设置酒店 ID: ```sql SET @hotel_id = 'HOTEL-TEST'; ``` ## 5. 清理 SQL ```sql START TRANSACTION; CREATE TEMPORARY TABLE tmp_dev_legacy_reservation_task_ids ( id BIGINT PRIMARY KEY ); INSERT INTO tmp_dev_legacy_reservation_task_ids (id) SELECT id FROM workflow_reservation_task WHERE hotel_id = @hotel_id; DELETE attempt FROM workflow_reservation_opera_operation_attempt attempt JOIN tmp_dev_legacy_reservation_task_ids legacy_task ON legacy_task.id = attempt.task_id WHERE attempt.hotel_id = @hotel_id; DELETE operation_row FROM workflow_reservation_opera_operation operation_row JOIN tmp_dev_legacy_reservation_task_ids legacy_task ON legacy_task.id = operation_row.task_id WHERE operation_row.hotel_id = @hotel_id; DELETE audit_row FROM workflow_reservation_audit_log audit_row JOIN tmp_dev_legacy_reservation_task_ids legacy_task ON legacy_task.id = audit_row.task_id WHERE audit_row.hotel_id = @hotel_id; UPDATE workflow_reservation_invoice_generation invoice_row JOIN tmp_dev_legacy_reservation_task_ids legacy_task ON legacy_task.id = invoice_row.task_id SET invoice_row.task_id = NULL, invoice_row.updated_at = UTC_TIMESTAMP(6) WHERE invoice_row.hotel_id = @hotel_id; DELETE card FROM workflow_reservation_task_card card JOIN tmp_dev_legacy_reservation_task_ids legacy_task ON legacy_task.id = card.task_id WHERE card.hotel_id = @hotel_id; UPDATE workflow_reservation_order order_row JOIN tmp_dev_legacy_reservation_task_ids legacy_task ON legacy_task.id = order_row.created_from_task_id SET order_row.created_from_task_id = NULL, order_row.updated_at = UTC_TIMESTAMP(6) WHERE order_row.hotel_id = @hotel_id; DELETE task FROM workflow_reservation_task task JOIN tmp_dev_legacy_reservation_task_ids legacy_task ON legacy_task.id = task.id WHERE task.hotel_id = @hotel_id; DROP TEMPORARY TABLE tmp_dev_legacy_reservation_task_ids; COMMIT; ``` 如果确认要清理所有开发 / 测试酒店的旧任务,可去掉上述 SQL 中所有 `hotel_id = @hotel_id` 条件。不要在生产环境执行这种全量清理。 ## 6. 单个 Debug EML 旧任务残留定点清理 当联调时已明确某个旧 `workflow_reservation_task` 是 V4 Debug EML 误走历史 V2/V3 profile 产生的残留,可按旧 task ID 定点清理。该脚本仍只适用于开发 / 测试环境,不清理 SourceMessage、V4 order task、V4 cards、来源通知、目录、账号权限或酒店配置。 执行前应先从当次排查记录中确认旧 `workflow_reservation_task.id`,只把该 ID 填入 `@legacy_task_id`。Debug run ID、SourceMessage ID 只作为人工核对线索,不写入清理条件,避免误清理来源消息或 V4 数据。 ```sql -- 必填:替换为当次排查确认的旧 workflow_reservation_task.id。 -- 保持 NULL 时下方 SQL 不会命中任何旧任务。 SET @legacy_task_id = NULL; SELECT id, hotel_id, source_message_id, field_contract_version, system_task_type, route_code, task_status FROM workflow_reservation_task WHERE id = @legacy_task_id; START TRANSACTION; DELETE attempt FROM workflow_reservation_opera_operation_attempt attempt WHERE attempt.task_id = @legacy_task_id; DELETE operation_row FROM workflow_reservation_opera_operation operation_row WHERE operation_row.task_id = @legacy_task_id; DELETE audit_row FROM workflow_reservation_audit_log audit_row WHERE audit_row.task_id = @legacy_task_id; UPDATE workflow_reservation_invoice_generation invoice_row SET invoice_row.task_id = NULL, invoice_row.updated_at = UTC_TIMESTAMP(6) WHERE invoice_row.task_id = @legacy_task_id; DELETE card FROM workflow_reservation_task_card card WHERE card.task_id = @legacy_task_id; UPDATE workflow_reservation_order order_row SET order_row.created_from_task_id = NULL, order_row.updated_at = UTC_TIMESTAMP(6) WHERE order_row.created_from_task_id = @legacy_task_id; DELETE task FROM workflow_reservation_task task WHERE task.id = @legacy_task_id; COMMIT; SELECT COUNT(*) AS remaining_legacy_task_count FROM workflow_reservation_task WHERE id = @legacy_task_id; ``` ## 7. 执行后验证 单酒店清理时使用以下验证 SQL: ```sql SELECT COUNT(*) AS legacy_task_count FROM workflow_reservation_task WHERE hotel_id = @hotel_id; SELECT COUNT(*) AS legacy_task_card_count FROM workflow_reservation_task_card WHERE hotel_id = @hotel_id; SELECT COUNT(*) AS legacy_opera_operation_count FROM workflow_reservation_opera_operation WHERE hotel_id = @hotel_id; SELECT COUNT(*) AS legacy_opera_attempt_count FROM workflow_reservation_opera_operation_attempt WHERE hotel_id = @hotel_id; SELECT COUNT(*) AS legacy_invoice_task_link_count FROM workflow_reservation_invoice_generation WHERE hotel_id = @hotel_id AND task_id IS NOT NULL; ``` 如果执行的是全量开发 / 测试酒店清理,验证时同步去掉 `hotel_id = @hotel_id` 条件,确认全库旧任务及直接依赖已清空或解绑: ```sql SELECT COUNT(*) AS legacy_task_count FROM workflow_reservation_task; SELECT COUNT(*) AS legacy_task_card_count FROM workflow_reservation_task_card; SELECT COUNT(*) AS legacy_opera_operation_count FROM workflow_reservation_opera_operation; SELECT COUNT(*) AS legacy_opera_attempt_count FROM workflow_reservation_opera_operation_attempt; SELECT COUNT(*) AS legacy_invoice_task_link_count FROM workflow_reservation_invoice_generation WHERE task_id IS NOT NULL; ``` 订单列表验证口径: - `GET /api/reservation/orders` 中新 V4 订单的 `open_work_item_count` 只看 V4 未完成订单任务。 - 清理后,新 V4 订单不应再返回旧 `next_processable_task_id`。 - `platform_source_message_inbox`、V4 order task、V4 cards、V4 source notification、目录、用户权限和酒店配置应保持不变。