概览“最近事件”补全审计属性
概览“最近事件”补全审计属性
Title
feat(dashboard): show actor, resource and details in recent events
Target branch
main
摘要
概览的“最近事件”每行只有动作、资源类型和时间,两条同名动作无法区分。审计数据本身是完整的(audit_logs 含操作者、资源 ID、详情),只是 handleDashboard 手写了一个字段更少的投影。改为复用审计页使用的 publicAudit 投影,并把操作者、资源 ID、详情摘要与审计页入口放到界面上。
用户影响
- 每行变成两行信息:动作 +
资源类型 · 资源 ID+ 时间;操作者 + 详情摘要(前 3 组key=value,悬停看完整 JSON)。 - 系统事件(无操作者)显示“系统事件”,不再留空白。
- 卡片右上角新增“查看审计日志”,直接跳到可筛选、可看逐条详情的完整列表。
- 非管理员仍只看到自己造成的事件;管理员看到全部。可见性规则没有变化。
API、Schema 与配置影响
GET /api/v1/dashboard/summary的data.recentEvents[]新增actorUserId与details两个字段(纯增字段,旧客户端忽略即可);条数上限仍是 10。- OpenAPI 此前只写了
200: Dashboard summary,没有响应体 schema;本次补DashboardSummaryEnvelope,其recentEvents.items复用既有AuditLog,避免两处各自描述同一实体。 - 无数据库 Schema 变更、无
SchemaVersion变化、无配置项变化。
安全与授权影响
- 权限过滤仍发生在存储层 SQL(
WHERE actor_user_id=?),不是取回后再裁剪。 details是审计页对同一读者群已经暴露的字段,写入侧已排除 secret、密码、私钥与完整凭据;本次不新增泄露面,日志与响应都不含会话字节。
测试证据
红灯(实现前):
TestDashboardSummaryToleratesActorlessAuditEvents(扩展后)→actorless event lost its details;新增TestDashboardSummaryCarriesAuditAttributes→event attributes = {… ActorUserID: … Details:[]}, want actor "user-…"。npm test -- --run src/tests/dashboard-view.spec.ts→ 3 条全失败(无操作者/资源 ID/详情文本,无systemActor标签,无跳转按钮)。
绿灯:
go test ./internal/server -run TestDashboardSummary -count=1→ ok。npm test -- --run→ 42 文件 / 355 用例通过(含layout-overflow.spec.ts对新 grid 规则的静态检查)。- 全量 Go 门禁与 race 结果见“集成状态”。
发布步骤
- 合并后发布 Server(控制台产物随二进制 embed)。
- 打开概览:确认同名动作的两条事件现在能靠操作者/资源 ID/详情区分;用无操作者的系统事件(例如代理入口鉴权失败)确认显示“系统事件”。
回滚步骤
git revert本次合并:无数据影响。- 服务端回退后
recentEvents少两个字段,新版前端按“空操作者 + 无详情”渲染,不报错,因此可单向回退,无需前端同步降级。
Reviewer 关注点
- 详情摘要在视图层拼装(3 组上限、悬停看全文)。若希望摘要口径唯一,可下沉为组件或服务端字段,但那会让概览与审计页重新分叉,本次刻意选择共用投影。
- 概览不做用户名反查,展示的就是
actorUserId;若要“人名”,应在审计页与概览一起改,属另一项变更。 details为json.RawMessage:非法 JSON 会经defaultJSON兜底成对象,前端拿到的永远是对象或 null。
集成状态
- 实施计划:
docs/superpowers/plans/2026-09-29-dashboard-recent-event-attributes.md。 go test ./... -count=1 -timeout 30m→ 退出码 0(与同分支的发行管理页还原改动一起跑)。go test -race ./internal/server -count=1 -timeout 25m→ ok,590.9s,无DATA RACE,退出码 0。go vet ./...无输出;gofmt -l internal cmd为空;git diff --check干净。docs/api/openapi.yaml经 YAML 解析校验通过,新增的DashboardSummaryEnvelope指向既有AuditLog。