- pnpm workspace: apps/{web,server}, packages/{contracts,db,domain,adapters,tasks,agent,testkit}
- server: Hono + zod-openapi, API Key auth with scopes, redacting pino logger, SSE event bus with replay, worker heartbeat
- db: Kysely + pg, file migrator, 0001_init (settings/api_key/audit_event/outbox_event)
- web: React Router 7 SPA console shell with 12 workspace placeholders, uhd_web tokens/ui/guard scripts
- docs: ADR-001 (Node over Deno), dev runbook, design system rules
Co-Authored-By: Claude Fable 5.1 <[email protected]>
9.9 KiB
9.9 KiB
首个可用版本(v0.1)工程规划
编制:2026-09-27。需求基线:../../media_automation_requirements_architecture_v0.7.md(下称 REQ)。本文件是所有开发子任务的统一任务书;与 REQ 冲突时以 REQ 的产品要求为准,技术选型以本文件为准。
1. 技术决策(ADR 摘要,详见 docs/adr/)
| 项 | 决定 | 说明 |
|---|---|---|
| 运行时 | Node.js 24 LTS + pnpm workspace,TypeScript 5.9 strict | 用户指定沿用 /opt/uhd_web 技术栈;开发机无 Deno。REQ §9 允许"有明确依赖障碍时评估替代并记录代价"。ADR-001 记录此偏离。 |
| 前端 | React 19 + React Router 7(SPA, ssr:false)+ Vite 7 + Tailwind v4 + shadcn(new-york, radix-ui 统一包)+ TanStack Query 5 + zod 4 + sonner + lucide |
直接拷贝 uhd_web 的 app/app.css 设计 token、app/components/ui/*、app/lib/api.ts、app/lib/utils.ts、scripts/gen-design-tokens.mjs、scripts/check-design-tokens.sh、docs/features/{design-tokens,interface-materials,ui-controls}.md。不引入 uhd_web 的播放器/WASM 相关内容。 |
| 后端 HTTP | Hono 4(@hono/node-server),REST + SSE |
OpenAPI 由 zod schema 生成(@hono/zod-openapi)。 |
| 数据库 | PostgreSQL 16;Kysely + pg;SQL 迁移文件 + Kysely Migrator;kysely-codegen 或手写 DB 类型 |
开发用 docker-compose 起 postgres:16-alpine,端口 55433。 |
| 持久任务引擎 | 优先 [email protected](peer: postgres.js);须先通过 spike 验证(重启恢复/等待信号/取消/重试)。未通过则用 packages/tasks 内的 PG 租约式任务表(lease + attempts + dead-letter)。 |
结论写 ADR-002。 |
| Agent 内核 | @earendil-works/[email protected] + @earendil-works/[email protected],锁版本;通过自有 AgentRuntimePort 封装,显式工具白名单,不开放 bash/文件系统/任意网络 |
测试用脚本化 fake 模型 provider;真实上游由设置页配置。 |
| 校验/测试 | vitest(server/packages 单元 + 集成);web 沿用 token 守卫脚本;biome 做 lint/format | pnpm ci = typecheck + lint + test + check:tokens + build |
| 端口 | web dev 5180,API 4380,PG 55433 | 本机 3000/5175/5176/55432 已被占用,不要用 |
| 参考源码 | MoviePilot: /opt/moviepilot-plus/upstream/MoviePilot(GPLv3,只做行为对照与 TS 重写,不复制文件);MovieClaw 若本机不存在则按 REQ 附录链接对照 |
迁移对照记录写 docs/porting/ |
2. 仓库结构(pnpm monorepo)
apps/web React Router 7 SPA 控制台(复用 uhd_web 设计系统)
apps/server Node 服务:HTTP API + SSE + worker 入口(单进程可跑,也可 `--role api|worker` 分开)
packages/contracts zod schema + 类型:所有 API/事件/能力(capability)输入输出的唯一定义,web 与 server 共用
packages/db Kysely 类型、迁移、仓储辅助
packages/domain 纯业务逻辑(无 IO):标题解析/身份匹配/Slot 满足度/路径绑定/整理计划/策略评估
packages/adapters 外部系统适配:qBittorrent、RSS、站点(观众 NexusPHP / 馒头 API)、TMDB、Emby 兼容、文件系统
packages/tasks 持久任务定义与执行器(OpenWorkflow 或自研租约表),outbox
packages/agent Pi 接入:AgentRuntimePort、能力注册中心桥接、agent_run 持久化、fake provider
packages/testkit mock 服务:mock qB WebUI、mock NexusPHP 站点、mock M-Team API、mock RSS、mock TMDB、临时目录夹具
docs/adr 架构决策记录
docs/plan 本规划与里程碑验收清单
docs/porting MoviePilot/MovieClaw 迁移对照账本(REQ §14.1.2 格式)
docs/spikes 兼容性验证记录
docs/runbook 启动/备份/恢复/配置说明
scripts dev/ci 辅助脚本
约定:
- 所有共享类型只在
packages/contracts定义;web 不得手写与 server 重复的 DTO。 packages/domain不 import 任何 IO 库,100% 可单元测试。- 每个包有
src/index.ts作为唯一公开入口;跨包只通过入口引用。 - 命名:表名 snake_case 与 REQ §12 实体名一致;TS 类型 PascalCase;能力 ID 用
域.动作(如download.submit)。 - 提交:conventional commits(
feat(server): ...),每个子任务结束前pnpm ci必须绿再提交。 - 凭证一律 secret reference(
secret_ref列 + 加密存储),日志/错误/模型上下文脱敏;含 passkey 的 URL 不得进入日志。
3. v0.1 范围(= REQ M0 + M1 纵切,可在无真实 PT 账号下用 mock 全链路验证)
3.1 必做
- 底座:monorepo、配置(env + settings 表)、迁移、API Key 鉴权(scope:read/organize.read/organize.execute/admin)、审计日志
audit_event、SSE 事件流(带序号可补读)、全局"自动化总开关"。 - 数据模型(REQ §12 子集,表名照抄):media_entity、content_unit、external_identity、identity_revision、title_alias、media_asset、asset_location、path_binding、library_root、site_account、feed_source、observation、source_release、subscription、policy_revision、acquisition_slot、preference_tag、preference_suppression、acquisition_plan、download_task、asset_operation、decision、approval、automation_grant、agent_run、artifact、audit_event、outbox_event、reconcile_run、server_mapping、api_key、organization_record、organization_file_result、downloader_instance、media_server_instance、settings。
- 来源:多 RSS 抓取(ETag/Last-Modified、重叠窗口、GUID+摘要去重、退避/熔断、passkey 脱敏)、观众(NexusPHP 列表/详情/下载,参考 MovieClaw audiences.yaml 结构)与馒头(API Key)两类站点适配器、站点快照缓存 + 实时补查 + 站点启停 + 站点级限流。
- 身份与元数据:发布标题解析(对照 MP MetaInfo 行为:标题/年份/季集/分辨率/来源/编码/发布组/版本)、TMDB 查询与缓存、本地实体优先 + external_identity 映射(provider+type+id 唯一)、title_alias 模糊召回(pg_trgm)、临时 content_unit、待识别池。
- 规则与选片:subscription(单次/持续追踪)、acquisition_slot(硬条件/软偏好/升级阈值/完成条件,状态机 empty→reserved→downloading→verifying→satisfied/upgrade_pending/attention)、确定性 evaluateAcquisition(不含 Agent 主观选片,只留接口)、每日预算与并发限制、优先级(即时>追更>新作品>升级)。
- 下载:qB WebUI 适配(多实例、管理标签、提交/接管/查询/暂停恢复)、缓存卷硬阈值与恢复水位(暂停范围仅限纳管任务)、download_task 状态机、无进展只记录不换源。
- 入库:verifyAndImport → Copy/Move(临时文件+校验+提交;跨卷 Copy→核验→删源;EXDEV 不静默降级)、路径绑定固定(已绑定目录不因译名变化改变)、organization_record + 文件级结果、公开整理记录 API(API Key、游标增量)。
- 持久任务:ingestFeed、resolveObservation、evaluateAcquisition、submitDownload、verifyAndImport、refreshMetadata、reconcileLibrary(资产存在性)、cleanupDownloadCache、resolveDecision;outbox;重启恢复;幂等键;取消传播。
- Agent:Pi AgentSession 封装;能力注册中心(ID/版本/schema/权限/风险/幂等/预览/处理器),首批能力:catalog.lookup、release.search、release.inspect、identity.resolve、download.plan、download.submit、organize.plan、organize.execute、task.inspect、task.retry、task.cancel、policy.preview、policy.apply、inventory.query;授权校验在服务端;agent_run 持久化 + SSE 增量;后台事件触发有界 Agent 任务(识别歧义、下载失败诊断);设置页可配上游/模型/思考档位/上下文预算/压缩/子代理开关。
- 控制台页面(REQ §13):首页六区块(自动化概览/当前工作/需要我处理/缓存与保留/来源健康/最近产出)、媒体库(列表+详情:路径/身份映射/元数据来源/Slot/候选拒绝理由/下载历史)、订阅与收录规则、偏好标签(基础 CRUD+抑制记录)、PT 站点工作台(整理视图:列表/搜索/详情/库存叠加/统一下载入口;原站视图首版只留占位与说明)、来源/Feed/快照、下载与任务(含业务时间线)、整理记录、待处理中心、身份与元数据、系统设置(实例/路径映射/API Key/Pi 上游与预算/自动化开关)、Agent 会话页 + 侧栏。
- 可选 Emby 兼容查询:多实例,查有无/季集/版本,未知≠缺失。
- 运维:
scripts/backup.sh(pg_dump + 映射导出)、恢复后只读对账模式开关、docker-compose(生产:server + web(nginx) + pg)、runbook。 - 测试:domain 单元测试;adapters 对 mock 服务的集成测试;端到端:mock RSS → 观察 → 识别 → 计划 → mock qB 下载完成 → Copy 入库 → 整理记录 API 可读;Agent e2e:fake 模型按脚本调用能力完成"把 X 电影 1080p 收进来"闭环;崩溃恢复注入(worker 中断后续跑)。
3.2 v0.1 明确不做(留接口/占位)
国产综艺分段建模与正片覆盖(M2)、双版本 require_distinct_asset 组合校验(M2,但 Slot 多目标数据结构先建好)、浏览器/camofox 接入与原站视图(M2,BrowserProvider 接口定义先落)、HHClub/CHD 适配(M2)、旧库分范围接管预览(M2)、Agent 主观选片与规则学习回放(M2)、媒体级主动整理 UI(M2,organize.plan 能力可用)、多用户。
4. 里程碑与派工波次
- W0 底座(并行):A 脚手架与设计系统迁入;B OpenWorkflow+Pi 兼容性 spike(结论进 ADR-002);C MoviePilot 迁移对照账本(识别/刮削 + 转移入库)。
- W1 领域与适配(并行):domain(解析/身份/Slot/路径/整理计划)、adapters(qB/RSS/站点/TMDB/Emby)+ testkit mocks、db schema 全量迁移 + contracts 全量 schema、tasks 引擎接入。
- W2 服务编排:server API 全量路由 + 任务处理器串起纵切 + Agent 能力注册与 Pi 封装。
- W3 控制台(按页面分组并行)+ e2e。
- W4 集成验收与修复:跑 §3.1 第 13 条全部;补 runbook;打 tag v0.1.0。
每波结束的验收由独立审查子代理执行:pnpm ci 绿 + 对照本文件逐条勾选 + 抽查 REQ §2.1 五原则未被破坏。