概览“最近事件”补全审计属性实施计划
概览“最近事件”补全审计属性实施计划
1. 目标
- 概览的“最近事件”只显示
action、resourceType、时间三条属性,两条同名动作(例如两次agent.updated)无法区分。补出操作者、资源 ID 与详情摘要,并提供到审计日志页的入口。
2. 非目标
- 不改审计表结构、不新增列(
audit_logs现有id/actor_user_id/action/resource_type/resource_id/details/created_at,可用属性已全部落库,缺的只是展示与投影)。 - 不在概览做筛选、分页、逐条详情弹层——这些属于审计日志页。
- 不引入用户名反查:审计页展示的就是
actorUserId,概览另造一个“用户名”会形成两个口径。
3. 架构决策
- 单一投影:
handleDashboard之前手写了一个只含 5 个字段的 map,与publicAudit并行维护同一实体。改为直接复用publicAudit,概览与审计列表从此不可能漂移(DRY + 单一数据源)。 - 权限口径不变:非管理员的
recentEvents仍由存储层按actor_user_id=?在 SQL 内过滤,本次没有放宽任何可见性;details本就是审计页对同一批读者暴露的字段,不新增泄露面(写入侧已按规范排除 secret/密码/Token)。 - 详情做摘要而非原文:概览每行只有一行宽,
key=value取前 3 组 +title悬停看完整 JSON,避免整段 JSON 把卡片撑破。 - 无操作者要显式命名:系统事件(代理入口鉴权等)的
actor_user_id为 NULL,界面标为“系统事件”而不是空白列。
4. 技术栈与规格引用
- Go
net/http+ 既有publicAudit;Vue 3<script setup>+ Element Plus(el-button/el-empty);vue-router的useRouter().push。 - 接口:
GET /api/v1/dashboard/summary(docs/api/openapi.yaml),本次补齐其响应 schemaDashboardSummaryEnvelope,recentEvents.items复用AuditLog。
5. 全局约束
- 响应仍是
{code,msg,data};列表上限仍是 10 条,不引入分页。 - 不输出 secret、密码、私钥、完整 Authorization 或会话字节;
details沿用写入侧约束。 - 布局必须受约束:
web/src/tests/layout-overflow.spec.ts会扫描无列定义的display:grid。
6. 文件清单
internal/server/account_api.go:recentEvents改用publicAudit(event)。internal/server/account_api_test.go:扩展TestDashboardSummaryToleratesActorlessAuditEvents(NULL 操作者必须输出空串字段而不是丢字段);新增TestDashboardSummaryCarriesAuditAttributes。web/src/api/client.ts:DashboardSummary.recentEvents复用AuditLog[]。web/src/views/Dashboard.vue:两行式事件行(动作 + 资源类型·资源 ID + 时间 / 操作者 + 详情摘要)、卡片头“查看审计日志”、detailsSummary/detailsTitle、样式。web/src/tests/dashboard-view.spec.ts(新增):3 条挂载用例。web/src/i18n/messages/{zh-CN,en-US}.ts:新增dashboard.systemActor、dashboard.viewAudits。docs/api/openapi.yaml、docs/user-guide/server-admin.md。
7. 任务间接口
publicAudit输出id/actorUserId/action/resourceType/resourceId/details/createdAt,与前端AuditLog类型逐字段一致。details在前端为Record<string, unknown> | null;摘要函数对非对象值String(value)、对对象值JSON.stringify。
8. TDD 步骤与结果
- Go 先写两条断言 → 红灯:
actorless event lost its details、event attributes = {Action:token.rotated ActorUserID: ResourceType:service_token ResourceID:token-9 Details:[]}, want actor "user-…"(当时响应里没有actorUserId/details)。 - 服务端改用
publicAudit→go test ./internal/server -run TestDashboardSummaryok。 - Web 先写 3 条挂载用例 → 全部失败(无操作者/资源 ID/详情文本,无
systemActor,无跳转按钮)。 - 改视图与双语言包 → 3 passed;全量
npm test -- --run→ 42 文件 / 355 用例通过。
9. 验证命令
go test ./internal/server -run TestDashboardSummary -count=1
go test ./... -count=1 -timeout 30m
go test -race ./internal/server -count=1 -timeout 20m
go vet ./...
cd web && npm test -- --run && npm run build
cd .. && bash scripts/verify-web-embed.sh
git diff --check
10. 回滚
- 无 Schema、无配置变更,
git revert即可。 - 服务端回滚会让
recentEvents少掉actorUserId/details两个字段;前端旧版不读它们,新版读到缺失字段时按空操作者与无详情渲染,不报错,因此可单向回退。