feat: 任务模型物理合并,发布+回收并为单任务双阶段

- tasks 新增 recovery_enabled/recovery_due_at/recovery_instructions/recovery_example_images,回收挂自己名下(先发布后交截图),不再置 complete
- 存量 screenshot_collect 迁移并入父任务后删除(mysql/0020 含 DELETE,生产执行前务必备份)
- 新 action task_enable_recovery:ghost 面板一键开通回收,截止默认=发布截止
- 企微催办双阶段(待发布/截图待提交);超期自动释放仅发布阶段
- admin 删 groupTaskMasters 聚合改单卡双面板;portal 详情页回收截图区块+批次回收进度
- 测试 309 全绿 + Playwright E2E 20/20
This commit is contained in:
ABAPPLO
2026-09-24 15:52:45 +08:00
parent ab78b187c0
commit e2a93e22cf
29 changed files with 2219 additions and 2195 deletions

View File

@@ -29,7 +29,7 @@ test("merges distribution detail into the task center", async () => {
readFile(new URL("../app/globals.css", import.meta.url), "utf8"),
]);
assert.match(adminApp, /分发明细/);
assert.match(adminApp, /查看明细/);
assert.match(adminApp, /function TaskDistributionDetail/);
assert.match(adminApp, /选择一个数据回收任务/);
assert.doesNotMatch(adminApp, /"distributions"/);
@@ -212,7 +212,7 @@ test("issues external task links and supports one-to-one note submissions", asyn
assert.match(adminApp, /platform-logo/);
assert.match(adminApp, /task-scope-subline/);
assert.match(adminApp, /识别失败,请手动填写/);
assert.match(adminApp, /分发明细/);
assert.match(adminApp, /查看明细/);
assert.match(adminApp, /AdminImageLightbox/);
assert.match(adminApp, /CreatorScreenshotPreview/);
assert.match(adminApp, /admin-image-lightbox/);
@@ -362,7 +362,7 @@ test("supports task collection schedules and latest public metrics", async () =>
assert.doesNotMatch(mcpClient, /"collect_xhs_wen_note_detail"/);
});
test("supports fixed screenshot collection tasks without publish metrics", async () => {
test("supports merged task recovery screenshots without publish metrics", async () => {
const [adminApp, actionRoute, partnerRoute, uploadRoute, migration, multiMigration, exportRoute] =
await Promise.all([
readFile(new URL("../app/admin-app.tsx", import.meta.url), "utf8"),
@@ -374,13 +374,13 @@ test("supports fixed screenshot collection tasks without publish metrics", async
readFile(new URL("../app/api/screenshot-task-export/route.ts", import.meta.url), "utf8"),
]);
assert.match(adminApp, /内容发布/);
assert.match(adminApp, /截图回收/);
assert.match(adminApp, /小红书搜索关键词/);
assert.match(adminApp, /开启截图回收(第二阶段)/);
assert.match(adminApp, /批量下载截图/);
assert.match(actionRoute, /create_screenshot_task/);
assert.match(actionRoute, /task_enable_recovery/);
assert.doesNotMatch(actionRoute, /create_screenshot_task/);
assert.match(partnerRoute, /submit_screenshot_result/);
assert.match(partnerRoute, /截图回收任务无需填写发布链接/);
assert.match(partnerRoute, /请先回填这篇笔记的发布链接,再提交回收截图/);
assert.match(partnerRoute, /recovery_enabled/);
assert.match(uploadRoute, /task-results\//);
assert.match(uploadRoute, /task-result/);
assert.match(uploadRoute, /MAX_RESULT_SCREENSHOTS/);