Files
one-pipe-system/openspec/changes/add-audit-chain-frontend-integration/design.md
luo b8b2854aa6
Some checks failed
构建并部署前端到测试环境 / build-and-deploy (push) Failing after 59s
feat: 审计链路
2026-08-07 18:33:37 +08:00

54 lines
5.8 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.
## Context
本次变更横跨平台、代理和企业三类主体以及资产、订单、退款、钱包、通知等多个业务页面。OpenAPI 将关联关系明确建模为 `investigation_refs``linkage` 和稳定资源引用,并区分平台内部 ID 与代理/企业可见的业务标识。前端必须保持这些边界,不能为了补齐跳转而从名称、时间或摘要推断关联关系。
仓库目前没有已归档的基线 specs但存在通知中心和旧资产操作日志的活跃变更。本提案建立独立的审计链路能力通过明确的依赖点与它们集成不复制或覆盖其已有要求。
## Goals / Non-Goals
- Goals: 按 OpenAPI 实现 16 个只读接口的类型、查询、页面和跨视角跳转契约。
- Goals: 为平台、代理和企业提供符合各自权限与数据投影的业务审计入口。
- Goals: 统一分页、RFC3339 时间范围、枚举展示、在线保留窗口和错误处理。
- Non-Goals: 不修改后端接口、数据库、日志采集或保留策略。
- Non-Goals: 不提供恢复、重试、修改、删除、处置、封禁、任意全文搜索或导出。
- Non-Goals: 不替换现有资产操作日志组件,也不修改 C/H5 端。
## Decisions
- Decision: 新增独立审计 API 模块和共享类型按平台审计、主体活动、资金、风险、Integration、链路时间线分组暴露查询函数统一保留服务端响应包装和 nullable 字段。
- Decision: 平台业务入口使用响应中的内部稳定 ID。卡、设备、店铺、企业、订单和退款分别使用对应 `resource_type``response.data.id`;钱包通过资金时间线的 `wallet_id` 进入。
- Decision: 代理与企业入口使用响应中的稳定业务标识。卡使用 `iccid`,设备使用 `virtual_no`;代理的分配、换货、店铺和企业使用接口文档指定的业务编号。缺少稳定标识时隐藏入口。
- Decision: 前端只转发后端返回的调查引用。事件的 `event_id``actor_ref``resource_refs``request_id``correlation_id``integration_refs`,以及 Integration 的 `linkage`/`resource` 是跨视角导航的唯一数据来源。
- Decision: `request_id` 可以来自调查引用、Integration、或用户从 Access Log 明确粘贴;`correlation_id``integration_id` 只能来自接口返回的稳定字段。前端不使用 UUID 或其他方式生成这些 ID。
- Decision: 对不存在、为空或 `fidelity=false` 的引用隐藏对应跳转,禁止按名称、时间、摘要或相邻记录猜测缺失关系。
- Decision: 资源搜索严格使用 `resource_type + keyword` 精确查询,并把选中项的 `resource_type/resource_id` 原样传给资源时间线。`historical=true` 只作为历史快照命中提示。
- Decision: 列表和时间线统一消费 `page``page_size``total` 并保留 `retention` 语义。时间筛选发送含时区的 RFC3339 值,`created_to` 按接口定义为不包含该时刻;页面不展示全局在线窗口提示,也不提供归档查询假入口。
- Decision: 所有枚举筛选提交稳定 code并优先展示后端 `*_name``action`、Integration `operation` 等开放编码必须直接来自响应,不能从中文文案反推。
- Decision: 资金金额按分展示转换,权威性只认 `amount_authority.authoritative=true` 指向的业务字段;前端不得合并冲突金额或自行计算余额。
- Decision: 代理与企业活动共用展示外壳但使用独立 API。企业页面只展示主体安全投影不引入平台操作者、风险、内部原因或 before/after 字段。
- Decision: 通知目标仅在 `available=true``target_type=integration_log``target_key` 非空时跳转,并将 `target_key` 原样作为 Integration 详情的 `integration_id`。其他情况保留通知正文并提示目标不可用。
- Decision: 权限以最终菜单/按钮权限编码和服务端鉴权共同控制。平台、代理、企业不展示不属于其主体的审计入口,`401/403` 继续走共享认证与无权处理。
## Risks / Trade-offs
- 最终菜单与按钮权限编码尚未体现在 OpenAPI 中;实施前必须确认,否则只能依赖服务端 `403`,无法做到准确的入口隐藏。
- 审计事件和 Integration 模型字段较多;通过共享详情/时间线组件和严格类型避免各业务页重复实现,但不抽象为可以执行任意端点的动态页面。
- 在线保留窗口外的数据不可由这些接口查询;空状态使用“当前查询无记录”的中性表达,避免将空数据误报为无历史事件。
- 活跃通知中心变更也会修改通知导航;实施时需在其最新状态上追加 `integration_log` 规则,避免覆盖既有白名单映射。
- 旧资产操作日志与新审计中心含义相邻但数据源不同;两个入口并存并清晰命名,避免误将旧日志能力删除。
## Migration Plan
1. 确认平台、代理、企业的菜单和按钮权限编码,以及审计中心路由归属。
2. 建立 OpenAPI 对齐的类型、API 模块和共享只读展示组件。
3. 按平台审计、资金、风险、Integration、主体活动顺序接入页面。
4. 在业务页面与通知导航中增加稳定引用入口。
5. 完成角色、数据隔离、空引用、保留窗口、错误和跨视角跳转验收。
6. 若上线异常,隐藏新增路由与入口;现有业务接口和旧操作日志不受影响。
## Open Questions
- 平台审计中心、风险中心、Integration、代理资源活动和企业资源活动的最终菜单及按钮权限编码分别是什么
- 审计中心是作为一级菜单,还是归入现有系统管理/运维菜单?
- OpenAPI 未包含 `GET /api/admin/notifications/{id}/target` 的完整响应 schema是否继续以活跃通知中心变更定义的 `available/target_type/target_id/target_key` 为最终契约?