Files
2026-07-29 12:20:12 +08:00

7.3 KiB
Raw Blame History

ADDED Requirements

Requirement: 按完整自然日压缩归档审计相关日志

系统 SHALL 复用现有 S3 兼容对象存储、Worker 和 Asynq SchedulerAsia/Shanghai 将前一完整自然日的 Audit Event 及全部 Event Resource、Integration Log 分别生成 UTF-8 JSON Lines + gzip 冷归档。归档 MUST 使用半开时间区间MUST NOT 扫描或混入 Access Log、Domain Ledger、Outbox、Asynq 任务、手动轮询或旧 operation log。Access Log SHALL 继续使用应用服务器本地文件及现有 Lumberjack 轮转与保留策略MUST NOT 被本能力上传到对象存储。对象存储失败 MUST 只使归档任务重试和阻止后续清理MUST NOT 阻止新的业务审计正常落库。

Scenario: 每日归档前一天日志

  • WHEN Asia/Shanghai 新自然日的归档任务执行
  • THEN 系统只归档前一天 [00:00:00, 次日 00:00:00) 创建的目标日志
  • AND Audit 每行包含一个事件及其完整资源数组Integration 每行包含一条结构化持久化记录

Scenario: 对象存储暂时不可用

  • WHEN 上传归档对象或读取对象 metadata 失败
  • THEN 任务按既有 Asynq 重试策略重试并记录失败状态、日志和指标
  • AND Audit Event 与 Integration Log Writer 不调用对象存储且继续服务业务请求

Requirement: 归档对象必须具有可验证 manifest

每个归档对象 MUST 具有 manifest至少记录 schema_version、数据源、归档日期、时区、时间范围、实例 ID、事件/资源或记录数量、未压缩与压缩字节数、对象 Key、SHA-256、revision、生成时间和状态。系统 SHALL 使用 tb_log_archive_run 保存轻量运行 ledger并 MUST 以 source + archive_date + instance_id + schema_version 保证调度幂等;该表不得保存日志正文。

Scenario: 重复执行相同日归档

  • WHEN 同一数据源、日期、实例和 schema version 的任务被重复投递
  • THEN 系统校验并复用内容一致且已经成功的对象
  • AND 不重复创建相同事实或把重复执行计为新归档日

Scenario: 同一对象 Key 对应不同内容

  • WHEN 当前数据库数量或 SHA-256 与已成功 manifest 不一致
  • THEN 系统创建不可变的新 revision 并保留旧对象
  • AND 不静默覆盖原对象或直接宣称本次归档成功

Requirement: Integration Log 月度清理前必须形成最终快照

由于 Integration Log 可在创建后从 pending 更新为终态,系统 MUST 在月初清理前使用数据库当前内容复核上月每日归档。内容发生变化时 MUST 先创建新的最终 revision 并通过完整性校验;仍处于可变状态或无法形成最终快照的记录 MUST 阻止该月清理。

Scenario: 上月 pending 记录在本月完成

  • WHEN 某 Integration Log 的每日归档版本为 pending但月初复核时数据库记录已经完成
  • THEN 系统生成包含最终状态的新 revision 并更新成功 manifest
  • AND 只有最终 revision 验证通过后才允许清理数据库记录

Scenario: 上月记录仍无法最终确认

  • WHEN 月初复核发现上月 Integration Log 仍处于可变状态或归档内容无法与数据库一致
  • THEN 系统阻止整月清理并告警
  • AND 不删除该记录或其他 PostgreSQL 上月审计数据

Requirement: 月初清理必须以整月归档完整性为硬门禁

每月初系统 SHALL 在上月最后一天归档成功后检查上月全部自然日的 Audit 和 Integration 归档。只有 Audit Event 数量、Event Resource 数量、Integration 最终内容、对象存在性、对象大小、SHA-256、时间范围和 manifest 状态全部一致,且没有 pending 或 failed 任务时Retention Worker 才可物理删除 PostgreSQL 上月 Audit Event、Event Resource 和 Integration Log 数据。对象存储中的归档对象 MUST 长期保留且不得被该任务删除。Access Log 不参与归档或数据库删除门禁。任一检查失败 MUST 阻止整月数据库删除并产生 critical 日志和指标。

Scenario: 上月缺少一天 Audit 归档

  • WHEN 月度门禁发现某日 Audit manifest 缺失或 Event Resource 数量不一致
  • THEN 系统不删除上月任何 Audit Event、Event Resource 或 Integration Log
  • AND 后续调度继续补档并重新执行门禁

Scenario: 月度门禁全部通过

  • WHEN 上月全部 Audit/Integration 归档对象和 manifest 与数据库一致
  • THEN Retention Worker 使用 GORM、created_at 索引和有界批次对该完整自然月执行数据库物理 DELETE
  • AND Event Resource 与 Event 作为同一事实集合清理,任务中断后可从 ledger 安全继续

Scenario: 禁止用软删除代替物理删除

  • WHEN Retention Worker 清理 PostgreSQL 上月 Audit/Integration 数据
  • THEN 对应表记录从数据库中真实移除
  • AND 不新增或更新 deleted_at、archive status、隐藏标记也不迁移到另一张 PostgreSQL 历史表

Requirement: 清理权限和清理事实必须隔离

业务 Handler、Query、Writer 和 Repository MUST NOT 获得审计删除能力。只有 Retention Worker 的独立最小权限入口可按已通过门禁的月份物理删除 PostgreSQL Audit/Integration 数据。Audit Event 和 Event Resource Model MUST NOT 包含 gorm.DeletedAtIntegration Log 现有无软删除字段的模型保持不变。清理任务 MUST 以 retention_worker 系统身份在当前月写 Audit Event记录目标月份、数据源数量、manifest Key 和结果,不得把清理事件写回被清理月份。

Scenario: 调用方尝试删除审计记录

  • WHEN 平台账号或其他业务调用方尝试删除 Audit Event、Event Resource、Integration Log 或归档对象
  • THEN 系统不存在对应业务 API 或 Repository 方法

Scenario: 月度数据库清理完成

  • WHEN Retention Worker 完成 PostgreSQL 上月 Audit/Integration 数据删除
  • THEN 当前月产生一条可调查的系统 Audit Event
  • AND 该事件不属于本次已清理时间窗口

Requirement: 归档历史不再支持在线调查

清理后的 Audit Event 与 Integration Log SHALL 只保留在对象存储。第一阶段 MUST NOT 提供归档下载、对象存储扫描、跨冷热存储查询或恢复接口。所有审计与 Integration 列表、时间线和总览 DTO MUST 返回 retention{online_from, archived_before, timezone};显式时间范围全部位于归档区间或跨越在线边界时 MUST 返回稳定的已归档错误,不得返回看似完整的空结果或部分结果。

Scenario: 查询已清理月份的资源时间线

  • WHEN 调用方显式查询早于 online_from 的资源活动或 Audit 时间线
  • THEN 系统返回“数据已归档且第一阶段不支持在线查询”的稳定错误
  • AND 不扫描对象存储或返回成功空列表

Scenario: 查询范围跨越冷热边界

  • WHEN 调用方提交的开始和结束时间同时覆盖已归档区间与在线区间
  • THEN 系统拒绝部分查询并返回当前在线窗口
  • AND 调用方可缩小到 online_from 之后重新查询

Scenario: 查询当前在线月份

  • WHEN 查询条件完全位于当前在线窗口
  • THEN 系统按既有调查契约返回 PostgreSQL 在线结果和 retention 元数据
  • AND 不访问对象存储