From fcac68daf2f755dc1f61389df1a606fa6763a2b7 Mon Sep 17 00:00:00 2001 From: Lixi20 Date: Tue, 8 Sep 2026 14:47:29 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20M2=20=E6=94=B6=E5=AE=98=E2=80=94?= =?UTF-8?q?=E2=80=94E2E=20=E7=83=9F=E5=9B=B1=E6=8A=A5=E5=91=8A=E4=B8=8E?= =?UTF-8?q?=E6=94=B6=E5=AE=98=E6=80=BB=E7=BB=93=E5=85=A5=E6=A1=A3=EF=BC=8C?= =?UTF-8?q?=E9=AA=8C=E6=94=B6=20PASSED?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 28 E2E 烟囱:11/11 场景全绿、契约偏差 0、四条验收标准全过(真机两项方案 A 挂起) - 29 收官总结:终态对照开工基线(测试 82/34→191/272、契约 5→18 路径冻结、 ADR 001~015、生产埋点从零到贯通)、遗留清单与 M3 方向输入 - 看板终态更新 Co-Authored-By: Claude Fable 5 --- .../iteration-2/28-e2e-smoke-report.md | 407 ++++++++++++++++++ .../iterations/iteration-2/29-m2-summary.md | 72 ++++ .../iterations/iteration-2/index.md | 9 +- mkdocs.yml | 2 + 4 files changed, 486 insertions(+), 4 deletions(-) create mode 100644 docs/development/iterations/iteration-2/28-e2e-smoke-report.md create mode 100644 docs/development/iterations/iteration-2/29-m2-summary.md diff --git a/docs/development/iterations/iteration-2/28-e2e-smoke-report.md b/docs/development/iterations/iteration-2/28-e2e-smoke-report.md new file mode 100644 index 0000000..d673642 --- /dev/null +++ b/docs/development/iterations/iteration-2/28-e2e-smoke-report.md @@ -0,0 +1,407 @@ +# 28 M2 收官:E2E 烟囱测试报告(T2-18) + +- 执行人:Frontend Developer +- 日期:2026-09-08 +- 环境:patbond-flutter (dev 分支) + patbond-api (docker compose 编排,代码零改动) +- 测试脚本:`patbond-flutter/test_e2e_m2_manual.dart`(commit `720865b`,已推送 origin/dev) +- 参照模式:iteration-1/18 号收官报告(格式与取证标准沿用) + +--- + +## 0. 执行概要 + +### 测试目标 + +M2 第四波收官(工单 T2-18):在 compose 真实后端上跑通 M2 完整链路烟囱并收集证据—— +登录 → 建档 → 记体重 → 登记疫苗 → 记健康事件 → 摘要数值核对 → 第二账号访问被拒 → +第二设备同账号全量读回,外加埋点落库与乐观锁冲突两条链路。 + +### 测试结果 + +**✓ 11/11 场景全部通过**(单次运行一次通过;格式化后复跑再次 11/11) + +- Docker Compose 四容器健康运行(postgres + auth:8081 + user:8082 + pet:8083) +- 契约一致性:响应字段、错误码、HTTP 状态码与冻结契约 openapi v1.2.0 完全一致 +- **契约偏差数:0 个** +- Flutter 门禁三命令全绿:`dart format`(0 changed)/ `flutter analyze`(No issues)/ + `flutter test`(**272 passed**) +- 数据库证据齐备:`pet_health` 六表 + `platform.product_events` psql 查证一致 + +### ⚠️ 真机挂起项(显著标注:真机待补验) + +真机不可用(用户确认),以下两项按既定方案 A 挂起,**本报告不含其证据**, +待真机可用后补验: + +| # | 挂起项 | 说明 | +| --- | --- | --- | +| 1 | **Android 真机事件落库观察** | 本报告以脚本直连 `/api/v1/events`(platform=android 模拟真机值)替代验证服务端链路;真机端 AnalyticsClient → 持久化队列 → 上报的端上链路待真机补验 | +| 2 | **SessionTracker 30min 会话超时手测** | 前后台切换超时重建 sessionId 的真机手测;单元测试已覆盖规则(T2-15),真机行为待补验 | + +### 脱敏声明 + +全部 token 截断至前 20 字符 + ``;密码不出现在任何输出;`.env` 内容未引用。 + +--- + +## 1. 后端启动与健康检查 + +### 1.1 构建与启动(patbond-api 代码零改动) + +```bash +cd patbond-api +JAVA_HOME=/usr/lib/jvm/java-17-openjdk ./mvnw -DskipTests package +# BUILD SUCCESS + +docker compose up -d --build +# Container patbond-postgres-1 Healthy +# Container patbond-auth-1 Started +# Container patbond-user-1 Started +# Container patbond-pet-1 Started +``` + +### 1.2 容器健康状态 + +```text +NAMES STATUS PORTS +patbond-pet-1 Up 12 seconds 0.0.0.0:8083->8083/tcp +patbond-auth-1 Up 12 seconds 0.0.0.0:8081->8081/tcp +patbond-user-1 Up 12 seconds 0.0.0.0:8082->8082/tcp +patbond-postgres-1 Up 15 seconds (healthy) 5432/tcp +``` + +### 1.3 服务就绪验证 + +```bash +docker logs patbond-pet-1 | grep Started +# Started PetApplication in 6.286 seconds + +curl -s http://127.0.0.1:8083/api/v1/pets +# {"code":40101,"message":"token 无效或过期","data":null} ← 无 token 预期 401 +curl -s http://127.0.0.1:8082/api/v1/me +# {"code":40101,"message":"token 无效或过期","data":null} +``` + +--- + +## 2. E2E 烟囱测试执行记录(11 场景) + +### 2.1 测试脚本 + +`test_e2e_m2_manual.dart`(纯 dart HttpClient 脚本,无 Flutter 运行时依赖, +与第一迭代 `test_e2e_manual.dart` 并列放仓库根目录,**不在 test/ 目录**、 +不进 `flutter test`)。随机生成账号 `e2e_m2_a_` / `e2e_m2_b_` +避免冲突。运行方式:`docker compose up -d` 后 `dart run test_e2e_m2_manual.dart`。 + +本次取证运行:账号 A `e2e_m2_a_1788849543120`,petId `01a07fbd-dcad-756a-a844-fe5323aa0713`。 + +### 2.2 场景 1:注册账号 A → 登录 + +```text +[1/11] 注册账号 A → 登录 + POST /api/v1/auth/register → 200 + ✓ 注册成功 + userId(A): 01a07fbd-d92f-7ee7-a52c-d33c7fa80071 + accessToken: eyJhbGciOiJSUzI1NiJ9... + POST /api/v1/auth/login → 200 + ✓ 登录成功(设备 1 会话) +``` + +### 2.3 场景 2:建档(含品种)→ 列表/详情读回核对 + +```text +[2/11] 建档(POST /pets,含品种)→ 列表/详情读回核对 + GET /api/v1/breeds?species=dog → 200 + ✓ 品种目录返回 16 条 + 选用品种: 中华田园犬 (3a545503-a8ad-484a-8bbf-a38d08c6dcea) + POST /api/v1/pets → 201 + ✓ 建档成功(201) + petId: 01a07fbd-dcad-756a-a844-fe5323aa0713 + myRole: owner / version: 0 / breedDisplayName: 中华田园犬 + ✓ 创建者角色为 owner + ✓ 品种展示名解出一致 + GET /api/v1/pets → 200 + ✓ 列表读回 1 只宠物且 id 一致 + GET /api/v1/pets/{petId} → 200 + ✓ 详情读回核对通过(name/species/breedId/status) +``` + +契约验证:201 + PetEnvelope、`myRole=owner`(创建者自动 primary owner)、 +`breedDisplayName` 由字典解出、petId 为 UUIDv7(前缀 `01a07fbd`)。 + +### 2.4 场景 3:记体重 ×2 → cursor 分页读回 + +```text +[3/11] 记体重 ×2 → 列表 cursor 分页读回 + POST /weights (8.20kg, 2026-09-06T06:39:04.429336Z) → 201 + POST /weights (8.45kg, 2026-09-07T06:39:04.429336Z) → 201 + GET /weights?limit=1 → 200 + ✓ 第一页:最新体重 8.45kg 在前,hasMore=true,nextCursor 非空 + GET /weights?limit=1&cursor=... → 200 + ✓ 第二页:8.20kg,hasMore=false,nextCursor=null +``` + +契约验证:分页正典形态 `{items, nextCursor, hasMore}`;`measured_at DESC` 排序; +末页 `nextCursor` 恒为 null。 + +### 2.5 场景 4:登记疫苗(scheduled)→ 标记完成(乐观锁) + +```text +[4/11] 登记疫苗(scheduled)→ 标记完成(PATCH + version) + GET /api/v1/vaccine-catalog?species=dog → 200 + ✓ 疫苗目录返回 6 条 + 选用疫苗: 犬二联疫苗 (e07d9a48-a8d3-4b6a-a14b-03a42fe85589) + POST /vaccinations (scheduled, plannedOn=2026-09-08) → 201 + vaccinationId: 01a07fbd-ddc2-7dc8-aa2e-768a51785dc7 / version: 0 + PATCH /vaccinations/{id} (→completed, version=0) → 200 + ✓ 标记完成成功,version 0→1,administeredOn/nextDueOn 回读一致 +``` + +契约验证:`scheduled → completed` 状态机合法迁移;`version` 提交比对通过后 +1; +`vaccineName` 由目录解出;`administeredOn=2026-09-08`、`nextDueOn=2027-09-08` 原样回读。 + +### 2.6 场景 5:记健康事件(金额整数分)→ 时间线读回 + +```text +[5/11] 记健康事件(amountCents 整数分)→ 时间线读回 + POST /health-events (medical, amountCents=12500) → 201 + ✓ amountCents=12500 原样回读,createdByUserId=token subject + healthEventId: 01a07fbd-de0a-7532-8d71-023452ba21ad + GET /health-events → 200 + ✓ 时间线读回 1 条且字段一致 +``` + +契约验证:金额整数分传输无精度损耗;`createdByUserId` 取自验签 token +(等于账号 A userId),不收请求体。 + +### 2.7 场景 6:创建提醒 → 标记完成(completedAt 校验) + +```text +[6/11] 创建提醒 → 标记完成(completedAt 校验) + POST /care-reminders (deworming, dueAt=2026-10-08T06:39:04.429336Z) → 201 + ✓ 提醒创建成功,恒为 pending 且 completedAt=null + reminderId: 01a07fbd-de48-779f-87f6-11135ae93be7 + PATCH /care-reminders/{id} (→completed) → 200 + ✓ 标记完成成功,completedAt=2026-09-08T06:39:04.429336Z(客户端提交时刻回读) +``` + +契约验证:创建恒为 `pending`(不收 status);`completedAt` 由客户端提交、 +非空当且仅当 `status=completed`。 + +### 2.8 场景 7:摘要四项聚合逐项断言 + +```text +[7/11] GET /summary?tz=Asia/Shanghai 四项聚合逐项断言 + GET /summary → 200 + ✓ 最新体重 = 8.45kg(第二条写入,measured_at DESC 首行) + ✓ 疫苗进度 = 1/1(scheduled→completed 后) + ✓ 下次接种 = completed 行的 nextDueOn(2027-09-08,source=nextDue) + ✓ 当月花费 = 12500 分,month=2026-09,timezone 回显 Asia/Shanghai +``` + +四项聚合与前述写入逐项一致(口径 = iteration-2 报告 18 §3 定型表): + +| 聚合项 | 前述写入 | 摘要返回 | 结论 | +| --- | --- | --- | --- | +| latestWeight | 8.45kg(measured_at 最新) | weightKg=8.45 | ✓ | +| vaccinationProgress | 1 条 completed / 1 条已登记 | completedDoses=1, totalDoses=1 | ✓ | +| nextVaccination | completed 行 nextDueOn=2027-09-08 | dueOn=2027-09-08, source=nextDue, vaccinationId 命中 | ✓ | +| monthlyExpense | amountCents=12500(当月事件) | amountCents=12500, month=2026-09, timezone=Asia/Shanghai | ✓ | + +### 2.9 场景 8:权限拒绝——账号 B 访问 A 的宠物四路(防枚举) + +```text +[8/11] 注册账号 B → 用 B 的 token 访问 A 的宠物四路(防枚举核对) + POST /api/v1/auth/register (B) → 200 + 详情 GET /pets/{id} → 404 / code 40401 ✓ + 体重 GET /pets/{id}/weights → 404 / code 40401 ✓ + 疫苗 GET /pets/{id}/vaccinations → 404 / code 40401 ✓ + 摘要 GET /pets/{id}/summary → 404 / code 40401 ✓ + ✓ 四路响应体完全一致(防枚举):{"code":40401,"message":"宠物不存在","data":null} + ✓ B 的宠物列表为空(列表天然隔离) +``` + +契约验证:无关系调用者与「宠物不存在」响应逐字节一致,随机探测 UUID 无法区分 +是否命中真实记录(防枚举语义)。 + +### 2.10 场景 9:跨设备读取——账号 A 重新登录全量读回 + +```text +[9/11] 账号 A 重新登录(模拟第二设备新会话)→ 全量数据读回 + POST /api/v1/auth/login (设备 2) → 200 + ✓ 新会话 token 与设备 1 不同(独立 token family) + ✓ 宠物列表:1 只(旺财M2) + ✓ 体重记录:2 条 + ✓ 疫苗记录:1 条(completed) + ✓ 健康事件:1 条 + ✓ 提醒:1 条(completed,completedAt=2026-09-08T06:39:04.429336Z) +``` + +设备 1 写入的全部五类数据在设备 2 新会话完整读回,服务端为唯一事实源。 + +### 2.11 场景 10:埋点链路——v2 事件上报与落库 + +```text +[10/11] POST /api/v1/events 上报 v2 事件(platform=android 模拟真机值) + eventId: 0c673914-... (pet_create_succeeded) + eventId: dd59a83a-... (health_record_create_succeeded, recordType=weight) + eventId: 3993beb4-... (health_record_create_succeeded, recordType=vaccine) + eventId: 87a4a82b-... (page_viewed) + POST /api/v1/events (4 条) → 202 + ✓ 4/4 逐条 accepted(accepted=4, duplicated=0, rejected=0) +``` + +**落库查证(docker exec psql)**: + +```text +patbond=# SELECT event_name, event_version, platform, user_id, + left(event_id::text,8) AS event_id_prefix, props + FROM platform.product_events + WHERE session_id = '4d8375a7-ec77-45bf-90d6-1b7eff73a1ff' + ORDER BY event_name; + + event_name | event_version | platform | user_id | event_id_prefix | props +--------------------------------+---------------+----------+--------------------------------------+-----------------+------------------------------------------------------- + health_record_create_succeeded | 2 | android | 01a07fbd-d92f-7ee7-a52c-d33c7fa80071 | dd59a83a | {"durationMs": 640, "recordType": "weight"} + health_record_create_succeeded | 2 | android | 01a07fbd-d92f-7ee7-a52c-d33c7fa80071 | 3993beb4 | {"durationMs": 820, "recordType": "vaccine"} + page_viewed | 2 | android | 01a07fbd-d92f-7ee7-a52c-d33c7fa80071 | 87a4a82b | {"pageName": "pet_detail", "referrer": "pet_list"} + pet_create_succeeded | 2 | android | 01a07fbd-d92f-7ee7-a52c-d33c7fa80071 | 0c673914 | {"species": "dog", "petIndex": 1, "durationMs": 1200} +(4 rows) +``` + +4 条 v2 事件全部落 `platform.product_events`,eventId、props 白名单键、 +platform=android、user_id 归因逐项一致。(真机端上链路见 §0 挂起项 1。) + +### 2.12 场景 11:乐观锁冲突明确性 + +```text +[11/11] 两次 PATCH 宠物档案提交同一 version → 第二次 409/40902 + PATCH /pets/{id} (version=0, 第一次) → 200 + ✓ 第一次 PATCH 成功,version 0→1 + PATCH /pets/{id} (同一过期 version=0, 第二次/设备 2) → 409 + ✓ 第二次被明确拒绝:409/40902(数据已被修改,请刷新后重试),先写者数据保留 + ✓ 读回确认先写者数据保留(personality=沉稳) +``` + +契约验证:不静默覆盖;先写者胜出;后写者得到明确的 409/40902 与可行动 message。 +(Flutter 端对 40902 的「明确提示 + 取新 version 重提」交互已有 widget 测试覆盖, +见 `test/features/pets/pet_form_page_test.dart`。) + +--- + +## 3. 数据库查询证据(pet_health schema) + +```text +patbond=# SELECT name, species, status, version, personality FROM pet_health.pets WHERE id = '01a07fbd-...0713'; + name | species | status | version | personality +--------+---------+--------+---------+------------- + 旺财M2 | dog | active | 1 | 沉稳 + +patbond=# SELECT role, is_primary FROM pet_health.pet_owners WHERE pet_id = ...; + role | is_primary +-------+------------ + owner | t + +patbond=# SELECT weight_kg, measured_at FROM pet_health.pet_weight_records WHERE pet_id = ... ORDER BY measured_at DESC; + weight_kg | measured_at +-----------+------------------------------- + 8.45 | 2026-09-07 06:39:04.429336+00 + 8.20 | 2026-09-06 06:39:04.429336+00 + +patbond=# SELECT status, dose_no, administered_on, next_due_on, version FROM pet_health.pet_vaccinations WHERE pet_id = ...; + status | dose_no | administered_on | next_due_on | version +-----------+---------+-----------------+-------------+--------- + completed | 1 | 2026-09-08 | 2027-09-08 | 1 + +patbond=# SELECT event_type, title, amount_cents FROM pet_health.health_events WHERE pet_id = ...; + event_type | title | amount_cents +------------+-------------+-------------- + medical | M2 烟囱体检 | 12500 + +patbond=# SELECT reminder_type, status, completed_at FROM pet_health.care_reminders WHERE pet_id = ...; + reminder_type | status | completed_at +---------------+-----------+------------------------------- + deworming | completed | 2026-09-08 06:39:04.429336+00 +``` + +验证点:全部数据持久化落库;`pets.version=1`(一次成功 PATCH 后)与 40902 拒绝语义 +互证;`amount_cents` 整数分无损;`completed_at` 与 API 回读一致。 + +--- + +## 4. Flutter 门禁验证(三命令随行取证) + +### 4.1 格式化检查 + +```bash +dart format --output=none --set-exit-if-changed lib test +# Formatted 97 files (0 changed) in 0.39 seconds. +# EXIT: 0 +``` + +### 4.2 静态分析 + +```bash +flutter analyze +# Analyzing patbond-flutter... +# No issues found! (ran in 0.9s) +``` + +(含根目录两个 E2E 脚本在内全仓 0 issues;两脚本头部 `ignore_for_file: avoid_print`。) + +### 4.3 单元/组件测试 + +```bash +flutter test +# 00:17 +272: All tests passed! +``` + +**✓ 272 个测试全部通过**(E2E 脚本在仓库根目录,不被 `flutter test` 收集)。 + +--- + +## 5. M2 四条验收标准逐条对照 + +| # | 验收标准 | 证据 | 结论 | +| --- | --- | --- | --- | +| 1 | **跨设备数据一致**:同账号第二设备读到全部数据 | 场景 9:设备 2 新会话读回宠物/体重×2/疫苗/事件/提醒全量一致;§3 psql 证实服务端持久化 | ✓ 通过 | +| 2 | **无权限访问被拒**:他人宠物不可见 | 场景 8:账号 B 四路全部 404/40401 且响应体逐字节一致(防枚举);B 列表为空 | ✓ 通过 | +| 3 | **并发冲突明确**:不静默覆盖 | 场景 4(疫苗 version 0→1)+ 场景 11(同 version 二次 PATCH → 409/40902,读回证实先写者保留);前端 40902 交互有 widget 测试 | ✓ 通过 | +| 4 | **双端测试齐备** | 后端:compose 真实链路 11 场景全绿 + 契约测试基线(报告 20);前端:272 单元/组件测试全绿 + 门禁三命令 0 偏差 | ✓ 通过(真机两项挂起,见 §0) | + +## 6. 契约偏差声明 + +**契约偏差数:0 个。** + +本次烟囱对照冻结契约 openapi v1.2.0(报告 19 冻结)逐场景核验:HTTP 状态码 +(200/201/202/404/409)、业务错误码(40401/40902)、信封结构 `{code, message, data}`、 +分页正典形态、乐观锁语义、防枚举响应体、埋点逐条结果语义,全部一致,无需修复项。 + +--- + +## 7. 环境清理 + +```bash +cd patbond-api && docker compose down +# Container patbond-pet-1 / patbond-auth-1 / patbond-user-1 / patbond-postgres-1 Removed +# Network patbond_default Removed +``` + +## 8. 工作仓库状态 + +- patbond-flutter dev:`720865b` `test: M2 E2E 烟囱脚本(T2-18 收官)` 已推送 origin/dev +- patbond-api:**代码零改动**(仅 compose 起停) +- patbond-doc:本报告(28 号),提交与 mkdocs 导航由 T2-19 文档收口统一处理 + +## 9. 遗留清单 + +1. **真机待补验 ×2**(见 §0 显著标注):Android 真机事件落库观察、SessionTracker + 30min 会话超时手测——真机可用后按方案 A 补验并追加证据。 +2. caregiver/viewer 角色的 403/40300 路径本次未走(M2 无邀请入口,T2-10 已用 + 测试数据直构场景覆盖,见报告 20),烟囱层面留待 M3 邀请流程落地后自然覆盖。 +3. E2E 脚本可在 M3 纳入 CI 定期回归(当前为手动验收工具,与第一迭代建议一致)。 + +--- + +**Frontend Developer** +日期:2026-09-08 +验收状态:**PASSED**(11/11 场景,契约偏差 0,M2 四条验收标准全部通过;真机两项挂起待补验) diff --git a/docs/development/iterations/iteration-2/29-m2-summary.md b/docs/development/iterations/iteration-2/29-m2-summary.md new file mode 100644 index 0000000..411e798 --- /dev/null +++ b/docs/development/iterations/iteration-2/29-m2-summary.md @@ -0,0 +1,72 @@ +# 29 M2 收官总结:宠物健康档案 + +**迭代周期**:2026-09-07 ~ 2026-09-08(开工分析 + 四波交付) +**验收结论**:**PASSED**(E2E 烟囱 11/11、契约偏差 0、M2 四条验收标准全过;真机两项按方案 A 挂起待补验) + +--- + +## 0. 终态对照开工基线(07 号基线快照) + +| 维度 | 开工基线(2026-09-07) | 收官终态(2026-09-08) | +| --- | --- | --- | +| patbond-api 测试 | 82 | **191**(+109) | +| patbond-flutter 测试 | 34 | **272**(+238) | +| openapi.yaml | v1.0.0,5 路径 | **v1.2.0 冻结**,18 路径/24 操作/45 schema,契约测试锁定零漂移 | +| Flyway | V1/V2 | V1~V4(pet_health 8 表 + 字典种子) | +| 后端模块 | common/auth/user | + **patbond-pet**(:8083,ADR-009) | +| ADR | 001~008 | **001~015** | +| 错误码 | 基础段 | +8(40300/40401/40402/40902/40903/40904/42201/42202) | +| 档案功能 | Flutter demo 数据 | 全页面族真实后端,demo 消亡 | +| 生产埋点事件流 | **恒为零**(接线断链) | 端到端贯通,字典 v2 13 事件,分段持久化队列 | +| 迭代报告 | — | 29 份入档挂导航,strict 全程通过 | + +开工时的 2 个证据缺口均闭环:events 契约缺口第一波补录(v1.1.0);CI 全绿不可复核经 Gitea commit status API 建立实查惯例。 + +## 1. 交付主线回顾 + +- **开工分析**(报告 01~08):8 角色并行评估 + 正式 Reality Checker/Experiment Tracker 复核接管;CONDITIONAL PASS 5 项放行条件;ADR-009~015 拍板 +- **第一波**(09~12):M1 埋点债清偿(含收口期热修 5 项)+ V3/V4 + pet 骨架;放行条件①②④⑤闭环 +- **第二波**(13~21):pets 域 18 操作后端纵切 + 契约冻结 v1.2.0 + 契约一致性测试(抓修 1 漂移) +- **第三波**(22~27):Flutter 四态页面族接入 + 埋点端到端 + DEBT-1 偿还;三次 compose 实测零偏差 +- **第四波**(28~29):E2E 烟囱 11 场景收官取证 + 文档收口 + +## 2. M2 四条验收标准证据索引 + +| 标准 | 证据 | +| --- | --- | +| 跨设备读取 | 28 号场景 9(新会话五类数据全量读回)+ pet_health 六表 psql 证据 | +| 无权限拒绝 | 28 号场景 8(第二账号四路 404/40401 响应逐字节一致防枚举) | +| 并发冲突明确 | 28 号场景 4/11(40902 + 先写者保留)+ 前端自动重提 widget 测试 | +| 双端测试齐备 | 后端 191 + 前端 272 全绿;契约测试全响应矩阵;门禁三命令 0 偏差 | + +## 3. 协作模式沉淀(本迭代新验证项) + +- **迭代式契约冻结**:草案先行(TODO-FREEZE 标注)→ 实现定型表回填 → 拍板 → 冻结合入 + 字节级快照锁 CI——比第一迭代的一次性冻结更适应多工单纵切 +- **同仓串行、跨仓并行**的派工纪律避免了全部工作树冲突;agent 中断续跑(半成品检查 + 断点续作)实战有效 +- 实测取证纪律延续:每波 compose 实测、收官烟囱脚本化、证据脱敏入档 + +## 4. 遗留与 M3 建议 + +**挂起待补验(真机到位后,预计 0.5 天)**:Android 事件落库观察、SessionTracker 30 分钟手测(脚本在 10 号报告 §5)。 + +**M2 范围内遗留**: +1. T2-12 §8 三项交互待拍板:单宠直进/切换器、归档入口(listPets 过滤语义)、sterilizedOn 编辑 +2. auth 域契约测试补齐(机制可复用,S) +3. 埋点队列完善:30s 定时冲刷、退避/429(依赖后端限流)、anonymousId 持久化(15 号 §4) +4. 09 号契约-实现出入 5 项排期评估(64KB 上限、429 限流等) + +**跨迭代遗留(承自 M1,未变化)**:access token 黑名单、/internal 改 mTLS。 + +**M3 方向输入**: +- 照片/media 域(ADR-010 剪出项:对象存储选型 → 上传流程 → 宠物头像/疫苗证书/事件附件;health_event_media 表补建) +- 照护人邀请/绑定流程(ADR-015 后置项,权限框架已就绪) +- 北极星与 H1~H4 假设开始出数(首记日 +8 天成熟,对账 SQL 见 06 号 §6);A/B 前置 8 项按 06 号 §路线推进(目标 M3 末全绿) +- health_record_deleted 事件随删除端点设计 + +## 5. 收官提交索引 + +| 仓库 | 收官 HEAD | CI | +| --- | --- | --- | +| patbond-api | dev@64c9b72(191 测试) | success | +| patbond-flutter | dev@720865b(272 测试 + E2E 脚本) | 待本提交 CI | +| patbond-doc | 本收口提交(29 报告 + 看板终态) | strict 通过 | diff --git a/docs/development/iterations/iteration-2/index.md b/docs/development/iterations/iteration-2/index.md index 9450089..93dbaa3 100644 --- a/docs/development/iterations/iteration-2/index.md +++ b/docs/development/iterations/iteration-2/index.md @@ -1,7 +1,7 @@ # 第二迭代进展看板 > 目标:M2 宠物健康档案——宠物 CRUD + owner/caregiver/viewer 权限 + 体重/疫苗/健康事件/提醒 + 档案聚合,Flutter 档案页全量替换 demo 数据,依据[开发实施计划](../../development-plan.md)第 7 节。 -> 更新日期:2026-09-08(第三波收口,待第四波 E2E 收官)。本页是团队共享的进度事实来源,每波工作交付后更新。 +> 更新日期:2026-09-08(**M2 收官,验收 PASSED**)。本页是团队共享的进度事实来源。 ## 当前状态一览 @@ -10,8 +10,8 @@ | ✅ 第一波 | M1 遗留埋点清偿(接线/SessionTracker/page_viewed/持久化队列前置)+ 契约补录 events + Flyway V3/V4 + patbond-pet 骨架 | | ✅ 第二波 | 后端接口纵切 T2-03~08(pets 域 18 操作)+ 契约冻结 v1.2.0 + 契约一致性测试入 CI | | ✅ 第三波 | Flutter 页面接入 T2-11~14(档案 demo 数据消亡、四态齐备)+ 埋点字典 v2 端到端 + DEBT-1 偿还 | -| 🔜 第四波 | T2-18 E2E 烟囱收官战(需真机/联调配合)→ T2-19 收官总结 | -| ⚠️ 遗留 | 真机补验(Android 事件落库 + SessionTracker 30min,第一波方案 A 挂起);T2-12 §8 三项交互待拍板;auth 域契约测试;埋点队列完善(30s 定时冲刷/退避/anonymousId 持久化) | +| ✅ 第四波 | E2E 烟囱 11/11 全绿、契约偏差 0、M2 四条验收标准全过(报告 28);收官总结见报告 29 | +| ⚠️ 遗留 | 真机补验(Android 事件落库 + SessionTracker 30min,方案 A 挂起);T2-12 §8 三项交互待拍板;auth 域契约测试;埋点队列完善——完整清单见报告 29 §4 | ## 测试与契约演进 @@ -20,7 +20,8 @@ | M2 开工基线 | 82 | 34 | v1.0.0(5 路径) | | 第一波收口 | 95 | 51 | v1.1.0(+events) | | 第二波收口 | 182 | 64 | **v1.2.0 冻结**(18 路径/24 操作/45 schema) | -| 第三波收口 | **191** | **272** | v1.2.0(契约测试锁定零漂移) | +| 第三波收口 | 191 | 272 | v1.2.0(契约测试锁定零漂移) | +| **收官(E2E 后)** | **191** | **272**(+E2E 烟囱脚本) | v1.2.0(E2E 逐场景核验偏差 0) | ## 已完成(附提交) diff --git a/mkdocs.yml b/mkdocs.yml index 186b3a3..4c5406c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -59,6 +59,8 @@ nav: - 25 体重疫苗模块: development/iterations/iteration-2/25-weights-vaccines-ui-report.md - 26 时间线与提醒页: development/iterations/iteration-2/26-timeline-reminders-report.md - 27 第三波收口: development/iterations/iteration-2/27-wave3-closure.md + - 28 E2E 烟囱收官: development/iterations/iteration-2/28-e2e-smoke-report.md + - 29 M2 收官总结: development/iterations/iteration-2/29-m2-summary.md - API: - 契约说明: api/index.md - 架构: