mirror of
https://github.com/zyycn/codex-proxy-rs.git
synced 2026-11-06 16:06:08 +00:00
docs(backup): document S3 backup API and architecture
- api.md: backup endpoints under /api/admin/settings/backups/* - architecture.md: backup service wiring notes Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+76
-2
@@ -230,7 +230,81 @@ auditRetentionDays
|
||||
|
||||
`rotationStrategy` 可取 `smart`、`quota_reset_priority`、`round_robin`、`sticky`。
|
||||
|
||||
## 8. Dashboard、用量与错误
|
||||
## 8. 备份
|
||||
|
||||
全部备份端点位于 `/api/admin/settings/backups/*`,内部由独立 BackupService 承担,不并入设置用例。响应继续使用 `AdminEnvelope`,wire 字段 camelCase,`Cache-Control: no-store`。
|
||||
|
||||
| 方法 | 路由 | 请求 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `GET` | `/api/admin/settings/backups` | 无 | 读取存储配置(含明文 Secret)、验证状态与调度配置 |
|
||||
| `POST` | `/api/admin/settings/backups/storage/update` | S3 配置 | 更新存储配置;`secretAccessKey` 为空字符串会校验失败 |
|
||||
| `POST` | `/api/admin/settings/backups/storage/test` | 无 | 测试已保存的存储配置(Put/Head/Get/Delete 探针) |
|
||||
| `POST` | `/api/admin/settings/backups/schedule/update` | 调度配置 | 更新 Cron、时区与保留策略 |
|
||||
| `GET` | `/api/admin/settings/backups/records` | 查询参数 | 分页查询备份记录 |
|
||||
| `POST` | `/api/admin/settings/backups/create` | `{ expiresInDays? }` | 创建手动备份,返回 `202 Accepted`;`expiresInDays` 为过期天数(0 或缺省表示不过期) |
|
||||
| `POST` | `/api/admin/settings/backups/download-url` | `{ backupId }` | 创建 5 分钟有效预签名下载地址(仅 completed) |
|
||||
| `POST` | `/api/admin/settings/backups/delete` | `{ backupId }` | 请求删除(进入 `deleting`,由 Worker 收敛硬删除) |
|
||||
|
||||
读取设置响应(Secret 以明文返回,由前端掩码显示):
|
||||
|
||||
```text
|
||||
storageRevision, endpoint, region, bucket, accessKeyId, secretAccessKey, prefix,
|
||||
forcePathStyle, verified, scheduleEnabled, cronExpression, scheduleTimezone,
|
||||
retentionDays, retentionCount, nextRunAt, lastVerifiedAt, updatedAt
|
||||
```
|
||||
|
||||
更新存储请求字段:
|
||||
|
||||
```text
|
||||
endpoint, region, bucket, accessKeyId, secretAccessKey, prefix, forcePathStyle
|
||||
```
|
||||
|
||||
`secretAccessKey` 为空字符串会校验失败;由于 GET 会回传已保存的明文 Secret,保存时始终整体提交当前值。已有备份记录时,endpoint/region/bucket/forcePathStyle 不允许变化(存储身份锁定,`409`);只允许轮换凭据与修改 prefix。
|
||||
|
||||
更新调度请求字段:
|
||||
|
||||
```text
|
||||
scheduleEnabled, cronExpression, scheduleTimezone, retentionDays, retentionCount
|
||||
```
|
||||
|
||||
`cronExpression` 为 5 段格式;`retentionDays`/`retentionCount` 为 0 表示禁用对应清理。启用计划前必须已保存完整存储配置且通过连接测试。
|
||||
|
||||
记录列表查询参数:
|
||||
|
||||
```text
|
||||
page, pageSize, status, trigger
|
||||
```
|
||||
|
||||
`status` 可取 `queued/dumping/uploading/completed/failed/deleting`;`trigger` 可取 `manual/scheduled`。记录响应字段:
|
||||
|
||||
```text
|
||||
id, triggerKind, status, scheduledAt, objectKey, sizeBytes, sha256, attemptCount,
|
||||
errorCode, errorMessage, startedAt, completedAt, expiresAt, createdAt, updatedAt
|
||||
```
|
||||
|
||||
`expiresAt` 为创建时确定的手动过期时间;到期后由 Worker 自动清理(手动与计划备份均可设置)。
|
||||
|
||||
连接测试响应:
|
||||
|
||||
```text
|
||||
{ ok, stage, code, message }
|
||||
```
|
||||
|
||||
`stage` 为 `putObject/headObject/getObject/deleteObject`。探测成功后以 `storageRevision` CAS 写入 `lastVerifiedAt`;测试期间配置变化则丢弃结果。
|
||||
|
||||
备份错误映射(`AdminErrorCode` 既有体系):
|
||||
|
||||
| HTTP | 场景 |
|
||||
| --- | --- |
|
||||
| `400` | 配置、Cron、时区或状态参数无效 |
|
||||
| `404` | 备份记录不存在 |
|
||||
| `409` | 已有活跃任务、状态冲突或存储身份锁定 |
|
||||
| `502` | S3 兼容服务返回无效或失败响应 |
|
||||
| `503` | PostgreSQL、`pg_dump` 或对象存储暂不可用 |
|
||||
|
||||
审计动作:`backup.s3_config_updated`、`backup.s3_connection_tested`、`backup.schedule_updated`、`backup.created`、`backup.download_url_created`、`backup.delete_requested`。审计详情与记录表均不保存 Secret、数据库连接串或预签名 URL query。
|
||||
|
||||
## 9. Dashboard、用量与错误
|
||||
|
||||
| 方法 | 路由 | 说明 |
|
||||
| --- | --- | --- |
|
||||
@@ -255,7 +329,7 @@ OpenAI 的 `serviceTier` 只接受上游响应生命周期事件确认的实际
|
||||
`flex` 映射为 `Flex`,缺失或 `default` 映射为 `Default`;未知非空值原样展示。Fast 优先使用模型的
|
||||
priority 价格,缺少专用价格时回退到标准价格的 `2.00x`;Flex 为 `0.50x`,Default 为 `1.00x`。
|
||||
|
||||
## 9. 版本、更新与重启
|
||||
## 10. 版本、更新与重启
|
||||
|
||||
| 方法 | 路由 | 主要 query/body | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
|
||||
+19
-5
@@ -26,8 +26,8 @@ backend/
|
||||
├── apps/gateway/ composition root(Bundle 装配)
|
||||
├── crates/gateway-core/ operation、routing、engine、policy、accounting
|
||||
├── crates/gateway-protocol/ 可共享 wire contract 与 canonical event
|
||||
├── crates/gateway-admin/ 管理领域、用例与抽象端口
|
||||
├── crates/gateway-store/ PostgreSQL、Redis adapter
|
||||
├── crates/gateway-admin/ 管理领域、用例、抽象端口与备份 Worker 策略
|
||||
├── crates/gateway-store/ PostgreSQL、Redis、S3/R2 与 pg_dump adapter
|
||||
├── crates/gateway-api/ OpenAI Responses 与 Admin HTTP adapter
|
||||
├── crates/gateway-host/ 配置与日志、HTTP serve/drain、worker 运行时、自更新
|
||||
├── crates/providers/openai/ OpenAI credential、catalog、transport
|
||||
@@ -41,7 +41,7 @@ backend/
|
||||
- `gateway-protocol` 不依赖其他 workspace crate。
|
||||
- Provider crate 之间禁止互相依赖。
|
||||
- `gateway-api` 只面向 Admin/Core/Protocol 抽象,不导入具体 Provider。
|
||||
- `gateway-store` 实现 Admin/Core 端口,但不拥有业务策略。
|
||||
- `gateway-store` 实现 Admin/Core 端口与备份基础设施(S3/R2、`pg_dump`、受控暂存),但不拥有业务策略。
|
||||
- 只有 `apps/gateway` 组合具体实现。
|
||||
|
||||
依赖 DAG 主要由上述约定与评审维护,机器校验只覆盖两处:`gateway-api` 的 architecture 测试冻结自身源码树与测试树,并禁止 manifest 出现 store/Provider/基础设施依赖(禁止清单不含 `gateway-host`);`apps/gateway` 的 architecture 测试冻结应用源码树、禁止生产测试挂载并约束 bootstrap 只做装配。其余 crate 没有 architecture 测试。
|
||||
@@ -146,7 +146,7 @@ Admin API 不要求客户端提交配置 revision,也不向客户端暴露配
|
||||
|
||||
## 8. PostgreSQL 终态
|
||||
|
||||
`backend/migrations/0001_initial.sql` 创建且只创建七张业务表:
|
||||
`backend/migrations/0001_initial.sql` 创建且只创建七张业务表;`0003_s3_backup.sql` 增加备份配置与备份记录两张表:
|
||||
|
||||
| 表 | 权威事实 |
|
||||
| --- | --- |
|
||||
@@ -157,6 +157,16 @@ Admin API 不要求客户端提交配置 revision,也不向客户端暴露配
|
||||
| `provider_accounts` | 账号资料、Provider-owned 明文 credential JSON、revision、quota、cooldown |
|
||||
| `model_requests` | 请求、attempt、计费、交付与恢复事实 |
|
||||
| `ops_events` | 脱敏运行事件 |
|
||||
| `backup_settings` | S3/R2 存储、Cron 计划与保留策略单例配置 |
|
||||
| `backup_records` | 备份任务状态与归档事实(`queued/dumping/uploading/completed/failed/deleting`) |
|
||||
|
||||
备份设计边界见 `docs/s3-backup-design-audit.md`:单副本部署下备份由单个可取消
|
||||
`DaemonTask` 承担调度、执行、删除收敛与保留清理,不需要 leader lease、fencing token 或
|
||||
heartbeat;计划时间点冲突只记录日志/指标并推进游标,不产生 skipped 记录;删除成功后
|
||||
记录硬删除,操作历史进入 `admin_audit_events`。管理员身份事实不重复写入
|
||||
`backup_records`。存储身份在存在记录时锁定:endpoint/region/bucket/path-style 不允许
|
||||
变化,只允许轮换凭据与修改 prefix。每份备份可设置创建时确定的手动过期时间
|
||||
`expires_at`(手动与计划备份均可,`expiresInDays` 天数生成),到期由 Worker 自动清理。
|
||||
|
||||
设计规则:
|
||||
|
||||
@@ -202,12 +212,16 @@ claim owner 可以释放,账号事务提交后才原子删除整个 pending ke
|
||||
|
||||
## 10. 后台任务与恢复
|
||||
|
||||
HTTP serve/drain 与 worker 运行时都在 `gateway-host`:Host 负责注册校验、leader lease、失败退避、健康暴露与关闭;`apps/gateway` 的 bootstrap 只装配。WorkerContribution 由 Store、Core 与两个 Provider bundle 显式贡献,host bundle 自身不贡献任何 worker:
|
||||
HTTP serve/drain 与 worker 运行时都在 `gateway-host`:Host 负责注册校验、leader lease、失败退避、健康暴露与关闭;`apps/gateway` 的 bootstrap 只装配。WorkerContribution 由 Store、Core、Admin 与两个 Provider bundle 显式贡献,host bundle 自身不贡献任何 worker:
|
||||
|
||||
- Store:stale execution recovery、retention,以及 PostgreSQL execution observation、Redis client
|
||||
admission release 和 Provider circuit feedback 三个 OpsFlush daemon。native continuation 直接写 Redis,
|
||||
单次 Lua 记录只清理有界数量的过期/超限索引项,避免无界阻塞。
|
||||
- Core:RuntimeSnapshot revision 周期对账(无 lease,逐副本运行)与 Redis change 长驻订阅(daemon,逐副本运行)。
|
||||
- Admin:备份 daemon(`WorkerKind::Backup`)。单副本边界下它是一个可取消 `DaemonTask`,内部循环推进
|
||||
Cron 游标、恢复中间状态、完成删除收敛、领取并执行一个 queued 任务、执行一小批保留清理;长时间
|
||||
`pg_dump` 与 multipart 上传由 daemon 自身持有,Host 只负责 panic 后重启、健康与关闭。它不使用
|
||||
Redis leader lease(单副本无竞争),只依赖 PostgreSQL 部分唯一约束防御并发 API/调度创建。
|
||||
- Provider:credential refresh、quota/catalog 健康,以及模型 etag 与官方版本 release 检查(OpenAI CLI、OpenAI Desktop、xAI CLI)。
|
||||
|
||||
带 lease 的周期任务在每个周期开始向 Redis 申请一次 leader lease,周期内续租,周期结束即释放。这只是单周期互斥,不是跨周期 leader 选举:各副本独立计时,N 副本部署下同一任务的实际执行频率最坏可达单副本的 N 倍。
|
||||
|
||||
Reference in New Issue
Block a user