oh-my-muse/docs/agent-specs/2026-06-13-P1RAccountSecurityEventsCompletedApproval审阅版.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

12 KiB
Raw Blame History

P1R Account Security Events Completed Approval 审阅版

日期2026-06-13

结论

推荐 Account 下一批只推进 2 个用户安全事件只读 operation-level completed approval

account:appListSecurityEvents
account:appGetSecurityEvent

暂不推进 account:appAcknowledgeSecurityEvent。原因是 OpenAPI 当前仍承诺 session_revoked 会联动 session 管理并使相关会话失效,但当前实现返回“未接入 session 管理服务”的 fail-closed 文案。operation-level completed 不能排除单个 action 子路径;在 OpenAPI 或真实 session revoke 未闭合前,把整个 acknowledge operation 标为 completed 会制造 fake completed。

本切片 completed 口径只覆盖:对既有 muse_member_security_event 安全事件事实的当前登录用户可见读取、详情脱敏、latest ack 合并、owner/tenant 隔离、API version 和 read no-write 闭环。

本审阅版只冻结候选范围、证据标准、风险边界和后续执行版要求。不修改 OpenAPI不修改 scanner不修改 coverage report不修改业务实现不推进任何 operation completed。

flowchart TB
    Current["当前 Account<br/>10 completed / 23 needs_verification"] --> Candidate["下一批候选<br/>Security Events read 2 ops"]
    Candidate --> Read["list / detail<br/>owner 可见 + 脱敏 + latest ack"]
    Candidate --> Exclude["暂缓 acknowledge<br/>session_revoked 合同不闭合"]
    Read --> Review["fresh spec/scope review<br/>fresh quality/testing review"]
    Exclude --> Keep["继续 needs_verification"]
    Review --> Exec["双 PASS 后进入审批点"]
    Exec --> Approval{"用户明确批准后才实现"}
    Approval -->|"否"| Stay["保持 233/145/88"]
    Approval -->|"是"| Target["目标 233/147/86<br/>Account 12 completed / 21 needs_verification"]

当前事实状态

工作区:

/Users/qingse/.config/superpowers/worktrees/oh-my-muse/dev-1.0.0

当前 HEAD

304f665 test(p1r): 收口 Content Admin RiskAction completed approval 门禁

当前 coverage summary

total=233
completed=145
needsVerification=88
incomplete=0
genericPersistence=0
ssePlaceholder=0

当前 domain 状态:

account  completed=10  needsVerification=23
content  completed=14  needsVerification=37
market   completed=4   needsVerification=28
meta     completed=16  needsVerification=0
events   completed=1   needsVerification=0

目标 operation 当前状态:

appListSecurityEvents  dedicated  needs_verification  requiresCommandId=false  GET  /app-api/muse/account/security-events
appGetSecurityEvent    dedicated  needs_verification  requiresCommandId=false  GET  /app-api/muse/account/security-events/{eventId}

获批后的目标值:

total=233
completed=147
needsVerification=86
incomplete=0
genericPersistence=0
ssePlaceholder=0

account total=33
completed=12
needsVerification=21

推荐候选

operation key Method Path 推荐原因 必补 completed-grade evidence
account:appListSecurityEvents GET /app-api/muse/account/security-events 读当前登录用户安全事件摘要,支持 severity 筛选和 latest ack 合并,无写入副作用 MockMvc HTTP + 真实 PostgreSQL _test,覆盖 owner/tenant 隔离、severity filter、分页、latest ack、敏感字段不泄露、missing API version 拒绝、read no-write
account:appGetSecurityEvent GET /app-api/muse/account/security-events/{eventId} 读当前登录用户安全事件详情,服务端按 eventId + accountUserId 查询并脱敏 IP / User-Agent MockMvc HTTP + 真实 PostgreSQL _test,覆盖 detail 脱敏、跨 owner/跨 tenant/missing 不可见、ack detail 合并、非数字 eventId 404、read no-write

推荐理由:

  • 2 个 operation 都属于 Account 本域 AccountSecurityServiceImpl,不需要调用 New-API、FileService、Market、Content、AI 或 Knowledge 外部 owner。
  • App 端 Controller 使用 getLoginUserId(),不接受请求参数覆盖 owner适合用 HTTP + DB 证明 owner 隔离。
  • OpenAPI 的 list/detail 合同与当前实现方向一致:当前账户可见、安全事件详情、敏感值脱敏。
  • 读侧需要合并 muse_account_security_event_ack latest ack但不需要证明 ack 写命令 completed。

不纳入本批的 Account operation

以下 21 个 Account operation 必须继续 dedicated / needs_verification

account:adminCreateCallAttributionJob
account:adminGetCallAttributionJob
account:adminGetIntegrationCallByCorrelation
account:adminListNewApiBindings
account:adminListPurchaseRecords
account:adminListUsageRecords
account:adminCreateNewApiBinding
account:adminCreateQuotaRequest
account:appDownloadExport
account:appCreateExportTask
account:appGetExportTask
account:appGetIntegrationCallByCorrelation
account:appListLicenses
account:getAppNewApiBinding
account:appRecheckNewApiBinding
account:appListPublishRecords
account:appListPurchases
account:appCreateQuotaRequest
account:appGetQuotaRequest
account:appAcknowledgeSecurityEvent
account:getAppUsage

排除原因:

  • appAcknowledgeSecurityEventsession_revoked OpenAPI 合同承诺与当前实现 fail-closed 文案不闭合;必须单独处理合同或实现后再审批。
  • New-API binding、recheck、quota request 和 integration correlation 仍依赖真实 New-API runtime 或外部调用归因闭环。
  • FileService / export download 仍缺真实文件交付、下载字节、对象存储和凭证消费端到端 evidence。
  • call attribution job 当前 create 路径只创建 queued job 事实,真实归因执行仍由后续 owner/facade 接入;可作为后续独立切片,但不能夹入本批。
  • Market purchase / license / publish 仍缺 Market 主流程到 Account projection 的跨 owner 一致性 evidence。
  • usage summary / admin usage 仍受 muse_member_usage_record 和 attribution source 质量影响,本批不绕过上游事实缺口。

已有实现证据

OpenAPI 合同

OpenAPI 当前包含 2 个本批候选读 operation

GET /app-api/muse/account/security-events
GET /app-api/muse/account/security-events/{eventId}

本切片不需要修改 docs/api-contracts/account/openapi.yaml。但 OpenAPI 中 acknowledge 的 session_revoked 文案当前是阻塞项,因此本批明确不推进 appAcknowledgeSecurityEvent

Controller 入口

AppAccountSecurityController 当前链路:

GET /muse/account/security-events
GET /muse/account/security-events/{eventId}
AccountApiVersionGuard.requireVersion(apiVersion)
getLoginUserId()
AccountSecurityService

说明:

  • Controller-local mapping 是 /muse/account/...;对外 OpenAPI 路径仍以 /app-api/muse/... 为准。
  • 执行版必须用当前项目既有 app MockMvc / Web 测试上下文证明最终 app API 路径可访问。
  • list / detail 都必须证明缺少 X-API-Version 时不调用 service。

Service 读链路

AccountSecurityServiceImpl.appListSecurityEvents

  1. requireUser(accountUserId)
  2. normalize severity只允许 info / warning / critical
  3. MemberSecurityEventMapper.selectPageByAccountUserIdAndSeverity(...)
  4. 批量读取当前 owner 最新 ack。
  5. 转换摘要 VO敏感字段不直接外泄。

AccountSecurityServiceImpl.appGetSecurityEvent

  1. requireUser(accountUserId)
  2. 解析 eventId非数字或空值按 not found 处理。
  3. MemberSecurityEventMapper.selectByIdAndAccountUserId(...)
  4. 读取当前 owner 最新 ack。
  5. 转换详情 VO脱敏 IP / userAgent。

Schema 与测试前置

P1R SQL 当前定义目标事实表:

V2:  muse_member_security_event
V11: muse_account_security_event_ack

AccountSecurityServiceImpl.requireUser() 会通过 MemberUserMapper.selectById 读取 member_user,而 sql/muse 当前 V1-V21 不创建 member_user。执行版必须明确HTTP+DB _test 可以在隔离库完成 V1-V21 clean migrate 后创建 test-local member_user auth fixture 表并 seed 登录用户,用于满足认证前置;该 fixture 不计入 P1R Account schema evidence不能修改 production SQL也不能替代目标安全事件表/ack 表证据。

执行版必须 fresh 证明:

  • V1-V21 clean migrate 成功,且新 HTTP+DB IT 使用当前 live migration baseline。
  • 目标表 muse_member_security_eventmuse_account_security_event_ack 的列、索引、trigger 和 JSONB 字段真实存在。
  • test-local member_user fixture 只在 _test 库、Flyway migrate 后创建,并在测试内记录为 auth fixtureDDL 至少覆盖 MemberUserDOTenantBaseDOBaseDO 当前映射列:idmobilepasswordstatusregister_ipregister_terminallogin_iplogin_datenicknameavatarnamesexbirthdayarea_idmarkpointtag_idslevel_idexperiencegroup_idtenant_idcreatorcreate_timeupdaterupdate_timedeleted

风险与取舍

  1. appAcknowledgeSecurityEvent 暂缓是必须的。

    • 当前 OpenAPI 对 session_revoked 承诺真实 session revoke。
    • 当前实现只返回 fail-closed 文案。
    • 在合同或实现未闭合前,不能把整个 operation 标为 completed。
  2. member_user 是测试 harness 前置,不是目标业务证据。

    • 不能 mock MemberUserMapper 来掩盖真实 service 依赖。
    • 也不能修改 sql/muse 迁移补这个表。
    • 允许在隔离 _test 库、V1-V21 migrate 后创建 test-local fixture并明确不计入 P1R schema evidence。
    • fixture DDL 必须覆盖真实 MemberUserMapper.selectById 会读取的当前实体映射列,不能只建 id/nickname 等最小列。
  3. 安全事件生产路径不是本批完成条件。

    • 已知 AccountExportServiceImpl.insertSensitiveExportEvent 会写安全事件 source fact。
    • 但本批不证明高敏导出文件交付或所有安全事件来源 completed。
  4. App HTTP + real DB gate 必须避免假绿。

    • 不能只靠 Mockito service/controller tests。
    • 必须读取新鲜 Surefire XML检查 tests>0、failures=0、errors=0、skipped=0。

后续执行版必须包含

  1. 2 个目标 operation 的审批清单、当前状态和目标状态。
  2. 保持 needs_verification 的 21 个 Account operation 及原因。
  3. TDD RED先改 P1R gate 期望,旧 report 必须失败。
  4. TDD GREEN只把 2 个 account:* operation 加入 operation-level allowlist不加 account domain allowlist。
  5. 新增 P1rAccountSecurityEventsCompletedApprovalIT,使用 MockMvc HTTP + 真实 PostgreSQL _test
  6. App 端登录用户上下文、tenant interceptor、API version、真实 mapper、test-local member_user auth fixture 的组合方式。
  7. schema gate新 HTTP+DB IT 必须执行 V1-V21 clean migrateV2/V11 安全事件表、ack 表、唯一约束、索引、trigger、JSONB 字段断言Account 专属 P1rAccountEventsPublishFlywayMigrationIT 可继续作为 V20 outbox 证据,但不能替代新 IT 的 V21 baseline。
  8. runtime matrixhappy、empty page、severity filter、latest ack、detail 脱敏、cross owner、cross tenant、missing、invalid eventId、read no-write。
  9. P1R mixed gates至少覆盖 Account、Coverage、Events、AI、Knowledge、Market、Content、Meta。
  10. XML 防空跑、protected diff、allowed diff 和 rollback 策略。
  11. .agentdocs/memorys 留痕要求。

验收标准

本审阅版可以视为完成的条件:

  1. 文件写入 docs/agent-specs/2026-06-13-P1RAccountSecurityEventsCompletedApproval审阅版.md
  2. .agent 记录 Account Security Events completed approval 审阅版状态。
  3. git diff --check 通过。
  4. OpenAPI、scanner、coverage report、业务实现、SQL migration 当前无新增 diff。
  5. fresh spec/scope review PASS。
  6. fresh quality/feasibility/testing review PASS。

待确认项

  1. 是否确认 Account 下一批只做这 2 个 security events read operation-level completed approval。
  2. 是否确认 appAcknowledgeSecurityEventsession_revoked 合同不闭合继续保持 needs_verification
  3. 是否确认本批不把 account 加入 domain-level completed allowlist。
  4. 是否确认允许 HTTP+DB _test 在隔离 _test 库内创建 test-local member_user auth fixture但不修改 production SQL、不把该 fixture 计入 P1R schema evidence。