Files
danyang-match/docs/superpowers/plans/2026-10-19-demo-release-repair-plan.md
T
WorkBuddy 69ebf33e18
CI/CD Pipeline / Backend Build & Test (push) Canceled after 0s
CI/CD Pipeline / Admin Web Build (push) Canceled after 0s
CI/CD Pipeline / Mini Program Compile Check (push) Canceled after 0s
CI/CD Pipeline / Migration Validation (push) Canceled after 0s
CI/CD Pipeline / Test Shell Guard (Phase 23 Gate) (push) Canceled after 0s
CI/CD Pipeline / UI Contracts (source-structure gates) (push) Canceled after 0s
CI/CD Pipeline / E2E (live stack) (push) Canceled after 0s
release: freeze demo v1.1.0 2026-10-19
2026-10-19 20:36:22 +08:00

350 lines
15 KiB
Markdown

# V1.1 演示发布修复实施计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 在不依赖真实微信账号、生产证书、正式域名、真实用户 UAT 和外部备份介质的前提下,修复当前代码并形成可重复启动、可验证的 V1.1 演示版本。
**Architecture:** 保留现有模块化单体、Mock 微信 Provider、PostgreSQL、Redis、SeaweedFS、管理端和小程序结构。演示环境与生产环境配置分开;演示验收使用真实 HTTP、真实 PostgreSQL 和真实容器,不把 H2 或静态断言当作完整演示证据。
**Tech Stack:** Java 21 / Spring Boot 3 / Maven / PostgreSQL 16 / Redis 7 / SeaweedFS 4.47 / Docker Compose / Vue 3 / TypeScript / 微信原生小程序 / pytest。
**Spec:** `AGENTS.md`、`README.md`、`docs/PHASE26-GO-LIVE-CHECKLIST.md`、`docs/善缘丹阳 V1.1 客户需求基线增量开发与修复计划.md`。
## Global Constraints
- 演示环境允许 Mock 微信登录,但必须显式使用演示 profile,不能让生产 profile 误启用 Mock。
- PostgreSQL 是 Source of Truth;演示 E2E 必须使用真实 PostgreSQL,不得以 H2 结果替代。
- 活动互选必须经过双方确认后才创建 Match;红娘权限必须由服务端分配范围控制。
- 不修改真实微信、生产证书、正式域名、真实用户 UAT、外部备份介质相关范围;这些作为正式发布前遗留项记录。
- 不清理或回滚用户现有未提交改动;发布候选树必须通过显式文件清单建立。
- 不新增依赖;优先使用已有 Maven、pnpm、npm、pytest 和 Compose 工具链。
- 每个任务完成后先跑该任务的最小测试,再进入下一任务;全量回归最后执行。
---
### Task 1: 建立演示发布基线并隔离工作区变更
**Files:**
- Modify: `docs/STATUS.md`(追加本次演示修复批次状态)
- Modify: `docs/REMAINING_WORK.md`(把真实生产风险与演示阻塞分开)
- Create: `docs/demo/DEMO-RELEASE-BASELINE-2026-10-19.md`
- Inspect: `git status --short`、`git diff --stat`、`VERSION`、现有 release tag
**Interfaces:**
- Produces: 演示候选版本的文件清单、排除清单和验证命令。
- Later tasks consume: 候选版本范围,避免把 `.mimosa/`、`.trae/`、`.wb_tmp_bcrypt/` 和未审查演示文件混入发布。
- [ ] **Step 1: 记录当前失败基线**
记录当前命令及结果:
```powershell
git status --short
git diff --stat
mvn -B test -f backend/pom.xml
pnpm --dir admin-web type-check
pnpm --dir admin-web build
npm --prefix miniapp run type-check
python scripts/check-no-empty-tests.py
```
- [ ] **Step 2: 建立候选文件清单**
将生产代码、测试、迁移、演示 Compose、E2E 和文档分组;明确机器临时目录、H5 演示目录和新增迁移是否纳入本批次。
- [ ] **Step 3: 记录演示版接受边界**
在 `DEMO-RELEASE-BASELINE-2026-10-19.md` 写明:Mock 微信可用、HTTPS/正式域名不验收、演示账号不代表真实用户验收、备份只做本机可恢复性检查。
- [ ] **Step 4: 验证文档不再互相矛盾**
检查 README、STATUS、REMAINING_WORK、PHASE26 清单中的演示状态一致;不得把历史全绿报告写成当前证据。
**验收:** 文档能准确指出当前失败项、演示范围和排除范围;不改业务代码。
---
### Task 2: 修复后端当前 9 个失败门禁
**Files:**
- Modify: `backend/src/main/java/com/danyang/match/platform/shared/config/SecurityConfig.java` 或实际配置匿名路径的文件
- Modify: `backend/src/main/java/com/danyang/match/platform/auth/controller/AuthController.java`(仅在测试证明登录入口路径配置错误时)
- Modify: `backend/src/main/java/com/danyang/match/platform/health/controller/HealthController.java`(仅在映射存在但未放行时)
- Modify: `backend/src/test/java/com/danyang/match/platform/auth/AuthControllerTest.java`
- Modify: `backend/src/test/java/com/danyang/match/platform/auth/HealthControllerTest.java`
- Modify: `backend/src/test/java/com/danyang/match/platform/auth/PublicMiniappApiTest.java`
**Interfaces:**
- Produces: 未认证健康检查和公开小程序接口返回约定的 200;受保护接口仍返回 401/403。
- Preserves: `Authorization: Bearer`、运营端和用户端角色隔离、统一响应体格式。
- [ ] **Step 1: 先定位过滤链原因**
用失败测试和 `SecurityConfig` 的 request matcher 对照,列出每个失败 URI、期望状态、当前 matcher。不要通过降低测试断言来消除失败。
- [ ] **Step 2: 写最小回归断言**
为每个公开 URI 保留匿名 200 用例,并为一个受保护业务 URI 保留匿名 401 用例,确保放行规则没有扩大到用户数据接口。
- [ ] **Step 3: 修改一次共享安全配置**
在统一的 Security matcher 中补齐健康、版本、微信登录和公开小程序资源;不在各 Controller 增加重复鉴权绕过。
- [ ] **Step 4: 运行专项测试**
```powershell
mvn -B -f backend/pom.xml test `
"-Dtest=AuthControllerTest,HealthControllerTest,PublicMiniappApiTest"
```
- [ ] **Step 5: 运行权限回归**
```powershell
mvn -B -f backend/pom.xml test `
"-Dtest=SecurityPathCoverageTest,OperatorEndpointPermissionCoverageTest,V11PermissionMatrixContractTest"
```
**验收:** 上述专项测试全绿;匿名公开接口不泄露用户数据;受保护接口仍不能匿名访问。
---
### Task 3: 修复 V061 迁移与基线守卫
**Files:**
- Modify: `backend/src/main/resources/db/migration/V061__extend_matchmaker_assistance.sql`
- Modify: `backend/src/test/java/com/danyang/match/platform/deployment/MigrationValidationTest.java`
- Modify: `backend/src/test/resources/schema-h2.sql`(只有实体/测试 SQL 需要同步时才改)
- Modify: `docs/database/MIGRATION_GUIDE.md`
**Interfaces:**
- Produces: 唯一、连续、可被 Flyway 识别的 V061 迁移;测试基线与生产迁移目录一致。
- Preserves: 已部署 V001-V060,不重写历史迁移,不复用已发布版本号。
- [ ] **Step 1: 用现有正则定位失败原因**
现有守卫要求 `V\\d{3}__[^_]+(?:_[^_]+)*\\.sql`;确认 `extend_matchmaker_assistance` 中的双下划线是否导致描述段不符合当前规则,并记录选择。
- [ ] **Step 2: 选择兼容命名方案**
优先把文件名改为满足现有命名规则的单下划线描述;如果业务确实需要允许双下划线,则修改守卫并新增正例/负例,不能只把 `LATEST_MIGRATION` 改成 61。
- [ ] **Step 3: 更新迁移基线说明**
在测试注释和迁移指南中登记 V061 的用途、不可重复执行要求和 `matchmaker_services` 新字段。
- [ ] **Step 4: 做源码和构建产物双重验证**
```powershell
mvn -B -f backend/pom.xml -DskipTests package
mvn -B -f backend/pom.xml test `
"-Dtest=MigrationValidationTest,EntityMigrationParityTest,DeploymentTests"
```
**验收:** V061 命名守卫通过;构建产物中无重复版本;空库 Flyway 可从头执行到 V061。
---
### Task 4: 修复并验证演示 Compose
**Files:**
- Modify: `infrastructure/docker-compose.yml`
- Modify: `infrastructure/docker-compose.staging.yml`
- Modify: `infrastructure/docker-compose.prod.yml`(只修语法和清晰的演示/生产边界,不把生产风险伪装成已解决)
- Modify: `infrastructure/.env.example`
- Modify: `infrastructure/nginx.conf`
- Modify: `h5-demo/`(仅当容器构建或 `/h5/` 路由失败时)
- Create: `infrastructure/.env.demo.example`(若现有 `.env.example` 无法表达演示必需变量)
**Interfaces:**
- Produces: `danyang-demo` 项目可独立启动,端口、容器名、健康检查和演示 Mock 配置一致。
- Preserves: 生产 Compose 使用必需变量和 secret;不把演示密码复制进生产文件。
- [ ] **Step 1: 修正生产 Compose 插值语法**
把 `${MINIO_PUBLIC_ENDPOINT:http://seaweedfs:8333}` 改成 Compose 合法形式 `${MINIO_PUBLIC_ENDPOINT:-http://seaweedfs:8333}`,并扫描同类错误。
- [ ] **Step 2: 固化演示环境变量**
演示 `.env` 至少提供 `DB_PASSWORD`、`REDIS_PASSWORD`、`MINIO_ACCESS_KEY`、`MINIO_SECRET_KEY`、`JWT_ACCESS_SECRET`、`JWT_REFRESH_SECRET`、`ENCRYPTION_KEY` 和 `WECHAT_MOCK_OPENID`;文件中的值只用于本机演示。
- [ ] **Step 3: 隔离 Compose 项目名**
所有演示命令统一使用:
```powershell
docker compose -p danyang-demo -f infrastructure/docker-compose.yml config --quiet
docker compose -p danyang-demo -f infrastructure/docker-compose.yml up -d --build
```
- [ ] **Step 4: 验证容器健康和路由**
检查 PostgreSQL、Redis、SeaweedFS、storage-init、backend、admin-web、h5-web、nginx;验证 `/api/v1/health/live`、`/admin/`、`/h5/`。
- [ ] **Step 5: 清理演示栈**
```powershell
docker compose -p danyang-demo -f infrastructure/docker-compose.yml down
```
仅删除演示项目容器,不使用跨项目的 `--remove-orphans`。
**验收:** 本地 Compose 解析成功;演示栈可重复启动和停止;生产 Compose 至少能在提供必需变量后解析成功。
---
### Task 5: 修复演示 E2E 运行条件并完成核心闭环
**Files:**
- Modify: `tests/e2e/conftest.py`(仅修环境变量、URL 或账号种子问题)
- Modify: `tests/e2e/sql/seed_e2e_operators.sql`
- Modify: `tests/e2e/home_v11_test.py`
- Modify: `tests/e2e/local_eligibility_test.py`
- Modify: `tests/e2e/activity_mutual_consent_test.py`
- Modify: `tests/e2e/service_appointment_test.py`
- Modify: `tests/e2e/referral_v11_test.py`
- Modify: `tests/e2e/service_station_permission_test.py`
- Modify: `tests/e2e/counseling_permission_test.py`
- Modify: `tests/e2e/content_e2e_test.py`
- Inspect: `tests/e2e/run_v11_tests.py`(不得把未收集脚本算作 pytest 通过)
**Interfaces:**
- Produces: 面向演示栈的真实 HTTP + PostgreSQL E2E 结果。
- Preserves: 活栈不可达退出码 4;不使用 skip 伪装未执行;Mock 只替代微信登录。
- [ ] **Step 1: 先验证活栈失败路径**
在未启动栈时运行 `python -m pytest tests/e2e -q`,确认是明确的活栈退出,而不是大量测试被跳过。
- [ ] **Step 2: 启动演示栈并初始化 E2E 账号**
使用隔离 Compose 项目名;通过 SQL seed 创建 `e2e_admin`、`e2e_platform`、`e2e_counselor`、`e2e_station`、`e2e_matchmaker`、`e2e_content`,密码仅通过环境变量传入。
- [ ] **Step 3: 运行 E2E**
```powershell
$env:E2E_BASE_URL='http://localhost:8085/api/v1'
$env:E2E_OPERATOR_PASSWORD='演示环境密码'
python -m pytest tests/e2e -q
```
- [ ] **Step 4: 修复真实失败根因**
按失败类型处理:登录/fixture 配置、权限范围、迁移数据、HTTP 状态码、业务状态机。禁止直接放宽断言或给测试增加 skip。
- [ ] **Step 5: 验证核心跨端路径**
至少保留一条可复现证据:运营端分配红娘服务 → 用户端看到服务记录 → 用户提交服务操作 → Web 查询结果;确认服务端依据 `matchmaker_assignments` 判定范围。
**验收:** `tests/e2e` 在演示活栈中通过;活栈停止时套件明确失败;核心红娘跨端链路有日志和结果记录。
---
### Task 6: 演示功能冒烟与前端构建收口
**Files:**
- Modify: `infrastructure/scripts/smoke-test.sh`(仅补演示端口或健康接口)
- Modify: `docs/DEMO-VALIDATION-2026-10-13.md`(更新为当前命令和结果)
- Modify: `docs/PHASE26-GO-LIVE-CHECKLIST.md`(增加演示版状态,不删除正式发布要求)
- Inspect: `admin-web/src/`、`miniapp/`、`h5-demo/`
**Interfaces:**
- Produces: 管理端、小程序静态检查、H5 演示和后端健康检查的统一演示报告。
- Preserves: 不把 CSS 警告或构建成功误报为完整 UI 验收。
- [ ] **Step 1: 运行前端门禁**
```powershell
pnpm --dir admin-web type-check
pnpm --dir admin-web build
npm --prefix miniapp run type-check
node ui-tests/ui-document-baseline-contracts.mjs
python scripts/check-no-empty-tests.py
```
- [ ] **Step 2: 做演示端人工路径**
用浏览器验证 `/admin/` 登录、首页、红娘工作台、咨询、服务站、内容管理;用微信开发者工具验证 Mock 登录、首页、推荐、活动、服务记录和退出登录。
- [ ] **Step 3: 记录构建警告**
CSS `url(var(--...))` 警告和大 chunk 先作为 P2 记录;只有造成页面空白、资源加载失败或路由不可用时才提升为 P0。
- [ ] **Step 4: 输出演示验收报告**
报告按 PASS / PARTIAL / FAIL / NOT_VERIFIED 分类,附命令、时间、环境、失败截图或日志路径。
**验收:** 所有演示核心路径可操作;未通过项明确列出,不用“构建通过”替代人工路径。
---
### Task 7: 演示版冻结与回归门禁
**Files:**
- Create: `docs/demo/DEMO-RELEASE-REPORT-2026-10-19.md`
- Modify: `VERSION`(仅在验收通过后)
- Inspect: `git diff --check`、`git status --short`、发布 tag 和 bundle
**Interfaces:**
- Produces: 一个干净、可追溯、可重新部署的演示版本。
- Preserves: 不宣称正式生产发布;正式风险继续列在独立的 release blocker 区域。
- [ ] **Step 1: 执行全量回归**
```powershell
mvn -B -f backend/pom.xml test
pnpm --dir admin-web type-check
pnpm --dir admin-web build
npm --prefix miniapp run type-check
python -m pytest tests/e2e -q
docker compose -p danyang-demo -f infrastructure/docker-compose.yml config --quiet
git diff --check
```
- [ ] **Step 2: 检查发布候选树**
只允许本次修复和必要测试/文档进入候选树;临时目录、密码、token、数据库 dump 不得进入。
- [ ] **Step 3: 生成演示 tag 和 bundle**
```powershell
git tag demo-v1.1.0-20261019 <release-commit>
git bundle create demo-v1.1.0-20261019.bundle demo-v1.1.0-20261019
git show demo-v1.1.0-20261019 --stat
```
- [ ] **Step 4: 回读验证 tag 和 bundle**
```powershell
git tag --verify demo-v1.1.0-20261019
git bundle verify demo-v1.1.0-20261019.bundle
git status --short
```
**验收:** 全量门禁满足演示版标准;tag、bundle、报告三者指向同一提交;工作区没有未解释的发布变更。
---
## 依赖关系
```text
Task 1
↓
Task 2 ──┐
Task 3 ──┼─> Task 4 ─> Task 5 ─> Task 6 ─> Task 7
┘
```
## 演示版最终门禁
- **PASS:** 后端全量测试 0 failure / 0 error。
- **PASS:** 演示 Compose 解析、启动、健康检查、停止均成功。
- **PASS:** E2E 使用真实 PostgreSQL,核心场景通过,未使用 skip 伪绿。
- **PASS:** Admin 类型检查和构建、小程序类型检查、UI 契约守卫通过。
- **PASS:** Mock 微信登录只在演示 profile 生效。
- **PASS:** 演示账号、密钥和数据库数据均与生产隔离。
- **NOT_VERIFIED(允许保留):** 真实微信、生产证书、正式域名、真实用户 UAT、外部备份介质。
## 本计划明确跳过的内容
本批次不接入真实微信、不申请或验证生产证书、不配置正式域名、不进行真实用户验收、不验证外部备份介质恢复,也不借此宣称正式生产可发布。