feat(api): DELETE /api/projects/:id + store.deleteProject(连带 tasks/runs/events)
新增项目删除能力:store.deleteProject 事务内删 events(无 FK,手动)+ projects(tasks/runs/ approvals 经 schema ON DELETE CASCADE 连带清);DELETE /api/projects/:id 暴露之。 store.test 覆盖连带清除 + 重复删报错。用于清理 cutover 测试遗留的一次性 smoke-test 项目 (本次经直连 DB 删除,未重启打断在跑的 worker;端点下次重启生效)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -367,3 +367,23 @@ test('requeueTask:needs_attention → queued,重置 retryBaseline', () => {
|
||||
assert.throws(() => s.requeueTask(t.id), /needs_attention/);
|
||||
s.close();
|
||||
});
|
||||
|
||||
test('deleteProject:连带删 tasks/runs/approvals/events,不可恢复', () => {
|
||||
const s = freshStore();
|
||||
const p = s.createProject({ name: 'del', repoPath: '/tmp/del-' + Math.random() });
|
||||
const t = s.createTask({ projectId: p.id, title: 'x', complexity: 'easy' });
|
||||
s.setOperations(t.id, 'op');
|
||||
const r = s.startRun(t.id, 'executor');
|
||||
s.finishRun(r.id, 'succeeded');
|
||||
assert.ok(s.listEvents(p.id).length > 0, '删前有事件');
|
||||
assert.ok(s.listTasks(p.id).length > 0, '删前有任务');
|
||||
assert.ok(s.listRuns(t.id).length > 0, '删前有 run');
|
||||
|
||||
s.deleteProject(p.id);
|
||||
assert.equal(s.getProject(p.id), null, '项目已删');
|
||||
assert.equal(s.listTasks(p.id).length, 0, 'tasks 连带清');
|
||||
assert.equal(s.listRuns(t.id).length, 0, 'runs 连带清(经 tasks cascade)');
|
||||
assert.equal(s.listEvents(p.id).length, 0, 'events 连带清');
|
||||
assert.throws(() => s.deleteProject(p.id), /不存在/, '重复删 → 报错');
|
||||
s.close();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user