diff --git a/docs/plans/INBOX.md b/docs/plans/INBOX.md index ab3f77d..70d2c93 100644 --- a/docs/plans/INBOX.md +++ b/docs/plans/INBOX.md @@ -20,6 +20,115 @@ --- +## [待处理] 2026-10-17 | K3 客户端第三批:互动(评论 + 点赞 + 举报 + 分享) + +**用户指令(2026-10-17)**:客户端继续对接接口及 UI,严格执行 specs。 + +> **本批只做 K3,做完停下写回执,不要连做 K4。** +> 规范以 specs 为准(`docs/plans/codex-研发任务清单.md` 阶段 A6、`docs/16-测试用例库.md` INTERACT、`docs/09-测试计划.md`); +> 接口只认 `FruitServer/docs/api-phase1.md` §1.7,**契约里没有的接口一律不许自造**。 + +### 〇、开工前必读(按 specs 顺序,缺一不可) + +1. `AGENTS.md`(项目上下文、强制约束、自主执行与沟通节奏) +2. `CODING_STANDARDS.md`(三端红线、Dart/Flutter 专章、门禁总表) +3. `GIT_WORKFLOW.md`(Git Flow、提交格式、审查门槛) +4. `FruitServer/docs/api-phase1.md` §0 / §1.7(接口唯一权威) +5. `docs/plans/codex-研发任务清单.md`(A6)、`docs/16-测试用例库.md`(INTERACT-01~09)、`docs/09-测试计划.md` +6. 本 INBOX 条目 + +### 一、PM 已勘察的现状(实测,直接用) + +- ReelShort `develop` `45f5f25`(K2 已合并推送),互动现状全部是**本地演示数据**: + - [engagement_controller.dart](file:///Users/jianghaifeng/Desktop/ReelShort/ReelShort/lib/core/data/services/engagement_controller.dart#L8-L8) 注释明确 `Local demo interactions ... No public/social backend`,内部维护 `liked` / `comments` 两个本地集合; + - 播放页右栏已有三个入口:点赞 `rail-like`、评论 `rail-comments`、分享 `rail-share`([player_view.dart](file:///Users/jianghaifeng/Desktop/ReelShort/ReelShort/lib/pages/player/player_view.dart#L339-L366)); + - 评论弹窗 [drama_comments_sheet.dart](file:///Users/jianghaifeng/Desktop/ReelShort/ReelShort/lib/pages/player/widgets/drama_comments_sheet.dart#L28-L33) 直接 `addComment` 到本地 `List`,无分页、无回复、无删除、无举报; + - 分享走 [platform_share_service.dart](file:///Users/jianghaifeng/Desktop/ReelShort/ReelShort/lib/core/data/services/platform_share_service.dart) 的系统分享,**不需要后端接口**; + - 全工程没有举报入口。 +- 后端 §1.7 五个接口**均已实现**(`AppCommentController`、`AppInteractionController`),本批**不改后端**。 + +**契约字段(实测自后端 VO,直接用)** + +- `CommentRespVO`:`id,dramaId,episodeId,parentId,rootId,userId,uid,nickname,avatarUrl,content,status,auditReason,likeCount,replyCount,reportCount,createdAt,mine,liked`(ID 按字符串解析) +- `CommentPublishReqVO`:`dramaId`(必填)、`episodeId`、`content`(必填)、`parentId`(回复时传) +- 列表 `GET /app/comments?dramaId=&episodeId=&rootId=&cursor=&size=` → `CursorResult{list,nextCursor,hasMore}`;**匿名可读** +- `POST /app/likes/toggle`:`{targetType: DRAMA|COMMENT, targetId}` → `{liked, count}` +- `POST /app/reports`:`{targetType: COMMENT|USER|DRAMA, targetId, reasonCode(必填), description?}` → 工单 id +- 敏感词三档:`BLOCK` 直接报错、`REPLACE` 替换后放行、`REVIEW` 转待审(`status=pending`,仅自己可见) +- 限流:同一剧集每分钟 5 条评论(后端判定,客户端只展示返回的 `message`) + +### 二、本批范围(4 块,按顺序做) + +#### K3-A 评论 + +- 评论列表弹窗改为服务端数据:首屏 `size=20`,`hasMore` 时展示“加载更多”,用 `nextCursor` 续拉;三态(加载/空/失败可重试)。 +- 发布顶层评论:`dramaId + content`;发布回复:额外传 `parentId`(**只做一层楼层回复**,回复列表用 `rootId` 拉取,不做无限嵌套)。 +- 敏感词三档处理: + - `BLOCK`:原样展示后端 `message`,不清空输入框; + - `REPLACE`:展示后端替换后的内容(以响应为准); + - `REVIEW`:该条以 `status=pending` 出现在自己的列表里,并显示“审核中”标识(文案走 l10n)。 +- 删除自己的评论:仅 `mine=true` 显示删除入口,二次确认后调 `DELETE /app/comments/{id}`;失败回滚并提示。 +- 未登录:列表照常可看(匿名),**发布/点赞/举报前拦截**并弹现有 `AuthGate` 登录提示,不发业务请求。 +- 限流/重复提交:直接展示后端 `message`,前端不自造判断。 + +#### K3-B 点赞 + +- 剧集点赞:播放页 `rail-like` 接 `POST /app/likes/toggle`(`targetType=DRAMA`),乐观更新,失败回滚并提示;未登录先走 `AuthGate`。 +- 评论点赞:评论列表项内接 `targetType=COMMENT`,用返回 `{liked, count}` 更新该项。 +- **契约缺口(按此处理,不许改后端)**:`AppDramaDetailVO` / `AppDramaCardVO` 没有 `likeCount` / `liked`,客户端拿不到剧集点赞初始值。 + 本批**不展示剧集点赞数字**(避免假数据),只展示/切换当前会话内的 liked 状态;并在计划文档登记 + 「建议后端详情与卡片补 `likeCount` / `liked`(需 specs 负责人改契约)」。 + +#### K3-C 举报 + +- 入口:评论项“更多”菜单(举报评论)、详情页更多菜单(举报短剧)。**不做举报用户**(本批无用户主页入口)。 +- 弹窗:原因单选 + 可选描述,提交 `POST /app/reports`;成功后提示并关闭。 +- 失败透传:重复举报 `你已举报过该内容,我们正在处理`、举报自己 `不能举报自己发布的内容`,一律展示后端 `message`。 +- 未登录先走 `AuthGate`。 +- **契约缺口(登记并按下述降级)**:§1.7 未定义 `reasonCode` 枚举,后端不校验。本批前端固定 5 项: + `SPAM`(垃圾广告)、`ABUSE`(辱骂骚扰)、`PORN`(色情低俗)、`AD`(引流广告)、`OTHER`(其他);文案进三语 arb。 + 计划文档登记「建议后端补 `reasonCode` 枚举与后台映射」。 + +#### K3-D 分享 + +- 保持现有系统分享(`PlatformShareService`),**不新增后端接口**;只做回归验收(标题/简介/footer 走 l10n)。 + +### 三、明确不做(避免误判“没做完”) + +- 拉黑(TC-INTERACT-06):§1.7 无接口,本批不做。 +- 审核联动闭环(TC-INTERACT-09):属后台 `2.5 内容治理`,已实现,本批不做。 +- 后台敏感词管理、评论审核、举报工单处理:后台已有,本批不动。 +- 评论图片/表情/@提及/无限嵌套、我的评论列表:本批不做。 +- 并发点赞(TC-INTERACT-07):由后端幂等保证,客户端不压测,只做防连点。 + +### 四、UI 与规范约束(严格执行 specs) + +- **l10n**:所有新增文案(评论/回复/审核中/举报原因/失败提示)进 `lib/l10n/app_{en,zh,id}.arb` 三份齐全并重新生成;禁止硬编码。 +- **视觉**:沿用现有深色主题、`AppColors`、播放页右栏与底部弹窗样式;不自行改主题。 +- **三态**:评论列表必须有加载、空、失败(可重试);禁止白屏或假装成功。 +- **分层**:新增 `comment_api / interaction_api`(放 `lib/core/data/remote/`)、`comment_repository`、`comment_controller`;页面只依赖 controller/repository 抽象;沿用 K2 的分层与注入方式。 +- **ID**:全部按字符串解析(`json_numbers.dart`),禁止 `as int`。 +- **不要动**:K2 的分类/记录/收藏/下载逻辑、登录注册、播放进度核心;不改 `ReelShortWeb`、`FruitServer` 后端、specs。 +- 新文件首行 `// Author: fruit.com.cn`;public 类/方法必须有文档注释;无 AI 痕迹;测试命名 `should_<期望>_when_<条件>`。 +- 代码规模红线:函数 ≤50 行、参数 ≤5、类 ≤300 行、单文件 ≤500 行、嵌套 ≤4 层、圈复杂度 ≤10。 + +### 五、门禁(不达标不提交) + +1. `dart analyze lib test` 零告警;`flutter test` 全过(存量不得跑红)。 +2. `flutter build apk --debug` 通过;若缺 SDK,贴原始输出并标「未验证」。 +3. 新增测试至少覆盖:评论游标翻页与 hasMore、发布成功/敏感词 BLOCK/REPLACE/REVIEW、删除自己的评论与失败回滚、点赞乐观更新与回滚、举报成功/重复举报 message 透传、未登录 AuthGate、评论点赞计数更新。 +4. 真机/设备侧验证由用户执行(红线 7、10),回执给“用户可照做步骤 + 每步预期”,禁止用开发机 `curl` 冒充设备证据。 +5. Git:从 `develop` 拉 `feature/flutter-k3-interaction`,完成后 `git merge --no-ff` 回 `develop` 并 push;**不动 `main`**;只 `git add` 自己的文件。 + +### 六、节奏与留痕 + +- 先写 `FruitServer/docs/plans/2026-10-17-K3.md`:范围、影响文件、上述 3 个契约缺口、风险、待确认。 +- TDD:每块先红灯 → 实现 → 绿灯 → 重构;每完成一块跑一次 `dart analyze lib test` + 定向测试。 +- 每步「叙述 + 命令 + 原始输出 + 解读」追加到 `docs/plans/PROGRESS.md`。 +- 做完停下写回执:真数据/本地数据页面清单、用户验证步骤与预期、门禁原始输出、提交号。 + +--- + ## [已处理·待用户验收] 2026-10-17 | K2 客户端第二批:分类 + 观看记录 + 收藏列表 + 下载授权(A3/A5 剩余)+ UI **用户指令(2026-10-17)**:「现在先做客户端 对接相关接口 及ui 严格执行specs 内的要求」。