Files
patbond-doc/docs/development/iterations/iteration-2/01-pm-task-breakdown.md
T
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

347 lines
28 KiB
Markdown
Raw 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.
# Patbond 第二迭代任务分解(M2 宠物健康档案)
> 作者:Senior Project Manager
> 日期:2026-09-07
> 依据:`patbond-doc/docs/development/development-plan.md`(第 7 节 M2、第 6.2 节 Pets 接口、第 9/10 节质量门禁与 DoD)、`iterations/iteration-1/20-iteration-1-summary.md`(收官总结与遗留清单)、`docs/architecture/decisions.md`ADR-001~008)、`docs/database/patbond_postgresql.sql``pet_health` schema 8 张表)
> 编号约定:本迭代工单以 `T2-` 前缀编号(T2-01 起),避免与第一迭代 T0-x/T1~T12 冲突。
> 范围声明:严格限定为 M2 宠物健康档案。社区(M3)、AI 创作(M4)、预约(M5)不在本迭代范围;发现范围外需求一律记入 backlog。
---
## 1. 范围界定与依据
### 1.1 开发计划 M2 原文(正典依据)
开发计划第 7 节 M2 定义(引用原文要点):
- 目标:"替换 Flutter 档案页的本地宠物和疫苗数据。"
- "实现宠物、照护权限、体重、疫苗、健康事件和提醒接口。"
- "校验当前用户对宠物的 owner/caregiver/viewer 权限。"
- "Flutter 接入真实列表、详情、编辑、加载、空态和错误态。"
- "体重、疫苗进度、下次接种和月度花费从事实表聚合生成。"
- 验收标准:"数据可跨设备读取;无权限用户不能访问宠物;并发更新返回明确冲突;关键流程具备 API 集成测试和 Flutter 组件测试。"
第 6.2 节第一批接口中属于本迭代的端点:
| 端点 | 用途 |
| --- | --- |
| `GET/POST /api/v1/pets` | 查询、新建宠物 |
| `GET/PATCH /api/v1/pets/{petId}` | 宠物详情与更新 |
| `GET/POST /api/v1/pets/{petId}/weights` | 体重记录 |
| `GET/POST/PATCH /api/v1/pets/{petId}/vaccinations` | 疫苗记录 |
| `GET/POST /api/v1/pets/{petId}/health-events` | 健康时间线 |
数据模型依据:`pet_health` schema 共 8 张表(breeds、pets、pet_owners、pet_weight_records、vaccine_catalog、pet_vaccinations、health_events、health_event_media、care_reminders——含关联表 9 个对象),字段、约束、状态机均已在 bootstrap SQL 定稿评审。
### 1.2 与第一迭代总结口径的差异(须拍板,见 §4)
第一迭代总结把 M2 目标写为"档案 CRUD、照片管理、体重/**体温**记录、疫苗/驱虫提醒",与开发计划 M2 原文存在三处扩张,PM 逐条对照数据模型后的结论:
1. **照片管理**`pets.avatar_asset_id``pet_vaccinations.certificate_asset_id``health_event_media` 均引用 `media.assets`,但媒体上传流程(M1 后半段的 `POST /api/v1/media/uploads`)第一迭代未实现,且**对象存储供应商至今未拍板**(第一迭代决策清单 D4 遗留)。照片管理不是 M2 原文要求,纳入与否见决策 D2-1。
2. **体温记录**`pet_health` schema **没有体温表**。最接近的承载是 `health_events``measurement` 事件类型。是否需要结构化体温数据见决策 D2-4,本拆解默认不建新表。
3. **驱虫提醒**:数据模型已支持(`health_events.event_type='deworming'` + `care_reminders.reminder_type='deworming'`),属 M2 原文"提醒接口"范围内,纳入。
### 1.3 本迭代 MVP 范围(PM 建议口径,待 §4 拍板确认)
- **纳入**:宠物 CRUD(含品种目录)、pet_owners 权限校验框架、体重记录、疫苗记录(含疫苗目录、系列/剂次、scheduled→completed 状态机)、健康事件时间线、照护提醒(app 内列表,无推送)、四项聚合(最新体重、疫苗进度、下次接种、月度花费)、Flutter 档案页全量替换真实数据、两项高优先遗留埋点。
- **默认剪出(待拍板)**:照片/媒体上传、体温专表、共同照护人邀请流程(权限**校验**必须实现,邀请**交互**可后置)、提醒推送通知(通知系统属 M6)。
---
## 2. 工单列表
预估规模口径沿用第一迭代:S ≈ 半天内,M ≈ 1-2 天,L ≈ 3-5 天(含测试与文档)。
### A 组:数据与工程基础(后端)
#### T2-01 Flyway V3pet_health schema baseline 与种子数据分离
- **仓库**patbond-api(迁移脚本),patbond-doc(迁移说明)
- **描述**:从 bootstrap SQL 提取 `pet_health` 全部表结构为 Flyway V3 迁移;breeds、vaccine_catalog 的开发种子数据独立为不进生产的脚本(沿用第一迭代 identity/media 的做法)。
- **关键技术裁剪(必须遵守)**bootstrap SQL 第 1156~1166 行为 `pet_vaccinations`/`health_events``provider_id``booking_id` 增加了指向 `marketplace.providers`/`marketplace.bookings` 的外键。marketplace schema 属 M5,本迭代**不迁移**V3 必须**剥离这四条跨 schema 外键**(字段保留为裸 uuid 可空列),M5 迁移 marketplace 时再以新版本迁移补回。同理 `updated_at` 触发器依赖的公共函数需确认已在 V1 建立或随 V3 建立。
- **验收标准**
- 全新 postgres:18Testcontainers)上 V1→V2→V3 全量迁移一次成功,表结构与 bootstrap SQL 一致(跨 schema 外键除外,差异写入迁移说明)。
- 种子数据脚本与结构迁移分离,不进正式环境。
- `./mvnw clean test` 全绿(既有 82 测试不回归)。
- **依赖**:无(第一波首项)。
- **规模**M
#### T2-02 宠物健康后端模块骨架与鉴权接入
- **仓库**patbond-api
- **描述**:按开发计划 4.1 节"按迭代增加宠物健康模块;模块边界与数据库 schema 对齐",建立宠物健康业务模块(新建 Maven 模块 vs 并入现有服务见决策 D2-2,未拍板前先按 PM 建议方案搭骨架);复用第一迭代 JWT 资源侧校验,实现"当前用户"解析注入;模块只读写 `pet_health` schema。
- **验收标准**
- 模块编译入构建链,`./mvnw clean test` 全绿。
- 携带有效 access token 的请求能解析出当前用户 UUID;无 token / 过期 token 返回 401 + 既有错误码契约(40100 系)。
- Docker Compose 编排同步纳入新模块(若 D2-2 选独立服务)。
- **依赖**:D2-2 拍板(可先按建议方案开工,方案变更成本在骨架期最低)。
- **规模**M
### B 组:后端接口纵切
#### T2-03 宠物 CRUD 与 pet_owners 权限框架
- **仓库**patbond-api
- **描述**:实现 `GET/POST /api/v1/pets``GET/PATCH /api/v1/pets/{petId}` 与品种目录查询(breeds 只读列表,按 species 过滤)。创建宠物时当前用户自动成为 `pet_owners` 的 primary owner;所有 `/pets/**` 请求经统一权限校验(owner/caregiver 可写、viewer 只读、无关系 404/403,语义在契约中定死);`PATCH` 使用 `version` 乐观锁,冲突返回明确错误码;`status` 流转(active/archived 等)按数据库约束实现;软删除语义遵守 `ck_pets_deleted` 约束。
- **验收标准**
- 创建→列表→详情→更新→归档全链路走真实 PostgreSQL,重启不丢数据。
- 无权限用户访问他人宠物被拒绝(错误码与 HTTP 状态码在契约定死并有测试)。
- 并发更新(version 过期)返回明确冲突错误,有集成测试。
- breed_id 与 custom_breed_name 互斥校验(`ck_pets_breed`)应用层与数据库一致。
- **依赖**T2-01、T2-02。
- **规模**L
#### T2-04 体重记录接口
- **仓库**patbond-api
- **描述**`GET/POST /api/v1/pets/{petId}/weights`。列表 cursor 分页(`measured_at DESC, id DESC`,与既有索引对齐);创建校验 `weight_kg` 区间(>0 且 ≤500);写接口支持 `Idempotency-Key`(第 6.1 节要求)。
- **验收标准**
- 分页不丢失不重复;参数越界返回规范错误体。
- 相同 Idempotency-Key 重试不产生重复记录,有测试。
- 权限校验复用 T2-03 框架(viewer 只读)。
- **依赖**T2-03。
- **规模**M
#### T2-05 疫苗目录与疫苗记录接口
- **仓库**patbond-api
- **描述**vaccine_catalog 只读查询(按 species);`GET/POST/PATCH /api/v1/pets/{petId}/vaccinations`series_key + dose_no 唯一性(非 cancelled)、scheduled/completed/cancelled 状态机及日期约束(`ck_vaccination_dates`)、`next_due_on` 维护、`version` 乐观锁。`certificate_asset_id``provider_id``booking_id` 本迭代不开放写入(照片待 D2-1、预约属 M5),字段在契约中不出现或标记只读。
- **验收标准**
- 状态机非法迁移被拒绝并返回稳定错误码;同系列同剂次重复登记返回冲突。
- completed 必须带 administered_on、scheduled 必须带 planned_on(与数据库约束一致,应用层先行校验)。
- 集成测试覆盖成功、参数错误、不存在、无权限、并发冲突、幂等重试六类路径(第 9 节要求)。
- **依赖**T2-03。
- **规模**L
#### T2-06 健康事件时间线接口
- **仓库**patbond-api
- **描述**`GET/POST /api/v1/pets/{petId}/health-events`,建议补 `PATCH /api/v1/health-events/{eventId}`(编辑标题/备注/金额,乐观锁)。六类事件类型(medical/feeding/deworming/grooming/measurement/note);`amount_cents` 整数分(第 4.3 节);`occurred_at DESC` cursor 分页;`created_by_user_id` 记录操作者。`health_event_media` 本迭代不实现(随 D2-1)。
- **验收标准**
- 时间线分页正确;金额只收整数分且非负。
- 事件类型白名单校验与数据库约束一致。
- 六类测试路径覆盖同 T2-05。
- **依赖**T2-03。
- **规模**M
#### T2-07 照护提醒接口
- **仓库**patbond-api
- **描述**care_reminders 的列表/创建/状态流转(pending→completed/dismissedcompleted 必须写 completed_at,与 `ck_care_reminder_completed` 一致)。四类提醒类型(deworming/checkup/medication/other)。**仅 app 内数据接口,不做推送**(通知系统属 M6,见决策 D2-5)。
- **验收标准**
- 提醒可创建、按 due_at 查询待办、标记完成/忽略;状态与 completed_at 一致性有测试。
- 权限校验复用 T2-03 框架。
- **依赖**T2-03。
- **规模**M
#### T2-08 档案聚合摘要接口
- **仓库**patbond-api
- **描述**:实现档案页摘要所需聚合(建议 `GET /api/v1/pets/{petId}/summary`):最新体重、疫苗进度(completed 剂次/总剂次)、下次接种(scheduled 中最近 planned_on 或最近 next_due_on)、当月花费(health_events.amount_cents 按月求和)。全部从事实表实时聚合,**不持久化展示字符串**(第 4.3 节红线);聚合口径逐项写入契约描述。
- **验收标准**
- 各聚合值有集成测试锁定口径(含空数据、跨月边界、cancelled 疫苗不计入)。
- 时间按 `timestamptz` 存储、ISO 8601 传输,月度边界按客户端传入时区或明确定义的服务端口径(写入契约,避免歧义)。
- **依赖**T2-04、T2-05、T2-06。
- **规模**M
### C 组:契约与测试
#### T2-09 OpenAPI 契约扩展与冻结
- **仓库**patbond-doc`docs/api/openapi.yaml`),patbond-api(契约测试保证一致)
- **描述**:在既有 5 端点契约上扩展 pets 域全部端点(宠物、品种、体重、疫苗、目录、事件、提醒、摘要)。沿用既定规范:`/api/v1` 前缀、camelCase、UUID 字符串、统一信封、稳定业务错误码(pets 域新错误码段与 401/403/404/409 语义定死)、cursor 分页参数形态、`Idempotency-Key``version` 字段。**起草与 T2-03~05 并行,冻结须在 T2-03 权限/错误语义与 T2-08 聚合字段定型之后**——冻结是第三波前端联调的放行闸门(沿用第一迭代验证过的模式)。
- **验收标准**
- 契约文件评审通过;契约测试在 CI 中验证实际响应与文档一致。
- `mkdocs build --strict` 通过(契约文件更新不涉及导航变更)。
- 冻结后任何字段变更须显著上报,两端同步修改。
- **依赖**T2-03(错误/权限语义)、T2-08(聚合字段);起草仅依赖 §1.1 端点表。
- **规模**M
#### T2-10 后端集成测试滚动补齐与 CI
- **仓库**patbond-api
- **描述**:随 B 组各工单滚动补齐 Testcontainerspostgres:18)集成测试,交付前每单必须全绿(沿用第一迭代"每波 `./mvnw clean test` 必绿"纪律);V3 迁移在全新实例执行一次的校验并入 CI。本单为横切验收单,不单独排人。
- **验收标准**
- 每个业务接口覆盖成功、参数错误、资源不存在、无权限、并发冲突、幂等重试(第 9 节六类)。
- **caregiver/viewer 权限路径必须有测试覆盖**:邀请流程若按 D2-3 后置,则用测试数据直接写 pet_owners 构造三种角色场景,避免"权限代码存在但从未被验证"。
- Gitea Actions ci.yml 全绿;CI 时长若超 10 分钟记录并评估分层。
- **依赖**:随 T2-03~T2-08 滚动。
- **规模**M(分摊在各单内)
### D 组:Flutter 客户端
#### T2-11 pets feature 状态拆分与 API Client
- **仓库**patbond-flutter
- **描述**:按开发计划 4.2 节把宠物档案状态从 `AppState` 拆出独立 pets featureController → Repository → API Client 分层,对齐第一迭代 auth feature 的既有结构);依据 T2-09 冻结契约实现 DTO 与 Client(宠物、品种、体重、疫苗、事件、提醒、摘要),统一错误码解析复用既有网络层与 token 拦截。
- **验收标准**
- DTO 映射有单元测试;错误响应映射为类型化错误。
- 不再从 `AppState` 读写宠物/疫苗 demo 数据(体重、疫苗进度等展示字符串全部改为由服务端事实字段计算)。
- **依赖**:T2-09 冻结。UI 无关的分层骨架可提前与后端并行。
- **规模**M
#### T2-12 宠物列表、详情与编辑页接入真实数据
- **仓库**patbond-flutter
- **描述**:档案页(`lib/features/pets/pets_page.dart`)替换为真实列表/详情/创建/编辑:品种选择(目录接口 + 自定义品种互斥)、性别/生日/芯片号等字段对齐数据模型;**所有网络页面覆盖 loading、empty、error、retry 四态**(第 9 节硬要求);编辑冲突(409)给出明确的用户提示与刷新路径。头像照片按 D2-1 裁决处理(默认保留本地占位图,不做上传)。
- **验收标准**
- 新用户空态 → 建档 → 列表/详情展示全链路走真实后端。
- 四态齐备并有 widget 测试;乐观锁冲突提示有测试。
- **依赖**:T2-11;UI 稿可在第一波先行出设计(含四态与空态)。
- **规模**L
#### T2-13 体重与疫苗模块接入
- **仓库**patbond-flutter
- **描述**:体重录入与历史列表(分页加载);疫苗登记(选目录、系列/剂次、计划/完成状态)、疫苗进度与"下一针"改从 T2-08 摘要接口取数(替换 demo 的 `vaccines.reminderVaccine` 等本地字符串)。
- **验收标准**
- 体重与疫苗数据在另一登录设备(或清空本地数据重登)可见——对应 M2"跨设备读取"验收。
- 疫苗状态机操作的非法路径(如未填接种日期就标完成)被前端拦截且后端兜底。
- 相关 widget/单元测试补齐。
- **依赖**T2-11、T2-12。
- **规模**L
#### T2-14 健康时间线与提醒页接入
- **仓库**patbond-flutter
- **描述**:健康事件时间线(六类事件、金额录入以元展示/整数分传输、分页);照护提醒列表与完成/忽略操作;档案页"月度花费"改从摘要接口取数。demo 中硬编码的"健康提醒:已经半年没有进行体内外驱虫"改为真实提醒数据驱动。
- **验收标准**
- 时间线与提醒四态齐备;金额展示与传输换算有单元测试。
- 无提醒/无事件时空态正确。
- **依赖**T2-11、T2-12。
- **规模**M
### E 组:遗留项与收口
#### T2-15 遗留埋点:sessionId 生命周期(高优先,第一波插入)
- **仓库**patbond-flutter
- **描述**:第一迭代遗留 §1:引入 `WidgetsBindingObserver` 监听 app 前后台切换,定义会话超时与 sessionId 重建规则,修复"sessionId 只在退出时清空"的缺陷。
- **验收标准**:进后台超时回前台生成新 sessionId;规则有单元测试;不依赖 M2 契约,可与后端第一波并行。
- **依赖**:无。
- **规模**S
#### T2-16 遗留埋点:page_viewed 路由埋点(高优先,第一波插入)
- **仓库**patbond-flutter
- **描述**:第一迭代遗留 §2:接入 `RouteObserver` 挂接 `page_viewed` 事件(事件定义沿用报告 13 规范)。
- **验收标准**:主要页面路由切换产生 page_viewed 事件并能落库(复用既有 /api/v1/events 链路);有测试。
- **依赖**:无。
- **规模**S
#### T2-17 埋点:health_record_action 挂接与 M2 事件
- **仓库**patbond-flutter(挂接),patbond-doc(事件表更新)
- **描述**:第一迭代预留的 `health_record_action` 挂接点在 M2 档案功能落地后接通(建档、体重录入、疫苗登记、事件记录等动作);后端事件白名单同步扩充。埋点不得含健康敏感明文(沿用隐私红线)。
- **验收标准**:关键健康操作产生事件并落库;白名单与文档同步;有测试。
- **依赖**T2-12~T2-14(随页面落地滚动挂接)。
- **规模**S
#### T2-18 E2E 烟囱测试与真机联调收官
- **仓库**patbond-flutter(用例),patbond-apicompose 环境),patbond-doc(证据归档)
- **描述**:沿用第一迭代收官战模式:compose 起后端 → 真实链路烟囱:登录 → 建档 → 记体重 → 登记疫苗 → 记健康事件 → 摘要数值核对 → 第二账号访问该宠物被拒 → 第二设备(或重装态)同账号读到全部数据。收集 HTTP transcript(脱敏)、数据库查询证据、门禁输出。
- **验收标准**:烟囱场景全绿;契约偏差 0 个;M2 四条验收标准(跨设备、无权限拒绝、并发冲突明确、双端测试齐备)逐条有证据。
- **依赖**T2-05、T2-08、T2-13、T2-14。
- **规模**M
#### T2-19 文档与迭代收口
- **仓库**patbond-doc
- **描述**OpenAPI 定稿归档、feature-checklist 增补 M2 条目、迭代报告归档、任务板更新与收官总结。iteration-2 报告目录的 `mkdocs.yml` 导航条目由文档维护者在收口提交时统一添加(本拆解报告本身不改 mkdocs.yml)。
- **验收标准**`mkdocs build --strict` 通过;报告索引完整可还原全貌。
- **依赖**:各波交付。
- **规模**S
---
## 3. 波次划分与关键路径
沿用第一迭代验证过的"波次并行 + 契约冻结先行"模式。
### 第一波(并行开工,无互锁)
| 并行线 | 工单 | 说明 |
| --- | --- | --- |
| 后端数据基础 | T2-01 → T2-02 | 关键路径起点,一人连续负责 |
| 契约起草 | T2-09(起草态) | 按 §1.1 端点表 + 数据模型先出草案,随 T2-03 收敛 |
| 前端遗留埋点 | T2-15、T2-16 | 与 M2 契约零耦合,第一波消化掉两项高优先遗留 |
| UI 设计 | 档案页/四态/空态设计稿(供 T2-12) | 不占关键路径 |
### 第二波(后端纵切,契约收敛)
| 并行线 | 工单 | 说明 |
| --- | --- | --- |
| 后端主线 | T2-03 → T2-04/T2-05/T2-06/T2-0703 后三线可并行)→ T2-08 | T2-03 权限框架是全部业务单的前置 |
| 前端骨架 | T2-11 的分层骨架(不依赖契约的部分) | Repository/状态骨架先行 |
| 测试滚动 | T2-10 | 随各单交付即测即绿即提交 |
**波末闸门:T2-09 契约冻结**(条件:T2-03 权限/错误语义定型 + T2-08 聚合字段定型)。不冻结不放行第三波前端联调,偏差须显著上报。
### 第三波(冻结契约下两端并行)
| 并行线 | 工单 | 说明 |
| --- | --- | --- |
| 前端主线 | T2-11(完成)→ T2-12 → T2-13 / T2-14 | 12 完成后 13、14 可两人并行 |
| 后端旁路 | 契约测试补齐、种子数据完善、性能核对 | 不占关键路径 |
| 埋点 | T2-17 | 随页面落地滚动挂接 |
### 第四波(收官)
T2-18 E2E 烟囱 → T2-19 文档收口 → 任务板更新与验收报告。
### 关键路径
```text
T2-01 → T2-02 → T2-03(L) → T2-05(L) → T2-08 → [T2-09 冻结] → T2-11 → T2-12(L) → T2-13(L) → T2-18
```
四个 L 工单串在关键路径上,是周期决定因素。压缩手段:T2-09 草案与 T2-11 骨架前移(已排入一、二波);T2-04/06/07 走旁路不占主线;T2-12 的 UI 稿第一波先行。
---
## 4. 需要用户拍板的决策清单
以下决策 PM 只给建议,**不替用户拍板**。D2-1~D2-3 直接影响工单定稿,建议开工前优先裁决。
| # | 决策事项 | 影响 | PM 建议(仅供参考) |
| --- | --- | --- | --- |
| D2-1 | **照片/媒体是否纳入 M2**:宠物头像上传、疫苗证书、健康事件附件均依赖媒体上传流程(M1 遗留未做)与对象存储供应商(第一迭代 D4 至今未定) | 阻塞 T2-12 头像、T2-05 证书字段、health_event_media;若纳入需增补媒体上传专项工单(约 +1 L) | M2 首版**不含**照片上传,档案先跑通结构化数据;对象存储选型(建议 S3 兼容,如自建 MinIO 起步)拍板后以独立专项插入 M2 末波或 M3 |
| D2-2 | **后端模块归属**:新建独立宠物健康服务(对齐"模块边界与 schema 对齐"+ 独立部署)vs 作为模块并入 patbond-user 进程(降低双人团队运维面) | 决定 T2-02 骨架形态、compose 编排、CI 构建时长 | 新建 Maven 模块 `patbond-pet`(独立数据所有权),**部署形态倾向与 user 同进程或同 compose 独立容器均可接受**,请结合第一迭代 D2(单体 vs 多服务)一并裁决 |
| D2-3 | **共同照护人邀请流程是否入 M2**pet_owners 支持 owner/caregiver/viewer,但"邀请另一个用户"需要检索用户、发出/接受邀请等交互 | 决定 T2-03 是否扩为含邀请端点(约 +1 M)与前端邀请页 | M2 只做"创建者即 primary owner"+ 完整权限**校验**框架(测试数据覆盖三角色),邀请**交互**后置 M3+;这样 M2 验收标准"无权限用户不能访问"仍可完整验证 |
| D2-4 | **体温记录**:迭代一总结提及,但数据模型无体温表 | 若要结构化体温需新表与新迁移(超出已评审模型) | 用 `health_events``measurement` 类型承载文字化记录,不建新表;若产品明确要体温曲线图,另立数据模型变更提案再排期 |
| D2-5 | **提醒的通知形态**care_reminders 首版是否仅 app 内列表(无系统推送/本地通知) | 推送涉及通知渠道选型(platform.notifications 属 M6 | 首版仅 app 内列表 + 到期排序展示;推送后置 M6 |
| D2-6 | **breeds / vaccine_catalog 目录数据来源**:开发种子够用,但正式目录(犬猫品种表、疫苗名录)内容与量级谁提供、何时定稿 | 不阻塞开发(seed 兜底),影响上线数据质量 | 开发期用 seed(每 species 各 10~20 条常见项);正式目录数据作为独立内容任务由产品侧供稿 |
| D2-7 | **宠物删除语义**:前端提供什么入口——归档(archived)/ 软删除(deleted/ 不提供 | 影响 T2-03 状态流转范围与 T2-12 交互 | 首版仅提供"归档",软删除接口保留但前端不出入口,避免误删争议 |
| D2-8 | **中优先遗留是否纳入 M2**access token 黑名单、/internal 改 mTLS、auth_sessions 清理调优、埋点完善其余项(队列持久化等) | 纳入则挤占 M2 周期 | **不纳入**,维持技术债清单,M3 或加固阶段统一处理(TagPill 设计债同此) |
---
## 5. 遗留项插入位置汇总
| 遗留项(第一迭代总结编号) | 优先级 | 插入位置 |
| --- | --- | --- |
| 埋点 sessionId 生命周期(§1 | 高 | **T2-15,第一波**,独立工单 |
| page_viewed 路由埋点(§2 | 高 | **T2-16,第一波**,独立工单 |
| health_record_action 挂接(§7 之一) | 中(M2 天然落点) | **T2-17,第三波**随页面滚动挂接 |
| access token 黑名单(§4 | 中 | 不入 M2(待 D2-8 确认),技术债清单 |
| /internal 改 mTLS(§5 | 中 | 不入 M2(待 D2-8 确认),需先补 ADR |
| auth_sessions 清理调优(§6) | 中 | 不入 M2,性能阶段处理 |
| 埋点完善其余 4 项(§7) | 中 | 不入 M2;后端事件查询端点若 T2-17 验证需要可顺手做,超出即止 |
| TagPill 对比度设计债(§8) | 低 | 不入 M2,设计系统升级时统一处理 |
---
## 6. 风险清单
| # | 风险 | 影响 | 缓解措施 |
| --- | --- | --- | --- |
| R1 | **未提交/未推送风险**(第一迭代 R3 教训:两天工作量曾只存在于工作区) | 误操作全损;协作与 CI 失效 | 沿用已验证纪律:**每波每单交付即提交即推送**;PM 任务板每波核对三仓 `git status`。开工时基线:三仓工作区干净、与远端同步(2026-09-07 已核实) |
| R2 | **契约偏差风险**:pets 域端点数量约为第一迭代 4 倍,聚合字段口径(月度边界、进度分母)最易两端理解不一 | 联调返工 | 冻结闸门制度不放松;聚合口径在契约中逐字段写清(含时区口径);偏差显著上报,禁止任一端私改 |
| R3 | **V3 迁移照抄 bootstrap SQL 的跨 schema 外键**(第 1156~1166 行引用 marketplace) | 迁移在干净库直接失败,或被迫提前迁移 marketplace | 已写入 T2-01 描述为强制裁剪项;迁移说明记录差异与 M5 补回计划;Testcontainers 全新库验证兜底 |
| R4 | **对象存储未定拖累范围**:若 D2-1 拍板"要照片"而供应商未定 | T2-12/T2-05 范围反复 | 决策清单置顶 D2-1;默认口径按"不含照片"排期,拍板含照片则显式加 1 个 L 工单并顺延 |
| R5 | **权限路径测试盲区**:邀请流程后置时,caregiver/viewer 无自然产生入口 | "权限代码存在但从未验证",M2 验收标准落空 | T2-10 明确要求用测试数据直接构造三角色场景;E2E(T2-18)含第二账号拒绝场景 |
| R6 | **范围膨胀**:迭代一总结口径(照片/体温)比开发计划 M2 原文宽 | 周期失控、返工 | 本报告 §1.2 已逐条对照数据模型澄清;一切扩张走 §4 拍板,未拍板按 PM 建议默认剪出 |
| R7 | **CI 时长增长**:测试数将从 82 大幅增加,Testcontainers 全跑 | CI 反馈变慢、门禁被绕过 | T2-10 记录每波 CI 时长,超 10 分钟评估按模块分层执行;不降低"提交前全绿"标准 |
| R8 | **单接口面过宽的估算风险**:疫苗状态机 + 系列/剂次约束复杂度接近第一迭代 JWT 会话单 | T2-05 拖关键路径 | T2-05 已按 L 估算并置于关键路径显式管理;catalog 只读部分可先行拆出交付 |
| R9 | **文档导航遗漏**iteration-2 目录需入 mkdocs 导航,但本迭代规则限制随手改 mkdocs.yml | `mkdocs build --strict` 门禁或导航缺失 | 归入 T2-19 由文档维护者收口提交时统一处理,收口清单显式含此项 |
---
## 7. 质量要求(对全部工单生效)
- 遵守开发计划第 10 节 DoD:不依赖 Demo 常量;权限、校验、幂等、并发已处理;文档同步更新;干净环境可复现。
- 沿用既定契约规范:camelCase、UUID 字符串、ISO 8601 + timestamptz、金额整数分、统一信封与稳定错误码、cursor 分页、Idempotency-Key、version 乐观锁。
- 不提交任何密码、token、密钥;日志与埋点不含健康敏感明文与手机号全文。
- 自动化测试一律 Testcontainers postgres:18ADR-006/008);每单交付 `./mvnw clean test` / `flutter analyze` + `flutter test` 全绿。
- 所有网络页面四态(loading/empty/error/retry)齐备。
- 本迭代不实现社区、AI、预约的任何接口或页面;范围外需求记 backlog。
## 8. 工单统计
- 工单总数:**19**(数据与工程基础 2 + 后端接口 6 + 契约与测试 2 + Flutter 4 + 遗留与收口 5
- 规模分布:S × 5、M × 10、L × 4
- 关键路径长度:9 个工单(T2-01 → T2-02 → T2-03 → T2-05 → T2-08 → 冻结 → T2-11 → T2-12 → T2-13 → T2-18),其中 L × 4
- 待拍板决策:**8 项**(D2-1~D2-8,前三项建议开工前裁决)