docs: 迁入第一迭代过程报告并建立进展看板
- 新增 development/iterations/iteration-1/:15 份角色报告 + 进展看板(已完成/未闭环/下一步),作为双人协作的进度事实来源 - 新增 ADR-006:测试与交付容器化策略(Testcontainers / 交付 Docker 包 / 本机库仅个人联调) - Git 工作流规范补充:敏感信息只进忽略文件或 sample、测试数据不入库、测试代码限标准测试目录 - 门禁:mkdocs build --strict 通过(零警告)
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
# Patbond 第一迭代任务分解(M0 工程基线 + 真实登录纵切)
|
||||
|
||||
> 作者:Senior Project Manager
|
||||
> 日期:2026-09-03
|
||||
> 依据:`patbond-doc/docs/development/development-plan.md`(Draft 1.0,2026-09-03)
|
||||
> 范围声明:严格限定为第 7 节 M0 与第 8 节「真实登录纵切」8 项任务。社区、AI 创作、预约、宠物健康均不在本迭代范围内(文档第 8 节明确:"第一迭代暂不开发 AI Worker、社区 Feed 或预约")。
|
||||
|
||||
## 1. 范围与合并说明
|
||||
|
||||
- **M0 目标**(第 7 节):"让所有开发者能用一致方式启动、测试和联调。" 验收标准:"新机器仅依据仓库文档即可启动后端、连接本地数据库并运行自动化检查。"
|
||||
- **第一迭代目标**(第 8 节):真实登录纵切,端到端验证"数据库、认证、客户端和测试链路能够贯通"。
|
||||
- **重叠合并**:M0 的"将 bootstrap SQL 转为 Flyway baseline,并分离开发种子数据"与第 8 节任务 1"从 bootstrap SQL 提取 identity/media 的 Flyway baseline"是同一件事在本迭代的落地范围。合并为工单 T1,本迭代只做 identity/media 两个 schema 的 baseline,其余 schema 的 Flyway 化随后续迭代进行。
|
||||
- **媒体范围提示**:第 8 节 8 项任务不含媒体上传实现(那是 M1 后半段),T1 仅按文档字面提取 media 的表结构 baseline,不开发 `POST /api/v1/media/uploads`。
|
||||
|
||||
预估规模口径:S ≈ 半天内,M ≈ 1-2 天,L ≈ 3-5 天(含测试与文档)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 工单列表
|
||||
|
||||
### A 组:M0 工程基线(6 个工单)
|
||||
|
||||
#### T0-1 接入 Maven Wrapper
|
||||
- **仓库**:patbond-api
|
||||
- **描述**:为多模块 Maven 工程添加 `mvnw`/`mvnw.cmd` 与 wrapper 配置,锁定 Maven 3.9+;README 中的构建命令改用 `./mvnw`。
|
||||
- **验收标准**:
|
||||
- 干净检出后不安装本机 Maven,`./mvnw -pl patbond-common -am install` 可通过。
|
||||
- 文档中 Maven 版本与 wrapper 配置一致。
|
||||
- **依赖**:无。
|
||||
- **规模**:S
|
||||
|
||||
#### T0-2 Flutter/Dart 版本锁定
|
||||
- **仓库**:patbond-flutter
|
||||
- **描述**:提供 Flutter SDK 版本固定方案(如 FVM 或等效工具),版本满足 `pubspec.yaml` 约束,并写入仓库说明。
|
||||
- **验收标准**:
|
||||
- 仓库内有明确的版本锁定文件与使用说明。
|
||||
- 新机器按说明可 `flutter pub get && flutter analyze` 通过。
|
||||
- **依赖**:无。
|
||||
- **规模**:S
|
||||
|
||||
#### T0-3 可提交的默认配置与环境变量注入
|
||||
- **仓库**:patbond-api
|
||||
- **描述**:把 `application.yml.sample` 替换为可直接提交的 `application.yml` 默认配置;数据库、Nacos 等敏感/环境相关值全部通过环境变量注入,采用第 5.3 节变量名(`PATBOND_DB_URL`、`PATBOND_DB_USERNAME`、`PATBOND_DB_PASSWORD`、`NACOS_SERVER_ADDR`)。修复已知风险 5("干净检出无法按 README 直接启动服务")。
|
||||
- **验收标准**:
|
||||
- 干净检出 + 设置环境变量即可启动 `patbond-user`(8082)与 `patbond-auth`(8081),无需手工复制 sample。
|
||||
- 仓库中无任何密码、token、密钥明文(第 5.1 节红线)。
|
||||
- **依赖**:无(与 T0-4 联调)。
|
||||
- **规模**:M
|
||||
|
||||
#### T0-4 本地基础设施编排(PostgreSQL + Nacos)
|
||||
- **仓库**:patbond-api(编排文件),patbond-doc(启动文档)
|
||||
- **描述**:提供本地一键编排(PostgreSQL 16、Nacos);RabbitMQ 按文档"在异步任务阶段启用",本迭代不加入。数据库容器初始化仅建空库,结构由 Flyway 负责(T1)。
|
||||
- **验收标准**:
|
||||
- 一条命令拉起 PostgreSQL 16 与 Nacos,端口与 T0-3 的默认环境变量匹配。
|
||||
- 文档说明启动、停止、重置数据的方式。
|
||||
- **依赖**:无。
|
||||
- **规模**:M
|
||||
|
||||
#### T0-5 契约规范冻结文档
|
||||
- **仓库**:patbond-doc
|
||||
- **描述**:把第 4.3、6.1 节规则固化为规范文档并纳入 `mkdocs.yml` 导航:UUID(应用层 UUIDv7)、`timestamptz` + ISO 8601、金额整数分、统一错误响应(HTTP 状态码 + 稳定业务错误码)、cursor 分页、`Idempotency-Key`、`version` 乐观锁、日志脱敏。
|
||||
- **验收标准**:
|
||||
- 规范文档评审通过,`mkdocs build --strict` 通过。
|
||||
- T3/T4/T6 的实现均引用此文档而非各自发明。
|
||||
- **依赖**:无;是 T3、T6a 的前置。
|
||||
- **规模**:M
|
||||
|
||||
#### T0-6 建立 CI 最低门禁
|
||||
- **仓库**:patbond-api、patbond-flutter、patbond-doc(三条流水线)
|
||||
- **描述**:按第 9 节 CI 最低门禁配置:API `mvn clean test`;Flutter `dart format --set-exit-if-changed` + `flutter analyze` + `flutter test`;文档 `mkdocs build --strict`。加入基本代码检查。数据库迁移在全新 PostgreSQL 16 实例执行一次的校验,在 T1 合入后追加到 API 流水线。
|
||||
- **验收标准**:
|
||||
- 三仓 PR 均触发对应门禁,当前主干全绿。
|
||||
- 门禁失败可阻止合入。
|
||||
- **依赖**:T0-1(API 用 wrapper 构建)、T0-2(Flutter 版本确定)。
|
||||
- **规模**:M
|
||||
|
||||
### B 组:登录纵切(9 个工单,对应第 8 节 8 项任务,任务 6 拆为两单)
|
||||
|
||||
#### T1 identity/media Flyway baseline 与种子数据分离(第 8 节任务 1)
|
||||
- **仓库**:patbond-api(迁移脚本),patbond-doc(迁移说明)
|
||||
- **描述**:从 `patbond-doc/docs/database/patbond_postgresql.sql` 提取 `identity`、`media` 两个 schema 的结构,转为 Flyway 版本化迁移;开发种子数据独立为不进生产的脚本。遵守第 4.3 节:已导入的本地库先备份,优先重建开发库或核对 checksum 后 baseline,"禁止直接重复执行 bootstrap"。
|
||||
- **验收标准**:
|
||||
- 全新 PostgreSQL 16 实例上 Flyway 迁移一次成功,`identity`、`media` 表结构与 bootstrap SQL 一致。
|
||||
- 种子数据脚本与结构迁移分离,且不会进入正式环境。
|
||||
- 本地既有库的接入路径(重建或 baseline)写入文档。
|
||||
- **依赖**:T0-4(本地 PostgreSQL 可用)。
|
||||
- **规模**:M
|
||||
|
||||
#### T2 patbond-user 接入 PostgreSQL,UUID 用户持久化(第 8 节任务 2)
|
||||
- **仓库**:patbond-api
|
||||
- **描述**:为 `patbond-user` 增加数据源与 Repository,把内存用户迁移到 `identity.users`、`identity.user_credentials`;用户 ID 由 `Long` 改为 UUID(应用层 UUIDv7 优先,`gen_random_uuid()` 兜底),消除已知风险 1。数据库账号使用最小权限(第 5.3 节)。
|
||||
- **验收标准**:
|
||||
- 注册的用户写入 PostgreSQL,重启服务后数据不丢失。
|
||||
- 对外 API 中用户 ID 为 UUID 字符串。
|
||||
- 现有注册/登录/查询/密码校验接口在新存储上行为正确。
|
||||
- **依赖**:T1、T0-3。
|
||||
- **规模**:L
|
||||
|
||||
#### T3 统一异常响应与数据库一致校验(第 8 节任务 3)
|
||||
- **仓库**:patbond-api
|
||||
- **描述**:实现统一错误响应(正确 HTTP 状态码 + 稳定业务错误码,禁止只返回异常文本,见 6.1 节);用户名、手机号唯一性校验以数据库约束为准,应用层校验与数据库约束一致,并发重复注册返回明确错误而非 500。
|
||||
- **验收标准**:
|
||||
- 参数错误、重复用户名/手机号、资源不存在均返回规范错误体。
|
||||
- 并发重复注册场景有测试覆盖,无脏数据。
|
||||
- 日志不记录密码、token、手机号全文。
|
||||
- **依赖**:T2、T0-5。
|
||||
- **规模**:M
|
||||
|
||||
#### T4 可校验 access token 与 refresh session(第 8 节任务 4)
|
||||
- **仓库**:patbond-api
|
||||
- **描述**:将随机字符串 token 替换为可校验的 access token;实现 refresh token 轮换、退出与会话撤销(会话落 `identity` 相关表);补齐 `POST /api/v1/auth/refresh`、`POST /api/v1/auth/logout`;消除已知风险 2。`/internal/**` 的服务间访问控制(风险 3)按 M1 范围至少加基础保护。
|
||||
- **验收标准**:
|
||||
- access token 可离线/在线校验,过期后用 refresh token 可换新。
|
||||
- refresh token 轮换后旧 token 立即失效;退出后 refresh token 不可再次使用(M1 验收标准)。
|
||||
- `/internal/users/**` 不可被无凭据外部调用直接访问。
|
||||
- **依赖**:T2;token 有效期与多设备策略需产品拍板(见决策 D3),未拍板前按建议默认值实现并做成配置项。
|
||||
- **规模**:L
|
||||
|
||||
#### T5 认证链路集成测试(第 8 节任务 5)
|
||||
- **仓库**:patbond-api
|
||||
- **描述**:使用真实 PostgreSQL/Testcontainers 为注册、登录、刷新、退出、鉴权建立集成测试(第 9 节),覆盖成功、参数错误、凭据错误、token 过期、已撤销 token 复用、无权限访问等路径。
|
||||
- **验收标准**:
|
||||
- 上述场景全部有自动化断言并纳入 `mvn clean test`。
|
||||
- CI(T0-6)中稳定通过,包含迁移在全新实例执行一次的校验。
|
||||
- **依赖**:T2、T3、T4、T0-6。
|
||||
- **规模**:M
|
||||
|
||||
#### T6a 建立 OpenAPI 契约(第 8 节任务 6 前半)
|
||||
- **仓库**:patbond-doc(契约文档),patbond-api(保证实现一致)
|
||||
- **描述**:为第 6.2 节第一批中本迭代涉及的接口编写 OpenAPI:`/api/v1/auth/register`、`/auth/login`、`/auth/refresh`、`/auth/logout`、`GET /api/v1/me`。统一 `/api/v1` 前缀、camelCase、UUID 字符串、规范错误体;加入契约测试验证实际响应与文档一致。
|
||||
- **验收标准**:
|
||||
- OpenAPI 文件评审通过并纳入文档站导航。
|
||||
- 契约测试在 CI 中验证以上接口响应与契约一致。
|
||||
- **依赖**:T0-5;接口最终形态受 T3/T4 影响(可先起草,随实现收敛)。登录方式字段依赖决策 D5。
|
||||
- **规模**:M
|
||||
|
||||
#### T6b Flutter API Client(第 8 节任务 6 后半)
|
||||
- **仓库**:patbond-flutter
|
||||
- **描述**:依据 T6a 的 OpenAPI 生成或手写 API Client 与 DTO,建立第 4.2 节分层(Repository -> API Client),实现统一错误码解析。
|
||||
- **验收标准**:
|
||||
- Client 覆盖 T6a 全部接口,DTO 映射有单元测试。
|
||||
- 错误响应能映射为客户端可处理的类型化错误。
|
||||
- **依赖**:T6a。
|
||||
- **规模**:M
|
||||
|
||||
#### T7 Flutter 登录页、安全 token 存储与登录态恢复(第 8 节任务 7)
|
||||
- **仓库**:patbond-flutter
|
||||
- **描述**:新增登录/注册页;access/refresh token 仅存安全存储(不得写入普通 `SharedPreferences`,第 4.2 节);实现鉴权拦截(自动附带 token、401 时刷新重试)与应用启动登录态恢复;`auth` 状态从 `AppState` 拆出独立 feature 状态。
|
||||
- **验收标准**:
|
||||
- 可完成真实注册与登录;杀进程重开后登录态恢复;token 过期自动刷新。
|
||||
- 登录页覆盖 loading、error、retry 状态(第 9 节要求)。
|
||||
- 有登录流程 Widget 测试与 Repository/状态单元测试。
|
||||
- **依赖**:T6b;端到端联调依赖 T4。
|
||||
- **规模**:L
|
||||
|
||||
#### T8 端到端用例:注册 → 登录 → 获取当前用户 → 退出(第 8 节任务 8)
|
||||
- **仓库**:patbond-flutter(E2E 用例),patbond-api、patbond-doc(联调环境与文档)
|
||||
- **描述**:建立一条贯通真实后端与数据库的端到端自动化用例:注册 → 登录 → `GET /api/v1/me` → 退出,退出后受保护接口访问失败。补充"新机器按文档从零跑通该用例"的操作说明,作为 M0 验收的最终证明。
|
||||
- **验收标准**:
|
||||
- 用例可在本地编排环境(T0-4)下自动执行并通过。
|
||||
- 新成员仅凭仓库文档可复现(M0 验收标准)。
|
||||
- **依赖**:T4、T5、T7。
|
||||
- **规模**:M
|
||||
|
||||
---
|
||||
|
||||
## 3. 关键路径与并行分组
|
||||
|
||||
### 关键路径(后端主线 → 客户端联调 → E2E)
|
||||
|
||||
```text
|
||||
T0-4 编排 → T1 Flyway baseline → T2 用户持久化(L) → T4 token/会话(L) → T7 Flutter 登录联调(L) → T8 E2E
|
||||
```
|
||||
|
||||
T2、T4、T7 三个 L 工单串在关键路径上,是迭代周期的决定因素。压缩手段:T4 的 token 方案设计、T7 的登录页 UI 与安全存储封装都可在前置工单完成前先行开工(见下)。
|
||||
|
||||
### 可并行任务组
|
||||
|
||||
| 组 | 工单 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| P1 工程基线(迭代第一周全部并行) | T0-1、T0-2、T0-3、T0-4、T0-5 | 互相无依赖,可 3-4 人同时开工;完成后 T0-6 收口 |
|
||||
| P2 后端主线(串行) | T1 → T2 → T4 | 关键路径,建议由同一名后端主力负责保持连续性 |
|
||||
| P3 后端旁路 | T3、T5 | T3 与 T4 都只依赖 T2,可两人并行;T5 随 T3/T4 完成滚动补齐 |
|
||||
| P4 契约与客户端 | T6a → T6b → T7 | T6a 可在 T0-5 后立即起草(与 T2 并行);T7 的 UI/安全存储部分可与后端并行,仅最终联调等 T4 |
|
||||
| P5 收口 | T8 | 全链路就绪后执行 |
|
||||
|
||||
最小人力建议:1 名后端主力(P2)+ 1 名后端(P3 与部分 P1)+ 1 名 Flutter(P4)即可维持关键路径不空转。
|
||||
|
||||
---
|
||||
|
||||
## 4. 开工前待确认决策清单(源自文档第 12 节)
|
||||
|
||||
文档明确:"上述事项未确认前,可以完成 M0 和身份持久化,但不应并行扩展所有业务模块。" 即本迭代大部分工单不被阻塞,但 D3、D5 直接影响本迭代实现,需优先拍板。
|
||||
|
||||
| # | 决策事项 | 对本迭代的影响 | 建议默认选项 |
|
||||
| --- | --- | --- | --- |
|
||||
| D1 | 第一版 MVP 是"注册登录 + 宠物档案"还是必须包含社区发布 | 不阻塞本迭代,决定第二、三迭代排期 | 注册登录 + 宠物档案(M1+M2),社区后置到 M3;与文档迭代顺序一致 |
|
||||
| D2 | 后端多服务部署 vs 模块化单体 | 影响 T0-3/T0-4 的配置与编排复杂度、是否长期保留 Nacos | 先模块化单体:保留 Maven 模块边界与 schema 所有权,单进程/同机部署降低早期运维成本;当前 auth/user 双服务与 Nacos 维持现状不扩散,待拍板后再收敛 |
|
||||
| D3 | access/refresh token 有效期与多设备登录策略 | **直接阻塞 T4 定稿**(可按默认值先实现为配置项) | access 15 分钟;refresh 30 天且每次刷新轮换;允许多设备并行会话,退出仅撤销当前会话 |
|
||||
| D4 | 对象存储、AI 模型、天气、地图供应商 | 本迭代不阻塞(T1 仅建 media 表结构);对象存储需在 M1 媒体上传前确定 | 本迭代不定 AI/天气/地图;对象存储在下迭代开始前选定一家 S3 兼容服务 |
|
||||
| D5 | 是否支持手机号登录、短信验证码、第三方登录 | **影响 T3 校验字段、T6a 注册/登录契约、T7 登录页表单** | 首版仅账号(用户名/手机号作为标识)+ 密码,不做短信验证码与第三方登录;数据模型预留凭证类型扩展 |
|
||||
| D6 | 预约首版是否包含支付、退款和服务商后台 | 不阻塞本迭代;影响 M5 范围与数据库是否需补支付域 | 首版不含支付与服务商后台,预约仅到"确认/完成"状态机;文档已注明当前数据库不含支付域 |
|
||||
| D7 | 首发平台:Android/iOS,还是含 Web/桌面 | 影响 T7/T8 的测试矩阵与后续 Golden 测试宽度 | 首发仅 Android + iOS;Web/桌面不在验收矩阵 |
|
||||
|
||||
另提请产品/技术负责人注意文档第 11 节风险 8(Spring Boot 2.7 已进入旧技术代际,是先交付 MVP 还是先升级 Boot 3)——它不在第 12 节清单中,但会影响 T4 选型的依赖库,建议与 D2 一并讨论。PM 建议:先按现有 Boot 2.7 交付本迭代,升级作为独立技术专项排期,避免纵切迭代被大版本升级绑架。
|
||||
|
||||
---
|
||||
|
||||
## 5. 质量要求(对全部工单生效)
|
||||
|
||||
- 遵守文档第 10 节 Definition of Done:不依赖 Demo 常量或仅存于进程内的数据;权限、校验、幂等、并发已处理;文档同步更新;干净环境可复现。
|
||||
- 不提交任何密码、token、密钥(第 5.1 节)。
|
||||
- 日志不得记录密码、token、手机号全文(第 6.1 节)。
|
||||
- 新增文档必须同步更新 `mkdocs.yml` 导航(第 1 节)。
|
||||
- 本迭代不实现社区、AI、预约、宠物健康的任何接口或页面改造;发现范围外需求一律记入 backlog。
|
||||
|
||||
## 6. 工单统计
|
||||
|
||||
- 工单总数:**15**(M0 工程基线 6 个 + 登录纵切 9 个)
|
||||
- 规模分布:S × 2、M × 10、L × 3
|
||||
- 关键路径长度:6 个工单(T0-4 → T1 → T2 → T4 → T7 → T8),其中 3 个 L
|
||||
Reference in New Issue
Block a user