test(p1r): require coverage evidence test files

This commit is contained in:
lili 2026-06-19 02:38:29 -07:00
parent 878acef255
commit 984c6db583
11 changed files with 2232 additions and 324 deletions

View File

@ -2,8 +2,8 @@
> **真实现状的权威 SSOT**:[`docs/agent-specs/2026-06-13-项目目标与模块现状基线.md`](../../docs/agent-specs/2026-06-13-项目目标与模块现状基线.md)(逐模块证据)+ [`2026-06-13-目标达成对抗复盘.md`](../../docs/agent-specs/2026-06-13-目标达成对抗复盘.md)(失控根因)。本文件只做导航 + 关键结论蒸馏;**冲突时以代码与覆盖率台账为准**。
## 关键结论(蒸馏,2026-06-13 只读判断,未实跑 mvn/npm)
- **后端不是空壳**:9 BC 后端普遍是真实业务逻辑(幂等 / 乐观锁 / 审计 / Shadow→Canonical 硬闸门 / 真实 HTTP 外部集成)。覆盖率台账 233 operation:**147 completed / 86 needs_verification;catch_all / generic_persistence / sse_placeholder / missing / blocked 全为 0**。逐域 operation:account 33 / ai 41 / content 51 / events 1 / knowledge 59 / market 32 / meta 16。
## 关键结论(蒸馏,基线源自 2026-06-13,coverage 状态已于 2026-06-19 同步)
- **后端不是空壳**:9 BC 后端普遍是真实业务逻辑(幂等 / 乐观锁 / 审计 / Shadow→Canonical 硬闸门 / 真实 HTTP 外部集成)。覆盖率台账 233 operation:**233 completed / 0 needs_verification;catch_all / generic_persistence / sse_placeholder / missing / blocked 全为 0**。逐域 operation:account 33 / ai 41 / content 51 / events 1 / knowledge 59 / market 32 / meta 16;completed operation 已带 `testFiles` 证据锚点并由覆盖门禁校验。
- **“completed” = 覆盖率门禁批准状态**(需 HTTP 入口 + 真实 PostgreSQL + Flyway + 证据),**≠ 端到端可用**;历史“完成”声称是低报而非高报。
- **三大真实缺口**:
1. **前端 muse-studio 严重滞后**:AI 候选闭环断链、知识库 / 市场生产侧 UI 缺失、个人中心约 21% 端面且跑 MSW mock——objective“先审后入”在用户可见层当前不可用。

View File

@ -24,9 +24,9 @@
1. **完成的定义**:一个 operation / 功能 / 旅程标记 `completed` 必须有**自动化绿证据**(CI 实跑通过的单测/集成/端到端)。无证据只能 `needs_verification`。**禁止以手工台账数字作为完成的事实源。**
2. **CI 必须真跑测试**:门禁 job 禁用 `-Dmaven.test.skip` / `skipTests`;必须在项目真实 JDK(**21**)下编译+跑测试。新增模块的测试必须纳入 CI。
3. **门禁断言"计算而非硬编码"**:禁止 `assertEquals(<魔法数>, completed)` 这类被人工拨动的常量;完成数/状态必须**从真实判据重新计算/扫描**得出(参见 `muse-server/.../P1rApiCoverageReportTest`,P0 已改造为 summary 自洽 + completed 必须引用磁盘真实存在的源码文件)。
3. **门禁断言"计算而非硬编码"**:禁止 `assertEquals(<魔法数>, completed)` 这类被人工拨动的常量;完成数/状态必须**从真实判据重新计算/扫描**得出(参见 `muse-server/.../P1rApiCoverageReportTest`,P0 已改造为 summary 自洽 + completed 必须引用磁盘真实存在的源码文件;2026-06-19 已继续加固为 completed 必须引用真实 `testFiles` 证据文件,且不得引用 coverage/gate 自身)。
4. **三口径报完成,禁单一 %**:对内对外只报 ① 代码实现度 ② 自动化验证度(CI 实跑通过数)③ 端到端可用度(真实形态跑通的旅程数)。**禁止合并成一个"X% 完成"**(合并数是高估来源)。
5. **契约变更挂 CI 校验**:接口/DB 契约改动必须有机械校验(`openapi-diff` / `flyway validate`)在 CI 阻断,不能只靠"契约先行"的文档纪律。契约 SSOT = `contracts/`(建设中)。
5. **契约变更挂 CI 校验**:接口/DB 契约改动必须有机械校验(`openapi-diff` / `flyway validate`)在 CI 阻断,不能只靠"契约先行"的文档纪律。契约 SSOT = `docs/api-contracts/**` 与 `muse-cloud/sql/muse/V*.sql`(原地认定,见 `contract-first`)。
6. **BC 边界由 ArchUnit 机械约束**:模块不得 `import` 他域 `.dal..`(DO/Mapper)。跨 BC 只能走对外 API / facade-api 契约。已存在的违例(如 AI 模块直连 content DAL)登记为"已知违例 + 整改期",新违例一律 CI 阻断。(ArchUnit 规则建设中,见 [[rules/bc-boundaries]])
7. **前端 mock 不算"已实现"**:MSW/mock 下的通过**不构成**可用证据。"可用"= 关该旅程 mock、对真后端、自动化端到端跑通(见 [[skills/golden-journey-vertical-slice]])。
8. **证据规则**:区分"已验证事实 / 推断 / 假设";**没有验证证据,绝不声称"完成/修复/通过/无问题"**。能只读核实的先核实。
@ -42,8 +42,9 @@
## 四、已落地(本规则的首批机械门禁)
- ✅ P0:`maven.yml` 删 `skip` + JDK 矩阵→21 + 开 PR 门;`P1rApiCoverageReportTest` 去硬编码 147 → summary 自洽 + 文件存在性牙齿(23/23 绿,JDK21 实跑)。
- ✅ P0:`maven.yml` 删 `skip` + JDK 矩阵→21 + 开 PR 门;`P1rApiCoverageReportTest` 去硬编码 147 → summary 自洽 + 文件存在性牙齿(23/23 绿,JDK21 实跑);2026-06-19 加 `testFiles` 证据牙齿,completed 必须锚定真实测试源码。
- ✅ P0-2:收口刷分回路冻结令落档。
- ⏳ 待建:ArchUnit BC 边界门 [[rules/bc-boundaries]];`contracts/` SSOT + `openapi-diff` CI;进度总账(done=自动化绿旅程)。
- ✅ ArchUnit BC 边界门已落地,见 [[rules/bc-boundaries]]。
- 🔧 待接线:`openapi-diff` CI 触发管道首跑验证;进度总账仍需坚持 done=自动化绿旅程。
> 维护:本规则随机械门禁逐条落地而更新"已落地"清单;新发现的假绿形态追加进第一节并补对应门禁。

View File

@ -94,6 +94,6 @@ oh-my-muse/
- ✅ 契约先行门([`contract-first`](.agents/rules/contract-first.md)):Flyway 迁移卫生 + OpenAPI **存在性/结构**(注:挡不住语义破坏;openapi-diff CI 已materialize,需首次 CI 运行验证)。
- ✅ loop 机械牙([`AgentsInfraIntegrityTest`](muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/arch/AgentsInfraIntegrityTest.java)):每业务 BC 有 `.agent`、README 索引每篇 `.agents` 文档、总账在——把写回/索引同步从自觉变机械。
- ✅ knowledge 蒸馏 / skills / workflow(AI 开发协议)/ 进度总账 + 7 BC `.agent`。
- ⏳ 后续:openapi-diff CI 首跑验证、`completed=测试证据`兜底(testFiles)、`dev-baseline` 收敛进 rules、跨域 `.application` 边界、market-server→member-server pom 坐标收口、**ai/平台预存红测试整改**(CI 接电后暴露,非本轮引入:`MuseAiTaskServiceTest` 桩缺失、`MuseAiEventPublishOutboxMapperTest` 需真实 PG、平台 `QiniuSmsClientTest` 时区)。
- ⏳ 后续:openapi-diff CI 首跑验证、`dev-baseline` 收敛进 rules、Meta/schema 投影真实化、前端深页继续关 MSW 活体验收。`completed=测试证据`兜底(testFiles)、跨域 `.application` 边界、market-server→member-server pom 坐标收口、ai/平台预存红测试整改均已完成。
> 进度只进 [`docs/mvp/进度总账.md`](docs/mvp/进度总账.md) + 各模块 `.agent`,不新增状态过程文档。

View File

@ -22,7 +22,7 @@
**market 写路径整改(2026-06-14,ultracode)**:member 暴露写端口 `MuseAccountRecordProjectionApi` + DTO(member-server 实现读写自有 DAL、tenantId 由实现侧从上下文注入防伪造、事务沿用调用方),market 5 类改消费端口、移除 member.dal 依赖 → `KNOWN_VIOLATION_EXEMPTIONS` 清空、BC 门全绿。**附带修复**:round-2 重构 `ContentKnowledgeWorkOwnerFacade` 时遗留的旧测试 `KnowledgeWorkOwnerFacadeTest`(仍断言旧 WorkMapper 行为)已删除,其装配守卫/兜底两用例并入 `ContentKnowledgeWorkOwnerFacadeTest`(5/0F)——此为 round-2 一处假绿(当时构建在平台时区用例处中止、未真正跑到 knowledge),现已补正。
**后续基建 TODO**:openapi-diff CI 首跑验证(🔧 检测逻辑+循环聚合已本地实证 2026-06-17:oasdiff v1.19.1 对 7 域真实契约 5/5 拦真破坏/放行安全演化,镜像钉版本+复现脚本已落地;**仅余 GHA 触发管道未接线**——诊断 2026-06-17:maven.yml 在 `muse-cloud/.github/workflows/`、**仓库根无 `.github/workflows/`**、remote 是**自建 Gitea**(`101.200.34.71:2222` 非 github.com),GHA/Gitea-Actions 只读仓库根 `.github/workflows/`,故 monorepo 层级**不触发**(真 PR 也不会跑);需 workflow 移到仓库根[带路径过滤分 muse-cloud/admin/studio]或 muse-cloud 单独成库,并确认 Gitea Actions 已启。**`mvn -B package`[CI 确切命令]已本地实证全绿(2026-06-17,全 reactor 单测 + 打包步骤),接线后即应绿**——属基建接线决策,留人类)、`completed=测试证据`兜底(台账加 testFiles 字段 + 门禁)、`dev-baseline` 收敛进 rules、跨域 `.application` 边界门(✅ **已完成 2026-06-17**:BcBoundaryArchTest 加 `no_business_bc_may_depend_on_another_bc_application` 平行规则,0 违例绿 + 反向证 238 例非空转;详见 bc-boundaries §四)、market-server→member-server pom 坐标收口(✅ **已完成 2026-06-17**:接口 `MarketAccountProjectionFacade` 移入 member-api→market-server pom 收窄至 member-api + 直接声明 tenant starter[依赖诚实化];编译/4 测试 26 用例/BcBoundaryArchTest 0 违例全绿;顺带修预存潜伏 test 编译破损 AppMuseMarketPublishControllerTest;详见 bc-boundaries §三)、**ai/平台预存红测试整改**(CI 接电后将暴露;均非本轮改动引入):`MuseAiTaskServiceTest` 缺 `eventPublishOutboxService`/`candidateReviewService` 桩致 11 例 NPE **✅ 已整改 40/40(2026-06-15,补桩 + review lenient,零产代码改动)**;`QiniuSmsClientTest` 时区硬编码 **✅ 已整改 5/5(2026-06-15,断言改用与生产同款 `LocalDateTimeUtil.of` 由系统时区换算→机器无关)**;`MuseAiEventPublishOutboxMapperTest` **✅ 真实 PG 实跑 5/5(2026-06-15,mini-infra PG 100.64.0.8:5433;跑法=`source infra.env` + `-DargLine='-DsocksProxyHost= -DsocksProxyPort='`;隔离 schema 自建自清;**2026-06-17 把无 PG 时的硬 fail 改 `assumeTrue` skip-gate(见下🎯⑤),反假绿双向实证:有 PG→5/0/0/0 真跑 PASS、无 PG→skip 非 fail 不拖红 CI**)**。**至此 ai/平台预存红三项全清。**
**后续基建 TODO**:openapi-diff CI 首跑验证(🔧 检测逻辑+循环聚合已本地实证 2026-06-17:oasdiff v1.19.1 对 7 域真实契约 5/5 拦真破坏/放行安全演化,镜像钉版本+复现脚本已落地;**仅余 GHA 触发管道未接线**——诊断 2026-06-17:maven.yml 在 `muse-cloud/.github/workflows/`、**仓库根无 `.github/workflows/`**、remote 是**自建 Gitea**(`101.200.34.71:2222` 非 github.com),GHA/Gitea-Actions 只读仓库根 `.github/workflows/`,故 monorepo 层级**不触发**(真 PR 也不会跑);需 workflow 移到仓库根[带路径过滤分 muse-cloud/admin/studio]或 muse-cloud 单独成库,并确认 Gitea Actions 已启。**`mvn -B package`[CI 确切命令]已本地实证全绿(2026-06-17,全 reactor 单测 + 打包步骤),接线后即应绿**——属基建接线决策,留人类)、`dev-baseline` 收敛进 rules。✅ 已完成项:`completed=测试证据`兜底(2026-06-19:coverage JSON 增 `testFiles`;生成器 `--check` + `P1rApiCoverageReportTest` 校验 completed 必须引用真实 `src/test/java` 证据文件且不得引用 coverage/gate 自身)、跨域 `.application` 边界门(2026-06-17:BcBoundaryArchTest 0 违例 + 反向证 238 例非空转)、market-server→member-server pom 坐标收口(2026-06-17:market-server 收窄至 member-api + tenant starter 直接声明)、ai/平台预存红测试整改(2026-06-15~17:三项全清)。
**🎯 全 reactor `mvn test` 史上首次全绿(2026-06-17)**:本特性分支 30+ commit 从未 push、maven.yml 只在 push/PR-to-main 触发故 **CI 从未在本分支真跑过**,积累若干潜伏红。以 `mvn -pl muse-server -am test -fae` 全 reactor 排查,逐模块解锁(上游失败 fail-fast 会 SKIP 下游),共清 **6 处**:① market `AppMuseMarketPublishControllerTest` 9 参 `PublishRecordItem` 构造(record 自 a00c758 加 marketAssetId/appealStatus 变 10 参)② coverage 台账 33 op serviceFiles 陈旧引用(本会话 facade 移 member-api 所致)③④ knowledge/ai 的 `Content*WorkOwnerFacadeTest` 仍断言 `@ConditionalOnBean`(2026-06-14 单体修复已去除、改 @Primary)⑤ ai `MuseAiEventPublishOutboxMapperTest` 真 PG 用例无 PG 时硬 fail→改 `assumeTrue` skip(与 P1r external-acceptance env 缺失即 skip 约定一致、honest 非假绿)⑥ muse-server `P1rKnowledgeMigrationSqlTest` 元测试钉死 `TARGET_VERSION="14"`(IT 已按 4d46d7a 动态自适应)→版本无关化。**全 reactor BUILD SUCCESS、0 失败**(真 PG 类无 PG 时 skip)。教训:跨模块重构后须跑 `-fae` 全量,勿只跑改动模块。**前端 muse-studio 同步复验绿(2026-06-17:`tsc -b` 0 错误 + `vitest run` 12 文件/47 用例全过;本分支前端改动 35 文件全在 studio、admin 未动)**——故**整分支(后端 `mvn -B package` + 前端 `tsc`/`vitest`)deterministic CI 检查全绿,均本会话实证**(e2e/playwright 需活体后端+浏览器,未在本轮跑;真 PG IT 多数 2026-06-17 已人工批准且本会话变更为 import-only+单测已覆盖,未重跑)。
@ -32,7 +32,7 @@
- 各模块目标 / 边界 / out-of-scope / 现状 / TODO → 见对应 **`muse-cloud/muse-module-*/.agent`**。
- 真实完成度与逐项证据 → 见 [现状基线 spec §四/§五](../agent-specs/2026-06-13-项目目标与模块现状基线.md)。
- 接口完成台账(门禁批准口径,≠端到端可用)→ `P1rApiCoverageReportTest` + `docs/superpowers/reports/p1r-api-coverage.json`。
- 接口完成台账(门禁批准口径,≠端到端可用)→ `P1rApiCoverageReportTest` + `docs/superpowers/reports/p1r-api-coverage.json`;completed operation 现在必须带 `testFiles` 证据锚点。
| BC 模块 | 只读评估 | `.agent` |
|---|---|---|

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
# P1R API Coverage Report
- Generated at: `2026-05-25T14:04:44+00:00`
- Generated at: `2026-05-25T00:10:50+00:00`
- Total operations: `233`
- Completed: `147`
- Needs verification: `86`
- Completed: `233`
- Needs verification: `0`
- Incomplete: `0`
- Catch-all: `0`
- Generic persistence: `0`
@ -14,36 +14,36 @@
| Domain | Side | Method | Path | Operation | Implementation | Completion | Target Stage |
|--------|------|--------|------|-----------|----------------|------------|--------------|
| account | admin | POST | `/admin-api/muse/account/call-attribution-jobs` | `adminCreateCallAttributionJob` | dedicated | needs_verification | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/call-attribution-jobs/{jobId}` | `adminGetCallAttributionJob` | dedicated | needs_verification | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/integration-calls/by-correlation/{correlationId}` | `adminGetIntegrationCallByCorrelation` | dedicated | needs_verification | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/new-api-bindings` | `adminListNewApiBindings` | dedicated | needs_verification | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/purchase-records` | `adminListPurchaseRecords` | dedicated | needs_verification | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/usage-records` | `adminListUsageRecords` | dedicated | needs_verification | P1R-3 Account Real API |
| account | admin | POST | `/admin-api/muse/account/call-attribution-jobs` | `adminCreateCallAttributionJob` | dedicated | completed | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/call-attribution-jobs/{jobId}` | `adminGetCallAttributionJob` | dedicated | completed | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/integration-calls/by-correlation/{correlationId}` | `adminGetIntegrationCallByCorrelation` | dedicated | completed | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/new-api-bindings` | `adminListNewApiBindings` | dedicated | completed | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/purchase-records` | `adminListPurchaseRecords` | dedicated | completed | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/usage-records` | `adminListUsageRecords` | dedicated | completed | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/users` | `adminListAccountUsers` | dedicated | completed | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/users/{userId}/balance-snapshots` | `adminGetBalanceSnapshots` | dedicated | completed | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/users/{userId}/entitlements` | `adminGetUserEntitlements` | dedicated | completed | P1R-3 Account Real API |
| account | admin | POST | `/admin-api/muse/account/users/{userId}/new-api-binding` | `adminCreateNewApiBinding` | dedicated | needs_verification | P1R-3 Account Real API |
| account | admin | POST | `/admin-api/muse/account/users/{userId}/new-api-binding` | `adminCreateNewApiBinding` | dedicated | completed | P1R-3 Account Real API |
| account | admin | GET | `/admin-api/muse/account/users/{userId}/quota-adjustments` | `adminListQuotaAdjustments` | dedicated | completed | P1R-3 Account Real API |
| account | admin | POST | `/admin-api/muse/account/users/{userId}/quota-adjustments` | `adminCreateQuotaAdjustment` | dedicated | completed | P1R-3 Account Real API |
| account | admin | POST | `/admin-api/muse/account/users/{userId}/quota-requests` | `adminCreateQuotaRequest` | dedicated | needs_verification | P1R-3 Account Real API |
| account | admin | POST | `/admin-api/muse/account/users/{userId}/quota-requests` | `adminCreateQuotaRequest` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/balance-snapshots` | `getAppBalanceSnapshots` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/downloads/{credentialId}` | `appDownloadExport` | dedicated | needs_verification | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/downloads/{credentialId}` | `appDownloadExport` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/entitlements` | `getAppEntitlements` | dedicated | completed | P1R-3 Account Real API |
| account | app | POST | `/app-api/muse/account/export-tasks` | `appCreateExportTask` | dedicated | needs_verification | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/export-tasks/{taskId}` | `appGetExportTask` | dedicated | needs_verification | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/integration-calls/by-correlation/{correlationId}` | `appGetIntegrationCallByCorrelation` | dedicated | needs_verification | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/licenses` | `appListLicenses` | dedicated | needs_verification | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/new-api-binding` | `getAppNewApiBinding` | dedicated | needs_verification | P1R-3 Account Real API |
| account | app | POST | `/app-api/muse/account/new-api-binding/recheck` | `appRecheckNewApiBinding` | dedicated | needs_verification | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/publish-records` | `appListPublishRecords` | dedicated | needs_verification | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/purchases` | `appListPurchases` | dedicated | needs_verification | P1R-3 Account Real API |
| account | app | POST | `/app-api/muse/account/quota-requests` | `appCreateQuotaRequest` | dedicated | needs_verification | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/quota-requests/{requestId}` | `appGetQuotaRequest` | dedicated | needs_verification | P1R-3 Account Real API |
| account | app | POST | `/app-api/muse/account/export-tasks` | `appCreateExportTask` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/export-tasks/{taskId}` | `appGetExportTask` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/integration-calls/by-correlation/{correlationId}` | `appGetIntegrationCallByCorrelation` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/licenses` | `appListLicenses` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/new-api-binding` | `getAppNewApiBinding` | dedicated | completed | P1R-3 Account Real API |
| account | app | POST | `/app-api/muse/account/new-api-binding/recheck` | `appRecheckNewApiBinding` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/publish-records` | `appListPublishRecords` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/purchases` | `appListPurchases` | dedicated | completed | P1R-3 Account Real API |
| account | app | POST | `/app-api/muse/account/quota-requests` | `appCreateQuotaRequest` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/quota-requests/{requestId}` | `appGetQuotaRequest` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/security-events` | `appListSecurityEvents` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/security-events/{eventId}` | `appGetSecurityEvent` | dedicated | completed | P1R-3 Account Real API |
| account | app | POST | `/app-api/muse/account/security-events/{eventId}/acknowledge` | `appAcknowledgeSecurityEvent` | dedicated | needs_verification | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/usage` | `getAppUsage` | dedicated | needs_verification | P1R-3 Account Real API |
| account | app | POST | `/app-api/muse/account/security-events/{eventId}/acknowledge` | `appAcknowledgeSecurityEvent` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/account/usage` | `getAppUsage` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/me` | `getCurrentUser` | dedicated | completed | P1R-3 Account Real API |
| account | app | GET | `/app-api/muse/profile` | `getProfile` | dedicated | completed | P1R-3 Account Real API |
| account | app | PATCH | `/app-api/muse/profile` | `updateProfile` | dedicated | completed | P1R-3 Account Real API |
@ -88,56 +88,56 @@
| ai | app | POST | `/app-api/muse/works/{workId}/agent-slots/{slotKey}/bind` | `bindAgentSlot` | dedicated | completed | P1R-4 AI Real API |
| ai | app | POST | `/app-api/muse/works/{workId}/agent-slots/{slotKey}/prechecks` | `precheckAgentSlot` | dedicated | completed | P1R-4 AI Real API |
| ai | app | GET | `/app-api/muse/works/{workId}/suggestions` | `listWorkSuggestions` | dedicated | completed | P1R-4 AI Real API |
| content | admin | GET | `/admin-api/muse/content/export-tasks` | `adminListExportTasks` | dedicated | needs_verification | P1R-1 Content Real API |
| content | admin | GET | `/admin-api/muse/content/import-tasks` | `adminListImportTasks` | dedicated | needs_verification | P1R-1 Content Real API |
| content | admin | GET | `/admin-api/muse/content/export-tasks` | `adminListExportTasks` | dedicated | completed | P1R-1 Content Real API |
| content | admin | GET | `/admin-api/muse/content/import-tasks` | `adminListImportTasks` | dedicated | completed | P1R-1 Content Real API |
| content | admin | GET | `/admin-api/muse/content/works` | `adminListWorks` | dedicated | completed | P1R-1 Content Real API |
| content | admin | GET | `/admin-api/muse/content/works/{workId}` | `adminGetWork` | dedicated | completed | P1R-1 Content Real API |
| content | admin | GET | `/admin-api/muse/content/works/{workId}/chapters` | `adminListChapters` | dedicated | completed | P1R-1 Content Real API |
| content | admin | POST | `/admin-api/muse/content/works/{workId}/risk-actions` | `adminRiskAction` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/chapter-parse-results/{resultId}/confirm` | `confirmChapterParseResult` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/chapter-parse-results/{resultId}/reject` | `rejectChapterParseResult` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/downloads/{credentialId}` | `downloadExportPackage` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/export-tasks/{taskId}` | `getExportTask` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/import-tasks/{taskId}` | `getImportTask` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/parse-jobs/{jobId}` | `getParseJob` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/parse-jobs/{jobId}/chapters` | `listParseJobChapters` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/parse-jobs/{jobId}/chapters/batch-confirm` | `batchConfirmChapters` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/parse-jobs/{jobId}/retry` | `retryParseJob` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/chapter-parse-results/{resultId}/confirm` | `confirmChapterParseResult` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/chapter-parse-results/{resultId}/reject` | `rejectChapterParseResult` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/downloads/{credentialId}` | `downloadExportPackage` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/export-tasks/{taskId}` | `getExportTask` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/import-tasks/{taskId}` | `getImportTask` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/parse-jobs/{jobId}` | `getParseJob` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/parse-jobs/{jobId}/chapters` | `listParseJobChapters` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/parse-jobs/{jobId}/chapters/batch-confirm` | `batchConfirmChapters` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/parse-jobs/{jobId}/retry` | `retryParseJob` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works` | `listWorks` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works` | `createWork` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | DELETE | `/app-api/muse/works/{workId}` | `deleteWork` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works` | `createWork` | dedicated | completed | P1R-1 Content Real API |
| content | app | DELETE | `/app-api/muse/works/{workId}` | `deleteWork` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}` | `getWork` | dedicated | completed | P1R-1 Content Real API |
| content | app | PUT | `/app-api/muse/works/{workId}` | `updateWork` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | DELETE | `/app-api/muse/works/{workId}/blocks/{blockId}` | `deleteBlock` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | PUT | `/app-api/muse/works/{workId}` | `updateWork` | dedicated | completed | P1R-1 Content Real API |
| content | app | DELETE | `/app-api/muse/works/{workId}/blocks/{blockId}` | `deleteBlock` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/blocks/{blockId}` | `getBlock` | dedicated | completed | P1R-1 Content Real API |
| content | app | PUT | `/app-api/muse/works/{workId}/blocks/{blockId}` | `saveBlock` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/blocks/{blockId}/merge` | `mergeBlocks` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/blocks/{blockId}/merge` | `mergeBlocks` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/blocks/{blockId}/source-attribution` | `getBlockSourceAttribution` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/blocks/{blockId}/split` | `splitBlock` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/blocks/{blockId}/suggestion-merges` | `mergeBlockSuggestion` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/blocks/{blockId}/split` | `splitBlock` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/blocks/{blockId}/suggestion-merges` | `mergeBlockSuggestion` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/chapters` | `listChapters` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/chapters` | `createChapter` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | DELETE | `/app-api/muse/works/{workId}/chapters/{chapterId}` | `deleteChapter` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/chapters` | `createChapter` | dedicated | completed | P1R-1 Content Real API |
| content | app | DELETE | `/app-api/muse/works/{workId}/chapters/{chapterId}` | `deleteChapter` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/chapters/{chapterId}` | `getChapter` | dedicated | completed | P1R-1 Content Real API |
| content | app | PUT | `/app-api/muse/works/{workId}/chapters/{chapterId}` | `updateChapter` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | PUT | `/app-api/muse/works/{workId}/chapters/{chapterId}` | `updateChapter` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/chapters/{chapterId}/blocks` | `listBlocks` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/chapters/{chapterId}/blocks` | `createBlock` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | PUT | `/app-api/muse/works/{workId}/chapters/{chapterId}/reorder` | `reorderChapters` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/dynamic-fields/validate` | `validateDynamicFields` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/export` | `exportWork` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/export-tasks` | `createExportTask` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/import-tasks` | `createImportTask` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/meta-projections` | `listMetaProjections` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/meta-projections/{projectionKey}` | `getMetaProjection` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/parse-jobs` | `createParseJob` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/chapters/{chapterId}/blocks` | `createBlock` | dedicated | completed | P1R-1 Content Real API |
| content | app | PUT | `/app-api/muse/works/{workId}/chapters/{chapterId}/reorder` | `reorderChapters` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/dynamic-fields/validate` | `validateDynamicFields` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/export` | `exportWork` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/export-tasks` | `createExportTask` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/import-tasks` | `createImportTask` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/meta-projections` | `listMetaProjections` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/meta-projections/{projectionKey}` | `getMetaProjection` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/parse-jobs` | `createParseJob` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/planning` | `getPlanning` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/planning/candidates` | `listPlanningCandidates` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/planning/candidates` | `createPlanningCandidate` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/planning/candidates/{candidateId}` | `getPlanningCandidate` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/planning/candidates/{candidateId}/confirm` | `confirmPlanningCandidate` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/planning/candidates/{candidateId}/discard` | `discardPlanningCandidate` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/planning/style-checks` | `createStyleCheck` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/planning/style-checks/{jobId}` | `getStyleCheckResult` | dedicated | needs_verification | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/planning/candidates` | `listPlanningCandidates` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/planning/candidates` | `createPlanningCandidate` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/planning/candidates/{candidateId}` | `getPlanningCandidate` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/planning/candidates/{candidateId}/confirm` | `confirmPlanningCandidate` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/planning/candidates/{candidateId}/discard` | `discardPlanningCandidate` | dedicated | completed | P1R-1 Content Real API |
| content | app | POST | `/app-api/muse/works/{workId}/planning/style-checks` | `createStyleCheck` | dedicated | completed | P1R-1 Content Real API |
| content | app | GET | `/app-api/muse/works/{workId}/planning/style-checks/{jobId}` | `getStyleCheckResult` | dedicated | completed | P1R-1 Content Real API |
| content | app | PUT | `/app-api/muse/works/{workId}/planning/{sectionKey}` | `savePlanningItem` | dedicated | completed | P1R-1 Content Real API |
| events | app | GET | `/app-api/muse/events` | `streamEvents` | dedicated | completed | P1R-7 End-to-End Acceptance |
| knowledge | admin | GET | `/admin-api/muse/knowledge/drafts` | `listKnowledgeDraftsGovernance` | dedicated | completed | P1R-5 Knowledge Real API |
@ -199,38 +199,38 @@
| knowledge | app | DELETE | `/app-api/muse/works/{workId}/knowledge-bindings/{bindingId}` | `deleteKnowledgeBinding` | dedicated | completed | P1R-5 Knowledge Real API |
| knowledge | app | GET | `/app-api/muse/works/{workId}/knowledge-drafts` | `listKnowledgeDrafts` | dedicated | completed | P1R-5 Knowledge Real API |
| knowledge | app | GET | `/app-api/muse/works/{workId}/local-knowledge` | `getLocalKnowledge` | dedicated | completed | P1R-5 Knowledge Real API |
| market | admin | GET | `/admin-api/muse/market/appeals` | `adminListAppeals` | dedicated | needs_verification | P1R-6 Market Real API |
| market | admin | GET | `/admin-api/muse/market/appeals/{appealId}` | `adminGetAppeal` | dedicated | needs_verification | P1R-6 Market Real API |
| market | admin | POST | `/admin-api/muse/market/appeals/{appealId}/resolve` | `adminResolveAppeal` | dedicated | needs_verification | P1R-6 Market Real API |
| market | admin | GET | `/admin-api/muse/market/assets` | `adminListMarketAssets` | dedicated | needs_verification | P1R-6 Market Real API |
| market | admin | GET | `/admin-api/muse/market/assets/{assetId}` | `adminGetMarketAsset` | dedicated | needs_verification | P1R-6 Market Real API |
| market | admin | POST | `/admin-api/muse/market/assets/{assetId}/delist` | `adminDelistAsset` | dedicated | needs_verification | P1R-6 Market Real API |
| market | admin | POST | `/admin-api/muse/market/assets/{assetId}/governance-impact` | `adminPreviewGovernanceImpact` | dedicated | needs_verification | P1R-6 Market Real API |
| market | admin | POST | `/admin-api/muse/market/assets/{assetId}/recall` | `adminRecallAsset` | dedicated | needs_verification | P1R-6 Market Real API |
| market | admin | GET | `/admin-api/muse/market/publish-requests` | `adminListPublishRequests` | dedicated | needs_verification | P1R-6 Market Real API |
| market | admin | POST | `/admin-api/muse/market/publish-requests/{requestId}/approve` | `adminApprovePublishRequest` | dedicated | needs_verification | P1R-6 Market Real API |
| market | admin | POST | `/admin-api/muse/market/publish-requests/{requestId}/reject` | `adminRejectPublishRequest` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/appeals` | `submitAppeal` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/appeals/{appealId}/supplements` | `supplementAppeal` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/appeals/{appealId}/withdraw` | `withdrawAppeal` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | GET | `/app-api/muse/marketplace/assets` | `listMarketplaceAssets` | dedicated | needs_verification | P1R-6 Market Real API |
| market | admin | GET | `/admin-api/muse/market/appeals` | `adminListAppeals` | dedicated | completed | P1R-6 Market Real API |
| market | admin | GET | `/admin-api/muse/market/appeals/{appealId}` | `adminGetAppeal` | dedicated | completed | P1R-6 Market Real API |
| market | admin | POST | `/admin-api/muse/market/appeals/{appealId}/resolve` | `adminResolveAppeal` | dedicated | completed | P1R-6 Market Real API |
| market | admin | GET | `/admin-api/muse/market/assets` | `adminListMarketAssets` | dedicated | completed | P1R-6 Market Real API |
| market | admin | GET | `/admin-api/muse/market/assets/{assetId}` | `adminGetMarketAsset` | dedicated | completed | P1R-6 Market Real API |
| market | admin | POST | `/admin-api/muse/market/assets/{assetId}/delist` | `adminDelistAsset` | dedicated | completed | P1R-6 Market Real API |
| market | admin | POST | `/admin-api/muse/market/assets/{assetId}/governance-impact` | `adminPreviewGovernanceImpact` | dedicated | completed | P1R-6 Market Real API |
| market | admin | POST | `/admin-api/muse/market/assets/{assetId}/recall` | `adminRecallAsset` | dedicated | completed | P1R-6 Market Real API |
| market | admin | GET | `/admin-api/muse/market/publish-requests` | `adminListPublishRequests` | dedicated | completed | P1R-6 Market Real API |
| market | admin | POST | `/admin-api/muse/market/publish-requests/{requestId}/approve` | `adminApprovePublishRequest` | dedicated | completed | P1R-6 Market Real API |
| market | admin | POST | `/admin-api/muse/market/publish-requests/{requestId}/reject` | `adminRejectPublishRequest` | dedicated | completed | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/appeals` | `submitAppeal` | dedicated | completed | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/appeals/{appealId}/supplements` | `supplementAppeal` | dedicated | completed | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/appeals/{appealId}/withdraw` | `withdrawAppeal` | dedicated | completed | P1R-6 Market Real API |
| market | app | GET | `/app-api/muse/marketplace/assets` | `listMarketplaceAssets` | dedicated | completed | P1R-6 Market Real API |
| market | app | GET | `/app-api/muse/marketplace/assets/{assetId}` | `getMarketplaceAsset` | dedicated | completed | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/assets/{assetId}/bind-precheck` | `createBindPrecheck` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/assets/{assetId}/bind-precheck` | `createBindPrecheck` | dedicated | completed | P1R-6 Market Real API |
| market | app | DELETE | `/app-api/muse/marketplace/assets/{assetId}/favorite` | `unfavoriteAsset` | dedicated | completed | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/assets/{assetId}/favorite` | `favoriteAsset` | dedicated | completed | P1R-6 Market Real API |
| market | app | GET | `/app-api/muse/marketplace/assets/{assetId}/governance-impact` | `getGovernanceImpact` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/assets/{assetId}/install` | `installMarketplaceAsset` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/assets/{assetId}/purchase` | `purchaseAsset` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | GET | `/app-api/muse/marketplace/assets/{assetId}/governance-impact` | `getGovernanceImpact` | dedicated | completed | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/assets/{assetId}/install` | `installMarketplaceAsset` | dedicated | completed | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/assets/{assetId}/purchase` | `purchaseAsset` | dedicated | completed | P1R-6 Market Real API |
| market | app | GET | `/app-api/muse/marketplace/categories` | `listMarketplaceCategories` | dedicated | completed | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/handoffs` | `createMarketplaceHandoff` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | GET | `/app-api/muse/marketplace/handoffs/{handoffToken}` | `getHandoffStatus` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/handoffs/{handoffToken}/cancel` | `cancelHandoff` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | GET | `/app-api/muse/marketplace/my-publish-records` | `listMyPublishRecords` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/publish-drafts` | `savePublishDraft` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/publish-drafts/{draftId}/checks` | `runPublishCheck` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/publish-requests` | `submitPublishRequest` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/publish-requests/{requestId}/withdraw` | `withdrawPublishRequest` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | GET | `/app-api/muse/marketplace/recommendations` | `listMarketplaceRecommendations` | dedicated | needs_verification | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/handoffs` | `createMarketplaceHandoff` | dedicated | completed | P1R-6 Market Real API |
| market | app | GET | `/app-api/muse/marketplace/handoffs/{handoffToken}` | `getHandoffStatus` | dedicated | completed | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/handoffs/{handoffToken}/cancel` | `cancelHandoff` | dedicated | completed | P1R-6 Market Real API |
| market | app | GET | `/app-api/muse/marketplace/my-publish-records` | `listMyPublishRecords` | dedicated | completed | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/publish-drafts` | `savePublishDraft` | dedicated | completed | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/publish-drafts/{draftId}/checks` | `runPublishCheck` | dedicated | completed | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/publish-requests` | `submitPublishRequest` | dedicated | completed | P1R-6 Market Real API |
| market | app | POST | `/app-api/muse/marketplace/publish-requests/{requestId}/withdraw` | `withdrawPublishRequest` | dedicated | completed | P1R-6 Market Real API |
| market | app | GET | `/app-api/muse/marketplace/recommendations` | `listMarketplaceRecommendations` | dedicated | completed | P1R-6 Market Real API |
| meta | admin | GET | `/admin-api/muse/governance/function-chains` | `listFunctionChains` | dedicated | completed | P1R-2 Meta Real API |
| meta | admin | POST | `/admin-api/muse/governance/function-chains/{chainKey}/impact-preview` | `previewFunctionChainImpact` | dedicated | completed | P1R-2 Meta Real API |
| meta | admin | POST | `/admin-api/muse/governance/function-chains/{chainKey}/versions/{version}/activate` | `activateFunctionChainVersion` | dedicated | completed | P1R-2 Meta Real API |

View File

@ -6,5 +6,5 @@
- **边界(不可违反)**:**正文 Canonical 唯一写入方**;Block 写入须带 expectedRevision 且 revision 单调递增;**Accept Suggestion 是候选进正文的唯一合法入口**——只写正文 + 候选归档 + 来源归因,**不写 Local KB**;守 BC 边界不碰他域 `.dal`([bc-boundaries](../../.agents/rules/bc-boundaries.md))。
- **out-of-scope**:知识入库(归 knowledge BC)、AI 生成(归 ai BC)。
- **现状**:只读评估 82%;后端齐全,契约高度一致。
- **2026-06-17 验收债**:批1 已补 work/chapter/block 生命周期 11 op 真实 PG 证据;批20-28 已补 planning candidate 5 + meta-projection 3 + style-check 2 + chapter-parse-result 决策 2 + parse-job 生命周期/创建 5 + import-task 2 + export-task 4 + 管理端任务列表 2 + mergeBlockSuggestion 1,均真实 PG 绿且证据已人工批准并翻 completed。批26 `P1rContentExportTaskCompletedApprovalIT` 补 export-task 簇 4 op(getExportTask/exportWork/createExportTask/downloadExportPackage)并修正 `ContentExportServiceImpl` public `exportWork/createExportTask` 事务边界,IT 已用 command_log 0 残留断言验证预占命令回滚。批27 扩展 `P1rContentAdminReadCompletedApprovalIT` 补 adminListImportTasks/adminListExportTasks:真实 `/admin-api` + method security + 租户行拦截器,读 `muse_content_import_task`/`muse_content_export_task` 真实行,覆盖分页/筛选/workTitle 回填/跨租户不泄露/RBAC/API version/no-write,并补齐老 harness 专属 `_test` 库自动创建。批28 扩展 `P1rContentParseJobLifecycleCompletedApprovalIT` 补 createParseJob 守卫/fail-closed/事务回滚证据,并修正 `P1rContentMergeSuggestionIT` 老 harness 专属 `_test` 库自动创建后复验 mergeBlockSuggestion 真实写 Canonical 正文链路。content/account/market needs_verification 验收债均已清零;coverage JSON completed 已按人工批准翻转。
- **2026-06-17 验收债**:批1 已补 work/chapter/block 生命周期 11 op 真实 PG 证据;批20-28 已补 planning candidate 5 + meta-projection 3 + style-check 2 + chapter-parse-result 决策 2 + parse-job 生命周期/创建 5 + import-task 2 + export-task 4 + 管理端任务列表 2 + mergeBlockSuggestion 1,均真实 PG 绿且证据已人工批准并翻 completed。批26 `P1rContentExportTaskCompletedApprovalIT` 补 export-task 簇 4 op(getExportTask/exportWork/createExportTask/downloadExportPackage)并修正 `ContentExportServiceImpl` public `exportWork/createExportTask` 事务边界,IT 已用 command_log 0 残留断言验证预占命令回滚。批27 扩展 `P1rContentAdminReadCompletedApprovalIT` 补 adminListImportTasks/adminListExportTasks:真实 `/admin-api` + method security + 租户行拦截器,读 `muse_content_import_task`/`muse_content_export_task` 真实行,覆盖分页/筛选/workTitle 回填/跨租户不泄露/RBAC/API version/no-write,并补齐老 harness 专属 `_test` 库自动创建。批28 扩展 `P1rContentParseJobLifecycleCompletedApprovalIT` 补 createParseJob 守卫/fail-closed/事务回滚证据,并修正 `P1rContentMergeSuggestionIT` 老 harness 专属 `_test` 库自动创建后复验 mergeBlockSuggestion 真实写 Canonical 正文链路。content/account/market needs_verification 验收债均已清零;coverage JSON completed 已按人工批准翻转,且 2026-06-19 已补 `testFiles` 证据锚点门禁。
- **关键风险 / TODO**:Content 验收债已补齐真实 PG 证据;外部 owner(AI/Meta/FileService/解析投影)未接入的路径仍按合同 fail-closed,需要配置真实外部依赖或 owner 服务后才能从 fail-closed 升级为完整成功路径。

View File

@ -6,4 +6,4 @@
- **边界(不可违反)**:**授权 ≠ 所有权转移**;市场**非**源事实 owner,目标事实回目标 owner;Work 资产仅只读且排除出 install(`INSTALLABLE_ASSET_TYPES=Set.of(agent,knowledge_base)`);守 BC 边界不碰他域 `.dal`([bc-boundaries](../../.agents/rules/bc-boundaries.md))。
- **out-of-scope**:完整电商支付结算 DRM(项目非目标);模板化/参考写入/AI 上下文受 Feature Gate 默认关闭。
- **现状**:只读评估 82%;核心不变式已被代码强制。**生产者飞轮已端到端打通并活体证(2026-06-15)**:发布草稿→检查→提交→上架状态可视化→申诉(提交/补充材料/撤回)→申诉态回显(`MarketPublish`+`market-publish.spec.ts` 8/8,见[总账](../../docs/mvp/进度总账.md) §五C)。本会话新增 3 处 app-api 契约:`PublishRecordItem.marketAssetId`(物化资产 id,解申诉 assetId 映射 gap)、`GET /marketplace/appeals`(我的申诉列表)、记录 `appealStatus` 回填(`selectLatestByAssetIdAndUser`)。**2026-06-16 补真实 PG 验收证据**:`P1rMarketPublishProducerCompletedApprovalIT` 覆盖发布生产侧 5 op,真实 PG 3/3 绿;`P1rMarketAdminAppealCompletedApprovalIT` 覆盖管理端申诉 3 op(adminListAppeals/adminGetAppeal/adminResolveAppeal),真实 PG 6/6 绿;`P1rMarketAdminPublishReviewCompletedApprovalIT` 覆盖管理端发布审核 3 op(adminListPublishRequests/adminApprovePublishRequest/adminRejectPublishRequest),真实 PG 6/6 绿;`P1rMarketProducerAppealCompletedApprovalIT` 覆盖生产者申诉写路 3 op(submitAppeal/supplementAppeal/withdrawAppeal,app 入口 + owner 隔离 + 脱敏 + 状态 CAS + 冲突回滚),真实 PG 7/7 绿(独立复跑)。**2026-06-17 续补**:`P1rMarketAdminAssetReadsCompletedApprovalIT` 覆盖管理端资产治理读 2 op(adminListMarketAssets/adminGetMarketAsset:tenant 隔离 + assetType/listingStatus(not_listed↔draft 归一)/publisherId 过滤、详情资产快照 + 授权/安装/绑定/受影响任务计数全 0(关联表空)、缺资产/跨租户→MARKET_ASSET_NOT_EXISTS、API version/RBAC(muse:market:asset:query)fail-closed、纯读 no-write),真实 PG 2/2 绿(独立复跑)。`P1rMarketGovernanceWriteCompletedApprovalIT` 覆盖管理端资产治理写 3 op(adminPreviewGovernanceImpact/adminDelistAsset/adminRecallAsset:影响预览→凭预览下架 listed→delisted 的 expectedStatus CAS→凭预览召回 listed→recalled + 目标 owner 传播 fail-closed 如实记录 recalled/recorded/TARGET_OWNER_UNAVAILABLE;命令幂等、合同枚举 @Pattern→BAD_REQUEST、缺预览/CAS 阻断/缺资产/API version/RBAC fail-closed 0 写),真实 PG 4/4 绿(独立复跑)。`P1rMarketplaceDiscoveryReadsCompletedApprovalIT` 覆盖 marketplace 发现读 3 op(listMarketplaceAssets/listMarketplaceRecommendations/getGovernanceImpact:App 可见性隔离 listed 公开/非公开仅 publisher 自见 + assetType 过滤、fallback 推荐 + 理由、治理影响读 publisher/受影响者门禁 非属主无关联→MARKET_RESOURCE_FORBIDDEN、缺资产/API version fail-closed、纯读 no-write),真实 PG 4/4 绿(独立复跑)。`P1rMarketLicenseInstallCompletedApprovalIT` 覆盖采纳链 2 op(purchaseAsset/installMarketplaceAsset:购买写授权快照+购买事实+命令并跨 BC 同步 purchase/license 两条 Account 投影、安装要求已购授权+仅 agent/kb 可安装+写 installed 记录、命令幂等、未上架/缺资产/授权类型不符/无授权/作品不可安装/API version fail-closed 0 写),真实 PG 3/3 绿(独立复跑);证据已人工批准并翻 completed。`P1rMarketHandoffClusterCompletedApprovalIT` 覆盖 handoff 簇 4 op(createBindPrecheck/createMarketplaceHandoff/getHandoffStatus/cancelHandoff:已购 active 授权快照→来源授权摘要(handoffReady)→一次性 handoff token(明文不入库、只存 sha256 hash,事件快照不含明文)→只读回显 pending→expectedStatus CAS 取消(pending→cancelled)的端到端链;bind/handoff 回放幂等、cancel 终态后再取消被取消性守卫拒绝且不双写;非法 version/缺资产/无授权(授权≠可达)/目标 owner 白名单外(LocalMarketTargetOwnerFacade 本地目标页 fail-closed)/跨属主 token 读取与取消(属主隔离 RESOURCE_FORBIDDEN)/取消 CAS 期望态不匹配(reserveCommand MANDATORY 预占随事务回滚)失败路径 0 写),真实 PG 3/3 绿(独立复跑);至此 market needs_verification 28 op 全补 dedicated 真实 PG 证据,证据已人工批准并翻 completed。
- **关键风险 / TODO**:① **资产物化只在 admin 审核通过(`markListed`)发生**——submit 阶段 `publish_request.asset_id=draft.id` 占位,故未上架资产无 `muse_market_asset` 行,申诉(`requireAsset`)仅对已物化(曾上架)资产可达;② 申诉证据材料附件上传(`attachmentIds` 当前前端置空);③ 上架后下架/召回的生产者自助入口;④ **market 验收债已清零(2026-06-17)**:批15-19 补 14 op(资产治理读 2 + 治理写 3 + marketplace 发现读 3 + 采纳链 purchase/install 2 + handoff 簇 4)叠加本战役前 14 op(发布生产 5 + 管理端申诉 3 + 发布审核 3 + 生产者申诉 3)= market needs_verification 28 op 全有 dedicated 真实 PG 证据;**台账 completed flip 与覆盖门禁 `P1rApiCoverageReportTest.APPROVED_COMPLETED_OPERATIONS` 已按人工批准同步**。
- **关键风险 / TODO**:① **资产物化只在 admin 审核通过(`markListed`)发生**——submit 阶段 `publish_request.asset_id=draft.id` 占位,故未上架资产无 `muse_market_asset` 行,申诉(`requireAsset`)仅对已物化(曾上架)资产可达;② 申诉证据材料附件上传(`attachmentIds` 当前前端置空);③ 上架后下架/召回的生产者自助入口;④ **market 验收债已清零(2026-06-17)**:批15-19 补 14 op(资产治理读 2 + 治理写 3 + marketplace 发现读 3 + 采纳链 purchase/install 2 + handoff 簇 4)叠加本战役前 14 op(发布生产 5 + 管理端申诉 3 + 发布审核 3 + 生产者申诉 3)= market needs_verification 28 op 全有 dedicated 真实 PG 证据;**台账 completed flip 与覆盖门禁批准集合已按人工批准同步,2026-06-19 已补 `testFiles` 证据锚点门禁**。

View File

@ -6,4 +6,4 @@
- **边界(不可违反)**:是用户可见权益的聚合**读模型**与跳转入口,**不是消费账本事实源,不能反写**作品/知识/智能体/市场事实;高危审计 append-only + WORM/哈希链;Entitlement/Quota/Usage/Security/Binding 唯一写入 authority;守 BC 边界不碰他域 `.dal`([bc-boundaries](../../.agents/rules/bc-boundaries.md))。
- **out-of-scope**:他域事实写入。
- **现状**:只读评估 68%。**2026-06-15 活体订正**:单体内 `MarketAccountProjectionFacade` 由 market 的 `MarketAccountProjectionProvider` 真实提供,purchases/licenses/publish-records 三端可读投影,不是 `*_UNAVAILABLE` 缺口。**2026-06-16 补真实 PG 验收证据**:`P1rAccountMarketRecordsCompletedApprovalIT` 覆盖 appListPurchases/appListLicenses/appListPublishRecords,真实 PG 3/3 绿;`P1rAccountQuotaRequestCompletedApprovalIT` 覆盖 appCreateQuotaRequest/appGetQuotaRequest/adminCreateQuotaRequest(命令幂等+commandId 冲突回滚+owner/tenant 隔离+RBAC+类型白名单),真实 PG 5/5 绿(独立复跑);`P1rAccountUsageObservabilityCompletedApprovalIT` 覆盖 getAppUsage/appGetIntegrationCallByCorrelation/adminGetIntegrationCallByCorrelation(用量按 owner 聚合 token/pending/anomaly/byModel+跨用户隔离+period 白名单、外部调用 app owner 守卫/admin 无 owner 限制+RBAC、三 op 纯读 no-write、缺用户/not-found/API version/RBAC fail-closed),真实 PG 4/4 绿(独立复跑);`P1rAccountNewApiBindingClusterCompletedApprovalIT` 覆盖 getAppNewApiBinding/adminListNewApiBindings/appRecheckNewApiBinding(绑定摘要 owner 读 + active→bound 归一、admin 列表以账户用户为分页主表 + EXISTS/NOT EXISTS 状态筛选 + RBAC、两读 no-write、recheck 单体 New-API 不可用正确 fail-closed:命令预占回滚但失败调用 REQUIRES_NEW 独立落库),真实 PG 4/4 绿(独立复跑);`P1rAccountExportDownloadClusterCompletedApprovalIT` 覆盖 appCreateExportTask/appGetExportTask/appDownloadExport(FileService 未接入时非敏感导出落 queued 任务+命令+审计、不伪造 completed/凭证、敏感类型缺 step-up fail-closed、命令幂等;get owner 读 + 跨 owner not found + no-write;download 凭证门禁 + FileService 不可用正确 fail-closed:@Transactional 回滚一次性消费、不写审计),真实 PG 4/4 绿(独立复跑);`P1rAccountAdminReadsCompletedApprovalIT` 覆盖 adminListUsageRecords/adminGetCallAttributionJob(用量以账户用户为分页主表库内聚合 token/pending/failed/attributionStatus、调用归因 job 按 jobId 读 job+items 归一状态+分桶计数、RBAC+API version fail-closed、纯读 no-write),真实 PG 3/3 绿(独立复跑);`P1rAccountAdminWritesCompletedApprovalIT` 覆盖 adminCreateNewApiBinding/adminCreateCallAttributionJob(binding 单体 New-API 不可用正确 fail-closed:命令回滚+失败调用 REQUIRES_NEW 独立落库+binding 不写;attribution job 基于已存在 correlationId 调用建 queued job+命令幂等+callIds 白名单/expectedCallRevision/缺调用记录/RBAC/API version fail-closed),真实 PG 3/3 绿(独立复跑);`P1rAccountSecurityEventAckCompletedApprovalIT` 覆盖 appAcknowledgeSecurityEvent(owner 校验事件归属 + 追加表写处理轨迹 + 基础事件 acknowledged 置真 + 命令幂等 + 审计;非法 action/跨 owner NOT_FOUND/非数字 eventId/缺用户/API version fail-closed 且 0 写),真实 PG 2/2 绿(独立复跑);`P1rAccountAdminPurchaseRecordsCompletedApprovalIT` 覆盖 adminListPurchaseRecords(跨模块 base-package=cn.iocoder.muse.module + 单体内 market 的 `MarketAccountProjectionProvider` 真实判定 purchase 投影可用,读端只读 Account 自有投影表 muse_account_record_projection;无 userId→跨用户全量、userId 过滤→owner 限定 + source_status→admin status 归一 + 资产信息从 title/snapshot 回填、非法 status/API version/RBAC(muse:account:query) fail-closed、纯读 no-write,Account 投影写端口 stub 越界反假绿),真实 PG 2/2 绿(独立复跑);证据已人工批准并翻 completed。
- **关键风险 / TODO**:account needs_verification 验收债**已清零**:末位 adminListPurchaseRecords 经 `P1rAccountAdminPurchaseRecordsCompletedApprovalIT`(跨模块 base-package=cn.iocoder.muse.module + import MarketAccountProjectionProvider)真实 PG 2/2 绿补证;批3(市场记录读)+ 批7-14 account needs_verification op 全部补真实 PG 证据、证据已人工批准并翻 completed。截至 2026-06-17,content/market/account 三域 needs_verification 验收债均已补齐真实 PG 证据,coverage JSON completed flip 与覆盖门禁批准集合已按人工批准同步。前端仍有深页未全覆盖真实后端。
- **关键风险 / TODO**:account needs_verification 验收债**已清零**:末位 adminListPurchaseRecords 经 `P1rAccountAdminPurchaseRecordsCompletedApprovalIT`(跨模块 base-package=cn.iocoder.muse.module + import MarketAccountProjectionProvider)真实 PG 2/2 绿补证;批3(市场记录读)+ 批7-14 account needs_verification op 全部补真实 PG 证据、证据已人工批准并翻 completed。截至 2026-06-17,content/market/account 三域 needs_verification 验收债均已补齐真实 PG 证据,coverage JSON completed flip 与覆盖门禁批准集合已按人工批准同步,2026-06-19 已补 `testFiles` 证据锚点门禁。前端仍有深页未全覆盖真实后端。

View File

@ -35,6 +35,7 @@ class P1rApiCoverageReportTest {
"completionStatus",
"controllerFiles",
"serviceFiles",
"testFiles",
"notes"
);
@ -280,6 +281,7 @@ class P1rApiCoverageReportTest {
assertFalse(operation.path("completionStatus").asText().isBlank(), operationId + " 的 completionStatus 不能为空");
assertTrue(operation.path("controllerFiles").isArray(), operationId + " 的 controllerFiles 必须是数组");
assertTrue(operation.path("serviceFiles").isArray(), operationId + " 的 serviceFiles 必须是数组");
assertTrue(operation.path("testFiles").isArray(), operationId + " 的 testFiles 必须是数组");
assertTrue(operation.path("notes").isTextual(), operationId + " 的 notes 必须是字符串");
assertFalse(operation.path("notes").asText().isBlank(), operationId + " 的 notes 不能为空");
}
@ -431,6 +433,35 @@ class P1rApiCoverageReportTest {
}
}
/**
* completed 的 operation 还必须引用真实测试文件,防止只靠源码文件和批准集合形成自证回路。
*
* @throws IOException 读取覆盖报告失败时抛出
*/
@Test
void should_back_completed_operations_with_existing_test_files() throws IOException {
Path repoRoot = findRepoRoot();
for (JsonNode operation : readOperations()) {
String operationId = operation.path("operationId").asText("<missing-operationId>");
if (!"completed".equals(operation.path("completionStatus").asText())) {
assertEquals(0, operation.path("testFiles").size(),
operationId + " 未完成 operation 不应引用 testFiles 证据");
continue;
}
assertTrue(operation.path("testFiles").size() > 0,
operationId + " 标记 completed 必须至少引用一个 testFiles");
for (JsonNode file : operation.path("testFiles")) {
String testFile = file.asText();
assertTrue(testFile.contains("/src/test/java/") && testFile.endsWith(".java"),
operationId + " 引用的 testFiles 必须指向 Java 测试源码: " + testFile);
assertFalse(testFile.endsWith("P1rApiCoverageReportTest.java") || testFile.endsWith("RealApiGateTest.java"),
operationId + " testFiles 不能引用 coverage/gate 自身形成自证: " + testFile);
assertTrue(Files.exists(repoRoot.resolve(testFile)),
operationId + " 引用的 test 文件不存在: " + testFile);
}
}
}
private JsonNode readOperations() throws IOException {
return objectMapper.readTree(findReportPath().toFile()).path("operations");
}

View File

@ -44,59 +44,232 @@ SSE_PLACEHOLDER_READY_MARKERS = {
"muse event stream ready",
}
APPROVED_COMPLETED_DOMAINS = {"ai", "knowledge"}
APPROVED_COMPLETED_OPERATIONS_BY_DOMAIN = {
# Account / Content / Market 在 2026-06-17 经真实 PG 证据 + 用户批准后仍保持 operation-level approval。
"account": {
"adminCreateCallAttributionJob",
"adminCreateNewApiBinding",
"adminCreateQuotaAdjustment",
"adminCreateQuotaRequest",
"adminGetBalanceSnapshots",
"adminGetCallAttributionJob",
"adminGetIntegrationCallByCorrelation",
"adminGetUserEntitlements",
"adminListAccountUsers",
"adminListNewApiBindings",
"adminListPurchaseRecords",
"adminListQuotaAdjustments",
"adminListUsageRecords",
"appAcknowledgeSecurityEvent",
"appCreateExportTask",
"appCreateQuotaRequest",
"appDownloadExport",
"appGetExportTask",
"appGetIntegrationCallByCorrelation",
"appGetQuotaRequest",
"appGetSecurityEvent",
"appListLicenses",
"appListPublishRecords",
"appListPurchases",
"appListSecurityEvents",
"appRecheckNewApiBinding",
"getAppBalanceSnapshots",
"getAppEntitlements",
"getAppNewApiBinding",
"getAppUsage",
"getCurrentUser",
"getProfile",
"updateProfile",
},
"content": {
"adminGetWork",
"adminListChapters",
"adminListExportTasks",
"adminListImportTasks",
"adminListWorks",
"adminRiskAction",
"batchConfirmChapters",
"confirmChapterParseResult",
"confirmPlanningCandidate",
"createBlock",
"createChapter",
"createExportTask",
"createImportTask",
"createParseJob",
"createPlanningCandidate",
"createStyleCheck",
"createWork",
"deleteBlock",
"deleteChapter",
"deleteWork",
"discardPlanningCandidate",
"downloadExportPackage",
"exportWork",
"getBlock",
"getBlockSourceAttribution",
"getChapter",
"getExportTask",
"getImportTask",
"getMetaProjection",
"getParseJob",
"getPlanning",
"getPlanningCandidate",
"getStyleCheckResult",
"getWork",
"listBlocks",
"listChapters",
"listMetaProjections",
"listParseJobChapters",
"listPlanningCandidates",
"listWorks",
"mergeBlockSuggestion",
"mergeBlocks",
"rejectChapterParseResult",
"reorderChapters",
"retryParseJob",
"saveBlock",
"savePlanningItem",
"splitBlock",
"updateChapter",
"updateWork",
"validateDynamicFields",
},
"events": {"streamEvents"},
"market": {
"adminApprovePublishRequest",
"adminDelistAsset",
"adminGetAppeal",
"adminGetMarketAsset",
"adminListAppeals",
"adminListMarketAssets",
"adminListPublishRequests",
"adminPreviewGovernanceImpact",
"adminRecallAsset",
"adminRejectPublishRequest",
"adminResolveAppeal",
"cancelHandoff",
"createBindPrecheck",
"createMarketplaceHandoff",
"favoriteAsset",
"getGovernanceImpact",
"getHandoffStatus",
"getMarketplaceAsset",
"installMarketplaceAsset",
"listMarketplaceAssets",
"listMarketplaceCategories",
"listMarketplaceRecommendations",
"listMyPublishRecords",
"purchaseAsset",
"runPublishCheck",
"savePublishDraft",
"submitAppeal",
"submitPublishRequest",
"supplementAppeal",
"unfavoriteAsset",
"withdrawAppeal",
"withdrawPublishRequest",
},
"meta": {
"activateFunctionChainVersion",
"activateMetaSchemaVersion",
"deprecateMetaSchemaVersion",
"getMetaSchema",
"getMetaSchemaVersion",
"getProtectionNode",
"listFunctionChains",
"listMetaSchemas",
"listProtectionNodes",
"previewFunctionChainImpact",
"previewMetaSchemaDraftImpact",
"publishMetaSchemaDraft",
"rollbackMetaSchemaVersion",
"saveMetaSchemaDraft",
"setMetaSchemaGrayRules",
"validateMetaSchemaDraft",
},
}
APPROVED_COMPLETED_OPERATIONS = {
"events:streamEvents",
# P1R Meta completed approval 使用 operation-level 清单,避免整域 Meta 被误升 completed。
"meta:listMetaSchemas",
"meta:getMetaSchema",
"meta:getMetaSchemaVersion",
"meta:saveMetaSchemaDraft",
"meta:validateMetaSchemaDraft",
"meta:previewMetaSchemaDraftImpact",
"meta:publishMetaSchemaDraft",
"meta:activateMetaSchemaVersion",
"meta:rollbackMetaSchemaVersion",
"meta:deprecateMetaSchemaVersion",
"meta:setMetaSchemaGrayRules",
"meta:listProtectionNodes",
"meta:getProtectionNode",
"meta:listFunctionChains",
"meta:previewFunctionChainImpact",
"meta:activateFunctionChainVersion",
# P1R Account completed approval 第一批仍使用 operation-level 清单,避免整域 Account 被误升 completed。
"account:getCurrentUser",
"account:getProfile",
"account:updateProfile",
"account:adminListAccountUsers",
"account:adminGetUserEntitlements",
"account:getAppEntitlements",
"account:adminGetBalanceSnapshots",
"account:getAppBalanceSnapshots",
"account:adminCreateQuotaAdjustment",
"account:adminListQuotaAdjustments",
# P1R Account Security Events read completed approval 只推进两个只读接口。
"account:appListSecurityEvents",
"account:appGetSecurityEvent",
# P1R Market completed approval 第一批仍使用 operation-level 清单,避免整域 Market 被误升 completed。
"market:getMarketplaceAsset",
"market:listMarketplaceCategories",
"market:favoriteAsset",
"market:unfavoriteAsset",
# P1R Content completed approval 仍使用 operation-level 清单,避免整域 Content 被误升 completed。
"content:listWorks",
"content:getWork",
"content:listChapters",
"content:getChapter",
"content:listBlocks",
"content:getBlock",
"content:saveBlock",
"content:getBlockSourceAttribution",
"content:getPlanning",
"content:savePlanningItem",
"content:adminListWorks",
"content:adminGetWork",
"content:adminListChapters",
"content:adminRiskAction",
f"{domain}:{operation_id}"
for domain, operation_ids in APPROVED_COMPLETED_OPERATIONS_BY_DOMAIN.items()
for operation_id in operation_ids
}
AI_DOMAIN_TEST_FILES = (
"muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAiRuntimeEndToEndLiveAcceptanceIT.java",
"muse-cloud/muse-module-ai/muse-module-ai-server/src/test/java/cn/iocoder/muse/module/ai/application/muse/facade/P1rNewApiLiveAcceptanceIT.java",
)
KNOWLEDGE_DOMAIN_TEST_FILES = (
"muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rKnowledgeRuntimeEndToEndLiveAcceptanceIT.java",
"muse-cloud/muse-module-knowledge/muse-module-knowledge-server/src/test/java/cn/iocoder/muse/module/knowledge/application/muse/facade/P1rRagFlowLiveAcceptanceIT.java",
)
TEST_FILES_BY_OPERATION = {
"events:streamEvents": (
"muse-cloud/muse-module-events/muse-module-events-server/src/test/java/cn/iocoder/muse/module/events/application/stream/EventsStreamServiceTest.java",
),
"meta:listMetaSchemas": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminMetaSchemaControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/MetaSchemaServiceTest.java",
),
"meta:getMetaSchema": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminMetaSchemaControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/MetaSchemaServiceTest.java",
),
"meta:getMetaSchemaVersion": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminMetaSchemaControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/MetaSchemaServiceTest.java",
),
"meta:saveMetaSchemaDraft": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminMetaSchemaControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/MetaSchemaServiceTest.java",
),
"meta:validateMetaSchemaDraft": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminMetaSchemaControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/MetaSchemaValidationServiceTest.java",
),
"meta:previewMetaSchemaDraftImpact": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminMetaSchemaControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/MetaSchemaImpactPreviewServiceTest.java",
),
"meta:publishMetaSchemaDraft": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminMetaSchemaControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/MetaSchemaServiceTest.java",
),
"meta:activateMetaSchemaVersion": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminMetaSchemaControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/MetaSchemaServiceTest.java",
),
"meta:rollbackMetaSchemaVersion": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminMetaSchemaControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/MetaSchemaServiceTest.java",
),
"meta:deprecateMetaSchemaVersion": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminMetaSchemaControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/MetaSchemaServiceTest.java",
),
"meta:setMetaSchemaGrayRules": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminMetaSchemaControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/MetaSchemaServiceTest.java",
),
"meta:listProtectionNodes": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminProtectionNodeControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/ProtectionNodeServiceTest.java",
),
"meta:getProtectionNode": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminProtectionNodeControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/ProtectionNodeServiceTest.java",
),
"meta:listFunctionChains": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminFunctionChainControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/FunctionChainServiceTest.java",
),
"meta:previewFunctionChainImpact": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminFunctionChainControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/FunctionChainServiceTest.java",
),
"meta:activateFunctionChainVersion": (
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/controller/admin/AdminFunctionChainControllerTest.java",
"muse-cloud/muse-module-meta/muse-module-meta-server/src/test/java/cn/iocoder/muse/module/meta/application/FunctionChainServiceTest.java",
),
}
@ -115,6 +288,7 @@ class Operation:
completionStatus: str
controllerFiles: list[str]
serviceFiles: list[str]
testFiles: list[str]
notes: str
@ -178,6 +352,7 @@ def collect_operations() -> list[Operation]:
completionStatus=implementation["completionStatus"],
controllerFiles=implementation["controllerFiles"],
serviceFiles=implementation["serviceFiles"],
testFiles=evidence_test_files_for(domain, operation_id, implementation["completionStatus"]),
notes=implementation["notes"],
)
)
@ -296,6 +471,268 @@ def status(implementation: str, completion: str, controllers: list[str], service
}
def evidence_test_files_for(domain: str, operation_id: str, completion_status: str) -> list[str]:
if completion_status != "completed":
return []
if domain == "ai":
return list(AI_DOMAIN_TEST_FILES)
if domain == "knowledge":
return list(KNOWLEDGE_DOMAIN_TEST_FILES)
operation_test_files = TEST_FILES_BY_OPERATION.get(operation_key(domain, operation_id))
if operation_test_files is not None:
return list(operation_test_files)
if domain == "account":
return account_test_files_for(operation_id)
if domain == "content":
return content_test_files_for(operation_id)
if domain == "market":
return market_test_files_for(operation_id)
return []
def account_test_files_for(operation_id: str) -> list[str]:
p1r_root = "muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api"
member_root = "muse-cloud/muse-module-member/muse-module-member-server/src/test/java/cn/iocoder/muse/module/member"
mapping = {
"adminCreateCallAttributionJob": (
f"{p1r_root}/P1rAccountAdminWritesCompletedApprovalIT.java",
f"{member_root}/application/account/AccountAttributionServiceTest.java",
),
"adminCreateNewApiBinding": (
f"{p1r_root}/P1rAccountAdminWritesCompletedApprovalIT.java",
f"{member_root}/controller/admin/account/AdminAccountNewApiControllerTest.java",
),
"adminCreateQuotaAdjustment": (
f"{member_root}/controller/admin/account/AdminAccountUserControllerTest.java",
f"{member_root}/application/account/AccountQuotaServiceTest.java",
),
"adminCreateQuotaRequest": (
f"{p1r_root}/P1rAccountQuotaRequestCompletedApprovalIT.java",
f"{member_root}/application/account/AccountQuotaServiceTest.java",
),
"adminGetBalanceSnapshots": (
f"{member_root}/controller/admin/account/AdminAccountUserControllerTest.java",
f"{member_root}/application/account/AccountEntitlementServiceTest.java",
),
"adminGetCallAttributionJob": (
f"{p1r_root}/P1rAccountAdminReadsCompletedApprovalIT.java",
f"{member_root}/application/account/AccountAttributionServiceTest.java",
),
"adminGetIntegrationCallByCorrelation": (
f"{p1r_root}/P1rAccountUsageObservabilityCompletedApprovalIT.java",
f"{member_root}/application/account/AccountUsageServiceTest.java",
),
"adminGetUserEntitlements": (
f"{member_root}/controller/admin/account/AdminAccountUserControllerTest.java",
f"{member_root}/application/account/AccountEntitlementServiceTest.java",
),
"adminListAccountUsers": (
f"{member_root}/controller/admin/account/AdminAccountUserControllerTest.java",
),
"adminListNewApiBindings": (
f"{p1r_root}/P1rAccountNewApiBindingClusterCompletedApprovalIT.java",
f"{member_root}/controller/admin/account/AdminAccountNewApiControllerTest.java",
),
"adminListPurchaseRecords": (
f"{p1r_root}/P1rAccountAdminPurchaseRecordsCompletedApprovalIT.java",
f"{member_root}/controller/admin/account/AdminAccountPurchaseControllerTest.java",
),
"adminListQuotaAdjustments": (
f"{member_root}/controller/admin/account/AdminAccountUserControllerTest.java",
f"{member_root}/application/account/AccountQuotaServiceTest.java",
),
"adminListUsageRecords": (
f"{p1r_root}/P1rAccountAdminReadsCompletedApprovalIT.java",
f"{member_root}/controller/admin/account/AdminAccountUsageControllerTest.java",
),
"appAcknowledgeSecurityEvent": (
f"{p1r_root}/P1rAccountSecurityEventAckCompletedApprovalIT.java",
f"{member_root}/controller/app/account/AppAccountSecurityControllerTest.java",
),
"appCreateExportTask": (
f"{p1r_root}/P1rAccountExportDownloadClusterCompletedApprovalIT.java",
f"{member_root}/controller/app/account/AppAccountExportControllerTest.java",
),
"appCreateQuotaRequest": (
f"{p1r_root}/P1rAccountQuotaRequestCompletedApprovalIT.java",
f"{member_root}/application/account/AccountQuotaServiceTest.java",
),
"appDownloadExport": (
f"{p1r_root}/P1rAccountExportDownloadClusterCompletedApprovalIT.java",
f"{member_root}/controller/app/account/AppAccountExportControllerTest.java",
),
"appGetExportTask": (
f"{p1r_root}/P1rAccountExportDownloadClusterCompletedApprovalIT.java",
f"{member_root}/controller/app/account/AppAccountExportControllerTest.java",
),
"appGetIntegrationCallByCorrelation": (
f"{p1r_root}/P1rAccountUsageObservabilityCompletedApprovalIT.java",
f"{member_root}/application/account/AccountUsageServiceTest.java",
),
"appGetQuotaRequest": (
f"{p1r_root}/P1rAccountQuotaRequestCompletedApprovalIT.java",
f"{member_root}/application/account/AccountQuotaServiceTest.java",
),
"appGetSecurityEvent": (
f"{p1r_root}/P1rAccountSecurityEventsCompletedApprovalIT.java",
f"{member_root}/controller/app/account/AppAccountSecurityControllerTest.java",
),
"appListLicenses": (
f"{p1r_root}/P1rAccountMarketRecordsCompletedApprovalIT.java",
f"{member_root}/application/account/AccountMarketRecordServiceTest.java",
),
"appListPublishRecords": (
f"{p1r_root}/P1rAccountMarketRecordsCompletedApprovalIT.java",
f"{member_root}/application/account/AccountMarketRecordServiceTest.java",
),
"appListPurchases": (
f"{p1r_root}/P1rAccountMarketRecordsCompletedApprovalIT.java",
f"{member_root}/application/account/AccountMarketRecordServiceTest.java",
),
"appListSecurityEvents": (
f"{p1r_root}/P1rAccountSecurityEventsCompletedApprovalIT.java",
f"{member_root}/controller/app/account/AppAccountSecurityControllerTest.java",
),
"appRecheckNewApiBinding": (
f"{p1r_root}/P1rAccountNewApiBindingClusterCompletedApprovalIT.java",
f"{member_root}/controller/app/account/AppAccountNewApiControllerTest.java",
),
"getAppBalanceSnapshots": (
f"{member_root}/controller/app/account/AppAccountEntitlementControllerTest.java",
f"{member_root}/application/account/AccountEntitlementServiceTest.java",
),
"getAppEntitlements": (
f"{member_root}/controller/app/account/AppAccountEntitlementControllerTest.java",
f"{member_root}/application/account/AccountEntitlementServiceTest.java",
),
"getAppNewApiBinding": (
f"{p1r_root}/P1rAccountNewApiBindingClusterCompletedApprovalIT.java",
f"{member_root}/controller/app/account/AppAccountNewApiControllerTest.java",
),
"getAppUsage": (
f"{p1r_root}/P1rAccountUsageObservabilityCompletedApprovalIT.java",
f"{member_root}/application/account/AccountUsageServiceTest.java",
),
"getCurrentUser": (
f"{member_root}/controller/app/account/AppAccountProfileControllerTest.java",
f"{member_root}/application/account/AccountProfileServiceTest.java",
),
"getProfile": (
f"{member_root}/controller/app/account/AppAccountProfileControllerTest.java",
f"{member_root}/application/account/AccountProfileServiceTest.java",
),
"updateProfile": (
f"{member_root}/controller/app/account/AppAccountProfileControllerTest.java",
f"{member_root}/application/account/AccountProfileServiceTest.java",
),
}
return list(mapping.get(operation_id, ()))
def content_test_files_for(operation_id: str) -> list[str]:
p1r_root = "muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api"
content_root = "muse-cloud/muse-module-content/muse-module-content-server/src/test/java/cn/iocoder/muse/module/content"
mapping = {
"adminGetWork": (f"{p1r_root}/P1rContentAdminReadCompletedApprovalIT.java",),
"adminListChapters": (f"{p1r_root}/P1rContentAdminReadCompletedApprovalIT.java",),
"adminListExportTasks": (f"{p1r_root}/P1rContentAdminReadCompletedApprovalIT.java",),
"adminListImportTasks": (f"{p1r_root}/P1rContentAdminReadCompletedApprovalIT.java",),
"adminListWorks": (f"{p1r_root}/P1rContentAdminReadCompletedApprovalIT.java",),
"adminRiskAction": (f"{p1r_root}/P1rContentAdminRiskActionCompletedApprovalIT.java",),
"batchConfirmChapters": (f"{p1r_root}/P1rContentParseJobLifecycleCompletedApprovalIT.java",),
"confirmChapterParseResult": (f"{p1r_root}/P1rContentChapterParseResultDecisionCompletedApprovalIT.java",),
"confirmPlanningCandidate": (f"{p1r_root}/P1rContentPlanningCandidateClusterCompletedApprovalIT.java",),
"createBlock": (f"{p1r_root}/P1rContentWorkLifecycleCompletedApprovalIT.java",),
"createChapter": (f"{p1r_root}/P1rContentWorkLifecycleCompletedApprovalIT.java",),
"createExportTask": (f"{p1r_root}/P1rContentExportTaskCompletedApprovalIT.java",),
"createImportTask": (f"{p1r_root}/P1rContentImportTaskCompletedApprovalIT.java",),
"createParseJob": (f"{p1r_root}/P1rContentParseJobLifecycleCompletedApprovalIT.java",),
"createPlanningCandidate": (f"{p1r_root}/P1rContentPlanningCandidateClusterCompletedApprovalIT.java",),
"createStyleCheck": (f"{p1r_root}/P1rContentStyleCheckClusterCompletedApprovalIT.java",),
"createWork": (f"{p1r_root}/P1rContentWorkLifecycleCompletedApprovalIT.java",),
"deleteBlock": (f"{p1r_root}/P1rContentWorkLifecycleCompletedApprovalIT.java",),
"deleteChapter": (f"{p1r_root}/P1rContentWorkLifecycleCompletedApprovalIT.java",),
"deleteWork": (f"{p1r_root}/P1rContentWorkLifecycleCompletedApprovalIT.java",),
"discardPlanningCandidate": (f"{p1r_root}/P1rContentPlanningCandidateClusterCompletedApprovalIT.java",),
"downloadExportPackage": (f"{p1r_root}/P1rContentExportTaskCompletedApprovalIT.java",),
"exportWork": (f"{p1r_root}/P1rContentExportTaskCompletedApprovalIT.java",),
"getBlock": (f"{p1r_root}/P1rContentCoreCompletedApprovalIT.java",),
"getBlockSourceAttribution": (f"{p1r_root}/P1rContentCoreCompletedApprovalIT.java",),
"getChapter": (f"{p1r_root}/P1rContentCoreCompletedApprovalIT.java",),
"getExportTask": (f"{p1r_root}/P1rContentExportTaskCompletedApprovalIT.java",),
"getImportTask": (f"{p1r_root}/P1rContentImportTaskCompletedApprovalIT.java",),
"getMetaProjection": (f"{p1r_root}/P1rContentMetaProjectionClusterCompletedApprovalIT.java",),
"getParseJob": (f"{p1r_root}/P1rContentParseJobLifecycleCompletedApprovalIT.java",),
"getPlanning": (
f"{p1r_root}/P1rContentPlanningCompletedApprovalIT.java",
f"{content_root}/application/ContentPlanningServiceTest.java",
),
"getPlanningCandidate": (f"{p1r_root}/P1rContentPlanningCandidateClusterCompletedApprovalIT.java",),
"getStyleCheckResult": (f"{p1r_root}/P1rContentStyleCheckClusterCompletedApprovalIT.java",),
"getWork": (f"{p1r_root}/P1rContentCoreCompletedApprovalIT.java",),
"listBlocks": (f"{p1r_root}/P1rContentCoreCompletedApprovalIT.java",),
"listChapters": (f"{p1r_root}/P1rContentCoreCompletedApprovalIT.java",),
"listMetaProjections": (f"{p1r_root}/P1rContentMetaProjectionClusterCompletedApprovalIT.java",),
"listParseJobChapters": (f"{p1r_root}/P1rContentParseJobLifecycleCompletedApprovalIT.java",),
"listPlanningCandidates": (f"{p1r_root}/P1rContentPlanningCandidateClusterCompletedApprovalIT.java",),
"listWorks": (f"{p1r_root}/P1rContentCoreCompletedApprovalIT.java",),
"mergeBlockSuggestion": (f"{p1r_root}/P1rContentMergeSuggestionIT.java",),
"mergeBlocks": (f"{p1r_root}/P1rContentWorkLifecycleCompletedApprovalIT.java",),
"rejectChapterParseResult": (f"{p1r_root}/P1rContentChapterParseResultDecisionCompletedApprovalIT.java",),
"reorderChapters": (f"{p1r_root}/P1rContentWorkLifecycleCompletedApprovalIT.java",),
"retryParseJob": (f"{p1r_root}/P1rContentParseJobLifecycleCompletedApprovalIT.java",),
"saveBlock": (f"{p1r_root}/P1rContentCoreCompletedApprovalIT.java",),
"savePlanningItem": (
f"{p1r_root}/P1rContentPlanningCompletedApprovalIT.java",
f"{content_root}/application/ContentPlanningServiceTest.java",
),
"splitBlock": (f"{p1r_root}/P1rContentWorkLifecycleCompletedApprovalIT.java",),
"updateChapter": (f"{p1r_root}/P1rContentWorkLifecycleCompletedApprovalIT.java",),
"updateWork": (f"{p1r_root}/P1rContentWorkLifecycleCompletedApprovalIT.java",),
"validateDynamicFields": (f"{p1r_root}/P1rContentMetaProjectionClusterCompletedApprovalIT.java",),
}
return list(mapping.get(operation_id, ()))
def market_test_files_for(operation_id: str) -> list[str]:
p1r_root = "muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api"
mapping = {
"adminApprovePublishRequest": (f"{p1r_root}/P1rMarketAdminPublishReviewCompletedApprovalIT.java",),
"adminDelistAsset": (f"{p1r_root}/P1rMarketGovernanceWriteCompletedApprovalIT.java",),
"adminGetAppeal": (f"{p1r_root}/P1rMarketAdminAppealCompletedApprovalIT.java",),
"adminGetMarketAsset": (f"{p1r_root}/P1rMarketAdminAssetReadsCompletedApprovalIT.java",),
"adminListAppeals": (f"{p1r_root}/P1rMarketAdminAppealCompletedApprovalIT.java",),
"adminListMarketAssets": (f"{p1r_root}/P1rMarketAdminAssetReadsCompletedApprovalIT.java",),
"adminListPublishRequests": (f"{p1r_root}/P1rMarketAdminPublishReviewCompletedApprovalIT.java",),
"adminPreviewGovernanceImpact": (f"{p1r_root}/P1rMarketGovernanceWriteCompletedApprovalIT.java",),
"adminRecallAsset": (f"{p1r_root}/P1rMarketGovernanceWriteCompletedApprovalIT.java",),
"adminRejectPublishRequest": (f"{p1r_root}/P1rMarketAdminPublishReviewCompletedApprovalIT.java",),
"adminResolveAppeal": (f"{p1r_root}/P1rMarketAdminAppealCompletedApprovalIT.java",),
"cancelHandoff": (f"{p1r_root}/P1rMarketHandoffClusterCompletedApprovalIT.java",),
"createBindPrecheck": (f"{p1r_root}/P1rMarketHandoffClusterCompletedApprovalIT.java",),
"createMarketplaceHandoff": (f"{p1r_root}/P1rMarketHandoffClusterCompletedApprovalIT.java",),
"favoriteAsset": (f"{p1r_root}/P1rMarketDiscoveryFavoriteCompletedApprovalIT.java",),
"getGovernanceImpact": (f"{p1r_root}/P1rMarketplaceDiscoveryReadsCompletedApprovalIT.java",),
"getHandoffStatus": (f"{p1r_root}/P1rMarketHandoffClusterCompletedApprovalIT.java",),
"getMarketplaceAsset": (f"{p1r_root}/P1rMarketDiscoveryFavoriteCompletedApprovalIT.java",),
"installMarketplaceAsset": (f"{p1r_root}/P1rMarketLicenseInstallCompletedApprovalIT.java",),
"listMarketplaceAssets": (f"{p1r_root}/P1rMarketplaceDiscoveryReadsCompletedApprovalIT.java",),
"listMarketplaceCategories": (f"{p1r_root}/P1rMarketDiscoveryFavoriteCompletedApprovalIT.java",),
"listMarketplaceRecommendations": (f"{p1r_root}/P1rMarketplaceDiscoveryReadsCompletedApprovalIT.java",),
"listMyPublishRecords": (f"{p1r_root}/P1rMarketPublishProducerCompletedApprovalIT.java",),
"purchaseAsset": (f"{p1r_root}/P1rMarketLicenseInstallCompletedApprovalIT.java",),
"runPublishCheck": (f"{p1r_root}/P1rMarketPublishProducerCompletedApprovalIT.java",),
"savePublishDraft": (f"{p1r_root}/P1rMarketPublishProducerCompletedApprovalIT.java",),
"submitAppeal": (f"{p1r_root}/P1rMarketProducerAppealCompletedApprovalIT.java",),
"submitPublishRequest": (f"{p1r_root}/P1rMarketPublishProducerCompletedApprovalIT.java",),
"supplementAppeal": (f"{p1r_root}/P1rMarketProducerAppealCompletedApprovalIT.java",),
"unfavoriteAsset": (f"{p1r_root}/P1rMarketDiscoveryFavoriteCompletedApprovalIT.java",),
"withdrawAppeal": (f"{p1r_root}/P1rMarketProducerAppealCompletedApprovalIT.java",),
"withdrawPublishRequest": (f"{p1r_root}/P1rMarketPublishProducerCompletedApprovalIT.java",),
}
return list(mapping.get(operation_id, ()))
def operation_key(domain: str, operation_id: str) -> str:
return f"{domain}:{operation_id}"
@ -702,6 +1139,7 @@ def validate_report(report: dict[str, Any]) -> None:
"completionStatus",
"controllerFiles",
"serviceFiles",
"testFiles",
"notes",
}
if report["summary"]["totalOperations"] <= 0:
@ -719,10 +1157,25 @@ def validate_report(report: dict[str, Any]) -> None:
)
if operation["completionStatus"] == "completed" and not approved_completed_operation(operation):
raise SystemExit(f"{operation['operationId']} is incorrectly marked completed")
if operation["completionStatus"] == "completed" and not operation["testFiles"]:
raise SystemExit(f"{operation['operationId']} completed operation must reference testFiles evidence")
if operation["completionStatus"] != "completed" and operation["testFiles"]:
raise SystemExit(f"{operation['operationId']} unfinished operation must not reference testFiles")
for test_file in operation["testFiles"]:
validate_test_file(operation, test_file)
if "message" in json.dumps(operation, ensure_ascii=False):
raise SystemExit(f"{operation['operationId']} contains forbidden response evidence field: message")
def validate_test_file(operation: dict[str, Any], test_file: str) -> None:
if "/src/test/java/" not in test_file or not test_file.endswith(".java"):
raise SystemExit(f"{operation['operationId']} testFiles must point to Java test source: {test_file}")
if "P1rApiCoverageReportTest.java" in test_file or "RealApiGateTest.java" in test_file:
raise SystemExit(f"{operation['operationId']} testFiles must not self-reference coverage gates: {test_file}")
if not (REPO_ROOT / test_file).exists():
raise SystemExit(f"{operation['operationId']} testFiles path does not exist: {test_file}")
def approved_completed_operation(operation: dict[str, Any]) -> bool:
# completed 只能来自已批准推进的 dedicated 域或单项 operation,避免非目标 domain 被误计完成。
if operation["implementationStatus"] != "dedicated":