只推进 Market 4 个 operation-level completed approval,保持 market domain-level allowlist 关闭,并保留剩余 28 个 Market operation 为 needs_verification。
263 lines
9.6 KiB
Markdown
263 lines
9.6 KiB
Markdown
# P1R Market 状态推进
|
||
|
||
日期:2026-06-11
|
||
|
||
## 结论
|
||
|
||
本轮只推进 Market 第一批 4 个 operation-level completed approval:
|
||
|
||
- `market:getMarketplaceAsset`
|
||
- `market:listMarketplaceCategories`
|
||
- `market:favoriteAsset`
|
||
- `market:unfavoriteAsset`
|
||
|
||
Market 仍不是整域 completed。`listMarketplaceAssets`、`listMarketplaceRecommendations` 以及 purchase/install/handoff/governance/publish/review/appeal/projection 相关 28 个 Market operation 继续 `dedicated/needs_verification`。
|
||
|
||
本轮未修改 Market 业务实现,未修改数据库迁移,未把 `market` 加入 domain-level completed allowlist。
|
||
|
||
## 工作区与基线
|
||
|
||
工作区:
|
||
|
||
```text
|
||
/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0
|
||
```
|
||
|
||
基线 HEAD:
|
||
|
||
```text
|
||
f18116a test(p1r): 收口 Account 第一批 completed approval 门禁
|
||
```
|
||
|
||
实施前 coverage summary:
|
||
|
||
```text
|
||
233 127 106 0 0 0
|
||
```
|
||
|
||
实施后 coverage summary:
|
||
|
||
```text
|
||
233 131 102 0 0 0
|
||
```
|
||
|
||
实施后 Market 状态:
|
||
|
||
```text
|
||
completed=4
|
||
needs_verification=28
|
||
```
|
||
|
||
## 允许变更与实际变更
|
||
|
||
OpenAPI 只修改:
|
||
|
||
- `docs/api-contracts/market/openapi.yaml`
|
||
|
||
变更内容只是在:
|
||
|
||
- `POST /app-api/muse/marketplace/assets/{assetId}/favorite`
|
||
- `DELETE /app-api/muse/marketplace/assets/{assetId}/favorite`
|
||
|
||
增加 required `X-Command-Id` header。原因是 Java Controller / Service 已强制校验 command id,而原 OpenAPI 没有声明,coverage report 因此误显示 `requiresCommandId=false`。
|
||
|
||
scanner 只修改:
|
||
|
||
- `muse-cloud/scripts/p1r-audit-api-coverage.py`
|
||
|
||
实际只追加 4 个 operation-level completed key,没有把 `market` 加入 `APPROVED_COMPLETED_DOMAINS`。
|
||
|
||
coverage report 已重新生成:
|
||
|
||
- `docs/superpowers/reports/p1r-api-coverage.json`
|
||
- `docs/superpowers/reports/p1r-api-coverage.md`
|
||
|
||
## TDD 证据
|
||
|
||
RED 阶段先修改 gate 期望值和 Market operation 断言,在旧 scanner/report 下运行 focused P1R gates,预期失败已出现:
|
||
|
||
- 失败点包括 expected completed=131 but was 127。
|
||
- 失败点包括 Market expected 4 completed but was 0。
|
||
- 该失败证明 gate 会阻止未获 scanner/report 支撑的 completed 推进。
|
||
|
||
GREEN 阶段完成 OpenAPI commandId 合同修正、scanner operation-level allowlist、report 重新生成和 focused evidence tests 后,目标验证通过。
|
||
|
||
## MockMvc HTTP 入口 + DB 证据
|
||
|
||
新增:
|
||
|
||
- `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rMarketDiscoveryFavoriteCompletedApprovalIT.java`
|
||
|
||
验证方式:
|
||
|
||
- 使用 Spring Mock web context + `MockMvc`。
|
||
- 使用真实 PostgreSQL `_test` 数据库。
|
||
- 使用 Flyway clean/migrate V1-V15。
|
||
- 密码只从环境变量读取,禁止通过 JVM system property 传入。
|
||
|
||
说明:这里的 HTTP 入口证据是执行版要求的 WebApplicationContext + MockMvc 请求路径证据,不是启动真实 socket 端口的 live servlet container 证据。
|
||
|
||
验证数据库:
|
||
|
||
```text
|
||
muse_p1r_market_discovery_favorite_completed_approval_test
|
||
```
|
||
|
||
通过结果:
|
||
|
||
```text
|
||
P1rMarketDiscoveryFavoriteCompletedApprovalIT: tests=9, failures=0, errors=0, skipped=0
|
||
```
|
||
|
||
覆盖内容:
|
||
|
||
- 资产详情 happy path。
|
||
- missing asset / invisible asset 不泄露详情、不写 command。
|
||
- 分类聚合包含 fallback slot 与 unavailable exposure summary。
|
||
- favorite 缺少 `X-Command-Id` 不写 DB。
|
||
- favorite 写 active favorite 与 command,重复 command 回放不重复写。
|
||
- unfavorite 写 inactive,不删除审计事实,重复 command 回放不重复写。
|
||
- missing/invisible target 对 favorite/unfavorite 不污染 command/favorite fact。
|
||
|
||
## Flyway 证据
|
||
|
||
增强:
|
||
|
||
- `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rMarketFlywayMigrationIT.java`
|
||
|
||
验证数据库:
|
||
|
||
```text
|
||
muse_p1r_market_completed_approval_test
|
||
```
|
||
|
||
通过结果:
|
||
|
||
```text
|
||
P1rMarketFlywayMigrationIT: tests=4, failures=0, errors=0, skipped=0
|
||
```
|
||
|
||
验证内容:
|
||
|
||
- V1-V15 clean migrate。
|
||
- `muse_market_favorite` 表存在。
|
||
- favorite user/asset/command 相关索引存在。
|
||
- `uk_muse_market_favorite_user_asset` 唯一约束存在。
|
||
- `trg_muse_market_favorite_updated_at` trigger 存在。
|
||
- 同 tenant/user/asset duplicate insert 被 PostgreSQL 唯一约束拒绝,SQLState 为 `23505`。
|
||
- 同 tenant/command_id duplicate insert 被 PostgreSQL partial unique index 拒绝,SQLState 为 `23505`。
|
||
- favorite status 更新为 `inactive` 时,`trg_muse_market_favorite_updated_at` 会覆盖旧 `update_time`。
|
||
|
||
额外组合验证:
|
||
|
||
```text
|
||
P1rMarketDiscoveryFavoriteCompletedApprovalIT -> P1rMarketFlywayMigrationIT: tests=13, failures=0, errors=0, skipped=0
|
||
P1rMarketFlywayMigrationIT -> P1rMarketDiscoveryFavoriteCompletedApprovalIT: tests=13, failures=0, errors=0, skipped=0
|
||
```
|
||
|
||
该组合验证使用真实 PostgreSQL `_test` 库:
|
||
|
||
```text
|
||
muse_p1r_market_combined_completed_approval_test
|
||
```
|
||
|
||
组合验证用于证明新增 Discovery IT 与增强 Flyway IT 对 `p1r.flyway.url/user` 的脱敏不会污染同一 Surefire JVM 内其他测试类。曾复现一次失败:Discovery IT 先运行后,Flyway IT 读到脱敏 system property,报缺少原始 `p1r.flyway.url`。修复方式是在 Discovery IT 与 Flyway IT 中都保存原始 `p1r.flyway.url/user`,并在 `@AfterAll` 恢复;随后补充 `-Dsurefire.runOrder=reversealphabetical`,日志确认先跑 Flyway IT、再跑 Discovery IT,合计 13/13 pass。
|
||
|
||
注意:Surefire XML 的 `<properties>` 会记录原始 `p1r.flyway.url` host 与 `p1r.flyway.user`,未发现 password 泄露。raw XML 只能作为本地验证产物,不应直接外发;如需外发测试报告,应先清洗 host/user 或改造为不通过 JVM system property 传递 URL/user。
|
||
|
||
review 处理:
|
||
|
||
- correctness reviewer 指出的 system property 污染为有效问题,已修复并用双向 combined IT 13/13 pass 关闭。
|
||
- data/testing reviewer 提到“真正 HTTP”若理解为 socket 级 live server则当前证据不足。核对执行版后,本轮要求是 WebApplicationContext/MockMvc + real mapper + `_test` DB,不是 live socket server;本文档已把措辞收窄为 MockMvc HTTP 入口,避免过度声明。
|
||
- data/testing reviewer 提到 favorite `status` 没有 DB-level CHECK、`asset_id/user_id` 没有 FK。该问题属于后续 schema hardening;本轮执行版明确禁止改迁移,只能在现有 V8/V15 约束上补强 unique/index/trigger 断言,不把它扩成新增迁移。
|
||
- 最终 fresh implementation review 已双 PASS:Raman spec/correctness review PASS、Hubble data-integrity/testing review PASS,均无 P0/P1/P2/P3 阻塞项。两名 reviewer 均确认 `market` 未进入 domain-level allowlist、只推进 4 个 `market:*` operation、Market 仍为 4 completed / 28 needs_verification、`listMarketplaceAssets` 与 `listMarketplaceRecommendations` 继续 needs_verification、OpenAPI diff 仅限 favorite/unfavorite required `X-Command-Id`、Market main/java 与 SQL diff 为空、13 个目标 XML 合计 85 tests 且 failures/errors/skipped 均为 0。非阻塞注意事项仍是 raw Surefire XML 暴露 host/user 但不含 password,外发前需清洗。
|
||
|
||
## focused gates
|
||
|
||
Market focused verification 通过:
|
||
|
||
```text
|
||
AppMuseMarketplaceAssetControllerTest: tests=11, failures=0, errors=0, skipped=0
|
||
MarketAssetQueryServiceTest: tests=6, failures=0, errors=0, skipped=0
|
||
MarketFavoriteServiceTest: tests=7, failures=0, errors=0, skipped=0
|
||
MuseMarketAssetMapperTest: tests=2, failures=0, errors=0, skipped=0
|
||
P1rMarketMigrationSqlTest: tests=9, failures=0, errors=0, skipped=0
|
||
P1rMarketRouteOwnershipTest: tests=4, failures=0, errors=0, skipped=0
|
||
P1rMarketRealApiGateTest: tests=6, failures=0, errors=0, skipped=0
|
||
P1rApiCoverageReportTest: tests=6, failures=0, errors=0, skipped=0
|
||
```
|
||
|
||
跨域 P1R focused gates 通过:
|
||
|
||
```text
|
||
P1rApiCoverageReportTest: tests=6, failures=0, errors=0, skipped=0
|
||
P1rMarketRealApiGateTest: tests=6, failures=0, errors=0, skipped=0
|
||
P1rEventsRealApiGateTest: tests=6, failures=0, errors=0, skipped=0
|
||
P1rAiRealApiGateTest: tests=7, failures=0, errors=0, skipped=0
|
||
P1rKnowledgeRealApiGateTest: tests=8, failures=0, errors=0, skipped=0
|
||
```
|
||
|
||
合计:
|
||
|
||
```text
|
||
P1R mixed gates: 33/33 pass
|
||
```
|
||
|
||
## scanner 与 diff 证据
|
||
|
||
scanner:
|
||
|
||
```bash
|
||
python3 muse-cloud/scripts/p1r-audit-api-coverage.py --check
|
||
```
|
||
|
||
结果:
|
||
|
||
```text
|
||
Generated docs/superpowers/reports/p1r-api-coverage.json
|
||
Generated docs/superpowers/reports/p1r-api-coverage.md
|
||
233 131 102 0 0 0
|
||
```
|
||
|
||
Market operation 状态确认:
|
||
|
||
```text
|
||
getMarketplaceAsset completed false
|
||
listMarketplaceCategories completed false
|
||
favoriteAsset completed true
|
||
unfavoriteAsset completed true
|
||
listMarketplaceAssets needs_verification false
|
||
listMarketplaceRecommendations needs_verification false
|
||
```
|
||
|
||
diff check:
|
||
|
||
```text
|
||
git diff --check: pass
|
||
```
|
||
|
||
OpenAPI diff:
|
||
|
||
```text
|
||
docs/api-contracts/market/openapi.yaml
|
||
```
|
||
|
||
仅包含 favorite/unfavorite 两个 operation 的 required `X-Command-Id` header。
|
||
|
||
## 后续边界
|
||
|
||
本轮完成后仍不得宣称:
|
||
|
||
- Market 32/32 completed。
|
||
- Content completed。
|
||
- Account remaining 23 completed。
|
||
- 总 P1R completed。
|
||
|
||
后续如果继续 Market completed approval,推荐单独处理:
|
||
|
||
1. `listMarketplaceAssets`:先补 pageNo/pageSize 1..100 边界与防全量查询证据。
|
||
2. `listMarketplaceRecommendations`:先解决 OpenAPI 个性化推荐语义与 fallback 排序实现的合同不一致。
|
||
3. publish/review/governance 13 个 operation:另写执行版冻结范围、Events outbox 边界和 fresh runtime evidence。
|
||
4. purchase/install/handoff/governanceImpact:必须先补目标 owner 消费闭环与 Account 读侧 E2E。
|
||
5. appeal/projection:不能把申诉审计、治理 outbox 和 Account projection 混成一个 completed 闭环。
|