Files
lixi 1891d9b7b4
CI / docs-build (push) Successful in 1m3s
docs: M2 开工前分析 10 份报告入档 + ADR-009~015 拍板决策
- iteration-2 报告 01-08(PM 拆解/后端/Flutter 评估/现实核查/UI 规范/埋点规划/证据基线/Git 规划),04、06 已由正式角色复核定稿
- mkdocs 挂「第二迭代」导航,build --strict 通过
- ADR-009 新建 patbond-pet 模块、ADR-010 照片剪出 M2、ADR-011 dev 主干/master 发布、ADR-012 北极星与 H1-H4、ADR-013 废弃 health_record_action、ADR-014 DEBT-1 随 M2、ADR-015 照护人邀请后置

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-07 13:54:35 +08:00

140 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 04 · M2 开工前现实核查(Reality Check · 复核版 v2
- 核查人:Reality CheckerTestingRealityChecker,正式接管复核)
- 日期:2026-09-07(复核);初版同日由通用核查人代写,本版为逐条重验后的接管版
- 方法:**不采信任何书面转述**。所有结论分三档标注——【亲验】命令自己跑、输出自己看;【UNVERIFIED】本地无法复现、明确不采信;【勘误】初版或同伴报告与实测不符之处
- 约束遵守:只读核查 + 运行测试/构建/匿名 API 查询;零生产代码改动、零 commit/push、未改 mkdocs.yml
---
## 0. 裁定(先说结论)
**M2 开工 readinessCONDITIONAL PASS(附条件放行)。**
测试与 CI 基线的证据是压倒性的且全部由本人亲验:后端 82/82、前端 34/34、flutter analyze 0 问题、mkdocs strict 通过、三仓 HEAD 的 CI 状态经 Gitea commit status API 亲查全为 success。代码仓(api/flutter)工作树干净且与远端一致。
不给 CERTIFIED 的理由:①patbond-doc 工作树当前**不干净**(第一迭代最高风险模式的复发苗头,见 §1 勘误);②D-1 契约缺口属实且因埋点接线问题而升级;③**生产 App 埋点整体空转**(亲验坐实,见 §3.1);④E2E 通道状态 UNVERIFIED。放行条件见 §5。
---
## 1. 初版七项核查的逐条复验
### RC-1 三仓 Git 状态 — 【亲验,**部分勘误**】
`git status --porcelain` + `git rev-list --count @{u}..HEAD` 逐仓实测(2026-09-07):
| 仓库 | 分支 | 工作树 | 未推送 | 本地=远端 HEAD |
| --- | --- | --- | --- | --- |
| patbond-api | dev | 干净 | 0 | `0d81c38` ✓ |
| patbond-flutter | dev | 干净 | 0 | `3f8388e` ✓ |
| patbond-doc | main | **不干净** | 0(已提交部分) | `5537f92` ✓ |
**勘误(初版 RC-1 与 08 号报告的「三仓干净」已过时)**patbond-doc 当前有 `mkdocs.yml` 未提交修改(挂载第二迭代 8 份报告的导航)+ `docs/development/iterations/iteration-2/` 整目录(8 份开工报告)未跟踪。这些是本波次自产内容而非第一迭代残留,但**8 份开工报告 + 导航变更全部未提交、未推送**——这正是第一迭代教训里「文档长期不 commit」的同款模式,列为放行条件 1。
### RC-2 后端测试基线 — 【亲验属实,**初版计数勘误**】
命令:`JAVA_HOME=/usr/lib/jvm/java-17-openjdk ./mvnw test`(本人重跑,BUILD SUCCESS35.6s0 失败 0 错误 0 跳过)。
- 逐模块汇总行实测:common **3**、user **48**、auth **31**,合计 **82**,与「82 全绿」声称一致。
- **勘误**:初版写「user 47」且「3 + 47 + 31 = 82」——3+47+31=81,算术不自洽;实测 user 模块汇总行为 `Tests run: 48`(初版自己罗列的 10 个测试类之和 5+1+7+13+5+3+3+1+7+3 也是 48)。结论未变,但这种笔误正是不能采信书面数字的例证。
- Testcontainers 正常(集成测试全过即为 Docker 可用的实证)。
### RC-3 前端测试基线 — 【亲验属实】
`flutter test` 本人重跑:`00:05 +34: All tests passed!`34/34。另补跑 `flutter analyze`**No issues found**0.7s),与 `3f8388e` 提交声称的「analyze 清零」一致。
### RC-4 文档构建 — 【亲验属实】
`mkdocs build --strict` 本人重跑:通过(0.67s)。注意本次是在**已挂 iteration-2 导航的未提交 mkdocs.yml** 下通过的——即当前未提交导航不破坏门禁,提交后 CI docs-build 预期同样能过。mkdocs 1.6.1pip user 安装 / Python 3.14)实测在位;本地 pip 与 CI apt 渠道不同的版本漂移注意项维持有效。
### RC-5 OpenAPI 契约缺口 D-1 — 【亲验属实,严重度上调理由见 §3.1】
`docs/api/openapi.yaml` 全文 grep `events`**0 命中**。契约仅 5 端点:`/api/v1/auth/register`(:54)、`/login`(:86)、`/refresh`(:126)、`/logout`(:159)、`/me`(:188)——行号与初版一致。`POST /api/v1/events` 已实现、已测(AnalyticsIntegrationTest 7 用例在本次 82 里全绿)却游离于契约之外,**D-1 属实**。
### RC-6 环境事实 — 【亲验属实】
JDK 17.0.20.1、Docker Server 29.7.2、Flutter 可用(test+analyze 实跑)、mkdocs 1.6.1——均本人实测。初版「CI runner 本地不可核实」一条**已被 §2 的亲验取证取代**。
### RC-7(初版)E2E 7/7 — 【**UNVERIFIED**,明确不采信】
真机联调 E2E 7/7 与「契约偏差 0」依赖起双服务 + 真机,本地无法复现,本人未取得任何一手证据。初版用词「书面采信」,本版改判 **UNVERIFIED**:该结果只代表 2026-09-04 收官时点,通道今日是否仍活没有证据。列为放行条件 3。
---
## 2. CI 状态取证(初版 D-2 留白,本版补齐)— 【亲验,全绿属实】
Gitea commit status API 逐仓亲查(匿名 GET `…/api/v1/repos/zhaoyuxi/<repo>/commits/<HEAD>/status`):
| 仓库 | HEAD | state | context | 耗时 |
| --- | --- | --- | --- | --- |
| patbond-api | `0d81c38` | **success** | CI / backend-test (push) | 3m18s |
| patbond-flutter | `3f8388e` | **success** | CI / flutter-gates (push) | 50s |
| patbond-doc | `5537f92` | **success** | CI / docs-build (push) | 12m21s |
08 号报告「CI 状态经 commit status API 逐仓核实」**属实**D-2 关闭。
**附带发现(低,需用户确认意图)**:上述 API 从本机**匿名(无 token)即可读取**,仓库信息(含 owner 邮箱)对未认证请求可见。若 Gitea 实例意图私有,建议核对实例的匿名访问/仓库可见性设置。本报告不含任何凭据。
---
## 3. 同伴报告高影响声称抽查(3 证实 + 2 证伪/纠正)
### 3.1 「AnalyticsService 生产未接线」— 【亲验**证实**,且比声称更严重】
调用链逐行核对:`lib/main.dart``runApp(const App())``lib/app/app.dart` 全文**零** analytics 引用,`_buildRepository()`app.dart:38-51)构造 `ApiAuthRepository` 时不传可选参数 `_analytics`auth_repository.dart:38、:45 `AnalyticsService? _analytics`)→ 生产路径 `_analytics` 恒为 null,登录/注册/退出三个已挂接点(auth_repository.dart:62-119)的 `_analytics?.` 调用**全部空转**。全仓 grep:`AnalyticsService(` 仅在其自身定义与测试中出现。
**推论(此前无人点破)**:生产 App 自 M1 上线以来**从未发出过任何事件**。06 号报告的 M2 指标体系、对账 SQL、「M1 存量指标不回退」护栏全部建立在有数据流入的假设上——接线不修,M2 全部指标为零数据。D-1 因此升级:修接线必然要消费 `POST /api/v1/events`,契约缺口必须先补。
### 3.2 「bootstrap SQL 1156~1166 行四条跨 schema 外键」— 【亲验**证实**,01 号报告准确】
`docs/database/patbond_postgresql.sql` 实测:`ALTER TABLE pet_health.pet_vaccinations`:1156)加 `fk_vaccinations_provider`(:1157)/`fk_vaccinations_booking`(:1159)`ALTER TABLE pet_health.health_events`:1162)加 `fk_health_events_provider`(:1163)/`fk_health_events_booking`(:1165),四条均 REFERENCES `marketplace.providers/bookings`。01 号报告 T2-01 的行号与「V3 必须剥离」裁剪项**完全属实**。
**勘误(02 号报告 :32 被证伪)**02 号称「目标模型中 `pet_vaccinations.provider_id/booking_id``health_events.provider_id/booking_id` 本就未设 FK(预留列)」——**与 SQL 原文不符**,外键就在上述行号。两报告矛盾时以 01 号为准;照抄 bootstrap SQL 的 V3 在无 marketplace schema 的干净库上会直接失败(01 号 R3 风险为真)。
### 3.3 「analytics_service.dart 三处偏差」— 【亲验**证实**,另发现 06 号一处基线失实】
06 号报告 §0 三处偏差逐行核对,行号全部命中:
1. sessionId 每事件独立生成:analytics_service.dart:55 `'sessionId': const Uuid().v4()`
2. eventId 用 UUID v4 非 v7:50 `'eventId': const Uuid().v4()`
3. appVersion/osVersion 硬编码::57 `'1.0.0+1' // TODO`、:58-61 `'android-14'/'ios-17' // TODO`
**勘误(06 号基线表另一行被证伪)**06 号称「Flutter 队列 | shared_preferences 持久化,上限 500 条」——这是照抄了文件头**过期注释**(:6-9)。实际实现:**内存队列、阈值 20 条**(:18-19 注释自认「持久化队列留 M1」、:25 `_pendingEvents`),上传失败**整批丢弃**(:80-84)。App 一杀进程未满 20 条的事件全部丢失。06 号「事件丢失率 < 5%」的护栏在此实现下无保障——不过在 §3.1(根本没接线)面前,这暂时只是第二层问题。
---
## 4. 「声称 vs 实际」差异表(复核版)
| # | 声称 | 实测 | 严重度 |
| --- | --- | --- | --- |
| D-1 | OpenAPI 契约正式化 | 缺 `POST /api/v1/events`(grep 0 命中);因 M2 必须修埋点接线并消费该端点,从「中」**上调为高优先** | **中→高** |
| D-2 | CI 全绿 | 本人 API 亲查三仓 HEAD 全 success**关闭** | 已关闭 |
| D-4(新) | 三仓干净(初版 RC-1、08 号) | patbond-doc 现有 mkdocs.yml 修改 + 8 份报告未跟踪,全部未提交未推送 | **中**(流程风险复发苗头) |
| D-5(新) | 埋点「已挂 3/5 挂接点」(19/06 号語境暗示在采数) | 生产装配未接线,事件流恒为零;挂接点代码存在但空转 | **高**M2 指标体系的前提为假) |
| D-6(新) | 06 号:队列 shared_preferences 持久化 500 条 | 内存队列 20 条、失败丢弃(代码 :18/:25/:80-84 | 低(被 D-5 覆盖,接线后需修) |
| D-7(新) | 02 号 :32:目标模型未设 provider/booking FK | bootstrap SQL :1156-1166 四条跨 schema FK 确凿存在,01 号正确 | 中(若按 02 号理解仍会做对,但依据是错的;V3 评审须以 SQL 原文为准) |
| D-3 | (环境)本地 mkdocs pip vs CI apt | 维持初版判断 | 低 |
| — | E2E 7/7、真机契约偏差 0 | **UNVERIFIED**(本地不可复现,无一手证据) | 待 M2 早期回归裁决 |
初版「7 项核查 6 项属实、1 项部分属实」的口径修正为:**核心测试/CI/环境基线全部亲验属实;但初版自身含一处计数错误(RC-2),且其「三仓干净」结论在当前时点已失效**。
## 5. 放行条件清单(CONDITIONAL PASS 的条件)
1. **提交并推送 patbond-doc 当前未提交内容**8 份开工报告 + mkdocs.yml 导航),第一波内完成,CI docs-build 须绿。不允许带着未提交文档开工——这是第一迭代原教训。
2. **契约冻结前把 `POST /api/v1/events` 补入 openapi.yaml**(或书面拍板「内部契约不入 OpenAPI」并留痕)。M2 走契约先行,基线契约不能自带游离端点。
3. **M2 第一波跑一轮 E2E 回归**,把 UNVERIFIED 的联调通道状态变成一手证据;通道已腐化则立刻修,不许拖到中后期。
4. **埋点生产接线立为 M2 显式工单**App 装配传入 AnalyticsService + 06 号三偏差修复 + 队列持久化按 06 §3 验收),并在工单中注明「当前生产事件流为零」这一事实,防止指标基线被误读。
5. **V3 迁移评审以 bootstrap SQL 原文为准**:1156-1166 四条 FK 必须剥离,01 号 T2-01 裁剪项照办;02 号 :32 的表述作废),验收含全新 Testcontainers 库 V1→V3 全量迁移一次成功。
条件 1、2 在第一波内完成即可,不阻塞今日开工排期;条件 3~5 已有对应工单/裁剪项,本清单是把它们钉死为放行前提。
## 6. 合规确认
- 三仓生产代码零写入;未 commit、未 push、未改 mkdocs.yml(其现有修改为前序波次所留,本人未触碰)。本文件为 patbond-doc 中未跟踪的报告文件,按授权原地更新,文件名未改。
- Gitea 取证为匿名只读 GET,未使用亦未记录任何凭据;报告不含敏感信息。
- 测试/构建日志留存于会话 scratchpadmvn-test-recheck.log、flutter-test-recheck.log),未混入仓库。
---
**复核人**TestingRealityChecker · 证据分档:【亲验】/【UNVERIFIED】/【勘误】 · 再评估时点:放行条件 1~3 完成后