缺陷本体(实施计划附 B.1,2026-09-19 登记并实测复现,本轮处置):
OrganizationService 的 createOrganization / disableOrganization / enableOrganization
分别写入 Constants.ACCOUNT_STATUS_NORMAL("normal") 与 ACCOUNT_STATUS_SUSPENDED("suspended")。
那是 users.account_status 的取值,而 organizations.status 的 CHECK 白名单
(V001 chk_org_status)只有 ('active','inactive') → 三个写操作全部违约,
生产必崩 PSQLException violates check constraint "chk_org_status" → HTTP 500。
二阶影响:activities.organizer_org_id NOT NULL ⇒ 无机构即无法新建活动,
运营端「建机构 → 建活动 → 报名 → 互选」链路的第一环是断的。
修复:
- Constants 新增 ORG_STATUS_ACTIVE / ORG_STATUS_INACTIVE(独立于 users.account_status,
附注释说明两者白名单不同,禁止互相复用)
- 三处状态值改为 ORG_STATUS_ACTIVE / ORG_STATUS_INACTIVE
- 新增 OrganizationService.ALLOWED_TYPES + type 白名单前置校验:
非法值返回 VALIDATION_ERROR(400),不再打到 PostgreSQL 才 500
- 「机构不存在」由裸 RuntimeException(→500 SERVER_ERROR) 改为 NOT_FOUND(404)
- 异常类型统一为 GlobalExceptionHandler.BusinessException —— 独立类
shared.exception.BusinessException 没有 @ExceptionHandler,抛它仍会退化成 500
根因第三重盲区(缺陷长期隐身的直接原因):
schema-h2.sql 的 organizations 表此前未复刻这两条 CHECK,H2 上写 'normal' 畅通无阻。
已补齐 chk_org_type / chk_org_status 及 NOT NULL / DEFAULT,与生产 DDL 逐值一致。
新增守卫:
- OrganizationConstraintParityTest:生产迁移 DDL ↔ 测试库 schema ↔ 后端白名单 ↔
Constants 四方比对 + 解析器自检(虚构约束名必须解析失败,防断言静默永真)。
其中 status DEFAULT 的解析必须先把范围切到 organizations 建表块 —— 全文件搜索会
误命中 users.account_status(本轮自检脚本实测踩到并修正该缺陷)。
- OrganizationServiceTest:走真实 DB 的 H2 集成测试,9 用例覆盖创建/停用/启用/
停启往返/六个合法 type/非法 type/名称空白/404 语义,断言落库值而非返回值。
⚠️ 未在本机运行测试:本轮探测确认本机无 Docker、无 JDK,wsl.exe 被安全策略阻止
(与 known-risks.md 的 WSL/Docker 故障一致),mvn -o test 与负向注入均无法执行。
已用等价正则的独立脚本验证守卫判别力与两处 DDL 一致性(PASS,脚本留痕
.workbuddy/_verify_org_guard.py)。
补跑全量回归 + 负向注入前,本项记为「待验证」,不得计入已验收。
13 KiB
项目进度评估报告 — 2026-09-21
评估方式:以
docs/STATUS.md(权威状态表)为索引,逐项回溯代码、迁移、测试与 CI 配置实测复核, 不采信文档中的历史「✅」声明。凡本文标注「实测」的结论均可按「核查证据」栏复现。评估基线:
main@60c591f(2026-09-21 11:13),工作区干净;最新 tagv101-dod-complete-2026-09-21。
一、总体结论
代码与测试面已具备进入 UAT 的条件;阻塞点是人工确认与环境补绿,外加一处此前登记但未修复的运营端写操作缺陷。
| 维度 | 结论 |
|---|---|
| 业务功能 | Phase 01 |
| 质量门禁 | 后端 741 / 0 失败 / 0 错误 / 3 跳过;UI 契约门禁 18/18;E2E 本机活栈 65 通过 |
| 数据层 | 迁移 V001~V051(51 个文件,无缺号);H2 测试库表漂移盲区已在本轮前多轮补齐 |
| 停点 | Phase 24(UAT)启动门前 —— 按项目规则须由用户确认,不得自动进入 |
| 风险等级 | 中 —— 无架构级问题,但存在 1 项 High 未修缺陷 + 2 项环境/流程阻塞 |
二、进度快照
2.1 Phase 矩阵
| Phase 区间 | 状态 | 证据 |
|---|---|---|
| 01~06 基线 / Auth / RBAC / Profile / 审核 / Match Engine | ✅ 关闭 | 各 Phase Completion Report |
| 07 V1.1 首页 + 找对象 | ✅ 关闭 | 2026-09-16 用户验收(基本达标);11 页 UI 验收通过 |
| 08~13A Like/Match/Block · Chat · 图片安全 · 通知 · 关系扩展 · 红娘转介 · 咨询辅导 | ✅ 关闭 | 2026-09-16/17 KEEP-VERIFY,共修复 40+ 真实缺陷 |
| 14~20 多类型活动 · 报名签到 · 互选双确认 · 举报风控 · 申诉 · 运营后台 · Analytics | ✅ 关闭 | 2026-09-17 复验,修复 60+ 缺陷(含 4 处必崩级) |
| 21 账户生命周期 | ✅ 关闭 | 2026-09-18;注销三处 TODO 桩已实现;数据保留流程 V049 落地 |
| 22 Feature Flag | ✅ 关闭 | 死配置已移除;PUT /feature-flags 真持久化(V048) |
| 23 可信系统测试重建 | ⚠️ 部分关闭 | 假覆盖归零、E2E 场景真实实现;仅余 CI 上首次跑绿 |
| 23B E2E 基建 + 横向加固(HTTP 语义 / 身份收敛 / 幂等键) | ✅ 关闭 | 幂等键 30 端点、105 处真实状态码 |
| V1.0.1 配置与规则纠偏 | ✅ 关闭 | rc.21(2026-09-21);governance 六表 + 并发强校验 + canonical key |
| 24 UAT | ⏳ 待启动 | 用例 46 条(9 角色 × 7 路径)已编写;需用户确认 |
| 25 RC 内容 / 26 生产 Smoke | ⏳ 待运营 | 真实素材未提供;13 项 smoke 待执行 |
2.2 量化指标
| 指标 | 实测值 | 核查方式 |
|---|---|---|
| 后端测试 | 741 / 0 failures / 0 errors / 3 skipped | docs/STATUS.md rc.21 行(离线容器 mvn -o test,命令见计划附 B-9) |
| 测试类文件 | 108 个 | backend/src/test/**/*.java 计数 |
| UI 契约门禁 | 18/18(UI_GUARDS_MIN 下限守卫防删除报绿) |
ui-tests/ 18 个 .mjs;执行器 scripts/run-ui-contracts.mjs |
| E2E 用例 | 65 通过(本机真栈真库) | tests/e2e/ 14 个测试文件 |
| 数据库迁移 | V001~V051,51 个,无缺号重复 | backend/src/main/resources/db/migration |
| CI job | 7 个:backend / admin-web / miniapp / migration / test-shell-guard / ui-contracts / e2e | .github/workflows/ci.yml |
| 待产品决策 | 13 项 + 第三方开放遗留 7 项 | docs/PENDING_DECISIONS.md、docs/governance/open-questions.md |
三、关键发现:一处 High 缺陷登记后未修复
3.1 机构创建 / 停用 / 启用三个写操作必然失败(High,2026-09-21 已修复,待补跑回归验证)
处置更新(2026-09-21 当天):本项已按第五节 P0-1 执行完毕 ——
Constants新增ORG_STATUS_ACTIVE/INACTIVE、三处状态值修正、type白名单前置校验、 测试库schema-h2.sql补两条 CHECK 及 NOT NULL/DEFAULT、 新增OrganizationConstraintParityTest与OrganizationServiceTest(9 用例)。 但本机无 Docker / 无 JDK(wsl.exe被安全策略阻止),mvn -o test与负向注入未能执行, 故当前状态为「已修复待验证」而非「已验证」。 详见docs/superpowers/plans/2026-09-18-phase23-closeout-and-uat-readiness.md附 B.1 的处置留痕 与docs/STATUS.md版本行 rc.22。
该问题于 2026-09-19 已在实施计划「附 B.1」中登记并实测复现,但截至本次评估(2026-09-21)代码未改动。
缺陷本体(实测复核,2026-09-21):
| 位置 | 写入值 | 生产约束 | 结果 |
|---|---|---|---|
OrganizationService.java:43 createOrganization |
ACCOUNT_STATUS_NORMAL = "normal" |
V001:45 chk_org_status CHECK (status IN ('active','inactive')) |
违约 → 500 |
OrganizationService.java:63 disableOrganization |
ACCOUNT_STATUS_SUSPENDED = "suspended" |
同上 | 违约 → 500 |
OrganizationService.java:73 enableOrganization |
ACCOUNT_STATUS_NORMAL = "normal" |
同上 | 违约 → 500 |
根因:organizations.status 复用了语义上属于 users 表的常量 Constants.ACCOUNT_STATUS_*。
Constants 中不存在机构状态常量(ORG_STATUS_ACTIVE/INACTIVE 均无)—— 典型的「跨表常量误用」,
与项目此前多轮修复的「实体↔迁移漂移」「CHECK 白名单未对齐」同族。
二阶影响(决定优先级):
activities.organizer_org_id 为 NOT NULL → 无机构则无法创建活动。
即运营端「新建机构 → 新建活动 → 用户报名 → 互选」这条链路的第一环是断的。
而 UAT 用例覆盖活动互选、报名、签到等场景,因此该缺陷可能阻塞 UAT 执行。
为什么门禁全绿却没发现:
- 108 个测试类中没有任何一个引用
OrganizationService/createOrganization(实测:0 命中); tests/e2e/sql/seed_e2e_activity.sql是直接写库插入机构与活动,绕过了 Service 层 —— E2E 全绿掩盖了 API 路径的失败;- H2 测试库此前长期缺约束复刻,即便有测试也可能静默通过。
这正好复现项目已总结过两次的模式:「测试环境用数据为空 / 直连绕过,掩盖代码必崩」。
附带问题(同文件,Low):
createOrganization与updateOrganization均未校验type白名单 (chk_org_type仅允许 women_federation / trade_union / charity_center / volunteer_team / civil_affairs_partner / other);- 私有
saveAuditLog未填ip/userAgent(Phase 17 只增强了AuditLogService.recordSensitiveAccess)。
建议修法:新增 Constants.ORG_STATUS_ACTIVE/INACTIVE,三处改为 active / inactive;
补 type 白名单校验;新增 OrganizationServiceTest(走真实 DB,覆盖创建/停用/启用/type 非法),
另加一条解析 V001 DDL 取最终白名单的常量守卫(参照 MatchmakerReferralPhase13Test 的写法,
不要硬编码白名单副本 —— 那条教训已记录在 Phase 13 报告中)。修复后需 git tag 打点并回读验证。
3.2 其余已登记未处置项
| 项 | 级别 | 说明 |
|---|---|---|
| 用户侧取消预约不校验状态 | Medium | ServiceAppointmentService.cancelAppointment 只校验归属,已确认/已完成也能被本人取消;运营侧明确拒绝 completed。两侧口径不一致,需产品裁定(计划附 B.3) |
| Phase 22 Deployment/Ops 5 项未复验 | Medium | 删除镜像跳过测试的发布路径、生产关 Mock/Seed/Swagger、端口依赖检测、备份加密 + 真实恢复演练、Rollback 目标(REMAINING_WORK.md B 组) |
| 多实例下 flag 内存值不自动刷新 | Low | 已知边界,需各自重启(Phase 22 报告) |
四、环境与流程风险
4.1 Git 在当前执行环境不可用(阻塞提交纪律)
实测:git 报 fatal: detected dubious ownership in repository。
仓库目录属主为 S-1-5-21-881075190-…,当前用户为 CLIMBER/13070,二者不匹配。
影响:AGENTS.md 的版本控制约定(每批独立 commit + 单段名 tag + git bundle 自保 + 回读验证)
是项目防御「常驻进程删 refs 导致 HEAD 悬空」的核心手段,该链路当前无法执行。
本次评估为只读目的,以 GIT_CONFIG_COUNT/KEY/VALUE 环境变量临时注入 safe.directory 绕过,
未修改任何全局配置。
建议:由用户决定是否执行
git config --global --add safe.directory 'E:/develop/公益婚恋服务平台'。
在修复前,任何需要提交的工作都应先确认该前提,否则改动无法被打点保护。
(另:feat-ui-v11 已被 main 完全包含(落后 71 个提交、领先 0),仅为冗余锚点,
可考虑清理,但 AGENTS.md 目前要求保留 —— 属文档与事实的轻微不一致。)
4.2 CI 回归防线从未在真实 CI 上验证过
7 个 job 均已配置,其中 ui-contracts(18 门禁)与 e2e(Compose 起全栈 + seed + pytest)配置完整,
但 E2E 作业从未在 GitHub Actions 上跑绿过一次(计划 Task 2.3 Step 3)。
本机已用同一序列模拟实测 65/65,但「本机绿」与「CI 绿」不是同一件事
—— 此前已发生过「本机有遗留 admin 账号所以本地一直绿、CI 全新库必然 401」的先例。
4.3 文档体量与自相矛盾
docs/ 91 个文件、STATUS.md 单文件 90KB,内含多处「历史声明块(已作废)」并列保留;
PENDING_DECISIONS.md 与 docs/governance/* 三表职责交叉并依赖「矛盾以 governance 三表为准」的约定;
REMAINING_WORK.md 被迫以「原编号索引」兼容历史引用。
这是治理的必要代价,但已产生实际成本:文档中出现过与实际严重不符的陈述
(如 CHANGELOG.md 3.3MB vs 实际 4.2KB、指向从未存在的报告文件)。
建议:不再新增并列的「状态类」文档;本评估报告即为一次性快照,结论应回写进 STATUS.md 而非另立体系。
五、下一步建议
优先级 P0 — 建议立即做(无需用户决策,纯技术清偿)
- 修复机构三个写操作 + 补测试与守卫(3.1)。✅ 代码已完成(2026-09-21);
⚠️ 验收项中的「全量回归 + 负向注入 + 活栈实测」因本机无 Docker/JDK 未执行,待在有该环境处补跑。
原验收标准:
mvn -o test全绿 + 新增用例经负向注入可变红 + 活栈实测POST /operator/organizations返回 2xx。 - 确认 Git 可用性(4.1)。决定是否加
safe.directory,否则先不要写代码 —— 写了也打不了点。
优先级 P1 — 需用户/环境配合
- 推送一次 CI,拿到 E2E 与 ui-contracts 的首次真绿(需有 Docker Hub 出口的 runner)。 完成后 Phase 23 可由「部分关闭」转为关闭。
- 管理端桌面端目视复验(1440px)(批 4 Task 4.1)。小程序 375px 增补页面同理。 这是当前唯一「代码已就绪但从未被真人看过」的验收项。
- 13 项产品决策 + 7 项第三方开放遗留(批 4 Task 4.2)。
建议分批:先决
OQ-MATCH-001(推荐阈值)、OQ-PROFILE-001(照片上限)、OQ-IDENTITY-001(活体核验)三项 —— 它们已被配置化,决策后只需改配置值; Banner 最大活跃数(OQ-BANNER-001)是真缺口,需产品定值后需实现 active-count 校验。
优先级 P2 — UAT 启动后的并行工作
- Phase 24(UAT)启动确认 —— 按项目规则须用户明确同意,AI 不得自动进入。 启动前建议先完成 P0-1 与 P1-4。
- Phase 22 Deployment/Ops 5 项复验,其中「备份加密 + 真实恢复演练」是上线硬门槛。
- 用户侧取消预约口径统一(3.2)—— 一次性产品裁定即可关闭。
优先级 P3 — 运营侧长周期
- Phase 25 真实素材(Banner / 课堂 / 反诈 / 关于我们 / 组织信息),不得 Seed 假数据。
- Phase 26 上线前 13 项 smoke + RC 冻结(镜像 / DB 版本 / 配置清单 / Rollback 目标)。
六、本次评估的核查证据
| 结论 | 证据 |
|---|---|
| 代码与测试就绪 | docs/STATUS.md 文首「当前有效结论」+ rc.19~rc.21 版本演进行 |
| 机构缺陷未修 | backend/src/main/java/com/danyang/match/platform/organization/service/OrganizationService.java:43,63,73;Constants.java:11,14;V001__init_base_tables.sql:45(三处逐一读源确认) |
| 机构零测试覆盖 | backend/src/test/** 全量检索 OrganizationService / createOrganization → 0 命中(108 个测试类) |
| E2E 绕过 Service 层 | tests/e2e/sql/seed_e2e_activity.sql 直插库 |
| CI 配置完整但未验证 | .github/workflows/ci.yml 全文;计划 Task 2.3 Step 3 仍为未勾选项 |
| Git 不可用 | git rev-parse HEAD 报 dubious ownership;属主 SID 与当前用户不一致 |
| 迁移基线 | db/migration 计数 51,最新 V051__canonical_liveness_flag_key.sql |
| 剩余项清单 | REMAINING_WORK.md、docs/PENDING_DECISIONS.md、计划「批 4 / 批 5」 |
评估人:WorkBuddy · 创建:2026-09-21
性质:一次性快照。结论请回写 docs/STATUS.md,本文件不作为长期状态源。