# 运营审计当前行为 ## Purpose 描述审计调查、资源活动与审计时间线的当前可观察行为。 ## Requirements ### Requirement: 审计时间线 系统 SHALL 支持按事件、操作者、资源、请求、关联标识和资金维度查询已记录的审计事实。新建的 `tb_integration_log` 在已取得稳定审计事件时 SHALL 写入其内部 ID 作为 `audit_event_id`,并且该日志的非空 `integration_id` SHALL 出现在对应事件列表和事件详情的 `investigation_refs.integration_refs` 中;关联生成失败时系统 MUST 保留 Integration Log 并记录可排查告警,且 MUST NOT 按名称、时间或摘要推断关联。历史 Integration Log 不在本要求的回填范围内。审计事件的构造、校验或持久化失败 MUST 记录可关联的结构化错误日志和二次失败记录,且 MUST NOT 改变已通过业务校验的业务操作结果或接口响应。尚无完成物理清理记录时,审计调查接口 MUST 继续查询在线审计事实,且返回的留存边界不得将数据标记为已归档。 #### Scenario: 审计时间线 - **GIVEN** 审计事实已存在 - **WHEN** 使用对应维度查询 - **THEN** 返回匹配的事实与稳定动作编码,不用访问日志替代 #### Scenario: 事件返回已关联外部交互引用 - **GIVEN** 一个在线审计事件有 `tb_integration_log.audit_event_id` 指向其内部 ID 的外部交互记录 - **WHEN** 查询全局审计事件列表或该事件详情 - **THEN** 该事件的 `investigation_refs.integration_refs` 返回该记录的 `integration_id` #### Scenario: 事件没有关联外部交互引用 - **GIVEN** 一个在线审计事件没有稳定关联的外部交互记录 - **WHEN** 查询全局审计事件列表或该事件详情 - **THEN** `investigation_refs.integration_refs` 返回空数组 #### Scenario: 新外部交互日志具有稳定审计关联 - **GIVEN** 系统即将记录一次新的外部调用、入站回调或未发送裁决 - **WHEN** 写入对应 Integration Log - **THEN** 该记录保存非空 `audit_event_id`,且其目标 Audit Event 已存在 #### Scenario: 缺少审计关联时保留外部交互日志 - **GIVEN** 一次新的外部交互日志没有稳定审计事件关联 - **WHEN** 系统尝试写入该 Integration Log - **THEN** 系统持久化该 Integration Log、记录可排查告警,并返回空 `integration_refs` #### Scenario: 审计写入失败不阻断业务 - **GIVEN** 一个业务操作已通过自身输入、权限和状态校验 - **WHEN** 该操作的审计事件构造、校验或持久化失败 - **THEN** 系统提交或返回该业务操作原本的结果,并以请求关联标识、动作编码和资源标识记录审计失败 #### Scenario: 尚无物理清理记录时查询在线审计 - **GIVEN** 审计或外部交互日志尚无完成物理清理的归档运行记录 - **WHEN** 调用任一依赖留存边界的审计调查接口 - **THEN** 系统返回当前在线数据或空列表 - **AND** 响应中的 `archived_before` 为空 - **AND** 系统不得因空留存边界返回服务端错误 ### Requirement: 轮询审计事实保留边界 系统 SHALL 仅为产生业务事实变化、轮询失败、结果未知或人工触发的轮询操作持久化统一审计事件及资源快照。成功且无业务变化的自动轮询 MUST 不创建 `tb_audit_event` 或 `tb_audit_event_resource`,审计调查接口仅返回实际已保留的历史事实。 #### Scenario: 自动轮询成功但无业务变化 - **GIVEN** 一次自动轮询成功且没有改变任何业务状态、有效流量或风险结论 - **WHEN** 系统结束该轮询处理 - **THEN** 审计事件和审计资源表不新增该次轮询记录 #### Scenario: 自动轮询改变业务事实 - **GIVEN** 一次自动轮询产生可应用的业务状态或有效流量变化 - **WHEN** 系统提交该变化 - **THEN** 系统保留对应的审计事实与资源快照 ### Requirement: 审计归档与日留存受控执行 系统 SHALL 提供独立的审计归档与日留存任务总开关。总开关关闭时,系统 MUST 不调度、不消费且安全跳过已入队的 Audit 日归档、Integration Log 日归档和日志日留存任务,不扫描或修改在线日志表。总开关开启时,每次任务执行 MUST 至多处理一个已结束的上海自然日;维护者可在低峰期重复执行以推进历史积压。 #### Scenario: 归档与留存总开关关闭 - **GIVEN** 审计归档与日留存任务总开关关闭 - **WHEN** 定时器触发或 Worker 取得已入队的归档或留存任务 - **THEN** 系统跳过该任务,不扫描 `tb_audit_event`、`tb_audit_event_resource` 或 `tb_integration_log`,且不创建归档或清理记录 #### Scenario: 总开关开启时处理积压 - **GIVEN** 审计归档与日留存任务总开关开启,且存在多个未处理的已结束自然日 - **WHEN** Worker 执行一次归档或留存任务 - **THEN** 系统至多处理一个自然日,并保留其余日期供后续受控执行 ### Requirement: 审计在线数据逐日物理留存 系统 SHALL 以 Asia/Shanghai 已结束的自然日为单位处理统一审计事件及其资源快照的在线留存。每次留存执行 SHALL 从最早尚未完成清理的归档日开始,至多处理一个已结束的自然日;Integration Log 的 `pending` 记录不得阻断已通过完整性校验的审计事件及资源快照清理。任一审计归档日未通过完整性校验时,系统 MUST 保留该日及其后续日期的在线审计数据,且不得将它们标记为已清理。系统 MUST 先删除该日的审计资源快照,再删除该日的审计事件,并保留对象存储归档对象及清单作为恢复凭证。 #### Scenario: 已验证日期完成物理清理 - **GIVEN** 某已结束自然日的审计归档成功,归档对象和清单可读取且与在线记录范围、数量和校验摘要一致 - **WHEN** 日留存任务处理该日期 - **THEN** 系统分批删除该日在线审计资源快照和审计事件,并将该归档日标记为已清理 #### Scenario: Integration Log pending 不阻断审计清理 - **GIVEN** 某已结束自然日的审计归档已通过完整性校验,且同日存在 pending Integration Log - **WHEN** 日留存任务处理该日期 - **THEN** 系统仍完成该日在线审计资源快照和审计事件的物理清理 #### Scenario: 归档校验失败阻断连续清理 - **GIVEN** 某尚未清理的归档日缺少归档、归档校验失败或清单与在线数据不一致 - **WHEN** 日留存任务处理该日期 - **THEN** 系统不删除该日或更晚日期的在线审计数据,并将失败信息写入独立日留存日志 #### Scenario: 失败后从未完成日期续跑 - **GIVEN** 日留存任务在某个归档日失败,较早日期已经标记为已清理 - **WHEN** 后续日留存任务再次执行 - **THEN** 系统从最早未完成清理的归档日继续处理,不重复删除已完成日期的数据 ### Requirement: 日留存独立运行日志 系统 SHALL 将日留存的日期推进、清理成功和阻断失败写入独立轮转日志。该日志 MUST 位于 Worker 工作目录下配置的 `logs/audit-retention.log`,每条失败记录 MUST 包含归档日期、数据来源、失败分类和安全错误摘要。日留存和日归档路径 MUST NOT 将失败详情写入 `tb_log_archive_run.error_summary`。 #### Scenario: 留存日期被阻断 - **GIVEN** 日留存处理某个归档日时发生缺失账本、pending 记录、归档校验或删除错误 - **WHEN** 系统停止该日期推进 - **THEN** `logs/audit-retention.log` 记录该日期、来源、失败分类和错误摘要 - **AND** 对应账本记录的 `error_summary` 不写入该失败详情 #### Scenario: 留存日期清理成功 - **GIVEN** 某归档日通过全部校验并完成在线数据物理删除 - **WHEN** 系统完成该日期处理 - **THEN** `logs/audit-retention.log` 记录归档日期、各来源清理数量和耗时 ### Requirement: 审计调查留存边界连续 系统 SHALL 仅将连续完成物理清理的审计归档日期间公开为已归档边界。在线审计调查接口 MUST 继续允许查询任何尚未物理清理的较早日期,且不得因某个较晚日期已归档而将仍在线的日期错误标记为已归档。 #### Scenario: 清理链存在未完成日期 - **GIVEN** 某较早归档日尚未完成清理 - **WHEN** 后续日期的归档已成功生成 - **THEN** 审计调查接口仍将较早未清理日期视为在线可查询数据 ## 可达操作索引 本节只用于入口导航,不是行为 Requirement;业务义务以上述 Requirements 为准。 ### 审计调查 `GET /api/admin/audit/actors/{kind}/{id}/events`(查询操作者行为时间线);`GET /api/admin/audit/correlations/{correlation_id}/timeline`(查询业务关联时间线);`GET /api/admin/audit/events`(查询全局审计事件);`GET /api/admin/audit/events/{event_id}`(查询审计事件详情);`GET /api/admin/audit/finance/timeline`(查询资金调查时间线);`GET /api/admin/audit/integrations`(查询外部集成交互列表);`GET /api/admin/audit/integrations/{integration_id}`(查询外部集成交互详情);`GET /api/admin/audit/integrations/overview`(查询外部集成交互总览);`GET /api/admin/audit/requests/{request_id}/timeline`(查询请求关联时间线);`GET /api/admin/audit/resources/{resource_type}/{resource_id}/timeline`(查询通用资源时间线);`GET /api/admin/audit/resources/search`(精确搜索注册资源);`GET /api/admin/audit/risks/events`(查询风险事件明细);`GET /api/admin/audit/risks/overview`(查询风险调查总览)。 ### 资源活动 `GET /api/admin/agent/resource-activities/{resource_type}/{identifier}`(查询代理资源活动);`GET /api/admin/enterprise/resource-activities/{resource_type}/{identifier}`(查询企业资源活动)。