3.4 KiB
数据、通知与备份
SQLite 与迁移
数据库位于 ${DATA_DIR:-/data}/codex-helper.db,启用 WAL、5 秒 busy timeout 和 foreign keys。backend/internal/store/store.go 是 schema 与启动迁移的事实来源:
settings保存通用、SMTP、Telegram、绑定码及安装标记;秘密单独以密文 key 保存。admin与sessions保存唯一管理员和登录会话。accounts保存唯一 CPAauth_index、Codex 连接元数据、期望套餐类型和public_visible;公开响应会隐藏auth_index。旧账号迁移后索引为空且保持私有,只有管理员绑定 CPA 凭据并明确开启后才进入匿名总览。daily_usage和limit_snapshots按account_id保存历史,删除账号时级联删除。notifications保存稳定去重键、调度时间、结构化消息、状态、次数和错误。telegram_updates保存 Bot API offset。
启动迁移必须幂等并兼容早期单账号库:已有默认账号 1 及其旧用量、限额数据继续保留,账号行补空 auth_index、expected_kind 和通知 body;新数据库不再主动创建默认账号。schema 变化应增加覆盖旧结构且保留已有行的测试。
清理与备份
每分钟调度器根据 retentionDays 清理旧限额、通知和每日用量;允许范围为 30–365 天。maintenance/backup 使用 SQLite VACUUM INTO 创建独立一致性快照,包含已提交 WAL 数据且不中断写入。
数据库快照不包含 /data/secret.key,因此不能单独恢复通知凭据。Codex OAuth 凭据位于外部 CLIProxyAPI,不属于 Codex Helper 备份;两套服务必须分别备份。恢复 Codex Helper 必须停止容器并备份、恢复整个 /data,同时保持 UID 10001 可读。不得把 docker compose down -v 写成普通升级步骤。
提醒生成与重试
限额快照按 (account_id, limit_id, window_type) 比较。计划提醒的 key 还包含 resets_at 和 before|after;异常提前重置以旧快照 ID 生成 detected_after key。百分比回落必须超过 0.01,旧快照不得超过六小时。
处理器每分钟为当前 Dashboard 生成到期提醒,并只发送 scheduled_at 后六小时内的未发送记录。Telegram 与 SMTP 中任何启用渠道失败都会把记录标记为 failed,后续周期在窗口内重试;全部启用渠道成功才标记 sent。稳定 key 和 INSERT OR IGNORE 是防重复边界。
Telegram 与 SMTP
Telegram 保存加密 Token、Chat ID 和 Bot 信息。保存 Token 前调用 getMe;long polling timeout 为 25 秒,HTTP client timeout 为 35 秒。六位绑定码十分钟有效且一次成功后清除。存在绑定 Chat ID 时自动启用额度提醒和查询菜单;启动时如发现旧版本已绑定但关闭了菜单,会主动发送带键盘的启用通知,成功后写回新状态。每条 update 在处理前重新核对当前 Token 和 Chat ID。更换 Token 或删除配置会重置 update offset。解除绑定原子删除 Token、Chat ID、Bot 信息、兼容开关值和绑定码;随后清理 Telegram 键盘失败不会恢复本地秘密。
SMTP 支持 starttls、隐式 tls 和 none,TLS 最低 1.2;支持可选 PLAIN AUTH,发送 multipart text/html。TCP 连接和后续 SMTP/TLS 读写共享 35 秒 deadline。修改外部调用时必须保留这一超时边界、TLS server name、HTML 转义和不记录秘密的错误处理。