docs: 待办收尾,补测试与代码布局约定

- 待办:任务恢复边界、注册断言、测试装配去重、大文件拆分、MP 对照 6.4 已完成并移除;
  BrowserService 类拆分与超长函数写明暂缓原因;真实环境验收列出所需条件;
  continuous-series 偶发超时改为观察项(已核实不是业务竞争)
- CLAUDE.md:test/support、contracts api/ 与整理服务的文件布局、起子进程的测试进串行组
- lessons 第 26 条:检查命令不接管道

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-02 17:40:43 +08:00
1 parent 8bec4bad5d
commit 501b4eb403
3 files changed
+14 -9

No files matched your search

+4 -1
View File
@@ -16,6 +16,8 @@ deno task ci # 提交前完整检查(含 web 构建与编译产物自
deno task release # 测试环境发布,见下
```
REST 端点定义按领域分在 `packages/contracts/src/api/*.ts`,`api.ts` 按顺序合并成 `Api`(顺序即路由注册顺序)。整理服务按阶段分在 `organize-plan / -exec / -finalize / -records / -types.ts`,外部仍从 `organize.ts` 引用。
只改一个包时可在包目录跑 `deno run -A npm:vitest run <文件>`;web 包用 `../../node_modules/.bin/vitest run`(Node)。改迁移后跑 `deno task gen:types` 重新生成 `packages/db/src/types.ts`,contracts 枚举顺序与数据库保持一致(`packages/contracts/test/db-sync.test.ts` 会查)。
## 约定
@@ -31,7 +33,8 @@ deno task release # 测试环境发布,见下
- 位置:server 的测试统一放 `apps/server/test/<模块>/`(不再用 `src/**/__tests__`);web 与 adapters 测试和源码放同目录 `*.test.ts`;其它包放 `test/`。
- 命名按测的行为(`crash-recovery.test.ts`、`two-stage-search.test.ts`),不要用任务编号(`e4-`、`w5a2`、`-md1`)。
- server 分三组(`apps/server/vitest.config.ts`):`unit` 不碰 PG;`pg` 真实 PG + 假引擎,文件并行;`serial` 起真实引擎 / worker / 子进程的集成与 e2e,串行。新文件缺省进 `pg`,起真实 worker 的必须加进 `SERIAL`。
- server 分三组(`apps/server/vitest.config.ts`):`unit` 不碰 PG;`pg` 真实 PG + 假引擎,文件并行;`serial` 起真实引擎 / worker / 子进程的集成与 e2e,串行。新文件缺省进 `pg`,起真实 worker / 引擎 / 子进程的必须加进 `SERIAL`。
- server 测试的建库、schema 锁、假引擎统一用 `apps/server/test/support/`(`pg.ts`、`engine.ts`),各模块 harness 只写自己的装配。
- 每个 PG 测试文件用自己的 schema;等待异步结果用轮询到条件,不写固定 sleep。
- 真机测试用 `*.real.test.ts`,靠环境变量开启,缺省跳过。
+9 -8
View File
@@ -26,14 +26,15 @@
### 工程
- 任务恢复的三处边界:升级前未结束任务的版本处置(发布前查在途任务版本,没有在途旧任务就不保留旧处理器);业务结果提交、run 关联、事件派发三个时点分别注入失败确认最终状态;引擎查询异常时只记录并跳过本轮,仅在明确查无 run 或终态时补投。
- 生产模块装配的处理器来源断言(防止漏注册的任务静默回显 todo),下次改任务注册时补。
- 测试装配去重:server 6 份 harness(约 1800 行)各自实现建 schema、迁移、假引擎、临时目录,抽公共部分到 `@umt/testkit`,各模块只留自己的装配;下次改到相关 harness 时做。
- 大文件拆分候选,改到相关功能时顺手拆,不单独重构:`packages/contracts/src/api.ts`(~2700 行)、`acquisition-organize/services/organize.ts`(~2600)、`browser/service.ts`(~2400)、`web/app/components/organize-wizard/organize-wizard.tsx`。
- `BrowserService`(`apps/server/src/modules/browser/service.ts`,约 2300 行)仍是单个类。纯函数已移到 `session-view.ts`;Cloudflare 挑战流程(`beginChallenge`~`fetchSiteHtml`,约 400 行)要拆成独立协作对象,需要先把它用到的私有方法改成公开接口,下次改挑战流程时做。
- 超长函数:`planImport`(`organize-plan.ts`,约 830 行)、`finalizeRecord`(`organize-finalize.ts`,约 460 行)、`OrganizeWizard` 组件(约 800 行)。文件已按阶段拆开,函数内部等改到相关逻辑时再拆,不单独重构。
### 业务
### 业务(需要真实环境或决定)
- 疑似竞争:同一 Slot 两个版本几乎同时评估时,`evaluateForSlot`(`acquisition.ts`)读在途计划与写计划 / 延后之间没有锁,可能都不被延后。现象:`test/e2e/continuous-series.test.ts`「另一版本延后」在全量跑时偶发等待超时(2026-10-02 并行化后 3 次全量中 1 次,单跑 4 次均过)。先复现确认,再考虑按 Slot 加行锁。
- R06 通用 HTTP 失败转浏览器:要先定"哪些失败转浏览器、每站每小时上限、失败后怎么提示",再实现;真实 Cloudflare 挑战需要一个会触发挑战的站点账号验收。
- R21 缓存阈值里未纳管占用的专项验收:需要在真实下载盘上放一批不归本工具管理的文件,观察暂停 / 恢复水位。
- 四站与真实下载、媒体服务器的完整验收:需要真实站点账号、qB 与 Emby / Jellyfin 实例。
- 与 MP 对照里仍未定的项,见 [对照 §6.4/6.5](../porting/moviepilot-v3-comparison.md#64-用户反馈与后续讨论2026-10-02)。
- 需求里仍是"部分实现"的:R06 通用 HTTP 失败转浏览器、真实 Cloudflare 挑战验收;R21 缓存阈值里未纳管占用的专项验收;四站与真实下载、媒体服务器的完整验收。
### 观察项
- `test/e2e/continuous-series.test.ts`「另一版本延后」2026-10-02 全量跑时偶发等待超时 1 次。已核实不是业务竞争(`reserve()` 在 Slot 行锁内复核单元重叠,冲突即延后);单跑 4 次、3 份 / 8 份并发均未复现,疑为负载下评估任务重试退避超过 60s 等待。再出现时保留 `.local/test-logs/` 日志再查。
+1
View File
@@ -38,3 +38,4 @@
## 发布与检查(2026-10-02 补充)
25. v0.3.8~v0.3.13 六个版本都由未提交工作区构建部署,发布记录写"检查通过",实际 agent / db / contracts 测试与类型检查一直是红的:`deno task test` 在第一个失败的包就停、后面的包根本没跑;连不上库时数据库用例静默跳过也算通过;开发库落后 9 个迁移没人发现 → **规则**:发布只走 `deno task release`(工作区不干净直接拒绝,tag 即镜像版本);检查只认 `deno task test:all` 的汇总(逐包跑完、连不上库即失败);拉代码后 `deno task dev:up`。
26. 用 `deno task lint | tail -1 && git commit` 做提交前检查:管道的退出码是 `tail` 的,lint 失败照样提交,`b61335e` 因此带进了一批格式问题 → **规则**:检查命令不接管道,输出重定向到文件再看退出码(`cmd > log 2>&1; echo $?`)。