oh-my-muse/docs/memorys/2026-06-13-P1RAccountSecurityEvents状态推进.md
zizi 3a27e7ec2b test(p1r): 收口 Account Security Events completed approval 门禁
- approve only appListSecurityEvents and appGetSecurityEvent at operation level

- keep appAcknowledgeSecurityEvent needs_verification

- add HTTP+DB completed approval IT and update coverage gates/docs
2026-06-14 01:25:30 +08:00

275 lines
9.4 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.

# P1R Account Security Events 状态推进
日期2026-06-13
## 结论
本轮只推进 Account 用户安全事件只读 2 个 operation-level completed approval
- `account:appListSecurityEvents`
- `account:appGetSecurityEvent`
Account 仍不是整域 completed。`account:appAcknowledgeSecurityEvent` 继续保持 `dedicated/needs_verification/requiresCommandId=true`
本轮未修改 OpenAPI未修改 Account 业务实现,未修改 SQL migration未把 `account` 加入 domain-level completed allowlist。
## 工作区与基线
工作区:
```text
/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0
```
基线 HEAD
```text
304f665 test(p1r): 收口 Content Admin RiskAction completed approval 门禁
```
实施前 coverage summary
```text
233 145 88 0 0 0
```
实施后 coverage summary
```text
233 147 86 0 0 0
```
实施后 Account 状态:
```text
total=33
completed=12
needs_verification=21
incomplete=0
genericPersistence=0
ssePlaceholder=0
```
目标 operation 状态:
```text
appListSecurityEvents dedicated completed false GET /app-api/muse/account/security-events
appGetSecurityEvent dedicated completed false GET /app-api/muse/account/security-events/{eventId}
```
必须保持 needs_verification
```text
appAcknowledgeSecurityEvent dedicated needs_verification true POST /app-api/muse/account/security-events/{eventId}/acknowledge
```
## 修改范围
本轮修改:
- `muse-cloud/scripts/p1r-audit-api-coverage.py`
- `docs/superpowers/reports/p1r-api-coverage.json`
- `docs/superpowers/reports/p1r-api-coverage.md`
- `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rApiCoverageReportTest.java`
- `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAccountRealApiGateTest.java`
- `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rEventsRealApiGateTest.java`
- `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAiRealApiGateTest.java`
- `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rKnowledgeRealApiGateTest.java`
- `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rMarketRealApiGateTest.java`
- `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAccountSecurityEventsCompletedApprovalIT.java`
- `docs/agent-specs/.agent`
- `docs/agent-specs/2026-06-13-P1RAccountSecurityEventsCompletedApproval审阅版.md`
- `docs/agent-specs/2026-06-13-P1RAccountSecurityEventsCompletedApproval执行版.md`
- `docs/memorys/2026-06-13-P1RAccountSecurityEvents状态推进.md`
未修改:
- 7 个 OpenAPI。
- Account 业务实现。
- SQL migration。
- Account domain-level completed allowlist。
- 既有 Account focused tests。
## TDD evidence
RED 阶段先修改 P1R gate 期望值和 2 个 Security Events read operation completed 断言,在旧 scanner/report 下运行 focused P1R gates预期失败已出现
```text
Tests run: 49, Failures: 10, Errors: 0, Skipped: 0
BUILD FAILURE
```
失败点来自旧 report 仍为 `completed=145 / needsVerification=88`Account 仍为 `10 completed / 23 needs_verification`,以及 `appListSecurityEvents` / `appGetSecurityEvent` 仍为 `needs_verification`;没有编译错误或无关测试失败。
GREEN 阶段只把两个 `account:*` key 加入 scanner operation-level allowlist重新生成 report并完成 HTTP+DB `_test` evidence 和 focused gates。
## MockMvc HTTP 入口 + DB 证据
新增:
- `muse-cloud/muse-server/src/test/java/cn/iocoder/muse/server/framework/api/P1rAccountSecurityEventsCompletedApprovalIT.java`
验证方式:
- 使用 Spring Mock web context + `MockMvc`
- 通过 `/app-api/muse/account/security-events``/app-api/muse/account/security-events/{eventId}` HTTP 入口进入 `AppAccountSecurityController`
- 使用真实 `AccountSecurityServiceImpl`、mapper、tenant SQL interceptor 和 PostgreSQL `_test` 数据库。
- Flyway clean/migrate V1-V21。
- 在隔离 `_test` 库创建 test-local `member_user` fixture满足 `requireUser()` 的真实 `MemberUserMapper.selectById` 前置;该 fixture 不计入 P1R production schema evidence。
- 密码只从环境变量读取,拒绝 JVM password system property 和 JDBC credential query。
- `@AfterAll` 恢复 `p1r.flyway.url` / `p1r.flyway.user`,避免污染同一 Surefire JVM 后续 Flyway 测试。
单类验证数据库:
```text
muse_p1r_account_security_events_completed_approval_test
```
通过结果:
```text
P1rAccountSecurityEventsCompletedApprovalIT: tests=8, failures=0, errors=0, skipped=0
```
覆盖内容:
- 拒绝非 `_test` 数据库、JVM password system property 和 JDBC credential query。
- V1-V21 schema gate覆盖 `muse_member_security_event``muse_account_security_event_ack``muse_account_event_publish_outbox` 和 test-local `member_user`
- `idx_muse_member_security_user``trg_muse_member_security_updated_at``uk_muse_account_security_event_ack_command`、ack user/event 索引和 updated_at trigger。
- list 支持 severity、分页、owner/tenant 隔离,并合并当前用户最新 ack。
- detail 支持 eventId + owner 查询,返回脱敏 IP、脱敏 userAgent、脱敏 description / suggestedActions。
- 请求参数不能覆盖当前登录 owner。
- missing / invalid API version、invalid severity、missing user、missing event、非数字 eventId、跨 owner、跨 tenant 都不泄露目标事实。
- read happy/error 都使用 `row_to_json(t)::text``member_user``muse_member_security_event``muse_account_security_event_ack``muse_account_command``muse_account_audit``muse_account_event_publish_outbox` 做全表快照 no-write。
## 组合验证
Account focused Maven 命令通过muse-server 部分:
```text
P1rAccountSecurityEventsCompletedApprovalIT: tests=8, failures=0, errors=0, skipped=0
P1rApiCoverageReportTest: tests=6, failures=0, errors=0, skipped=0
focused muse-server total: tests=19, failures=0, errors=0, skipped=0
```
member-server focused XML
```text
AccountSecurityServiceTest: tests=8, failures=0, errors=0, skipped=0
AppAccountSecurityControllerTest: tests=6, failures=0, errors=0, skipped=0
AccountSecurityEventAckMapperTest: tests=4, failures=0, errors=0, skipped=0
MemberSecurityEventMapperTest: tests=2, failures=0, errors=0, skipped=0
AccountConvertTest: tests=9, failures=0, errors=0, skipped=0
focused member-server total: tests=29, failures=0, errors=0, skipped=0
```
Account V20 Flyway 迁移门禁使用真实 PostgreSQL `_test` 库:
```text
muse_p1r_account_security_events_flyway_test
```
通过结果:
```text
P1rAccountEventsPublishFlywayMigrationIT: tests=4, failures=0, errors=0, skipped=0
flyway_success=true
migrations_executed=20
successful_migration_count=20
target_schema_version=20
flyway_latest=20:extend account events publish outbox
```
P1R mixed gates
```text
P1rApiCoverageReportTest: tests=6, failures=0, errors=0, skipped=0
P1rAccountRealApiGateTest: tests=5, failures=0, errors=0, skipped=0
P1rEventsRealApiGateTest: tests=7, failures=0, errors=0, skipped=0
P1rAiRealApiGateTest: tests=7, failures=0, errors=0, skipped=0
P1rKnowledgeRealApiGateTest: tests=8, failures=0, errors=0, skipped=0
P1rMarketRealApiGateTest: tests=6, failures=0, errors=0, skipped=0
P1rContentRealApiGateTest: tests=5, failures=0, errors=0, skipped=0
P1rMetaRealApiGateTest: tests=5, failures=0, errors=0, skipped=0
mixed total: tests=49, failures=0, errors=0, skipped=0
```
fresh implementation testing review 后处理:
```text
Banach testing/data-integrity review: PASS
P2 residual: 新增 IT 未直接覆盖 X-API-Version: 2
处理结果: 已补 invalid API version HTTP+DB no-write 断言
复验: P1rAccountSecurityEventsCompletedApprovalIT 8/8 pass
复验: Account focused muse-server 19/19 pass
复验: P1R mixed gates 49/49 pass
复验: scanner/report 233/147/86
复验: XML 防空跑与 protected diff 通过
```
## scanner / report 验证
命令:
```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 147 86 0 0 0
```
Account 聚合:
```text
33 12 21 0 0 0
```
目标 operation 明细:
```text
account appListSecurityEvents dedicated completed false GET /app-api/muse/account/security-events
account appGetSecurityEvent dedicated completed false GET /app-api/muse/account/security-events/{eventId}
account appAcknowledgeSecurityEvent dedicated needs_verification true POST /app-api/muse/account/security-events/{eventId}/acknowledge
```
## protected diff
通过:
```bash
git diff --check
```
通过:
```bash
git diff --quiet -- docs/api-contracts muse-cloud/muse-module-member/muse-module-member-server/src/main/java muse-cloud/sql/muse
git diff --cached --quiet -- docs/api-contracts muse-cloud/muse-module-member/muse-module-member-server/src/main/java muse-cloud/sql/muse
```
结论:
```text
protected_diff_empty=true
```
## 后续边界
本轮完成候选只代表 2 个 Account Security Events read operation-level completed approval。
仍不代表:
- Account 33/33 completed。
- `account:appAcknowledgeSecurityEvent` completed。
- Account remaining 21 completed。
- Market remaining completed。
- Content remaining completed。
- 总 P1R completed。
提交或 push 前仍需要 fresh implementation spec/correctness review + fresh implementation quality/data-integrity/testing review 双 PASS。