- approve only appListSecurityEvents and appGetSecurityEvent at operation level - keep appAcknowledgeSecurityEvent needs_verification - add HTTP+DB completed approval IT and update coverage gates/docs
275 lines
9.4 KiB
Markdown
275 lines
9.4 KiB
Markdown
# 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。
|