视觉按最新原型,业务按已确认PRD。现有代码为满足设计而改造。执行见按设计实施与任务卡;当前代码与验证范围见消费者功能页。
App 注销与缓存归属
代码已写入 juku-mobile,复用 Better Auth 1.7.7 官方 Expo 客户端、现有 MMKV、TanStack Query 和文件适配器。账号注销、恢复界面与缓存归属清理基础已接入;真实离线下载仍待完成,当前下载入口提示暂不可用。API、安装包和 OTA 均未发布。
用户流程
“我的 → 账号安全 → 注销账号”:确认后向当前实际邮箱发送验证码,重新验证同一账号,再通过官方 deleteUser 提交。界面支持中英文;验证码为 6 位,按钮至少 48px。必要说明只保留注销后果与处理状态。
验证码验证必须产生同一 user.id 的新实际 session,并让服务端原意图进入 ready;客户端不相信 OTP 响应里的 token。429 按服务端等待秒数暂停发送;错误验证码可重新输入,过期后重新确认。
发送删除前保存执行阶段。成功、断线、冷启动均读取原 operation 的状态,自动恢复只发 GET,不重复发送删除。其他账号不能沿用原注销操作;服务端尚未确认终态时不显示“已注销”。
恢复和本机清理
现有 MMKV 的同一恢复 key 按 origin + userId 保留动作。兼容上一版的单条记录;A 的提交中收据不会被 B 开始或取消自己的操作覆盖,清理只删除对应 operation。记录仅含站点、UID、旧 session ID、operation ID、到期时间与阶段,不存邮箱、验证码、cookie 或会话 token。
确认原状态为 deleting/deleted 后,先读取官方会话;只允许原账号或实际无会话,不能清掉当前另一个账号。随后清理官方本机凭据、原 owner 的进度与已知缓存文件。已提交操作离开页面后仍可恢复。
文件先锁定再删除,删除失败保留 cleanup_pending 和重试提示;失败记录不能交给本地播放器。文件适配器只接受 App 媒体目录中的单层文件名,并在删除后核对是否仍存在。MMKV 写入未生效时停止提交;收据删除抛错或未生效时保留终态,允许再次查询并收尾,不重发注销。
旧无归属缓存保持锁定,不能按当前账号猜归属,也不随当前账号清空;提供独立确认的旧缓存清理入口。换号、退出、权威会话失效只清理明确归属的旧账号,迟到的 A 清理不会移除 B 的 viewer 或查询。
离线能力边界
| 当前能力 | 尚未完成 |
|---|---|
| 文件记录按 origin、UID 隔离;有效期与文件存在检查;本地列表、详情和播放器统一使用 | 来源的真实离线许可发行器、安装证明及许可证验证 |
| v1 无归属文件迁移为锁定,已有文件不猜账号 | Media3 / AVAssetDownloadURLSession 下载桥接、持久密钥与可恢复队列 |
| 失效或换号移除本地播放器 URI;有效期到达后重排定时检查 | 真机飞行模式、强退恢复、磁盘不足、系统后台与真实密钥擦除 |
| 旧 viewer 下载 URL 不再直接创建文件、任务或扣账 | O00/O01 的 preview、order、license、队列及到账完整接线 |
OfflineAuthorization 当前只是归属元数据,不是离线许可证;其中 deviceId 不是设备证明。文件删除替代测试不能证明 Android/iOS 已物理擦除,元数据 task 的移除也不是原生下载任务取消。本机 App 文件存储与“网站不落盘视频”的约束分别适用。
实际验证
- App 自动测试 203/203、TypeScript 检查通过。其中注销接口 11、实际 React 页面 12、缓存归属 10、本地页面/播放器 4;其余为既有功能回归。
- 注销测试使用已安装的官方 SDK;HTTP 故障、SecureStore、文件和原生控件采用隔离适配器。覆盖正常、错误 OTP、新旧/其他 session、429、请求丢失、匿名恢复、切换账号、存储失败、文件删除失败和 GET-only 重试。
- 独立复审发现并修复两项恢复 P2:B 覆盖 A 的收据、收据移除异常。此前缓存摘要、同 ID 隔离和长有效期 timer 的发现已修复。见App 独立复审。
- 实际官方 Expo SDK → 现有 Go → Better Auth → 隔离 RAM PostgreSQL 联调,核对 OTP、新同 owner session、后端 ready、删除提交后模拟响应丢失、原收据、真实无会话及身份表清空。详细检查数和完整组合测试结果见验证记录。邮件在本地截取,不是 SMTP 投递;原生存储/界面仍为测试适配器。
继续实施顺序
- O00:先复用原生开源下载能力,完成受控合法媒体的 asset/密钥桥接;分开测试首集、暂停恢复、飞行模式与强退,不把在线 URL 当 license。
- O01:接现有额度与归属记录,加入真实 preview/order/license 和恢复队列;测试重复提交、换号、到期、网络切换及空间不足。
- A03 真机收尾:测试官方 SecureStore、实际文件、原生任务与密钥擦除,再验证注销、退出、切号、重启和失败重试。最后接正式邮件、常驻任务、审计期限及真实发布。
源码位置
| 文件 | 用途 |
|---|---|
| src/auth/deletion.ts | 可导入的意图、OTP、提交、状态与恢复存储函数;复用官方 SDK |
| src/screens/DeleteAccountScreen.tsx | 中文/英文确认、验证码及原操作恢复 |
| src/auth/ConsumerAuthGate.tsx、auth/client.ts | 原 owner 清理和官方凭据生命周期 |
| src/playback/offlineOwnership.ts、store/downloads.ts、files.ts | 归属、锁定和受限文件删除 |
| src/screens/DownloadsScreen.tsx、DramaScreen.tsx、LocalPlayerScreen.tsx | 登录与归属限制,阻止失效文件播放 |
| tests/deletion-api.test.cjs、deletion-screen.test.cjs、download-owner.test.cjs、download-screen.test.cjs | 对应模块和失败场景回归 |
这些是当前代码与证据的范围,完整 O00/O01、A03 真机清理和整个产品尚未完成。后台清理及 Web 路线见账号注销与后台清理。