oh-my-muse/docs/memorys/2026-05-26-P1R0基线门禁收口.md

7.2 KiB
Raw Blame History

P1R0 基线门禁收口留痕

任务背景

本次执行 docs/superpowers/plans/2026-05-25-P1R-0-baseline-gate.md,目标是为 P1R 真实 API 改造建立可重复运行的基线门禁。

P1R-0 不负责实现真实业务 API不修改生产 Controller、Service、Mapper 或 DDL。它只回答

  • OpenAPI 合同里到底有多少 operation。
  • 当前 muse-cloud/ 后端对每个 operation 是真实专用入口、catch-all 合同入口、通用持久化入口、SSE 占位入口,还是缺入口。
  • 哪些 operation 绝不能在 P1R-0 阶段被误判为完成。
  • 后续 P1R-1 到 P1R-7 应该基于哪份机器可读矩阵继续推进。

计划原始目标

计划要求新增一套 API 覆盖矩阵门禁:

  • 新增 muse-cloud/scripts/p1r-audit-api-coverage.py
  • 解析 docs/api-contracts/*/openapi.yaml
  • 扫描 muse-cloud/ Java 源码。
  • 生成:
    • docs/superpowers/reports/p1r-api-coverage.json
    • docs/superpowers/reports/p1r-api-coverage.md
  • 新增 Maven 测试:
    • muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rApiCoverageReportTest.java
  • 保证 P1R-0 不把 catch-all、generic persistence、SSE placeholder、missing 这类非真实实现标记为完成。

实际完成内容

P1R-0 在独立 worktree 中完成:

/Users/qingse/.config/superpowers/worktrees/oh-my-muse/feature-p1r-0-baseline-gate

分支:

feature/p1r-0-baseline-gate

关键提交:

97f1f3a chore(p1r): 生成 API 覆盖基线矩阵
7d35ce7 fix(p1r): 修正 API 覆盖矩阵识别规则
4084fce fix(p1r): 收紧 API 覆盖矩阵路由匹配
0d16c21 fix(p1r): 修正 API 覆盖矩阵必填与入口归属
9a32e3d fix(p1r): 强化覆盖矩阵完成状态校验
83d7df1 test(p1r): 增加 API 覆盖矩阵门禁
19e673c fix(p1r): 对齐基线门禁验证规则

实际产物:

  • 审计脚本:muse-cloud/scripts/p1r-audit-api-coverage.py
  • JSON 报告:docs/superpowers/reports/p1r-api-coverage.json
  • Markdown 报告:docs/superpowers/reports/p1r-api-coverage.md
  • Maven 门禁:muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rApiCoverageReportTest.java
  • 规格与计划命令同步更新:
    • docs/superpowers/specs/2026-05-25-P1R-0-baseline-gate-design.md
    • docs/superpowers/plans/2026-05-25-P1R-0-baseline-gate.md

关键结果

最终报告统计:

totalOperations=233
completedOperations=0
catchAllOperations=36
genericPersistenceOperations=180
ssePlaceholderOperations=2
missingOperations=0

completedOperations=0 是预期结果。P1R-0 是基线审计,不跑领域真实验收,所以不能宣称任何 operation 已完成。

非真实实现状态规则已经统一到脚本、Maven 测试、规格和计划:

  • catch_all
  • generic_persistence
  • sse_placeholder
  • missing

这些 implementationStatus 对应的 completionStatus 只能是:

  • incomplete
  • blocked

不能是 completed,也不能是 needs_verification

Maven 行为结论

计划原始命令是:

cd muse-cloud
mvn -o test -pl muse-server -am -Dtest=P1rApiCoverageReportTest

实测该命令会失败在上游模块,例如 muse-common

No tests matching pattern "P1rApiCoverageReportTest" were executed!

根因:

  • -pl muse-server -am 会把 muse-server 的上游 reactor 模块一起拉入构建。
  • -Dtest=P1rApiCoverageReportTest 是全局 surefire 参数。
  • 上游模块没有这个测试类,默认会因为“指定测试不存在”失败。

正确行为不是修改父 POM。父 POM 全局关闭 failIfNoSpecifiedTests 会改变全仓测试语义,容易掩盖测试名拼写错误。

正确的局部命令是:

cd muse-cloud
JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" \
  mvn -o test -pl muse-server -am -Dtest=P1rApiCoverageReportTest -Dsurefire.failIfNoSpecifiedTests=false

含义:

  • 运行环境必须是 Java 21。
  • 上游 reactor 模块没有 P1rApiCoverageReportTest 不应失败。
  • 真正需要执行目标门禁测试的是 muse-server

验证记录

执行过的验证:

python3 muse-cloud/scripts/p1r-audit-api-coverage.py --check

结果:

Generated docs/superpowers/reports/p1r-api-coverage.json
Generated docs/superpowers/reports/p1r-api-coverage.md

报告一致性验证:

python3 - <<'PY'
import json
from pathlib import Path
report = json.loads(Path("docs/superpowers/reports/p1r-api-coverage.json").read_text())
summary = report["summary"]
count = len(report["operations"])
assert summary["totalOperations"] == count, (summary["totalOperations"], count)
assert summary["completedOperations"] == 0, summary["completedOperations"]
for op in report["operations"]:
    assert op["completionStatus"] != "completed", op["operationId"]
    if op["implementationStatus"] in {"catch_all", "generic_persistence", "sse_placeholder", "missing"}:
        assert op["completionStatus"] in {"incomplete", "blocked"}, op["operationId"]
print("P1R-0 report consistency OK:", count, "operations")
PY

结果:

P1R-0 report consistency OK: 233 operations

脚本负例验证:

  • 将内存中的 non-real operation 临时改成 needs_verification
  • 调用 validate_report(report)
  • 结果按预期失败,说明脚本会拒绝 non-real needs_verification

输出:

P1R-0 negative validate_report OK: adminCreateCallAttributionJob

Maven 门禁:

cd muse-cloud
JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" \
  mvn -o test -pl muse-server -am -Dtest=P1rApiCoverageReportTest -Dsurefire.failIfNoSpecifiedTests=false

结果:

Running cn.iocoder.muse.server.framework.api.P1rApiCoverageReportTest
Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS

当前集成状态

截至本留痕创建时:

  • P1R-0 已在 feature/p1r-0-baseline-gate 分支完成并提交。
  • 用户曾要求合并到 main,但随后中断该回合并改为“进行总结留痕”。
  • 因此当前记录只确认 P1R-0 分支完成,不确认已经合并到 main
  • 主工作区 /Users/qingse/Sync/local-git/oh-my-muse 当时仍在 feature/p1-muse-cloud-backend-20260524,且有其他未提交或未跟踪内容,不能当作干净 main 合并面。

后续如果要继续合并,需要重新执行:

cd /Users/qingse/.config/superpowers/worktrees/oh-my-muse/feature-p1r-0-baseline-gate
git status --short
git branch --show-current

确认干净后,再按实际 base 分支执行 merge / PR 流程。

下个阶段

下个阶段是:

P1R-1 Content Real API spec + plan

P1R-1 不应该继续做基线扫描,而应该基于 P1R-0 报告开始真实业务 API 改造设计。

建议步骤:

  1. docs/superpowers/reports/p1r-api-coverage.json 筛出 Content 域 operation。
  2. 分清哪些 Content operation 仍是 catch_allgeneric_persistence
  3. 写 P1R-1 Content Real API 规格,明确真实 Controller、Service、DTO、持久化、幂等、权限和审计闭环。
  4. 写 P1R-1 执行计划。
  5. 再进入实现,不要直接从 catch-all 适配拼接到另一个临时 spec。

P1R-1 的核心目标是把 Content 域从“合同可响应”推进到“真实业务 API 可验收”。