Dramivio项目文档下载文档包 ↗
2026.10.03 · 设计实施与自动回退修订本地实现与复审进展 · 真实服务尚未发布Markdown

视觉按最新原型,业务按已确认PRD。现有代码为满足设计而改造。执行见按设计实施与任务卡;技术增量和文档复审不等于产品完成。

Dramivio 播放进度边界复审

本页目录

2026 年 10 月 3 日。范围为当前工作区 H00 的逐集记录、续播、删除 epoch、会话 revision/CAS、App 离线队列,以及相关 Go 和 Better Auth 入口。发现并复现 3 个 P2;主线修复后,3 项均经独立复验关闭。本轮检查范围内没有遗留的已证实 P1/P2。

复审期间业务代码只读。复现使用隔离的 PostgreSQL 18 RAM 容器、真实服务端函数和当前 App 代码;未发布、未连接生产、未访问外部媒体。所有本轮测试容器均通过清理路径关闭。复现文件保存在当前任务的 work/progress-review/。

  1. P2:读取状态与 begin 之间的映射变化可把进度记到另一集。已关闭。

    原实现只携带源剧 ID、源集号和 epoch/revision。真实 PostgreSQL 复现了两条路径:首次播放尚无历史时,把源映射到另一部 canonical 剧;以及同一 edition 把源第 1 集重排到 canonical 第 2 集。两者的旧请求都曾被接受,37 秒位置最终写入新身份。单纯增加事务内表锁不能约束此前读取的身份。

    当前 begin 校验 强制要求并核对 canonicalId 和 episodeId;App begin 输入 携带相同身份,原始播放集在首次读取时也核对 episodeId;resume/open 已传递该字段。目录映射 也阻止对已有状态进行未迁移的集身份重排。

    修复后,旧 canonical 返回 drama_identity_mismatch,旧 episode 返回 episode_identity_changed,缺少身份返回 invalid_playback_session;旧请求没有创建 session/history,新读取的有效身份仍可开始播放。原始证据:mapping-race.mjs、mapping-race-result.json。复验:mapping-fix-verify.mjs、mapping-fix-result.json。

  2. P2:追剧页继续观看会重播已完成的一集。已关闭。

    原 FollowingScreen 续播入口 读取指定单集状态,并在 completed 时将位置改为 0。用真实 report 完成第 1 集后,服务端 resume 已返回第 2 集 0 秒,但执行真实页面的点击处理函数仍导航到第 1 集 0 秒。

    当前入口调用 fetchConsumerResume,使用返回的集号、位置、暂停状态和身份 capture,并拒绝已删除的历史。相同复验现在导航到第 2 集 0 秒。此检查执行了实际页面函数和点击处理逻辑;React Native 渲染与导航为测试替身,状态接口连接真实 PostgreSQL。原始证据:client-pg-boundaries.cjs、client-pg-result.json。复验:client-pg-fix-verify.cjs、client-pg-fix-result.json。

  3. P2:下一未完成集缺失时会跳集,或阻止重新打开当前集。已关闭。

    canonical 集序为 1、2、3,仅授权部分源时,完成第 1 集后的行为曾为:映射 [1,3] 直接跳到第 3 集;映射 [1] 返回 409。后一结果会阻断默认使用 consumer resume 的 Go open,尽管当前完成集仍可重看。这不符合续播规则要求的“下一集不可用时停留当前完成状态”。

    当前 resume 选择 只检查首个下一未完成集。缺失时保留当前集并暂停。两种部分源的真实 PostgreSQL 复验均返回第 1 集、10 秒、completed=true、resumePaused=true。原始证据:resume-gap.mjs、resume-gap-result.json。复验:resume-gap-fix-verify.mjs、resume-gap-fix-result.json。

本轮独立验证的其他边界如下。

检查 结果与证据范围
旧 open 后清历史,再收到首帧 实际 AccountProgress → PostgreSQL 联动:不 begin,不复活历史
新设备接管后旧页面重试或推进旧 run 同一联动:旧 report 被拒,旧页面不重新抢回;新设备 50 秒位置和 revision 2 保留
离线恢复位置 恢复的 10 秒不增加覆盖,也不使紧随其后的首次 live 区间增加覆盖;再下一段正常 live 增加 1 秒
乱序与后退 seek sequence 2 不覆盖已接收的 sequence 3;sequence 4 可把位置从 30 秒拖回 10 秒
不同 owner 上报 真实服务端按 session + owner 拒绝;请求体不能指定其他账号身份
owner/origin 队列和退出后的迟到 ack App 确定性测试通过;分区、清除和较新 bookmark 不被迟到 ack 破坏
幂等、过期与维护 当前 PostgreSQL 测试确认相同 begin 重试不重复创建;过期 session 不能上报或复活;维护只删过期且未被历史引用的会话
实际认证入口 Better Auth 1.7.7 + PostgreSQL HTTP fixture 通过,使用动态回环端口;OTP 邮件仅在内存捕获;伪造 userId、无登录写入、退出后写入均未获授权
Go 路由 独立运行 verified identity/revocation、auth proxy 和 consumer config 三个实际 router 测试,均通过;源码核对消费者 legacy 文件进度写入已拒绝

修复后独立回归结果:services/platform/tests/state.test.mjs 35/35;App consumer-progress.test.cjs 10/10;上述三个 Go 路由测试通过;动态端口的实际认证 HTTP fixture 1/1。原始复现脚本保留原失败断言用于审计,修复后的成功断言位于单独的 *-fix-verify 文件。

此结论不等于 H00 全端验收完成。复审时 Web H00 接入仍由主线标记为未完成;本轮未声称 Web 播放进度已通过。本轮也未测真实 Android/iOS 媒体播放、系统强杀及“约 10 秒退出保存误差”。validWatchSeconds 仍是保守的客户端位置估计,不构成邀请或额度证明。