From 2d70858887dd55c0ca71da4d46ffafc2a71c3986 Mon Sep 17 00:00:00 2001 From: jianghaifeng Date: Fri, 16 Oct 2026 18:06:02 +0800 Subject: [PATCH] =?UTF-8?q?docs(plans):=20K1-verify=20=E5=9B=9E=E6=89=A7?= =?UTF-8?q?=E4=B8=8E=E7=95=99=E7=97=95=EF=BC=88=E7=9C=9F=E6=9C=BA=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E4=BA=A4=E5=9B=9E=E7=94=A8=E6=88=B7=EF=BC=8C=E6=A0=87?= =?UTF-8?q?=E6=B3=A8=E6=9C=AA=E9=AA=8C=E8=AF=81=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/plans/INBOX.md | 66 +++++++++++++++++++++++++++++++++++- docs/plans/PROGRESS.md | 77 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 1 deletion(-) diff --git a/docs/plans/INBOX.md b/docs/plans/INBOX.md index f7078c8..6e50cdc 100644 --- a/docs/plans/INBOX.md +++ b/docs/plans/INBOX.md @@ -20,7 +20,7 @@ --- -## [待处理] 2026-10-16 20:30 | K1-verify:用**正确地址**重做真机验证(设备侧取证) +## [已交接 · 未验证(真机验证改由用户执行)] 2026-10-16 20:30 | K1-verify:用**正确地址**重做真机验证(设备侧取证) **用户指令(2026-10-16 20:20)**:「让 Codex 用正确地址重做一次真机验证」。 @@ -500,3 +500,67 @@ $ flutter test test/integration/live_watch_flow_test.dart → All tests passed! 这是接口模型决定的,不是顺手重构;`clampResumePosition` 等本地工具函数保留。 4. **未登录时**进度与收藏接口一律不发(匿名浏览/试看不受影响),收藏按钮沿用"先引导登录"。 5. 禅道里仍**没有 K1 任务**(项目 2 下只有 S0/S1、A1–A6、B1/B2、C1–C3),未动任何既有任务状态。 + +--- + +### 回执(Codex,2026-10-16):K1-verify —— **未验证(真机验证由用户执行,Codex 未执行)** + +**结论先说**:按用户 20:45 指令「codex 不用跑测试 我来执行」,本批的**真机验证状态 = 未验证**, +由用户执行后以其结果为准。我**没有**执行任何最终真机验证,也**没有**用任何"开发机 curl"当作设备可达证据。 + +**交付物(ReelShort `develop`,已推)** +- `pubspec.yaml`:dev_dependencies 加 `integration_test`(sdk)—— 唯一的新依赖 +- `integration_test/app_backend_test.dart`(新增,首行 `// Author: fruit.com.cn`):两个设备侧用例 + 1. 在手机进程里请求 `/app/home/feed` 与 `/app/dramas/{id}`,断言列表非空、详情 id 与卡片一致; + 2. 用**真 App**(真网络、真目录控制器)启动,轮询到首页底部标签栏出现 —— 即"剧目列表加载成功", + 也就是用户在真机上遇到的「剧目列表加载失败」是否消失。 +- 该文件**按用户要求保持原样,不再改动**。 + +**当前机器状态(交接前已清理)** +- 我起的 `flutter run` / `xcodebuild` / lsof 轮询进程**已全部终止**(`pgrep -fl "flutter_tools|xcodebuild"` 只剩 IDE 常驻 daemon,非构建)。 +- `build/` 里留着我被叫停那次构建的半成品 → **用户从 `flutter clean && flutter pub get` 起跑即可清掉**。 +- 后端 8080 / 8081 仍在跑(`admin=200` / `app=200`)。 + +**用户可直接复制执行的命令(⚠️ 本项目 iOS 用 SPM,没有 Podfile,不要跑 `pod install`)** +```bash +# 0) 起点:清掉残留构建产物(我被打断的那次留下的) +cd /Users/jianghaifeng/Desktop/ReelShort/ReelShort +flutter clean && flutter pub get + +# 1) 取开发机真实局域网地址(不要硬编码;换网络会变) +IP=$(ipconfig getifaddr en0) && echo "API_BASE_URL=http://$IP:8081" + +# 2) 设备侧集成测试(最硬的证据,跑在手机进程里) +flutter test integration_test -d 00008101-000875813E42001E --dart-define=API_BASE_URL=http://$IP:8081 + +# 2b) 只想跑网络那一条 +flutter test integration_test/app_backend_test.dart -d 00008101-000875813E42001E \ + --plain-name "should_fetch_home_feed_and_drama_detail_when_device_reaches_backend" \ + --dart-define=API_BASE_URL=http://$IP:8081 + +# 3) 真机手动看 App(可选,验证首页列表与交互) +flutter run -d 00008101-000875813E42001E --dart-define=API_BASE_URL=http://$IP:8081 +``` +(本次实测 `ipconfig getifaddr en0` = **192.168.31.187**;若换网络请以命令输出为准。) + +**前置条件** +1. 手机与开发机在**同一局域网**(例如都在 192.168.31.x)。 +2. iPhone 已授权「**本地网络**」权限:设置 → 隐私与安全性 → 本地网络 → 打开本项目(App 名 **FruitShorts**)。 + 没授权时 App 请求局域网会失败;`Info.plist` 里 `NSLocalNetworkUsageDescription` 与 + `NSAllowsLocalNetworking` 都已配好(上一批加的),所以系统应当会弹权限询问。 +3. 同一时刻**只跑一个** flutter 构建(并发写同一个 `build/` 会互相破坏产物 —— 这正是本次 + `video_player_avfoundation…bundle: No such file or directory` 的疑似成因)。 + +**设备侧证据看什么(红线第 10 条)** +- 测试输出里必须出现**由手机进程打印**的: + - `[device] API_BASE_URL=http://192.168.31.187:8081`(证明手机上用的是局域网地址,不是开发机环回/VPN 地址) + - `[device] 首页分区=4 剧目=3` / `[device] 详情 id=5 剧集=3`(证明设备真的拿到了数据) + - `[device] 首页剧目列表已渲染:API_BASE_URL=http://192.168.31.187:8081`(证明真 App 首页列表出内容) + - 最后一行 `All tests passed!` +- 若失败:`reason` 里会带上 `API_BASE_URL=…`,据此区分"地址不对"还是"设备连不上/权限未授权"。 + +**如实说明(失败与历史记录,详见 PROGRESS 的 K1-verify 段)** +- 我在 17:56 跑过一次,**那次是设备侧输出且全过**(上面那几行 `[device]` 就是它的原始输出)。 +- 随后两次执行失败:17:59 那次 `The Dart VM Service was not discovered after 60 seconds`(app 没 attach,我也没抓到任何手机→8081 的连接); + 18:03 那次 `flutter run` 构建完成后 PM 报产物缺失(`video_player_avfoundation…bundle: No such file or directory`)并叫停。 +- 因此**在用户重跑之前,本批一律按「未验证」计**;上面那次的历史输出只作参考,不作为结论。 diff --git a/docs/plans/PROGRESS.md b/docs/plans/PROGRESS.md index 16552c0..9149b9f 100644 --- a/docs/plans/PROGRESS.md +++ b/docs/plans/PROGRESS.md @@ -412,3 +412,80 @@ $ flutter test 残留核对:app_user 1 行(PM 的 id=28)、app_user_credential 1 行、watch_progress 0、user_favorite 0 ``` (第一次清理漏了 `app_user` 本体——它的主键列叫 `id` 不是 `user_id`,随后单独删掉并复核。) + +--- + +## 2026-10-16 K1-verify:用正确地址重做真机验证(设备侧取证)—— 结果:**未验证(已按用户要求交回用户执行)** + +红线第 10 条新增后,本轮目标是"用正确地址 + 设备侧证据"重做真机验证。以下是逐动作留痕。 + +### 动作 1:取真实地址(不硬编码) +``` +$ ipconfig getifaddr en0 +192.168.31.187 +$ for i in en0 en1 en2 utun0..3; do ipconfig getifaddr $i; done +en0 = 192.168.31.187 # 只有 en0 有地址;旧的 10.157.242.1 已不存在 +$ lsof -nP -iTCP:8081 -sTCP:LISTEN +java 80383 ... TCP *:8081 (LISTEN) +``` + +### 动作 2:加设备侧集成测试(可重复、可入库的证据) +- `pubspec.yaml` dev_dependencies 加 `integration_test`(sdk) +- 新增 `integration_test/app_backend_test.dart`:在**手机进程里**请求 `/app/home/feed` 与 `/app/dramas/{id}`, + 断言列表非空、详情 id 一致;再用真 App 跑一遍,断言首页底部标签栏出现(= 剧目列表加载成功)。 + 两个用例都把 `API_BASE_URL` 打进设备日志,便于区分"地址不对"还是"设备连不上"。 +- `dart analyze lib test integration_test` → No issues found! + +### 动作 3:第一次真机执行(**设备侧输出,17:56**) +``` +$ IP=$(ipconfig getifaddr en0) && flutter test integration_test -d 00008101-000875813E42001E \ + --dart-define=API_BASE_URL=http://$IP:8081 +Running Xcode build... Xcode build done. 31.3s +Installing and launching... 20.0s +00:00 +0: should_fetch_home_feed_and_drama_detail_when_device_reaches_backend +[device] API_BASE_URL=http://192.168.31.187:8081 +[device] 首页分区=4 剧目=3 +[device] 详情 id=5 剧集=3 +00:01 +1: should_render_home_drama_list_when_app_boots_on_device +[device] 首页剧目列表已渲染:API_BASE_URL=http://192.168.31.187:8081 +00:05 +2: (tearDownAll) +00:06 +2: All tests passed! +``` +解读:`[device]` 行是**手机进程里**打印的(不是开发机 curl),断言也在手机进程里跑;这一次是全过的。 + +### 动作 4:第二次执行(只跑第一个用例,17:59)—— 失败 +``` +Running Xcode build... Xcode build done. 17.8s +Installing and launching... +The Dart VM Service was not discovered after 60 seconds. This is taking much longer than expected... +``` +我同时起了 lsof 轮询想抓"手机 IP → 8081"的已建立连接,**一个连接都没抓到**(原始文件只有 lsof 表头)—— +因为 app 那次根本没 attach 上,也就没有发请求。这一步没有产出任何设备侧证据。 + +### 动作 5:第三次(`flutter run` 真机跑,18:03–18:04)—— 被叫停 +``` +Launching lib/main.dart on iPhone in debug mode... +Running Xcode build... Xcode build done. 30.4s +Installing and launching... +You may be prompted to give access to control Xcode... +``` +PM 报告:该轮后续撞上 iOS 构建报错 +`build/ios/iphoneos/video_player_avfoundation_video_player_avfoundation.bundle: No such file or directory`, +并把进程停掉、执行了 `flutter clean`(我自己的日志到 "Installing and launching" 为止,上面这条报错文本来自 PM 报告,不是我抓到的)。 +**推测成因(如实写,未定论)**:我这轮 flutter run 与另一次执行**并发写同一个 build/ 目录**, +产物被互相破坏(PM 也把"并发写 build 目录"列为成因之一)。 + +### 动作 6:按用户指令停止执行,转为交接 +用户 20:45 指令:「codex 不用跑测试 我来执行」。我随即: +``` +$ kill -TERM 76461 76458 76675 77472 76250 # 我的 flutter run / xcodebuild / frontend_server / lsof 轮询 +$ pgrep -fl "flutter_tools|xcodebuild|k1v_poller" +4173 ... flutter_tools.snapshot daemon # 只剩 IDE 常驻 daemon(非构建) +``` +`build/` 目录里留着我被 kill 的那次构建的半成品,用户按 `flutter clean && flutter pub get` 起跑即可清掉。 + +### 结论口径 +- 按**红线第 10 条**与用户要求:本批真机验证**标注「未验证」**,由用户执行后以用户的结果为准。 +- 动作 3 那次是**真实的设备侧输出且全过**,但随后两次执行失败(一次 VM service 未 attach、一次构建产物缺失), + 所以在用户重跑之前**不把它当作最终结论**;它作为历史记录保留在这里。 +- 我**没有**用任何"开发机 curl"作为设备可达证据。