From 111cbddb3677f56a150e881c1d29a05cc94fc76b Mon Sep 17 00:00:00 2001 From: root Date: Sat, 3 Oct 2026 17:09:51 +0800 Subject: [PATCH] =?UTF-8?q?docs(plan):=20=E9=9B=86=E6=95=B0=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E4=B8=8E=E6=98=A0=E5=B0=84=E8=AE=A1=E5=88=92;?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7=E6=9B=B4=E6=96=B0=E5=88=B0=20v0.3.2?= =?UTF-8?q?5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- README.md | 2 +- docs/plan/README.md | 3 +- docs/plan/episode-resolution.md | 59 +++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 docs/plan/episode-resolution.md diff --git a/README.md b/README.md index 70adf543..d5fb3470 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 内部使用、Agent 自动化优先的媒体整理入库平台。需求基线见 [media_automation_requirements_architecture_v0.7.md](media_automation_requirements_architecture_v0.7.md)。 -当前版本 v0.3.14,本机测试环境已部署;各版变化见 [CHANGELOG.md](CHANGELOG.md)。业务逻辑以 MoviePilot v3 为参考,逐项对照见 [MoviePilot v3 对照](docs/porting/moviepilot-v3-comparison.md)。正在推进的计划与待办见 [docs/plan](docs/plan/README.md),开发与发布约定见 [CLAUDE.md](CLAUDE.md)。 +当前版本 v0.3.25,本机测试环境已部署;各版变化见 [CHANGELOG.md](CHANGELOG.md)。业务逻辑以 MoviePilot v3 为参考,逐项对照见 [MoviePilot v3 对照](docs/porting/moviepilot-v3-comparison.md)。正在推进的计划与待办见 [docs/plan](docs/plan/README.md),开发与发布约定见 [CLAUDE.md](CLAUDE.md)。 ## 功能 diff --git a/docs/plan/README.md b/docs/plan/README.md index 8a48f451..6810b650 100644 --- a/docs/plan/README.md +++ b/docs/plan/README.md @@ -17,7 +17,7 @@ ## 当前状态 -- 版本 v0.3.14(`ceb66f8`),本机测试环境已部署。此前 v0.3.8~v0.3.13 由未提交工作区部署,源码已在 v0.3.14 统一提交。 +- 版本 v0.3.25,本机测试环境已部署。 - 开发与发布约定见仓库根 [CLAUDE.md](../../CLAUDE.md)。 ## 待办 @@ -31,6 +31,7 @@ ### 进行中 +- 集数解析与映射:[episode-resolution.md](episode-resolution.md),5 批,Agent 兜底在最后。 - 补字幕:[subtitles.md](subtitles.md),第 1、2 步已完成;待办:以后接进整理 / 订阅工作流。 - 沙箱第二批:站点网页、RSS、网页抓取的 HTML / XML 解析迁入常驻子进程池(ADR-005)。 diff --git a/docs/plan/episode-resolution.md b/docs/plan/episode-resolution.md new file mode 100644 index 00000000..6d314553 --- /dev/null +++ b/docs/plan/episode-resolution.md @@ -0,0 +1,59 @@ +# 集数解析与映射(2026-10-03 定) + +解析器只回答「发布者声称这是第几季第几集」;本模块回答「媒体库应当把它当成哪一集」。参考 MP 的偏移表达式、ANI-RSS 的订阅预览,在其上加元数据校验、确定性换算、规则与待处理,Agent 兜底放最后。 + +ANI-RSS(GPL-2.0,只借思路不抄代码)摸排结论:一条订阅 = 一条 feed + 一个字幕组 + 一个 bgm 条目;集号靠一条正则;偏移只有整数,自动推断 = `-(feed 最小集号 - 1)`,不核对元数据;TMDB 只用于集标题(可选 Episode Group);体验来自「订阅预览」(按偏移算好的集号 + 已下载 + 缺集)与缺集 / 摸鱼提醒。 + +## 现状与缺口 + +- 本地 UUID 主身份、外部身份表、集单元的 `kind / content_type / segment / source_issue` 已有。 +- `release-parser/offset.ts` 的偏移表达式求值器没有任何调用方。 +- `ensureUnits` 拿解析结果直接找或建集单元:TMDB 第 2 季 12 集,解析出 S02E13 会建临时 S02E13,不报错。 +- 整理(`organize-plan.ts`)、季包选文件(`downloads.ts`)、接管(`takeover.ts`)会对文件名重新解析,映射必须在这些地方同样生效。 + +## 判定流程 + +输入:解析结果 + 作品 + 季表(每季总集数、是否最新季、作品是否完结、已知每集播出日期)+ 资源发布时间 + 发布组 + 该作品的映射规则。只处理剧集类作品的正片(`content_type = main`、季号 ≥ 1);电影、特别篇、花絮原样通过。 + +1. **有适用规则**(作品 + 季 + 发布组,越具体越优先)→ 按规则换算 → 校验。校验失败:规则停用、开待处理,本条资源按「待确认」处理。 +2. **无规则,原号校验**: + - 季存在且集号 ≤ 该季总集数 → 通过。 + - 季总集数未知、或该季是最新季且作品未完结、且集号超出不多 → **放行**(元数据滞后),记 `unverified`。 + - 否则 → 不通过,进第 3 步。 +3. **确定性换算**(结果都要再校验,且只取唯一解): + - 季内绝对集号:`S02 13`、第 1 季 12 集 → `13 - 12 = S02E01`。 + - 跨季绝对集号:季号是推定的(`seasonInferred`),集号超出第 1 季 → 按各季总集数累加换算。 + - 与「元数据滞后」冲突时(最新在播季)用发布时间判:发布时间与换算后那集的播出日期相差 ≤ 7 天才认换算,否则按滞后放行。 + - 综艺:有 `airDate` 时按播出日期对集。 +4. **仍不行** → 资源已绑定作品但集数待确认:不建集单元,订阅评估跳过(原因 `episode_unresolved`),开待处理 `episode_mapping`(按作品 + 季 + 发布组去重),附建议规则。 + +结果写入 `source_release.episode_resolution`(原始季集、规范季集、方式 `raw / rule / absolute_in_season / absolute_cross_season / air_date / unverified / unresolved`、规则 id、证据),`parsed` 里的季集改为规范值,下游不用改口径。 + +## 映射规则 + +- 作用域:作品(必填)+ 来源季(可空)+ 发布组(可空)。不做全局 / 站点级(站点标题差异由别名表解决)。 +- 类型:`expression`(复用 `offset.ts`,如 `EP-12`、`EP*2-1`,可带目标季)、`table`(`26 → S02E01`、`27-28 → S02E02`)、`special`(映射为特别篇 / 花絮 / 忽略)。 +- 证据等级复用 `manual / rule_confirmed / multi_evidence / needs_review`,不用百分比。 +- 失效:规则算出的结果校验不通过 → 停用并开待处理,不做置信度衰减。 +- 规则建立或修改后,按作品重算已绑定资源的集数解析(不重做身份识别)。 +- 建议规则:同作品 + 季 + 发布组下的待确认资源,用发布时间对播出日期配对,试 `EP±n` / `EP*2` / `EP*2-1`,全部样本成立才给建议。 + +## 分批 + +| 批次 | 内容 | 验收要点 | +| --- | --- | --- | +| 1 领域纯函数 | `packages/domain/src/episode-resolution/`:类型、校验、确定性换算、规则应用、建议规则推导、总入口 | domain 单测覆盖上面每个分支(含滞后放行、发布时间判定、多解拒绝、表格规则、双集) | +| 2 存储与识别接入 | 迁移(`episode_mapping_rule` 表、`source_release.episode_resolution`);季表加载;识别(`resolve.ts` 及其他 `ensureUnits` 调用方)接入;`parsedOf` 叠加;订阅评估跳过待确认;待处理 `episode_mapping`;规则失效;按作品重算 | server pg 测试:ANi 连续编号进库即为 S02E01 并能被订阅覆盖;规则失效开待处理;滞后放行不卡追更 | +| 3 文件侧接入 | 整理计划、季包选文件、接管、文件管理识别统一套用同一作品的映射 | 下载按 S02E01 计划、文件名 ` - 13` 整理后命名为 S02E01;季包按缺集选对文件 | +| 4 接口与界面 | contracts 端点:规则增删改、模拟预览(给定作品 / 季 / 发布组 / 草稿规则,列近期资源的原始 → 规范与校验结果);待处理 `episode_mapping` 的确认 / 修改 / 忽略;作品页与订阅详情「集数映射」面板 | 契约测试、web 单测、冒烟;文案过 `check:copy` | +| 5 Agent 兜底 | 能力 `episode_mapping.propose`(只读上下文包 → 结构化规则建议)与 `episode_mapping.apply`(经授权写规则,必须先模拟全部样本通过);登记到 Skill 与能力地图;`episode_mapping` 待处理接后台自动调查 | agent 测试;模拟不通过的建议不能写入 | + +以后再做:TMDB Episode Group、Bangumi `sort / ep` 对照、综艺会员加更等变体细分。 + +## 状态 + +- [ ] 批次 1 +- [ ] 批次 2 +- [ ] 批次 3 +- [ ] 批次 4 +- [ ] 批次 5