oh-my-muse/docs/memorys/2026-05-28-P1R3账户真实API规格计划.md

294 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# P1R3 账户真实 API 规格计划
日期2026-05-28
## 背景
本次进入 P1R-3 Account Real API spec + plan 阶段,只完成 Account 域真实 API 的事实盘点、规格和执行计划,不进入代码实现。
P1R-3 的核心不是继续增强 `MuseContractPersistenceService`,也不是把 `generic_persistence` 包装成业务结果,而是把 Account 域从“通用持久化可响应”推进到“真实账户业务 API 可验收”的规格和计划阶段。
## 执行位置
```text
/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0
```
分支:
```text
dev/1.0.0
```
本阶段开始和收口时,工作树只包含本阶段新增文档改动,没有实现代码改动。
## 已验证事实
P1R 覆盖矩阵中 Account 域当前状态:
```text
33 generic_persistence / incomplete
```
同时保持:
- completed operations = 0
- Content 51 个 operation 为 `dedicated / needs_verification`
- Meta 16 个 operation 为 `dedicated / needs_verification`
当前代码事实:
- 仓库没有 `muse-cloud/muse-module-account/**`
- Account 当前真实 owner 应落在 `muse-module-member` 的 Account 子域。
- 当前 Account 合同入口仍是 `AdminMuseAccountContractController``AppMuseAccountContractController`
- 两个 Controller 仍通过 `MuseContractPersistenceService` 通用持久化处理 Account 路由,不是 P1R 完成证据。
当前 DDL 事实:
- V2 已有 `muse_member_entitlement``muse_member_entitlement_audit_log``muse_member_quota``muse_member_usage_record``muse_member_security_event``muse_member_new_api_binding`
- P1R-3 计划新增 `muse_account_profile``muse_account_audit``muse_account_command``muse_account_balance_snapshot``muse_account_quota_request``muse_account_integration_call``muse_account_call_attribution_job``muse_account_call_attribution_item``muse_account_export_task``muse_account_download_credential``muse_account_security_event_ack``muse_account_record_projection`
- purchase / license / publish records 统一使用 `muse_account_record_projection(record_type=...)` 作为 Account 视角读模型,不在 P1R-3 实现 Market 主流程。
## 本阶段产物
- 规格:`docs/superpowers/specs/2026-05-28-P1R-3-account-real-api-design.md`
- 计划:`docs/superpowers/plans/2026-05-28-P1R-3-account-real-api.md`
## 关键设计结论
- P1R-3 目标状态只能是 `dedicated / needs_verification`,不能写成 `completed`
- Account owner 采用 `muse-module-member/account` 子域,不新增孤立 `muse-module-account`
- `muse_account_profile` 承载 profile 扩展事实和 `expectedVersion` 乐观锁,不污染 `member_user`
- `muse_account_audit``muse_account_command` 是 commandId 幂等、requestHash 冲突和审计的必需基础设施。
- New-API binding / recheck 必须写内部 integration call并通过 `bindingId` / `jobId` 关联 `correlationId`;现有 OpenAPI 响应不新增 `correlationId`
- New-API、call attribution、FileService unavailable 只能通过合同内业务错误、内部 job 状态或 OpenAPI 已声明状态表达,不能返回未声明的 `pending` 等状态,也不能 fake success。
- `appDownloadExport` 成功响应按 OpenAPI 返回 `application/octet-stream`,错误响应仍走统一 `code/data/msg`
- AI runtime / task / SSE、Knowledge / RAGFlow、Market 主流程、统一 Events SSE 均不属于 P1R-3。
## Review 结果
本阶段使用 fresh subagent 做了两轮文档 review并按 review 结果修正后复审通过。
Spec compliance review 最终结果:
```text
SPEC REVIEW PASS
```
Quality review 最终结果:
```text
QUALITY REVIEW PASS
```
过程中修正的关键问题:
- 补齐 New-API binding create / recheck inline requestBody 的 typed VO。
- 明确 unavailable / failed / pending 等内部状态不得进入 OpenAPI 未声明 response status。
- 将 app quota request DTO 改为 `AppQuotaRequestCreateReqVO`,避免复用 admin DTO。
- 增加 `UnavailableNewApiAccountFacade``UnavailableMarketAccountProjectionFacade``UnavailableAccountFileServiceFacade` 的默认边界和测试要求。
- 移除会诱导创建独立 AI / Knowledge facade 的过宽表述AI / Knowledge 只通过 attribution source unavailable 边界表达。
- 移除 `-Dsurefire.failIfNoSpecifiedTests=false`,并要求关键指定测试命令用 `test -f` 防止缺失测试被掩盖。
## 当前阶段边界
本阶段只完成规格、计划、review 和 memory 留痕,没有实现代码。
未修改:
- `docs/api-contracts/account/openapi.yaml`
- `docs/superpowers/reports/p1r-api-coverage.*`
- `muse-cloud/scripts/**`
- `muse-cloud/muse-module-member/**` 实现代码
- `muse-cloud/sql/muse/**`
当前不应把任何 Account operation 标为 `completed`
## 残余风险
- 规格计划阶段未运行真实 PostgreSQL / Flyway 验证;实现阶段已在同一 PostgreSQL 实例的 `muse_local_test` 数据库补跑,结果见下文。
- 未接真实 New-API runtimebinding / recheck / quota request 仍需保持 `needs_verification`
- 未接真实 FileService runtimeexport task / download credential 仍需保持 `needs_verification`
- 外部 Market / Content / AI / Knowledge owner 未闭合时purchase / license / publish / attribution 只能走 Account 读模型和 unavailable 边界,不能标为 completed。
## 下一步(规格计划阶段记录)
进入 P1R-3 实现前,应从 `docs/superpowers/plans/2026-05-28-P1R-3-account-real-api.md` Task 1 开始,按 fresh subagent + spec compliance review + quality review 执行。
实现阶段完成口径:
- Account 33 个 operation 退出 `generic_persistence`
- Account 33 个 operation 全部为 `dedicated / needs_verification`
- Content 51 个 operation 保持 `dedicated / needs_verification`
- Meta 16 个 operation 保持 `dedicated / needs_verification`
- 不修改脚本掩盖缺口。
- 不把 Account 标为 `completed`
## 2026-05-29 实现阶段收口更新
### 实现任务范围
本轮实现阶段在以下真实 worktree 执行:
```text
/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0
```
`4d9a242..HEAD` 已覆盖 P1R-3 Task 1-12
1. Preflight 与覆盖基线冻结。
2. Account 基础设施与 V11 追加 DDL。
3. DTO / DAL / Mapper 骨架。
4. App `me` / `profile` 与 Admin 用户摘要。
5. 权益、配额、余额、用量。
6. New-API binding、recheck、quota request、integration call。
7. call attribution job。
8. purchase / license / publish records Account 投影。
9. security events。
10. export task / download credential。
11. Account 合同兜底退役。
12. P1R-3 覆盖门禁与报告对账。
Task 10 最新事实:
- 已新增 Account export/download Controller、Service、FileService facade、unavailable facade、凭证与导出任务相关 DAL 和测试。
- 下载凭证边界覆盖 credential hash、owner、expiresAt、revoked、consumed、source blocked。
- 高敏导出在缺少可信 step-up 证明时 fail closed。
- `appDownloadExport` 成功响应按 OpenAPI 返回 `application/octet-stream`;错误仍走统一 `code/data/msg`
- unavailable FileService 不返回伪造文件流。
Task 11 最新事实:
- 已删除旧 Account 合同兜底 Controller。
- 已新增 `P1rAccountRouteOwnershipTest`,证明 33 个 P1R-3 Account 路由进入 dedicated Controller不再回落到 `MuseContractPersistenceService`
Task 12 最新事实:
- 已新增 `P1rAccountRealApiGateTest`
- 已更新 `docs/superpowers/reports/p1r-api-coverage.json``docs/superpowers/reports/p1r-api-coverage.md`
- Account 33 个 operation 统一收口到 `dedicated / needs_verification`,仍保留真实运行态验收缺口。
### Coverage 前后状态
实现起点 `4d9a242`
```text
Account 33 generic_persistence / incomplete
Content 51 dedicated / needs_verification
Meta 16 dedicated / needs_verification
```
当前 `HEAD`
```text
Account 33 dedicated / needs_verification
Content 51 dedicated / needs_verification
Meta 16 dedicated / needs_verification
```
该状态只证明仓库内 dedicated 入口、覆盖报告和门禁已收口。PostgreSQL / Flyway 迁移链路已在同实例 test 库验证New-API、FileService 或端到端运行态仍未验收。
### Review 结果
本轮实现按计划要求在每个实现 Task 后执行:
1. spec compliance review。
2. code quality review。
已记录的收口事实:
- Task 10 在修正高敏导出 fail-closed、导出凭证消费边界、HMAC 凭证派生和 FileService 异常处理后spec compliance review 与 code quality review 均通过。
- Task 11 的 spec compliance review 与 code quality review 均通过。
- Task 12 的 spec compliance review 与 code quality review 均通过。
这些 review 结果只证明 P1R-3 代码、报告和门禁符合当前 spec / plan不代表外部 runtime owner 已闭合。
### 测试命令和结果
本阶段已记录的验证命令与结果:
```bash
python3 muse-cloud/scripts/p1r-audit-api-coverage.py --check
```
结果:通过;覆盖报告保持 Account 33、Content 51、Meta 16 均为 `dedicated / needs_verification`
```bash
cd muse-cloud
test -f muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAccountRealApiGateTest.java
test -f muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAccountRouteOwnershipTest.java
test -f muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rApiCoverageReportTest.java
test -f muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rContentRealApiGateTest.java
test -f muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rMetaRealApiGateTest.java
JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" \
mvn -o test -pl muse-server -am \
-Dtest=P1rApiCoverageReportTest,P1rContentRealApiGateTest,P1rMetaRealApiGateTest,P1rAccountRealApiGateTest,P1rAccountRouteOwnershipTest \
-Dsurefire.failIfNoSpecifiedTests=false
```
结果通过22 tests0 failures。
说明:原计划中的 `-pl muse-server -am -Dtest=...` 命令在上游 reactor 模块没有同名测试时会触发 `failIfNoSpecifiedTests` 问题。本轮通过 `test -f` 先校验目标测试存在,再局部追加 `-Dsurefire.failIfNoSpecifiedTests=false` 避免上游模块误失败;这不是全局放宽测试缺失门禁。
```bash
cd muse-cloud
JAVA_HOME=$(/usr/libexec/java_home -v 21) PATH="$JAVA_HOME/bin:$PATH" \
mvn -o test -pl muse-module-member/muse-module-member-server -am
```
结果通过member-server 272 tests0 failures。
```bash
git diff --check
```
结果:通过,无空白错误输出。
2026-05-30 追加真实 PostgreSQL / Flyway 验证:
```bash
# 使用 ~/.config/muse-repo/infra.env 中同一个 PostgreSQL 实例
# 基于 MUSE_POSTGRES_DATABASE=muse_local 创建固定 test 后缀数据库
createdb muse_local_test
# 使用 Flyway API 和 application.yaml 同口径的 filesystem:sql/muse 迁移目录
Flyway.configure()
.dataSource("jdbc:postgresql://<same-instance>/muse_local_test", username, password)
.locations("filesystem:sql/muse")
.baselineOnMigrate(true)
.baselineVersion("0")
.load()
.migrate()
```
结果:
```text
PostgreSQL 17.10
flyway_success=true
migrations_executed=11
target_schema_version=11
flyway_latest=11:extend account real api schema
flyway_versions=1,2,3,4,5,6,7,8,9,10,11
v11_tables=12
account_index_count=47
```
结论P1R-3 的 V11 迁移已在真实 PostgreSQL 实例的 `muse_local_test` 数据库通过 Flyway 迁移链验证。该验证覆盖 DDL/Flyway 可执行性,不等同于 New-API、FileService 或跨域端到端 runtime 验收。
### 未验证 runtime 风险
- PostgreSQL / Flyway 已在同实例 `muse_local_test` 数据库验证 V1-V11 迁移链;后续阶段若新增 DDL应继续先在同实例 `_test` 数据库跑真实 Flyway再允许阶段收口。
- 未接真实 New-API runtimebinding / recheck / quota request / integration call 仍保持 `needs_verification`
- 未接真实 FileServiceexport task / download credential 只能证明边界和状态机,不能证明真实文件交付。
- Market / AI / Knowledge owner 未闭合purchase / license / publish / attribution 只能走 Account 投影或 unavailable 边界。
- 端到端 auth、错误响应、SSE 与跨域 runtime 行为仍需后续阶段验收。
### 变更面记录
- OpenAPI未修改 `docs/api-contracts/account/openapi.yaml`
- Scanner未修改 `muse-cloud/scripts/**`
- SQL新增 `muse-cloud/sql/muse/V11__extend_account_real_api_schema.sql`
- Java新增 Account Controller / Service / DTO / VO / DAL / Mapper / Facade / Guard / AutoConfiguration 及 P1R gate tests删除旧 Account 合同兜底 Controller。
- Coverage更新 `docs/superpowers/reports/p1r-api-coverage.json``docs/superpowers/reports/p1r-api-coverage.md`