7.3 KiB
ADDED Requirements
Requirement: 按完整自然日压缩归档审计相关日志
系统 SHALL 复用现有 S3 兼容对象存储、Worker 和 Asynq Scheduler,按 Asia/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.DeletedAt;Integration 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 不访问对象存储