From f906289f3adb780542bfcffded039738ea842b5e Mon Sep 17 00:00:00 2001 From: skycurtain Date: Tue, 15 Sep 2026 00:18:44 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=AE=9E=E6=96=BD=E8=AE=A1=E5=88=92?= =?UTF-8?q?=E2=80=94=E2=80=94=E9=98=B6=E6=AE=B5=201=20=E5=AE=8C=E6=88=90?= =?UTF-8?q?=EF=BC=88=E8=BF=9B=E5=BA=A6=E8=A1=A8=20+=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=81=87=E8=AE=BE=E6=9B=B4=E6=96=B0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 阶段 1 标记完成(15 项单测绿 + 四表在库:api_keys 17 列 / usage_logs 23 列 / 索引 8 个) - 实现假设 #2 更新为落地形态(load-env.ts 显式加载根 .env);新增 #9(drizzle-kit 用 postgres 驱动) - 前提补「联调用的测试 key」准备说明(建 key + 发一次成功/一次失败请求) --- docs/design/实施计划.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/design/实施计划.md b/docs/design/实施计划.md index 997d93c..88c3bc7 100644 --- a/docs/design/实施计划.md +++ b/docs/design/实施计划.md @@ -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` | ☐ |