docs(plans): 记录 K2 实施与验收回执
This commit is contained in:
1 parent
4118efd0ca
commit
698bb78aeb
3 files changed
+633
-1
No files matched your search
@@ -489,3 +489,385 @@ $ pgrep -fl "flutter_tools|xcodebuild|k1v_poller"
|
||||
- 动作 3 那次是**真实的设备侧输出且全过**,但随后两次执行失败(一次 VM service 未 attach、一次构建产物缺失),
|
||||
所以在用户重跑之前**不把它当作最终结论**;它作为历史记录保留在这里。
|
||||
- 我**没有**用任何"开发机 curl"作为设备可达证据。
|
||||
|
||||
---
|
||||
|
||||
## 2026-10-17 K2:分类 + 观看记录 + 收藏列表 + 下载授权管理
|
||||
|
||||
### 动作 1:按 INBOX 指定顺序读取规范与契约
|
||||
|
||||
叙述:开工前先完整核对 INBOX K2 条目、项目约束、Git 流程、接口 §0/§1.3/§1.5/§1.6,
|
||||
再读 A3/A5、CONTENT/RECORD 用例与测试计划。当前没有启动客户端构建,也没有改业务代码。
|
||||
|
||||
```
|
||||
$ sed -n '1,260p' docs/plans/INBOX.md
|
||||
# INBOX — 给 Codex 的指令队列(FruitServer 仓库内)
|
||||
## [待处理] 2026-10-17 | K2 客户端第二批:分类 + 观看记录 + 收藏列表 + 下载授权(A3/A5 剩余)+ UI
|
||||
本批只做 K2,做完停下写回执,不要连做 K3/K4。
|
||||
接口只认 FruitServer/docs/api-phase1.md §1.3 / §1.5 / §1.6
|
||||
|
||||
$ sed -n '1,260p' /Users/jianghaifeng/Desktop/ReelShort/AGENTS.md
|
||||
# 水果短剧(FruitShorts)— Codex 项目上下文
|
||||
## 强制约束(不可违反)
|
||||
## 自主执行原则(Autonomy — 最高优先级)
|
||||
|
||||
$ sed -n '1,340p' /Users/jianghaifeng/Desktop/ReelShort/CODING_STANDARDS.md
|
||||
## 3. Dart / Flutter(ReelShort)
|
||||
TDD 强制:先写测试(红灯)→ 实现(绿灯)→ 重构
|
||||
门禁:dart analyze lib test 零告警 + flutter test 全过
|
||||
|
||||
$ sed -n '1,300p' /Users/jianghaifeng/Desktop/ReelShort/GIT_WORKFLOW.md
|
||||
## 一、分支模型(Git Flow)
|
||||
feature/*:具体功能开发,来源 develop
|
||||
合并一律 --no-ff(禁用 fast-forward)
|
||||
|
||||
$ sed -n '1,64p;150,158p;186,222p' docs/api-phase1.md
|
||||
## 0. 通用约定
|
||||
所有 ID 字段(主键与外键)在 JSON 里都是字符串
|
||||
### 1.3 内容浏览(已实现)
|
||||
GET /app/categories | 分类列表
|
||||
### 1.5 观看记录与收藏(已实现)
|
||||
GET /app/watch/recent?limit=20 | 最近观看
|
||||
DELETE /app/watch/progress/{dramaId} | 删除某剧记录
|
||||
DELETE /app/watch/progress | 清空记录
|
||||
### 1.6 离线下载(已实现)
|
||||
GET /app/downloads/policy
|
||||
PUT /app/downloads/settings
|
||||
POST /app/downloads
|
||||
GET /app/downloads
|
||||
GET /app/downloads/{episodeId}/url
|
||||
POST /app/downloads/{episodeId}/progress
|
||||
DELETE /app/downloads/{episodeId}
|
||||
DELETE /app/downloads
|
||||
|
||||
$ sed -n '1,90p' /Users/jianghaifeng/Desktop/ReelShort/docs/plans/codex-研发任务清单.md
|
||||
- A3 内容(03):首页 feed、发现 feed、分类、详情(一次请求渲染详情页)、搜索。
|
||||
- A5 记录/收藏(05):观看记录、最近观看、收藏切换与列表、下载授权。
|
||||
|
||||
$ sed -n '1,135p' /Users/jianghaifeng/Desktop/ReelShort/docs/16-测试用例库.md
|
||||
TC-CONTENT-09 | 分类题材 | 有分类 | 查看分类 | 分类列表正确 | P2
|
||||
TC-RECORD-01 | 观看历史 | 有播放 | 查看历史 | 按时间倒序,可删除 | P0
|
||||
TC-RECORD-03 | 取消收藏 | 已收藏 | 取消 | 状态反转 | P0
|
||||
TC-RECORD-04 | 收藏列表 | 有收藏 | 查看 | 分页正确 | P1
|
||||
TC-RECORD-09 | 历史清空 | 有历史 | 清空 | 全部清空 | P2
|
||||
|
||||
$ sed -n '1,100p' /Users/jianghaifeng/Desktop/ReelShort/docs/09-测试计划.md
|
||||
单元测试 | Dart 核心类 | flutter test | 核心模块 ≥80%
|
||||
UI 测试 | 关键页面 | Flutter widget test | 核心页面
|
||||
```
|
||||
|
||||
解读:K2 范围、TDD 顺序、接口白名单、三语言文案、三态、登录闸、门禁与设备验证边界均已确认。
|
||||
搜索没有契约接口,本批不做;收藏分页和观看记录卡片字段按 INBOX 的降级方案处理。
|
||||
|
||||
### 动作 2:只读核对两个仓库基线与客户端现状
|
||||
|
||||
叙述:确认客户端从干净 `develop` 开工,并核对现有网络层、记录/收藏实现和页面入口,
|
||||
用于计划中的真实文件清单。
|
||||
|
||||
```
|
||||
$ git status --short --branch && git log -5 --oneline --decorate
|
||||
## develop...origin/develop
|
||||
00280ca (HEAD -> develop, origin/develop) merge: 同步 main 的作者标识提交到 develop
|
||||
84a1f58 test(client): 新增设备侧集成测试(真机跑通后端可达性)
|
||||
d7eff4c feat(client): 对接详情/播放/进度续看/收藏(K1 看剧闭环)+ 三态 UI
|
||||
|
||||
$ git status --short --branch && git log -5 --oneline --decorate # FruitServer
|
||||
## develop...origin/develop
|
||||
4118efd (HEAD -> develop, origin/develop) docs(inbox): 按 specs 补全 K2 执行规范与门禁
|
||||
096e90c docs(inbox): 记录用户裁定——K2 先按现状契约执行,契约缺口后期再补
|
||||
582453f docs(inbox): 下发 K2 客户端第二批(分类/记录/收藏/下载授权 + UI)
|
||||
|
||||
$ find lib -maxdepth 4 -type f | sort
|
||||
lib/core/data/remote/catalog_api.dart
|
||||
lib/core/data/remote/library_api.dart
|
||||
lib/core/data/remote/watch_api.dart
|
||||
lib/pages/discover/discover_view.dart
|
||||
lib/pages/mine/mine_view.dart
|
||||
...
|
||||
```
|
||||
|
||||
解读:两仓均无未提交改动。分类 API、下载 API/page/controller 不存在;
|
||||
观看记录删除只有单条,没有清空;收藏数据层已有但无独立页面;
|
||||
`ApiClient` 只有 GET/POST/DELETE,下载设置所需的 PUT 需最小补齐。
|
||||
|
||||
### 动作 3:写 K2 计划
|
||||
|
||||
叙述:先落计划再动业务代码,明确四块范围、实施顺序、影响文件、三个契约缺口、
|
||||
风险和待确认项。
|
||||
|
||||
```
|
||||
文件:docs/plans/2026-10-17-K2.md
|
||||
章节:范围与完成口径 / 实施顺序与 TDD / 预计影响文件 /
|
||||
契约缺口 / 风险与控制 / 待确认 / 完成定义
|
||||
```
|
||||
|
||||
解读:后续实现按 K2-A → K2-B → K2-C → K2-D 推进;每块先红后绿并单独跑门禁。
|
||||
真机与 Android 构建结果按实际证据记录,缺失时明确标“未验证”。
|
||||
|
||||
### 动作 4:创建功能分支并跑存量基线门禁
|
||||
|
||||
叙述:客户端从 `develop` 创建任务指定分支;沙箱不允许写 `.git/index.lock`,
|
||||
Git 与 Flutter 工具链缓存写操作按权限流程在受控环境执行。先确认存量门禁本身是绿的。
|
||||
|
||||
```
|
||||
$ git checkout -b feature/flutter-k2-library develop
|
||||
Switched to a new branch 'feature/flutter-k2-library'
|
||||
## feature/flutter-k2-library
|
||||
|
||||
$ dart analyze lib test
|
||||
Analyzing lib, test...
|
||||
No issues found!
|
||||
|
||||
$ flutter test
|
||||
00:10 +188: All tests passed!
|
||||
```
|
||||
|
||||
解读:客户端基线 188 个测试全过、静态检查零告警,可以开始 K2-A。
|
||||
|
||||
### 动作 5:K2-A 测试红灯
|
||||
|
||||
叙述:先新增分类模型/API/控制器的契约测试,覆盖雪花 ID 字符串、分类到
|
||||
`category-{id}` 分区映射、缺失分区空态、hot/new 入口、全量去重和失败重试。
|
||||
|
||||
```
|
||||
$ flutter test test/category/category_controller_test.dart
|
||||
test/category/category_controller_test.dart:6:8: Error: Error when reading
|
||||
'lib/core/data/models/content_category.dart': No such file or directory
|
||||
test/category/category_controller_test.dart:10:8: Error: Error when reading
|
||||
'lib/core/data/remote/category_api.dart': No such file or directory
|
||||
test/category/category_controller_test.dart:11:8: Error: Error when reading
|
||||
'lib/core/data/repositories/category_repository.dart': No such file or directory
|
||||
test/category/category_controller_test.dart:12:8: Error: Error when reading
|
||||
'lib/core/data/services/category_controller.dart': No such file or directory
|
||||
00:00 +0 -1: Some tests failed.
|
||||
```
|
||||
|
||||
解读:红灯原因符合预期,目标实现尚不存在。下一步实现分类数据层与控制器。
|
||||
|
||||
### 动作 6:K2-A 实现绿灯与门禁
|
||||
|
||||
叙述:实现 `ContentCategory`、`CategoryApi`、`CategoryRepository`、
|
||||
`CategoryController`,发现页改为读取 `/app/categories` 与 `/app/discover/feed`;
|
||||
保留 For You / Hot / New 样式,服务端分类只匹配 `category-{id}`。
|
||||
|
||||
```
|
||||
$ flutter test test/category/category_controller_test.dart
|
||||
00:00 +5: All tests passed!
|
||||
|
||||
$ dart analyze lib test
|
||||
Analyzing lib, test...
|
||||
No issues found!
|
||||
|
||||
$ flutter test
|
||||
00:08 +191 ~1: All tests passed!
|
||||
```
|
||||
|
||||
解读:分类块绿。`~1` 是既有真实后端联调用例因本机 8081 未启动而按设计跳过,
|
||||
不是失败。分类 UI 仍保留 hot/new 入口;后端发现 feed 未下发对应分区时显示空态。
|
||||
|
||||
### 动作 7:K2-B 测试红灯
|
||||
|
||||
叙述:先固定观看记录页核心逻辑:`updatedAt` 解析、recent 按 dramaId 去重、
|
||||
详情并发上限 4、单条详情失败降级与单项重试、删除/清空乐观回滚、recent 失败态。
|
||||
|
||||
```
|
||||
$ flutter test test/watch/watch_records_controller_test.dart
|
||||
test/watch/watch_records_controller_test.dart:11:8: Error: Error when reading
|
||||
'lib/core/data/services/watch_records_controller.dart': No such file or directory
|
||||
test/watch/watch_records_controller_test.dart:23:3: Error: No named parameter
|
||||
with the name 'updatedAt'.
|
||||
test/watch/watch_records_controller_test.dart:49:21: Error: The getter
|
||||
'updatedAt' isn't defined for the type 'WatchProgress'.
|
||||
00:00 +0 -1: Some tests failed.
|
||||
```
|
||||
|
||||
解读:红灯符合预期,观看记录控制器与更新时间字段尚不存在。
|
||||
|
||||
### 动作 8:K2-B 实现与门禁
|
||||
|
||||
叙述:增加 `updatedAt`、观看记录清空 API/repository,新增独立
|
||||
`WatchRecordsController` 与 `WatchRecordsPage`。“我的 → 观看记录”已改为打开独立页。
|
||||
详情请求按 dramaId 去重、最多 4 个并发;单条详情失败显示占位与单项重试;
|
||||
单删和清空先更新 UI,失败回滚并提示;清空有二次确认。
|
||||
|
||||
```
|
||||
$ flutter test test/watch/watch_records_controller_test.dart test/watch/watch_records_page_test.dart
|
||||
00:00 +10: All tests passed!
|
||||
|
||||
$ dart analyze lib test
|
||||
Analyzing lib, test...
|
||||
No issues found!
|
||||
|
||||
$ flutter test
|
||||
00:08 +201 ~1: All tests passed!
|
||||
```
|
||||
|
||||
解读:K2-B 绿。`~1` 仍是既有真实后端联调用例跳过;本轮新增 10 个记录相关测试。
|
||||
|
||||
### 动作 9:K2-C 测试红灯
|
||||
|
||||
叙述:先补收藏取消失败的原位回滚测试,再新增独立收藏页的卡片、取消失败、
|
||||
空态、失败重试与未登录闸测试。
|
||||
|
||||
```
|
||||
$ flutter test test/library/favorite_controller_test.dart test/library/favorites_page_test.dart
|
||||
test/library/favorite_controller_test.dart:80:8: Error: The setter 'failRemove'
|
||||
isn't defined for the type 'InMemoryFavoriteRepository'.
|
||||
test/library/favorites_page_test.dart:13:8: Error: Error when reading
|
||||
'lib/pages/favorites/favorites_page.dart': No such file or directory
|
||||
test/library/favorites_page_test.dart:108:23: Error: The getter 'listCalls'
|
||||
isn't defined for the type 'InMemoryFavoriteRepository'.
|
||||
00:00 +0 -2: Some tests failed.
|
||||
```
|
||||
|
||||
解读:红灯符合预期:独立收藏页不存在,测试仓库也还不能模拟删除失败。
|
||||
|
||||
### 动作 10:K2-C 实现与门禁
|
||||
|
||||
叙述:新增独立 `FavoritesPage` 和复用列表卡片,服务端列表三态齐全;
|
||||
取消收藏采用乐观更新,失败时按原索引回滚;我的页增加“我的收藏”入口。
|
||||
|
||||
```
|
||||
$ flutter test test/library/favorite_controller_test.dart test/library/favorites_page_test.dart
|
||||
00:00 +13: All tests passed!
|
||||
|
||||
$ dart analyze lib test
|
||||
Analyzing lib, test...
|
||||
No issues found!
|
||||
|
||||
$ flutter test
|
||||
00:10 +207 ~1: All tests passed!
|
||||
```
|
||||
|
||||
解读:K2-C 绿。收藏页按契约全量读取,不发送 `page/size`;真实后端联调用例仍按设计跳过。
|
||||
|
||||
### 动作 11:K2-D 测试红灯
|
||||
|
||||
叙述:先用 API 契约测试钉住 §1.6 全部 8 个下载接口与字符串 ID;
|
||||
再用控制器测试固定策略/授权加载、后端 message 透传、设置回滚、删除和清空回滚。
|
||||
|
||||
```
|
||||
$ flutter test test/download/download_api_test.dart test/download/download_controller_test.dart
|
||||
test/download/download_api_test.dart:7:8: Error: Error when reading
|
||||
'lib/core/data/remote/download_api.dart': No such file or directory
|
||||
test/download/download_controller_test.dart:4:8: Error: Error when reading
|
||||
'lib/core/data/models/download_license.dart': No such file or directory
|
||||
test/download/download_controller_test.dart:9:31: Error: Type
|
||||
'DownloadController' not found.
|
||||
00:00 +0 -2: Some tests failed.
|
||||
```
|
||||
|
||||
解读:红灯符合预期,下载模型、API、仓库与控制器尚未实现。
|
||||
|
||||
### 动作 12:K2-D 数据层与页面实现
|
||||
|
||||
叙述:实现下载策略/授权模型、8 个接口的 `DownloadApi`、仓库与控制器;
|
||||
`ApiClient` 仅补契约需要的 `PUT`。新增“我的下载”页,展示策略、配额、
|
||||
授权/任务原始状态、进度、有效期,并提供仅 Wi-Fi、清晰度、单删和清空;
|
||||
详情页与播放页接入真实授权申请。授权失败直接展示后端 `message`。
|
||||
|
||||
```
|
||||
$ flutter test test/download/download_api_test.dart test/download/download_controller_test.dart test/download/downloads_page_test.dart
|
||||
00:00 +10: All tests passed!
|
||||
|
||||
$ dart analyze lib test
|
||||
Analyzing lib, test...
|
||||
No issues found!
|
||||
|
||||
$ flutter test
|
||||
00:10 +219 ~1: All tests passed!
|
||||
```
|
||||
|
||||
解读:K2-D 首轮绿。文件分片落盘、断点续传、离线播放、`licenseKey` 本地校验未做,
|
||||
`url` 与 `progress` 只交付 API 方法;这些边界不会写成“已完成”。
|
||||
|
||||
### 动作 13:提交前边界审查(清晰度下拉修复)
|
||||
|
||||
叙述:审查发现当后端策略 `maxQuality` 已是 `720P/1080P` 时,
|
||||
下拉选项会重复同一值并触发 Flutter 断言。先补测试得到红灯,再去重选项;
|
||||
同时处理退出后重新登录页面不刷新、登录闸文案覆盖观看记录/下载的问题。
|
||||
|
||||
```
|
||||
$ flutter test test/download/downloads_page_test.dart
|
||||
Failed assertion: There should be exactly one item with
|
||||
[DropdownButton]'s value: 720P.
|
||||
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
|
||||
00:01 +6 -1: Some tests failed.
|
||||
|
||||
$ flutter test test/download/downloads_page_test.dart
|
||||
00:00 +7: All tests passed!
|
||||
```
|
||||
|
||||
解读:边界缺陷已由测试固定并修复,避免特定后端清晰度值导致下载页崩溃。
|
||||
|
||||
### 动作 14:最终门禁与 Android 构建
|
||||
|
||||
叙述:整理掉格式化造成的无关测试 diff 后,在 develop 合并前后都复跑门禁。
|
||||
首次 Android 构建因本机 Gradle 依赖经代理下载持续约 12 分钟,但最终成功;
|
||||
修复后二次构建命中缓存(2.377 秒)。
|
||||
|
||||
```
|
||||
$ dart analyze lib test
|
||||
Analyzing lib, test...
|
||||
No issues found!
|
||||
|
||||
$ flutter test
|
||||
00:11 +220 ~1: All tests passed!
|
||||
|
||||
$ flutter build apk --debug
|
||||
Running Gradle task 'assembleDebug'... 705.7s
|
||||
✓ Built build/app/outputs/flutter-apk/app-debug.apk
|
||||
|
||||
$ flutter build apk --debug # 最终修复后
|
||||
Running Gradle task 'assembleDebug'... 2,377ms
|
||||
✓ Built build/app/outputs/flutter-apk/app-debug.apk
|
||||
```
|
||||
|
||||
解读:静态检查零告警、220 个测试通过;`~1` 是既有真实后端联调用例因本机未启动
|
||||
8081 服务按设计跳过。Android debug APK 构建通过。
|
||||
|
||||
### 动作 15:Git 提交、合并与推送
|
||||
|
||||
叙述:客户端从干净 develop 建功能分支,功能提交与 `--no-ff` 合并提交均使用
|
||||
项目规定作者。合并前确认 `origin/develop` 无新提交;合并后在 develop 复跑门禁,
|
||||
再 push,最后删除已完成 feature 分支。未改 main。
|
||||
|
||||
```
|
||||
commit=cc4d7c5a9dc6a4f6f0565a32503cce5973af703c
|
||||
author=Zhou Weidong <502333560@qq.com>
|
||||
subject=feat(flutter): 接入分类记录收藏与下载授权
|
||||
|
||||
merge=45f5f25640a274edb51bd90b3b5e52c43ba9d9cd
|
||||
author=Zhou Weidong <502333560@qq.com>
|
||||
subject=merge: 合并 K2 客户端分类记录收藏与下载授权
|
||||
|
||||
$ git push origin develop
|
||||
To http://git.reelshort2.com/jianghaifeng/ReelShort.git
|
||||
00280ca..45f5f25 develop -> develop
|
||||
|
||||
$ git branch -d feature/flutter-k2-library
|
||||
Deleted branch feature/flutter-k2-library (was cc4d7c5).
|
||||
```
|
||||
|
||||
解读:客户端 develop 已与 origin/develop 对齐,工作区干净。
|
||||
|
||||
### 动作 16:真实数据与未验证边界
|
||||
|
||||
叙述:生产环境注入的发现分类、观看记录、收藏、下载授权均调用契约 HTTP 接口,
|
||||
不再用本地演示目录补齐。由于设备侧验证归用户执行,本轮没有把任何开发机请求
|
||||
当作“设备可达”证据。
|
||||
|
||||
```
|
||||
已接生产 HTTP 链路:
|
||||
- GET /app/categories + GET /app/discover/feed
|
||||
- GET /app/watch/recent + DELETE /app/watch/progress/{dramaId} + DELETE /app/watch/progress
|
||||
- GET /app/favorites + DELETE /app/favorites/{dramaId} + POST /app/favorites/toggle
|
||||
- §1.6 全部 8 个 /app/downloads* 契约接口
|
||||
|
||||
仍未做:
|
||||
- 搜索(契约无接口)
|
||||
- 下载文件分片落盘 / 断点续传 / 离线播放 / licenseKey 本地校验
|
||||
- 真机 / 模拟器侧验证(未验证,由用户执行)
|
||||
```
|
||||
|
||||
解读:功能代码和构建门禁已完成;设备网络、实际授权状态与 UI 交互需用户按回执步骤验证。
|
||||
Reference in new issue
Block a user