153 lines
12 KiB
Markdown
153 lines
12 KiB
Markdown
# 宠小它 Phase 2 Pilot RC4 Release Manifest
|
||
|
||
> RC ID:`phase2-pilot-rc4`
|
||
> 冻结日期:2026-08-02
|
||
> 状态:**Ready for Release(未部署)**
|
||
> 适用范围:3~5 家独立宠物洗护单店真实试点
|
||
> 样本目标:约 200 次完整服务后进行 Phase 2 / 商业化决策
|
||
|
||
RC4 是当前唯一推荐候选:它继承 RC3 的单一微信登录契约和 cohort-safe 指标口径,并将浏览器跨域边界收口为全局 `CorsFilter` 唯一策略。真实生产配置、备份恢复、八个迁移、TLS、live CORS smoke、三角色验收和首份真实指标基线未形成证据前,不得把状态改为 `Released`。
|
||
|
||
## 1. 前序 RC 取代说明
|
||
|
||
- `phase2-pilot-rc1`:因指标默认覆盖全店/全历史、对象粒度混用和 24h 未成熟 cohort 被 RC2 取代。
|
||
- `phase2-pilot-rc2`:因公开微信网页 OAuth demo 会产生伪造身份,被 RC3 取代。
|
||
- `phase2-pilot-rc3`:应用主链、登录契约和指标可用,但 17 个 Controller 仍保留无参数 `@CrossOrigin`,形成危险的第二套跨域策略;被 RC4 取代。
|
||
|
||
RC4 删除全部 Controller 级 `@CrossOrigin`,白名单只来自 `CORS_ALLOWED_ORIGINS`;新增真实 Filter 契约测试和 production smoke 的 allow/deny 双分支。数据库、接口路径和现有 session 无迁移或兼容影响。既有 tag 与清单保持不动,只用于审计。
|
||
|
||
## 2. 冻结提交与回滚点
|
||
|
||
| 仓库 | RC4 commit / ref | 前一候选回滚点(RC3) | 冻结状态 |
|
||
|---|---|---|---|
|
||
| backend | `752fcaa38d849deaafcbbad1d70cb785d2f4000b` | `339c793855717970540ba752ba999d06e17becac` | `main == origin/main`,clean |
|
||
| admin | `078ae0f9d18e6598a1af13fa8bf2b5b97c25a410` | 同 commit | `main == origin/main`,clean |
|
||
| frontend | `a595ea8fa17dd0dbdfb607abea93e8c0d24b13a8` | 同 commit | `main == origin/main`,clean |
|
||
| docs | `refs/tags/phase2-pilot-rc4`(本清单所在 commit) | `c902bf47868158e9c0b3c21821f4f3d78594cfe1` | tag 推送后解析并复核 clean |
|
||
|
||
部署前必须在四仓分别解析 `phase2-pilot-rc4` 并与本表一致;任何源码变化、产物 hash 变化或 tag 不一致都必须建立新 RC,不得移动已有 tag 或覆盖本记录。
|
||
|
||
## 3. RC 产品范围
|
||
|
||
本 RC 收口以下真实试点业务内核:
|
||
|
||
1. 预约客户与服务执行人身份拆分;
|
||
2. 同店 `StoreCustomer` 客户主档及低敏事实时间线;
|
||
3. 不可变、幂等、低敏 `BusinessEvent` 与 `AuditLog`;
|
||
4. 服务时长快照、门店容量和连续时段占用;
|
||
5. 基于事实的门店行动工作台;
|
||
6. 报告 `unknown / unsent / sent` 显式发送确认;
|
||
7. 微信小程序核验老板入驻、门店开通清单和一次性员工邀请;
|
||
8. `FollowUpTask` 领取/改期/终结状态机与真实预约归因;
|
||
9. 三角色验收脚本、cohort-safe 试点指标字典和只读聚合查询 v2;
|
||
10. 单一微信小程序登录契约,未实现的网页 OAuth fail-closed 下线;
|
||
11. 生产配置、readiness、31 项数据库不变量、只读 smoke 与回滚模板;
|
||
12. 全局 CORS 单一策略,以及白名单精确允许、非白名单 403 的自动门禁。
|
||
|
||
明确排除支付、库存、储值、复杂会员、多门店组织、订单系统、泛 AI、PC 扫码登录、公众号网页授权,以及未授权的任何生产写入。
|
||
|
||
## 4. 本地验证证据
|
||
|
||
验证环境:
|
||
|
||
- macOS `26.5.2` / arm64
|
||
- OpenJDK `21.0.10`(项目按 Java 17 release 编译)
|
||
- Maven `3.9.14`
|
||
- Node.js `v22.22.2`
|
||
- npm `10.9.7`
|
||
- Python `3.9.6`
|
||
- 隔离指标查询既有验证:MySQL `8.0.46`
|
||
|
||
| 门禁 | 结果 |
|
||
|---|---|
|
||
| backend `mvn test` | **PASS**:224 tests,0 failure / 0 error / 0 skipped |
|
||
| backend `mvn -q -DskipTests package` | **PASS** |
|
||
| backend `bash -n deploy/*.sh` | **PASS** |
|
||
| `CorsBoundaryContractTest` | **PASS**:非白名单 403 且不进入业务链;白名单精确回显且允许凭据;OPTIONS 不进入业务代码;Controller 源码局部 CORS 为 0 |
|
||
| production smoke 输入门禁 | **PASS**:缺少 allowed origin、origin 含 path、allowed 与 blocked 相同时均按预期拒绝 |
|
||
| production smoke 无网络合成执行 | **PASS**:以受控 `curl` stub 跑通 7/7(liveness、readiness、门店、服务时长、容量、CORS allow、CORS deny);未连接外部服务 |
|
||
| admin `npm run build` | **PASS**:1671 modules;仅既有 >500 kB chunk warning |
|
||
| frontend `npm run build:h5` | **PASS** |
|
||
| frontend `npm run build:mp-weixin` | **PASS**;`verify-mp-app-json` PASS |
|
||
| pilot metrics v2 契约与既有隔离 MySQL 执行 | **PASS**:本 RC 查询 hash 未变化;门店/窗口隔离、同粒度转化、24h 成熟分母、事件顺序与四项反例已验证 |
|
||
| ontology validate | **PASS**:288 条;Action 75、Entity 29、Event 33、Relation 102、Rule 49 |
|
||
| ontology drift | **PASS**:68/68 HTTP、16/16 JPA,code-only / ontology-only / entity drift 均为 0 |
|
||
| 四仓 `git diff --check` | **PASS** |
|
||
| 四仓工作树与远端 | 清单提交及 tag 推送后再次复核 |
|
||
|
||
合成 smoke 只证明脚本分支与响应契约,不替代正式域名、反向代理和真实 Spring 服务上的 live smoke。本地仍未运行最终 production profile 的 JPA `validate` 与生产库 31 项不变量,这两项保留为生产 No-Go 门禁。
|
||
|
||
## 5. 本地构建产物与 SHA-256
|
||
|
||
目录 hash 的复验命令在目标目录中执行:`LC_ALL=C find . -type f -print0 | LC_ALL=C sort -z | xargs -0 shasum -a 256 | shasum -a 256`。因此清单使用 `./` 开头的相对路径、`shasum` 标准双空格格式和末尾换行。
|
||
|
||
| 产物 | 大小 | SHA-256 | 可部署性 |
|
||
|---|---:|---|---|
|
||
| `backend/target/petstore-backend-1.0.0.jar` | 50,995,371 bytes | `dba96221cda4cf5a91c760fea6b5d8525d32a06b1d464fad82d7274dc682df4f` | 候选 JAR;仍须真实配置与生产只读预检 |
|
||
| `backend/db/queries/pilot_metrics.sql` | source | `d2de4684722811028474001ed7e56bbf56297733509e1a71850d7ab404587210` | 仅限只读账号/副本;执行前显式填写门店集合与窗口 |
|
||
| admin `dist`(27 files) | 1,536 KiB | `181005e11373ef9bbdba50bce35eb40b5a159c6acd8f89196749d1c12a0b4f8c` | **不可部署**:当前包含 `.invalid` 占位域名,仅证明可编译 |
|
||
| H5 `dist/build/h5`(65 files) | 852 KiB | `1f810d55d25fa86906dfb5c2a8765d24af1258ac23d91e75858495e3c121d34a` | **不可部署**:当前包含 `.invalid` 占位域名,仅证明可编译 |
|
||
| 微信小程序 `dist/build/mp-weixin`(142 files) | 820 KiB | `b06ef5bdfd70c59ff91cc405ac99c0b15625c926f8f49dc9e561def9b1300587` | **不可上传**:当前包含 `.invalid` 占位域名,仅证明可编译 |
|
||
|
||
正式 Admin/H5/小程序必须以权限受控的真实域名配置重新执行 release preflight 与 build,并把新 hash 追加到生产发布记录。
|
||
|
||
## 6. 数据库迁移冻结
|
||
|
||
迁移只能按下列顺序执行;每一步先核对 SHA-256,再执行脚本末尾反例查询。失败时停止,不交换顺序、不自动 down migration、不猜测性回填。
|
||
|
||
| 顺序 | 文件 | SHA-256 |
|
||
|---:|---|---|
|
||
| 1 | `20260801_split_service_identity.sql` | `05fa560cb59a746681057187ffaccc1db4980de8e99bbcb0c42dd6ce25a759ac` |
|
||
| 2 | `20260801_create_store_customer.sql` | `5eabfc4689d5acc9400e70fc3cbdcd0549b8e9a8763176bef7ec3715f94002dd` |
|
||
| 3 | `20260801_create_business_event.sql` | `d0a3ebe3ac2f3bd0c4c125832df4895dec66d5cc95077b4292b10055b876c184` |
|
||
| 4 | `20260801_create_booking_capacity.sql` | `25e9c8817c48a2c4854d034981f765dfe4b6ebb90f95a8f45a54513106c4ad51` |
|
||
| 5 | `20260801_create_report_send_status.sql` | `321284bc44774c69de4b584f3eb3a8f235653be6c0a5e75e3557a697f78381a2` |
|
||
| 6 | `20260802_create_store_onboarding.sql` | `40d45f382a03c35e9e9696e65553488713cdaadf90094d824f406561f196039c` |
|
||
| 7 | `20260802_create_store_customer_timeline.sql` | `5185a03f9a983823c75aae6661b0e68d51c75e226d117039b22f81f383ac7c2d` |
|
||
| 8 | `20260802_create_follow_up_task.sql` | `a1ff5176b2775745ee1fb044a15d25d1cc52dba9fef72ffb45727f430db22c09` |
|
||
|
||
八迁移完成后,以正式 service user、最终 production 配置运行 `deploy/release-preflight.sh`。通过条件是静态配置门禁、JPA schema validate 和 31 项只读数据库不变量全部成功。
|
||
|
||
## 7. 生产 Go/No-Go
|
||
|
||
- [ ] Petstore 专用 API/Admin/报告域名与 TLS 就绪,不复用或修改其他产品域名;
|
||
- [ ] 权限受控的最终配置通过 backend、admin、frontend release preflight;
|
||
- [ ] `CORS_ALLOWED_ORIGINS` 只列正式 Admin/报告 H5 origin,Controller 局部 `@CrossOrigin` 为 0;
|
||
- [ ] 生产全量备份完成,记录大小/hash,并在隔离库完成恢复演练;
|
||
- [ ] 八迁移依次执行,文件 hash 一致且每步末尾反例为 0;
|
||
- [ ] production JPA `validate` 与 31 项只读数据库不变量通过;
|
||
- [ ] 正式 Admin/H5/小程序重新构建,记录 hash,微信合法域名一致;
|
||
- [ ] Petstore 独立 systemd/Nginx 配置完成,`nginx -t` 通过,diff 未改 Gitea/GitLab;
|
||
- [ ] liveness、readiness、7/7 只读 production smoke 通过;真实 allowed origin 精确回显,blocked origin 返回 403;
|
||
- [ ] 老板、员工、宠主三角色主链及权限/异常反例全部签署 PASS;
|
||
- [ ] 微信小程序真实 AppID/AppSecret、手机号 code 和 `wx.login` code 完成真机核验;
|
||
- [ ] 外部监控、告警联系人、值班窗口和回滚执行人已真实测试;
|
||
- [ ] Gitea/GitLab 既有入口健康,服务器端口和证书未受影响;
|
||
- [ ] 首批真实数据开始计样本时,显式填写 3~5 个门店 ID,保存指标窗口、数据库快照时间、四仓 commit、低敏结果与 hash,四项指标可靠性反例为 0。
|
||
|
||
任一项未完成,结论都是 `No-Go / Ready for Release`,不得标记已上线。
|
||
|
||
## 8. 试点验收与 Phase 2 决策
|
||
|
||
- 三角色执行与证据:[`试点三角色端到端验收清单-2026-08-02.md`](../试点三角色端到端验收清单-2026-08-02.md)
|
||
- 门店开通与运营边界:[`试点门店开通清单-2026-08-01.md`](../试点门店开通清单-2026-08-01.md)
|
||
- 指标口径与决策带:[`试点指标采集与Phase2决策方案-2026-08-02.md`](../试点指标采集与Phase2决策方案-2026-08-02.md)
|
||
- CORS 单一策略:[`架构决策-全局CORS单一策略-2026-08-02.md`](../架构决策-全局CORS单一策略-2026-08-02.md)
|
||
- 网页 OAuth 下线决策:[`架构决策-下线未实现微信网页OAuth-2026-08-02.md`](../架构决策-下线未实现微信网页OAuth-2026-08-02.md)
|
||
- 只读采集脚本:`backend/db/queries/pilot_metrics.sql`
|
||
- 发布与回滚步骤:[`生产发布与回滚Runbook-2026-08-01.md`](../生产发布与回滚Runbook-2026-08-01.md)
|
||
- 监控基线:[`生产监控与告警基线-2026-08-01.md`](../生产监控与告警基线-2026-08-01.md)
|
||
- 被取代候选:[`phase2-pilot-rc1-release-manifest.md`](./phase2-pilot-rc1-release-manifest.md)、[`phase2-pilot-rc2-release-manifest.md`](./phase2-pilot-rc2-release-manifest.md)、[`phase2-pilot-rc3-release-manifest.md`](./phase2-pilot-rc3-release-manifest.md)
|
||
|
||
样本闸门为 3~5 家门店、观察 4~8 周、合计至少 200 次完整服务且每家至少 25 次。达到闸门后只能形成 `Continue`、`Iterate Core` 或 `Stop/Redesign` 三类结论;在此之前不扩展支付、库存、储值、复杂会员、多门店组织、订单系统或泛 AI。
|
||
|
||
## 9. 已知风险与回滚边界
|
||
|
||
- Admin 主 bundle 的 >500 kB warning 是已知性能债;不阻断小流量试点,但正式包仍应观察首次加载和弱网体验。
|
||
- readiness 会因数据库、磁盘、上传目录、FFmpeg/ffprobe 任一依赖异常而拒绝接流;服务器端必须逐项核验权限和路径。
|
||
- CORS 合成测试不覆盖真实 Nginx/CDN 是否修改响应头;必须以两个真实 origin 完成 live allow/deny 验证。
|
||
- 指标 v2 已在 MySQL 8.0.46 隔离实例执行;生产实际版本、数据量与执行计划仍须用只读账号在发布窗口复核,不得在主库高峰期首次运行。
|
||
- 迁移均按向前兼容设计。常规故障只回退 backend/admin/H5 版本软链接及小程序平台版本,不删除列/表/索引,不自动恢复旧备份。
|
||
- 灾难性整库恢复会丢失备份时间点后的数据,必须另获业务负责人、DBA 与隐私负责人书面授权;本 RC 不授权该操作。
|
||
- 本地验证没有使用生产凭据、真实微信账号、真实门店数据,也没有连接或修改任何生产服务器、Gitea、GitLab、Nginx、证书或业务数据库。
|