- 新建常设「发布记录」页(挂开发文档导航),首条 v0.3.0 M3 社区 - 30 号报告:M2 11/11 + M3 14/14 同环境各连跑 3 轮零 flake、契约偏差 0; 附契约向后兼容结构化比对(removed/changed 均 NONE)与共享代码面回归分析 - 记录首次发布的一次性操作:api main 孤儿历史重建(方案 A)、flutter 快进推法改进 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,313 @@
|
||||
# 30 首次发布门禁:M2+M3 双份 E2E 回归(checklist 第 2 步)
|
||||
|
||||
- 执行人:QA(Explore / 回归执行)
|
||||
- 日期:2026-09-10
|
||||
- 依据:iteration-3/08 号《Git 工作流规划》**§3.3 发布 checklist 第 2 步**——
|
||||
「compose 全栈起,跑 M2+M3 两份 E2E 烟囱脚本,全场景 PASS,证据入波次报告」
|
||||
- 环境:`patbond-api`(docker compose 六容器)+ `patbond-flutter`(dart 脚本直连)
|
||||
- 测试脚本:`patbond-flutter/test_e2e_m2_manual.dart`(M2 收官版,11 场景)
|
||||
与 `patbond-flutter/test_e2e_m3_manual.dart`(M3 收官版,14 场景),均取 `flutter@0e87413`
|
||||
- 冻结契约:`patbond-doc/docs/api/openapi.yaml` **v1.3.0**(`doc@f848476`)
|
||||
- 参照模式:iteration-2/28 与 iteration-3/28 号收官报告(格式与取证标准沿用)
|
||||
|
||||
> **三仓代码零改动**:本次只起 compose、跑两份既有脚本、做只读 psql/git 取证。
|
||||
> 未修改、未 commit、未 push 任何代码仓;未改 `mkdocs.yml`。
|
||||
|
||||
---
|
||||
|
||||
## 0. 执行概要
|
||||
|
||||
### 门禁结论
|
||||
|
||||
**PASS**——发布 checklist 第 2 步满足。
|
||||
|
||||
| 项目 | 结果 |
|
||||
| --- | --- |
|
||||
| M2 场景通过数 | **11 / 11**(44 条断言全绿,`exit 0`) |
|
||||
| M3 场景通过数 | **14 / 14**(88 条断言全绿,`exit 0`) |
|
||||
| 契约偏差数 | **0 个**(对照冻结契约 v1.3.0) |
|
||||
| 失败项 | **0 项** |
|
||||
| 稳定性 | 同一 compose 环境内 **两份脚本各连跑 3 轮**,6 次全通过、零 flake |
|
||||
| 两域共存 | M2→M3→M2→M3 交叉执行,pet_health 与 community 数据同库共存,互不干扰 |
|
||||
| 容器异常 | 六容器 RestartCount 全 0;四个应用容器日志 `ERROR`/`Exception` 计数全 0 |
|
||||
|
||||
### 本单目标(与 M3 收官报告的区别)
|
||||
|
||||
M3 版脚本已在 M3 收官(iteration-3/28)跑过 14/14。**本单的增量价值在于复跑 M2 版**:
|
||||
M3 期间 pets 域未做功能变更,但两域共享 `patbond-common`、契约快照文件、CI 流水线与同一
|
||||
数据库实例——需要实测确认 M3 交付没有回归 M2 的宠物健康档案域。为把「共存」也一并证实,
|
||||
两份脚本在**同一次** compose 生命周期内交叉执行。
|
||||
|
||||
### 脱敏声明
|
||||
|
||||
token 一律截断至前 20 字符 + `<REDACTED>`(脚本内置 `redact()`);MinIO 预签名 URL 的
|
||||
查询串替换为 `<SIGNATURE_REDACTED>`;幂等键显示为 `<KEY-1>`;密码与 `.env` 内容不出现在
|
||||
任何输出。
|
||||
|
||||
---
|
||||
|
||||
## 1. 环境记录
|
||||
|
||||
### 1.1 构建与启动(patbond-api 代码零改动)
|
||||
|
||||
```bash
|
||||
cd <你的工作区>/patbond-api
|
||||
JAVA_HOME=/usr/lib/jvm/java-17-openjdk ./mvnw -DskipTests package
|
||||
# BUILD SUCCESS —— Total time: 4.263 s(增量编译,五模块 reactor 全 SUCCESS)
|
||||
# 产出四个 -exec.jar:auth 36MB / community 51MB / pet 25MB / user 41MB
|
||||
|
||||
docker compose up -d --build
|
||||
# Container patbond-postgres-1 Healthy
|
||||
# Container patbond-minio-1 Healthy
|
||||
# Container patbond-user-1 / auth-1 / community-1 / pet-1 Started
|
||||
```
|
||||
|
||||
### 1.2 六容器状态与镜像版本
|
||||
|
||||
```text
|
||||
CONTAINER REPOSITORY TAG SIZE STATUS
|
||||
patbond-postgres-1 postgres 18 162MB Up (healthy)
|
||||
patbond-minio-1 minio/minio RELEASE.2025-04-22T22-12-26Z 64MB Up (healthy)
|
||||
patbond-auth-1 patbond-auth latest(本次重建) 141MB Up :8081
|
||||
patbond-user-1 patbond-user latest(本次重建) 147MB Up :8082
|
||||
patbond-pet-1 patbond-pet latest(本次重建) 132MB Up :8083
|
||||
patbond-community-1 patbond-community latest(本次重建) 155MB Up :8084
|
||||
```
|
||||
|
||||
| 组件 | 版本 |
|
||||
| --- | --- |
|
||||
| PostgreSQL | 18.6 (Debian 18.6-1.pgdg13+2) |
|
||||
| MinIO | RELEASE.2025-04-22T22-12-26Z |
|
||||
| 容器内 JRE | Temurin OpenJDK 17.0.20+8 |
|
||||
| 宿主 Docker | 29.7.2 / Docker Compose 5.5.1 |
|
||||
| Dart SDK(跑脚本) | 3.12.2 (stable) |
|
||||
|
||||
### 1.3 启动耗时与就绪验证
|
||||
|
||||
依赖顺序符合编排:postgres/minio 先 Healthy,四应用容器随后 Started(容器创建到启动
|
||||
约 3 秒),Spring Boot 自身启动耗时:
|
||||
|
||||
```text
|
||||
Started AuthApplication in 9.752 seconds
|
||||
Started UserApplication in 13.194 seconds
|
||||
Started PetApplication in 9.255 seconds
|
||||
Started CommunityApplication in 11.135 seconds
|
||||
```
|
||||
|
||||
无 token 探活(预期 401 信封):
|
||||
|
||||
```bash
|
||||
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8082/api/v1/me # 401
|
||||
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8083/api/v1/pets # 401
|
||||
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8084/api/v1/feed # 401
|
||||
```
|
||||
|
||||
### 1.4 脚本执行耗时(第三轮,取权威计时)
|
||||
|
||||
| 脚本 | 场景数 | 耗时 | 退出码 | `✓` 断言数 | 失败标记 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `test_e2e_m2_manual.dart` | 11 | **1149 ms** | 0 | 44 | 0 |
|
||||
| `test_e2e_m3_manual.dart` | 14 | **1662 ms** | 0 | 88 | 0 |
|
||||
|
||||
### 1.5 数据残留说明(非缺陷)
|
||||
|
||||
`pgdata` / `minio-data` 卷延续自 M3 收官那次运行(compose 只重建容器与镜像,未 `down -v`)。
|
||||
两份脚本均以时间戳随机账号运行、且 M3 的全量翻页断言按「本轮新增 26 条 vs 全量 117 条」
|
||||
的相对口径校验,因此**残留数据不影响判定,反而额外证明了跨轮数据共存无干扰**。
|
||||
|
||||
---
|
||||
|
||||
## 2. M2 版 E2E 逐场景结果(11/11 PASS)
|
||||
|
||||
本轮取证账号 `e2e_m2_a_1789025850872`,petId `01a08a40-1ad6-7a26-962c-a5f6cd3706a1`。
|
||||
|
||||
| # | 场景 | 结果 | 关键断言实测 |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | 注册账号 A → 登录 | ✓ PASS | register 200 / login 200,token `eyJhbGciOiJSUzI1NiJ9...<REDACTED>` |
|
||||
| 2 | 建档(含品种)→ 列表/详情读回 | ✓ PASS | 品种目录 16 条;POST /pets **201**;`myRole=owner`、`version=0`、`breedDisplayName=中华田园犬`;列表/详情四字段一致 |
|
||||
| 3 | 记体重 ×2 → cursor 分页 | ✓ PASS | 8.20/8.45kg 各 201;第一页 8.45 在前 + `hasMore=true`;第二页 8.20 + `hasMore=false`、`nextCursor=null` |
|
||||
| 4 | 疫苗登记(scheduled)→ 标记完成 | ✓ PASS | 疫苗目录 6 条;PATCH 200,`version 0→1`,`administeredOn`/`nextDueOn` 回读一致 |
|
||||
| 5 | 健康事件(整数分)→ 时间线 | ✓ PASS | `amountCents=12500` 原样回读;`createdByUserId` = token subject;时间线 1 条 |
|
||||
| 6 | 提醒创建 → 标记完成 | ✓ PASS | 创建恒 `pending` + `completedAt=null`;PATCH 后 `completedAt` = 客户端提交时刻 |
|
||||
| 7 | `/summary?tz=Asia/Shanghai` 四项聚合 | ✓ PASS | 最新体重 8.45kg;疫苗进度 1/1;下次接种 2027-09-10(`source=nextDue`);当月花费 12500 分、`month=2026-09`、tz 回显 |
|
||||
| 8 | 账号 B 越权访问 A 的宠物四路(防枚举) | ✓ PASS | 详情/体重/疫苗/摘要四路全 **404 / 40401**,响应体逐字节一致 `{"code":40401,"message":"宠物不存在","data":null}`;B 列表为空 |
|
||||
| 9 | 账号 A 第二设备重新登录 → 全量读回 | ✓ PASS | 新会话 token 与设备 1 不同(独立 token family);宠物 1 / 体重 2 / 疫苗 1 / 事件 1 / 提醒 1 全量一致 |
|
||||
| 10 | `/api/v1/events` v2 事件上报 | ✓ PASS | 4 条 → **202**,`accepted=4, duplicated=0, rejected=0` |
|
||||
| 11 | 乐观锁冲突明确性 | ✓ PASS | 第一次 PATCH 200(`version 0→1`);同过期 version 第二次 **409 / 40902**;读回确认先写者数据保留 |
|
||||
|
||||
---
|
||||
|
||||
## 3. M3 版 E2E 逐场景结果(14/14 PASS)
|
||||
|
||||
本轮取证账号 `e2e_m3_a_1789025861236`,postId `01a08a40-422a-7d60-a915-f04d7b0061be`。
|
||||
(三轮运行的断言输出逐条一致,仅随机账号名与 UUID 不同;下表的字面值取自取证轮输出。)
|
||||
|
||||
| # | 场景 | 结果 | 关键断言实测 |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | 注册 A/B 两账号 → 登录 | ✓ PASS | 两账号注册 200 且为两个独立 userId(模拟两客户端) |
|
||||
| 2 | 两步上传直传 MinIO(`/media/uploads` → complete) | ✓ PASS | 登记 201 返回 SigV4 预签名凭据、`requiredHeaders` 恒且仅 `{Content-Type}`;344 字节直传 200;complete 后 `uploading→ready`(`byteSize=344`、`readyAt` 已写);重复 complete 幂等 200 同一 asset |
|
||||
| 3 | 草稿创建 → 发布(PATCH draft→published) | ✓ PASS | 草稿 `status=draft`/`publishedAt=null`、media 挂接 `position=0` 且服务端置唯一 `isCover`;发布后 `status=published`、`publishedAt` 已写、`version 0→1` |
|
||||
| 4 | **验收①** B 拉 `/feed` A 的帖首位可见 | ✓ PASS | `published_at DESC` 首位命中;FeedCard 必填齐备;`AuthorSummary` 不露 bio/username;裁剪生效(无 content 全文/media 整组/version) |
|
||||
| 5 | 预签名 GET 字节往返 + 桶私有 | ✓ PASS | 344 字节逐字节一致;去签名直访 **403** |
|
||||
| 6 | **验收②** 连续 3 次 PUT like → count 恰 1 | ✓ PASS | 三次均 200 权威终态 `{liked:true,likeCount:1}`(非 409);DELETE → 0;重复 DELETE 幂等 |
|
||||
| 7 | 收藏 → `/me/bookmarks` → 取消 | ✓ PASS | 列表项形态 = FeedCard,视角字段为 B;取消后不含 |
|
||||
| 8 | 评论 ×2 / 作者软删 / 帖主越权删被拒 | ✓ PASS | B 删自己 200;A(帖主)删 B 的 **403 / 40301**;`commentCount` 同事务 +1/-1 准确 |
|
||||
| 9 | 关注幂等 + follow-stats + 自关注拒绝 | ✓ PASS | 重复 PUT 幂等 200;自关注 **422 / 42204**;自取关 200 no-op;A 查自己 `followedByMe` 恒 false |
|
||||
| 10 | **验收③** 25 帖 → 双粒度全量翻页比对 | ✓ PASS | limit=7 → 17 页 117 条;limit=100 → 2 页 117 条;两种页大小**逐位一致**,零重复零遗漏 |
|
||||
| 11 | **验收④** 软删一帖 → 出 Feed + 直接 GET 404 | ✓ PASS | 删后全量恰少 1;B 与作者 A 直接 GET 均 **404 / 40403** 且响应体逐字节一致 |
|
||||
| 12 | 防枚举:草稿 vs 随机 UUID 响应体一致 | ✓ PASS | 四路全 **404 / 40403** 一致 `{"code":40403,"message":"帖子不存在","data":null}`;互动面恒为公开面;草稿对作者详情仍可见、不入公共 Feed |
|
||||
| 13 | v3 社区事件上报 + 白名单/字典兜底 | ✓ PASS | 8 条 → **202** `accepted=8`;白名单外键剥离后仍 accepted;字典外 `post_impression` 整条 rejected(`unknown_event_name`),批次仍 202 |
|
||||
| 14 | 幂等重放:同键同 hash / 异 hash / 缺头 / 跨作者 | ✓ PASS | 同键同 hash 返回原帖不产生第二帖;异 hash **409 / 40905**;缺 `Idempotency-Key` **400 / 40000**;幂等键按作者隔离 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 数据库证据(两域共存,只读 psql)
|
||||
|
||||
### 4.1 schema 与 Flyway 迁移
|
||||
|
||||
```sql
|
||||
-- \dn
|
||||
community | identity | media | pet_health | platform | public
|
||||
|
||||
-- select installed_rank, version, description, success from public.flyway_schema_history;
|
||||
1 | 1 | identity media baseline | t
|
||||
2 | 2 | create platform product events | t
|
||||
3 | 3 | pet health baseline | t
|
||||
4 | 4 | pet health dictionary seed | t
|
||||
5 | 5 | community baseline | t
|
||||
```
|
||||
|
||||
V1~V5 全 `success=t`,M3 的 V5 未触碰 M2 的 V3/V4(不可变迁移纪律保持)。
|
||||
|
||||
### 4.2 两域数据行数(六次脚本运行累计,含既有残留)
|
||||
|
||||
```sql
|
||||
pet_health.pets | 8 community.posts | 131
|
||||
pet_weight_records | 9 community.comments | 10
|
||||
pet_vaccinations | 7 community.post_likes | 3
|
||||
health_events | 6 community.user_follows | 3
|
||||
care_reminders | 6 media.assets | 17
|
||||
pet_owners | 8 platform.product_events | 61
|
||||
```
|
||||
|
||||
两域各 8 张表并存于同一实例,交叉执行无外键/唯一键冲突、无死锁。
|
||||
|
||||
### 4.3 埋点落库核对
|
||||
|
||||
M2 本轮会话(`session_id=1e1a8388-…`,共 4 条 = 上报数):
|
||||
|
||||
```sql
|
||||
health_record_create_succeeded | android | 1.0.0+e2e | 2
|
||||
page_viewed | android | 1.0.0+e2e | 1
|
||||
pet_create_succeeded | android | 1.0.0+e2e | 1
|
||||
```
|
||||
|
||||
M3 本轮会话(`session_id=a28da209-…`,8 白名单事件 + 1 条隐私兜底事件):
|
||||
|
||||
```sql
|
||||
comment_create_succeeded | 1 post_liked | 2
|
||||
feed_viewed | 1 post_media_upload_succeeded | 1
|
||||
page_viewed | 1 post_publish_succeeded | 1
|
||||
post_favorited | 1 user_followed | 1
|
||||
```
|
||||
|
||||
隐私红线兜底与字典守门实测:
|
||||
|
||||
```sql
|
||||
-- 字典外事件未落库
|
||||
select count(*) from platform.product_events where event_name='post_impression'; -- 0
|
||||
|
||||
-- 混入白名单外 postId 的 post_liked:落库 props 已剥离
|
||||
select props from platform.product_events where event_id='bc13cbbd-…';
|
||||
{"source": "feed"} -- 无 postId
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 契约偏差声明与共享面回归分析
|
||||
|
||||
### 5.1 契约偏差数:**0 个**
|
||||
|
||||
两份脚本共 132 条断言覆盖 HTTP 状态码、业务错误码、信封结构、字段形态、分页语义、
|
||||
幂等语义、乐观锁语义与防枚举一致性,与冻结契约 **v1.3.0** 全部一致,无需修复项。
|
||||
|
||||
### 5.2 M2 契约面在 v1.3.0 中零漂移(结构化取证)
|
||||
|
||||
M3 期间四模块契约快照从 `openapi-v1.2.0.yaml` 换名到 `openapi-v1.3.0.yaml`,
|
||||
是本次回归最需要盯的共享面。对 `doc@511617b`(v1.2.0 冻结)与 `doc@f848476`(v1.3.0 冻结)
|
||||
做结构化比对(YAML 解析后按键排序序列化对比,非文本 diff):
|
||||
|
||||
```text
|
||||
info.version: 1.2.0 -> 1.3.0
|
||||
paths:18 -> 31(+13,全部为 community/media 新增;removed: NONE)
|
||||
v1.2.0 的 18 条 path 定义 —— CHANGED/MISSING: NONE(全部完全一致)
|
||||
schemas:45 -> 72(+27)
|
||||
removed schemas: NONE
|
||||
changed schemas: NONE
|
||||
```
|
||||
|
||||
即 **v1.3.0 相对 v1.2.0 严格增量**:M2 的 18 条路径与 45 个 schema 一字未改,
|
||||
M2 版脚本对照 v1.3.0 运行等价于对照 v1.2.0 运行。
|
||||
|
||||
### 5.3 共享代码面回归分析(`64c9b72..8089c06`,即 M3 全区间)
|
||||
|
||||
```text
|
||||
patbond-pet/src/main/ → 0 个文件变更(pets 域生产代码 M3 期间未被触碰)
|
||||
patbond-pet/ 变更仅在测试侧:ContractConformanceTest / ContractValidator /
|
||||
OpenApiContract + 快照文件改名(v1.2.0 → v1.3.0)
|
||||
patbond-common/ → 仅 ErrorCode.java +9 行,纯新增枚举常量:
|
||||
POST_ACCESS_DENIED(40301) / POST_NOT_FOUND(40403) / IDEMPOTENCY_PAYLOAD_MISMATCH(40905)
|
||||
MEDIA_NOT_FOUND(40405) / COMMENT_NOT_FOUND(40404) / TARGET_USER_NOT_FOUND(40406)
|
||||
MEDIA_NOT_READY(42203) / FOLLOW_RULE_VIOLATION(42204) / MEDIA_UPLOAD_STATE_INVALID(42205)
|
||||
—— 无任何 `-` 行,M2 错误码(40401/40902/40000…)定义未被修改或删除
|
||||
```
|
||||
|
||||
三条共享面(契约快照、`patbond-common`、同一数据库实例)均验证为纯增量,
|
||||
与实测的 11/11 结果互为印证:**M3 交付未破坏 M2 功能,无回归**。
|
||||
|
||||
---
|
||||
|
||||
## 6. 失败项
|
||||
|
||||
**无。** 六次脚本运行(M2 ×3、M3 ×3)全部 `exit 0`,输出中 `✗`/`FAIL` 计数为 0,
|
||||
无需区分「脚本环境问题」与「真实回归」。
|
||||
|
||||
---
|
||||
|
||||
## 7. 三仓状态(零改动核验)
|
||||
|
||||
```bash
|
||||
cd <你的工作区>/patbond-api && git status --short # 空
|
||||
cd <你的工作区>/patbond-flutter && git status --short # 空
|
||||
cd <你的工作区>/patbond-doc && git status --short # 仅本报告(未 commit)
|
||||
```
|
||||
|
||||
| 仓 | HEAD |
|
||||
| --- | --- |
|
||||
| patbond-api | `8089c06` feat: 事件字典 v3 白名单扩充…(T3-20) |
|
||||
| patbond-flutter | `0e87413` test: M3 E2E 烟囱脚本(T3-21 收官) |
|
||||
| patbond-doc | `3ebe562` docs: M3 收官——E2E 报告与收官总结入档,验收 PASSED |
|
||||
|
||||
(`patbond-api/*/target/` 下的重建产物为 gitignore 覆盖项,不产生工作区脏状态。)
|
||||
|
||||
---
|
||||
|
||||
## 8. 环境清理
|
||||
|
||||
```bash
|
||||
cd <你的工作区>/patbond-api && docker compose down
|
||||
```
|
||||
|
||||
数据卷 `pgdata` / `minio-data` 按既往做法保留(未加 `-v`),便于下次复跑与事后取证。
|
||||
|
||||
---
|
||||
|
||||
## 9. 遗留与后续
|
||||
|
||||
1. **真机挂起项不变**:M2 的两项(Android 事件落库真机观察、SessionTracker 30min 手测)与
|
||||
M3 的真机项仍按方案 A 挂起,本次脚本直连不替代真机验证——见 `docs/development/device-verification.md`。
|
||||
2. **发布 checklist 后续步骤**:本报告只闭合 §3.3 第 2 步;第 3 步(命名统一 + api `main` 重建)、
|
||||
第 4~8 步(合并/打标/分支保护/发布说明/hotfix 纪律)待拍板后执行。
|
||||
3. **E2E 自动化仍为手动模式**:iteration-3/08 §5 的结论(保持「波次收尾手动跑、证据入档」,
|
||||
自动化做成 `workflow_dispatch` 手动工作流,低优先)未变;本次两份脚本 3 秒内跑完,
|
||||
手动成本极低,暂无自动化紧迫性。
|
||||
@@ -0,0 +1,61 @@
|
||||
# 发布记录(常设)
|
||||
|
||||
> **定位**:跨迭代常设文档——每次 `dev → main` 发布在此追加一条记录:版本号、三仓 tag 与哈希、门禁证据、已知遗留。
|
||||
> **维护约定**:按[发布 checklist](iterations/iteration-3/08-git-workflow-plan.md)(§3.3) 执行,完成后在此登记。最新版本在最上。
|
||||
> 发布分支为 `main`(ADR-011 原写 master,ADR-021 更正);日常开发直推 `dev`。
|
||||
|
||||
---
|
||||
|
||||
## v0.3.0 — M3 社区(2026-09-10)
|
||||
|
||||
**首次正式发布**,发布流程首次演练。
|
||||
|
||||
### 三仓 tag
|
||||
|
||||
| 仓库 | tag | 提交 | 内容 |
|
||||
| --- | --- | --- | --- |
|
||||
| patbond-api | `v0.3.0` | `8089c06` | 五模块(common/auth:8081/user:8082/pet:8083/community:8084),334 测试 |
|
||||
| patbond-flutter | `v0.3.0` | `0e87413` | 502 测试 + 三份 E2E 烟囱脚本(M1/M2/M3) |
|
||||
| patbond-doc | `v0.3.0` | 本记录所在提交 | 契约 v1.3.0 + 三迭代全部报告(20+30+30 份) |
|
||||
|
||||
### 版本内容
|
||||
|
||||
- **M1 认证纵切**:JWT RS256、refresh 轮换、多设备会话、登录锁定
|
||||
- **M2 宠物健康档案**:宠物 CRUD + 三角色权限 + 体重/疫苗/健康事件/提醒 + 档案聚合(18 操作)
|
||||
- **M3 社区**:图片媒体上传闭环(自托管 MinIO,ADR-016)+ 帖子草稿/发布/删除 + 公共 Feed 游标分页 + 单层评论 + 点赞收藏幂等 + 关注(13 路径/19 操作)
|
||||
- **契约**:openapi.yaml **v1.3.0 冻结**,31 路径/43 操作/72 schema;契约一致性测试矩阵 173 格、43/43 操作零漂移
|
||||
- **部署形态**:docker compose 六容器(postgres:18 + MinIO + auth + user + pet + community),应用容器无状态(ADR-007)
|
||||
- **数据库**:Flyway V1~V5(identity/media、platform 埋点、pet_health、字典种子、community)
|
||||
- **决策**:ADR-001~021
|
||||
|
||||
### 发布门禁证据
|
||||
|
||||
| 门禁项 | 结果 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| 三仓 CI 绿 | ✅ | Gitea commit status API 直查 success |
|
||||
| 全量测试 | ✅ | api 334 / flutter 502,`mvnw clean test` 与 `flutter test` 双绿 |
|
||||
| E2E 回归(M2+M3 同环境) | ✅ | **M2 11/11 + M3 14/14**,各连跑 3 轮零 flake,契约偏差 0 — [30 号报告](iterations/iteration-3/30-release-e2e-regression.md) |
|
||||
| M3 验收标准逐条取证 | ✅ | 四条全过 — [28 号报告](iterations/iteration-3/28-e2e-smoke-report.md) |
|
||||
| 契约向后兼容 | ✅ | v1.2.0→v1.3.0 结构化比对:paths/schemas **removed 与 changed 均为 NONE**(严格增量) |
|
||||
| 共享代码面回归分析 | ✅ | M3 全区间 `patbond-pet/src/main/` 0 文件变更;`patbond-common` 仅 ErrorCode +9 行纯新增 |
|
||||
| 凭证防泄漏 | ✅ | `check-secrets.sh --all` 三仓 exit 0(9 规则两层检查,ADR-021) |
|
||||
|
||||
### 发布操作记录(首次一次性项)
|
||||
|
||||
1. **命名统一**:ADR-011 的 `master` 更正为 `main`(ADR-021);api 本地孤儿 master 已删。
|
||||
2. **api main 重建**(方案 A,用户拍板):远端 main 原为建仓自动生成的单提交 `ff876bc "Add README"`,与 dev **无共同祖先**,无法 ff 也不宜缝合孤儿历史。操作:Gitea 默认分支临时切 dev → 删除远端 main → `git push origin dev:refs/heads/main` 重建 → 默认分支切回 main。结果:main 41 提交、与 dev 同点位、零 force push。原孤儿提交保留本地备份 ref `refs/backup/old-main-ff876bc`。
|
||||
3. **flutter main 快进**:main 本就是 dev 祖先,用 `git push origin dev:main` 完成——**较 checklist 第 4 步的 `checkout main && merge --ff-only` 改进**:不切换工作区(当时有 E2E 脚本正在该工作区运行),且非快进推送会被 git 自动拒绝,等于内建 ff-only 保护。建议固化此写法。
|
||||
|
||||
### 已知遗留(不阻塞发布)
|
||||
|
||||
**真机验证四项挂起**(步骤已备齐在[真机验证清单](device-verification.md)):媒体上传弱网、乐观更新手感、Feed 图片加载、社区事件落库;另有 M2 两项(Android 事件落库、SessionTracker 30min)。桌面/脚本不可替代——`platform=linux` 埋点整批 400 属契约内行为。
|
||||
|
||||
**功能遗留**:完整草稿列表与自动保存、大图下滑关闭手势、`widthPx/heightPx` 恒 null(单图帖回落 4:3)、`eventVersion` 口径未定型、uploading 超时清理任务、429 限流(连带客户端 Retry-After 分支)、话题/关注列表/作者主页(ADR-018 剪出)。
|
||||
|
||||
**跨迭代技术债**:access token 黑名单(退出后已签发 access 在剩余 ≤15 分钟内仍有效)、`/internal` 改 mTLS。
|
||||
|
||||
### 发布后生效的纪律
|
||||
|
||||
- 影响 `main` 的 hotfix 一律走短命分支 + PR(ADR-021 强制情形之二正式生效)
|
||||
- `main` 分支保护(禁直推、合并需 CI 状态检查通过)在 Gitea 平台启用;`dev` 保持直推流
|
||||
- 下次发布 `dev → main` 应能 `--ff-only` 通过;过不了说明 main 被绕过 dev 改动,先查明原因
|
||||
@@ -8,6 +8,7 @@ nav:
|
||||
- Git 工作流规范: development/git-workflow.md
|
||||
- 功能完成清单: development/feature-checklist.md
|
||||
- 真机验证清单: development/device-verification.md
|
||||
- 发布记录: development/releases.md
|
||||
- CI Runner 部署手册: development/ci-runner-setup.md
|
||||
- 第一迭代:
|
||||
- 进展看板: development/iterations/iteration-1/index.md
|
||||
@@ -94,6 +95,7 @@ nav:
|
||||
- 27 第三波收口: development/iterations/iteration-3/27-wave3-closure.md
|
||||
- 28 E2E 烟囱收官: development/iterations/iteration-3/28-e2e-smoke-report.md
|
||||
- 29 M3 收官总结: development/iterations/iteration-3/29-m3-summary.md
|
||||
- 30 发布 E2E 回归: development/iterations/iteration-3/30-release-e2e-regression.md
|
||||
- API:
|
||||
- 契约说明: api/index.md
|
||||
- 架构:
|
||||
|
||||
Reference in New Issue
Block a user