fix: 恢复旧通道报废催办投递
This commit is contained in:
parent
f670ccb5d5
commit
2e316a7104
@ -0,0 +1,57 @@
|
||||
-- 统一通知中心切换前,旧 work_notice 催办任务可能在零次投递时就把报废单标记为已催办。
|
||||
-- 保留旧任务用于审计,但仅对“仍待审批、从未尝试/发送、且尚无新通道任务”的记录开放一次重新催办。
|
||||
START TRANSACTION;
|
||||
|
||||
UPDATE `disposal_record` AS `disposal`
|
||||
SET `disposal`.`reminded_at` = NULL
|
||||
WHERE `disposal`.`status` = 'pending'
|
||||
AND `disposal`.`reminded_at` IS NOT NULL
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM `dingtalk_delivery` AS `legacy_delivery`
|
||||
WHERE `legacy_delivery`.`business_type` = 'disposal'
|
||||
AND `legacy_delivery`.`business_id` = `disposal`.`id`
|
||||
AND `legacy_delivery`.`event_type` = 'disposal_overdue_reminder'
|
||||
AND `legacy_delivery`.`provider_type` = 'work_notice'
|
||||
AND `legacy_delivery`.`status` IN ('pending', 'retrying', 'sending')
|
||||
AND `legacy_delivery`.`attempt_count` = 0
|
||||
AND `legacy_delivery`.`dingtalk_task_id` IS NULL
|
||||
AND `legacy_delivery`.`sent_at` IS NULL
|
||||
AND `legacy_delivery`.`read_at` IS NULL
|
||||
)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM `dingtalk_delivery` AS `current_delivery`
|
||||
WHERE `current_delivery`.`business_type` = 'disposal'
|
||||
AND `current_delivery`.`business_id` = `disposal`.`id`
|
||||
AND `current_delivery`.`event_type` = 'disposal_overdue_reminder'
|
||||
AND `current_delivery`.`provider_type` = 'notification_center'
|
||||
);
|
||||
|
||||
UPDATE `dingtalk_delivery` AS `legacy_delivery`
|
||||
JOIN `disposal_record` AS `disposal`
|
||||
ON `disposal`.`id` = `legacy_delivery`.`business_id`
|
||||
LEFT JOIN `dingtalk_delivery` AS `current_delivery`
|
||||
ON `current_delivery`.`business_type` = 'disposal'
|
||||
AND `current_delivery`.`business_id` = `legacy_delivery`.`business_id`
|
||||
AND `current_delivery`.`event_type` = 'disposal_overdue_reminder'
|
||||
AND `current_delivery`.`provider_type` = 'notification_center'
|
||||
SET `legacy_delivery`.`status` = 'failed',
|
||||
`legacy_delivery`.`next_attempt_at` = NOW(3),
|
||||
`legacy_delivery`.`lease_owner` = NULL,
|
||||
`legacy_delivery`.`lease_expires_at` = NULL,
|
||||
`legacy_delivery`.`last_error_code` = 'LEGACY_CHANNEL_RETIRED',
|
||||
`legacy_delivery`.`last_error_message` = '历史工作通知通道未实际投递,已开放由统一通知中心重新生成',
|
||||
`legacy_delivery`.`failure_notified_at` = NOW(3)
|
||||
WHERE `legacy_delivery`.`business_type` = 'disposal'
|
||||
AND `legacy_delivery`.`event_type` = 'disposal_overdue_reminder'
|
||||
AND `legacy_delivery`.`provider_type` = 'work_notice'
|
||||
AND `legacy_delivery`.`status` IN ('pending', 'retrying', 'sending')
|
||||
AND `legacy_delivery`.`attempt_count` = 0
|
||||
AND `legacy_delivery`.`dingtalk_task_id` IS NULL
|
||||
AND `legacy_delivery`.`sent_at` IS NULL
|
||||
AND `legacy_delivery`.`read_at` IS NULL
|
||||
AND `disposal`.`status` = 'pending'
|
||||
AND `current_delivery`.`id` IS NULL;
|
||||
|
||||
COMMIT;
|
||||
@ -0,0 +1,39 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import test from 'node:test'
|
||||
|
||||
const migrationPath = path.resolve(
|
||||
__dirname,
|
||||
'../../../prisma/migrations/20260717_recover_legacy_disposal_reminders/migration.sql'
|
||||
)
|
||||
|
||||
test('旧通道零次投递的报废催办可重新生成统一通知中心任务', () => {
|
||||
const sql = readFileSync(migrationPath, 'utf8')
|
||||
|
||||
assert.match(sql, /START TRANSACTION;/i)
|
||||
assert.match(sql, /UPDATE `disposal_record` AS `disposal`/i)
|
||||
assert.match(sql, /SET `disposal`\.`reminded_at` = NULL/i)
|
||||
assert.match(sql, /`disposal`\.`status` = 'pending'/i)
|
||||
assert.match(sql, /`legacy_delivery`\.`provider_type` = 'work_notice'/i)
|
||||
assert.match(sql, /`legacy_delivery`\.`attempt_count` = 0/i)
|
||||
assert.match(sql, /`legacy_delivery`\.`sent_at` IS NULL/i)
|
||||
assert.match(sql, /`legacy_delivery`\.`read_at` IS NULL/i)
|
||||
assert.match(sql, /`current_delivery`\.`provider_type` = 'notification_center'/i)
|
||||
assert.match(sql, /SET `legacy_delivery`\.`status` = 'failed'/i)
|
||||
assert.match(sql, /LEGACY_CHANNEL_RETIRED/i)
|
||||
assert.match(sql, /`legacy_delivery`\.`failure_notified_at` = NOW\(3\)/i)
|
||||
assert.match(sql, /LEFT JOIN `dingtalk_delivery` AS `current_delivery`/i)
|
||||
assert.match(sql, /`current_delivery`\.`id` IS NULL/i)
|
||||
assert.match(sql, /COMMIT;/i)
|
||||
assert.doesNotMatch(sql, /DELETE\s+FROM\s+`?dingtalk_delivery`?/i)
|
||||
})
|
||||
|
||||
test('已发送、已读或已有统一通知中心任务的催办不会被迁移重放', () => {
|
||||
const sql = readFileSync(migrationPath, 'utf8')
|
||||
|
||||
assert.match(sql, /`legacy_delivery`\.`dingtalk_task_id` IS NULL/i)
|
||||
assert.match(sql, /NOT EXISTS \([\s\S]*`current_delivery`\.`event_type` = 'disposal_overdue_reminder'[\s\S]*`current_delivery`\.`provider_type` = 'notification_center'/i)
|
||||
assert.doesNotMatch(sql, /`sent_at`\s*=\s*NULL/i)
|
||||
assert.doesNotMatch(sql, /`read_at`\s*=\s*NULL/i)
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user