All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m30s
2.0 KiB
2.0 KiB
Context
internal/query/retention 以聚合查询计算审计与外部交互日志的在线留存边界。PostgreSQL 在没有匹配行时会为 MAX 和 MIN 返回 NULL,而当前扫描目标不能接收空值,导致所有依赖该边界的审计调查接口失败。
Goals / Non-Goals
Goals:
- 将空聚合结果识别为“尚无边界”,而非数据库错误。
- 保持已有已清理边界、最早在线记录和当月兜底的语义。
- 修复所有通过同一留存边界查询函数进入的审计接口。
Non-Goals:
- 不执行审计物理清理,不改变归档或保留策略。
- 不修改数据库结构、迁移记录或历史审计数据。
- 不修改 API 路由、权限或响应字段。
Decisions
使用可空时间承接 SQL 聚合结果
留存边界查询使用标准库可空时间值承接 MAX(range_end) 与 MIN(<time-column>)。仅在值有效时转换为目标时区并作为边界返回。
拒绝将聚合结果用当前时间或固定时间 SQL COALESCE:这会把“尚未清理”误判为已归档,改变响应中的留存语义。
同时覆盖已清理和最早在线两个聚合路径
MAX(range_end) 是本次线上错误入口;MIN 在在线表为空时具有相同的空值扫描风险。两个路径共用相同的可空聚合边界,应一次修复。
Risks / Trade-offs
- [风险] 空边界被误判为已清理,错误拒绝历史查询 → 仅在聚合值有效时设置已清理标记与归档边界。
- [风险] 修复遗漏其他审计接口 → 保持修改在所有审计查询共用的留存边界函数内。
Migration Plan
- 修改留存边界的空时间扫描逻辑。
- 格式化并构建 API。
- 仅替换 API 二进制并重启 API Unit。
- 以
GET /api/admin/audit/events?page=1&page_size=20验证无已清理记录时接口不再返回 500。
Rollback
无数据库迁移。若 API 启动或查询异常,覆盖回本次发布前 API 二进制并重启 API Unit。