docs: 实施计划——阶段 1 完成(进度表 + 实现假设更新)

- 阶段 1 标记完成(15 项单测绿 + 四表在库:api_keys 17 列 / usage_logs 23 列 / 索引 8 个)
- 实现假设 #2 更新为落地形态(load-env.ts 显式加载根 .env);新增 #9(drizzle-kit 用 postgres 驱动)
- 前提补「联调用的测试 key」准备说明(建 key + 发一次成功/一次失败请求)
This commit is contained in:
2026-09-15 00:18:44 +08:00
parent 3ffbd030b9
commit f906289f3a
+7 -5
View File
@@ -7,7 +7,7 @@
| 状态 | 定稿(2026-09-14;**进度表随 loop 持续更新**) |
| 关联 | `docs/design/API契约.md` · `docs/design/同步引擎设计.md` · `docs/design/交互设计.md` · 四张表字段设计 · `AGENTS.md`(命令) |
| 范围 | 阶段划分、每批验收标准、loop 机制与推进规则;技术细节一律以设计文档为准 |
| 当前进度 | 阶段 0 已完成;下一批:**阶段 1**(数据层与密钥) |
| 当前进度 | 阶段 0 / 1 已完成;下一批:**阶段 2**(上游客户端 + key 管理) |
---
@@ -26,19 +26,21 @@
| # | 假设 | 依据 / 可逆性 |
|---|------|--------------|
| 1 | server 侧单测用 `bun test`(内建);前端仍用 Vitest | 零依赖;可换 |
| 2 | 根目录单一 `.env`;server 与 drizzle-kit 脚本显式 `--env-file=../../.env`(Bun 不向上找 .env) | 可改 |
| 1 | server 侧单测用 `bun test`(内建);前端仍用 Vitest | 零依赖;可换(已落地:`bun test` 跑 `src/**/*.test.ts`) |
| 2 | 环境变量:全仓单一根 `.env`;服务与 drizzle-kit 经 `src/lib/load-env.ts` 显式加载(Bun 只自动加载 cwd 的 `.env`,不会向上找) | 可改;已落地 |
| 3 | 上游请求超时 30 秒;失败即本轮失败(不单轮重试) | 常量,可调 |
| 4 | key 格式校验仅「非空 + trim」(不强制 `sk-` 前缀,格式真假交上游判定) | 更宽松,避免误拒 |
| 5 | 去重指纹 = `sha256(key_id|created_at|model_name|quota|prompt_tokens|completion_tokens)` | 表设计 §3.1 已给字段清单 |
| 6 | 购买期间匹配:`subscription_id` 优先;同 ID 多条按 `[period_start, period_end)`;无期间记录仅在「同 ID 唯一」时兜底 | 边界情况,可调 |
| 7 | 登记成功后立即异步跑一次该 key 的单轮同步(不等 tick) | 契约 §2.2 已定「立即异步补一轮」 |
| 8 | 前端提交时间用 `toISOString()`(`Z` 形式) | 契约 约定 9 允许 |
| 9 | drizzle-kit 的连库驱动用 `postgres`(postgres.js,纯 JS)——仅 CLI 需要;运行时仍走 Bun 内建 SQL(`drizzle-orm/bun-sql`) | devDependency,可换 `pg` |
## 2. 前提(2026-09-14 定)
- **开发库**:Docker 本地 PostgreSQL(`docker-compose.yml` 已落地;连接串走 `.env`,不入库)
- **开发库**:Docker 本地 PostgreSQL(`docker-compose.yml` 已落地;连接串走 `.env`,不入库)——四张表已建
- **上游联调**:真实 sk-key(作者已填 `.env`)——`NEWAPI_BASE` 实测可达:HTTP 200 / 5.2KB / 2.0s;`quota_per_unit = 500000`、`quota_display_type = USD`、`usd_exchange_rate = 6.8`,与文档一致
- **联调用的测试 key**:作者新建专用测试 key(用完可删),并**用它发一次成功调用**(产生 `type=2` 日志)与**一次故意失败调用**(产生 `type=5` 日志)——阶段 4/5 的验证依赖这些日志
- **提交**:loop 内直接提交已授权;push 由作者手工(仓库有两个远端)
## 3. 阶段与验收标准
@@ -46,7 +48,7 @@
| 批次 | 内容 | 验收标准 | 状态 |
|------|------|---------|------|
| 0 | 脚手架 + 契约类型 + 501 骨架 | 命令链全绿(type-check / test / build) | ✅ 2026-09-14 |
| 1 | **数据层与密钥**:crypto(HKDF 派生 / HMAC-SHA256 / AES-256-GCM)· 时间工具(+08:00 序列化、UTC 秒转换)· 建表 | 单测:哈希确定性 + 加解密往返;`db:push` 后四张表在库 | ☐ |
| 1 | **数据层与密钥**:crypto(HKDF 派生 / HMAC-SHA256 / AES-256-GCM)· 时间工具(+08:00 序列化、UTC 秒转换)· 建表 | 单测:哈希确定性 + 加解密往返;`db:push` 后四张表在库 | ✅ 2026-09-14(15 项单测绿;四表在库——`api_keys` 17 列 / `usage_logs` 23 列 / 索引 8 个) |
| 2 | **上游客户端 + key 管理**(`GET` / `POST` / `PATCH` 三端点) | curl 实测:登记 → 清单 → 停用/启用;三类错误码分支正确(`key_rejected` / `already_registered` / `upstream_unavailable`) | ☐ |
| 3 | **管理面其余**:purchases 五端点 + qpu 一端点 | curl 实测:CRUD 全流程 + 观测聚合(`matched_purchase_id` 判定正确) | ☐ |
| 4 | **同步引擎**:tick(5 分钟 + 防重入 + 启动即跑)· 日志整批事务入库 · 额度采集 · QPU 采样 · 401 状态机(N=3) | 库中出现真实数据;`[sync]` 日志符合引擎设计;连续 401 触发摘除且 `disabled_source = auto_401` | ☐ |