fix(prod): dedupe scheduled tasks and reconcile orphan delivery contracts
Memind CI / Test, build, and release guards (push) Successful in 2m58s

Prevent duplicate active scheduled tasks, fail static preparing contracts
when HTML is missing, raise MindSpace remote timeout default to 30s, and
add 103 repair scripts for inspection follow-ups.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-16 08:52:16 +08:00
parent f20302fe65
commit 843e4d1002
8 changed files with 296 additions and 5 deletions
+56
View File
@@ -19,6 +19,9 @@ test('createTask inserts scheduled automation row', async () => {
const inserts = [];
const service = createScheduledTaskService({
async query(sql, params) {
if (sql.includes('FROM h5_scheduled_tasks') && sql.includes('status = \'active\'')) {
return [[]];
}
if (sql.includes('INSERT INTO h5_scheduled_tasks')) {
inserts.push(params);
return [{ affectedRows: 1 }];
@@ -69,6 +72,59 @@ test('createTask inserts scheduled automation row', async () => {
assert.equal(inserts.length, 1);
});
test('createTask returns existing active duplicate for same schedule', async () => {
let insertCount = 0;
const service = createScheduledTaskService({
async query(sql) {
if (sql.includes('FROM h5_scheduled_tasks') && sql.includes('status = \'active\'')) {
return [[{
id: 'task-existing',
user_id: 'user-1',
title: '每日天气预报播报(上海+武穴)',
task_spec: 'old spec',
recurrence: 'daily',
hour: 8,
minute: 0,
weekday: null,
timezone: 'Asia/Shanghai',
next_run_at: 1780000000000,
last_run_at: null,
notify_channel: 'both',
status: 'active',
attempts: 0,
last_error: null,
last_result_json: null,
source_channel: 'agent',
source_session_id: null,
source_message_id: null,
source_text: null,
created_at: 1780000000000,
updated_at: 1780000000000,
}]];
}
if (sql.includes('INSERT INTO h5_scheduled_tasks')) {
insertCount += 1;
return [{ affectedRows: 1 }];
}
return [[]];
},
}, {
clock: { now: () => 1780000000000 },
});
const task = await service.createTask({
userId: 'user-1',
title: '每日天气预报播报(上海+武穴)',
taskSpec: 'new spec',
recurrence: 'daily',
hour: 8,
minute: 0,
});
assert.equal(task.id, 'task-existing');
assert.equal(insertCount, 0);
});
test('cancelTask updates status to cancelled', async () => {
const service = createScheduledTaskService({
async query(sql, params) {