docs: 设计文档体系落定(七篇定稿)

- docs/design:四张表字段设计 · 交互设计(方向层 + 细节层)· API 契约 · 同步引擎设计
- docs/upstream:sk-key 接口实证(430 行)· 接口范围(9 个接口)
- README(全景入口)· AGENTS.md(AI 协作者指引)
- 废弃旧稿已删除(不随仓库留存)
This commit is contained in:
2026-09-14 23:54:52 +08:00
parent b19d8693c1
commit 45b312b357
12 changed files with 1665 additions and 0 deletions
+93
View File
@@ -0,0 +1,93 @@
# NewAPI 接口范围
> new-api-key-usage 使用的 NewAPI 接口范围:本项目对接的全部 9 个接口,含鉴权档位与各自对本项目的用途——本项目所有上游调用都出自这份范围。与 `NewAPI-sk-key接口文档.md` 的分工:那边是「sk-key 能访问什么」的源码实证全集(430 行,字段级细节);本文是「本项目实际使用哪些接口」的范围清单。
>
> 整理日期:2026-09-09 · 重定位:2026-09-11 · 2026-09-13 增补 §3(范围之外)与 ④ 行为事实 · 依据:NewAPI 源码考证 + 接口实测 · 实测环境:NewAPI 实例
---
## 1. 鉴权三态总览
本项目对接的接口按鉴权中间件分三档:
| 鉴权档 | 中间件 | 语义 | 本项目的请求方式 |
|--------|--------|------|----------------|
| **公开**(none) | 无 / `HeaderNavModulePublicOrUserAuth` | 不持有任何凭证即可访问 | 直接请求,无需 key |
| **严格**(strict) | `TokenAuth` | 校验 key 有效、未过期、有剩余额度;无效直接被拒 | 携带 sk-key 请求 |
| **宽松**(lenient) | `TokenAuthReadOnly` | 只验 key 存在且用户未封禁;**过期/额度耗尽仍可查**,但**显式禁用(Disabled)会被 401 拒绝** | 携带 sk-key 请求;**本项目主要依赖此档** |
> 宽松档的「显式禁用被拒」是源码考证的补充结论(`middleware/auth.go` 的 `TokenAuthReadOnly`),影响本项目的 401 摘除逻辑:收到 401 应区分「key 被禁用」(摘除)与「瞬时故障」(重试)。
>
> 失败状态码全集(2026-09-13 源码复核):**401** = key 不存在(`MsgTokenInvalid`)或 token 被显式禁用(`MsgTokenStatusUnavailable`);**403** = 账号被封禁;**500** = 数据库错误。→ 摘除计数只认 401;403 / 500 视为其他故障,不计入。另:宽松档**允许** key 过期(Expired)与额度耗尽(Exhausted)状态查询,源码注释明确「only explicitly disabled tokens are denied」。
## 2. 接口清单
### 公开接口组(无需 sk-key)
#### ① `GET /api/user/groups` — 用户分组与倍率
- **返回**:站点配置的用户分组(default / vip 等)与倍率;**未启用分组时 `data` 为空对象**(当前站点实测即此状态)
- **用途**:解释「同一模型为什么计费不同」——分组倍率影响同一模型的实际消耗
- **本项目用途**:低优先级;仅当站点启用分组倍率后才有内容
#### ② `GET /api/perf-metrics/summary` — 全站模型服务质量
- **参数**:`hours`(统计窗口小时数,默认 24)
- **返回**:每个模型的 `avg_latency_ms`(平均延迟)、`success_rate`(成功率 %)、`avg_tps`(每秒 token 数)、`recent_success_series`(按小时采样的成功率时间序列);明细版 `/api/perf-metrics?model=xxx`(model 必填,另支持 group/hours)
- **鉴权细节**:`HeaderNavModulePublicOrUserAuth("pricing")`——默认公开,管理员可为 pricing 模块开启 requireAuth
- **实测**:HTTP 200,含站点真实模型的服务质量数据
- **本项目用途**:**高**——本工具独有视角。单个 sk-key 日志看不到全局服务质量;使用者反馈「慢/报错多」时,此接口能定位是模型问题还是自身问题。技术设计时可作为「模型健康度」功能的数据源
#### ③ `GET /api/rankings` — 全站模型用量排行
- **参数**:`period`(统计周期,默认 week)
- **返回**:每个模型的 `rank`(名次)、`previous_rank`(上期名次)、`total_tokens`(总用量)、`share`(份额)、`growth_pct`(环比增长 %)
- **实测**:HTTP 200,14KB 数据
- **本项目用途**:中——项目作者选「主推模型」(便宜且稳定)的数据依据;配合②的成功率可识别衰退模型
#### ④ `GET /api/status` — 站点配置与计费参数
- **返回**:60+ 字段,与本项目相关的计费字段:`quota_per_unit`(**换算比率当前生效值,管理员可改**)、`quota_display_type`(USD/CNY/TOKENS,影响 billing 接口语义)、`usd_exchange_rate`、`price` 等
- **本项目用途**:**关键**——换算比率的唯一权威来源。`QuotaPerUnit = 500000` 只是 NewAPI 默认值(源码 `common/constants.go:22`,`$0.002 / 1K tokens` 锚点),实现时必须从本接口实时读取、不得硬编码;同时感知 `quota_display_type` 切换(若切到 CNY/TOKENS,billing 接口数字语义会变)
- **补充:`quota_per_unit` 的行为事实(2026-09-13 源码评估)**:它由全局变量承载,改设置是「先写库、再热更新内存」(`model/option.go` 的 `UpdateOption` → `updateOptionMap` 的 `case "QuotaPerUnit"`)——改后**立即全站生效、无需重启**。三条关键行为:
- **无历史**:`options` 表一 key 一行、改即覆盖——任何接口都读不到过去的取值;管理审计只记"键名被改过"、**不记值**
- **无编辑入口**:后台设置页该字段默认隐藏且只读(`web/src/features/system-settings/general/pricing-section.tsx`),修改只能走 API
- **解读跟随当前值**:一切对外的金额换算(历史记录解读、billing 接口、界面显示)都在读取时实时使用当前值——改它 = 全站金额表达整体平移(数据库里的 quota 整数不受影响)
### 严格鉴权组(TokenAuth,sk-key)
#### ⑤ `GET /v1/dashboard/billing/subscription` — 总额度上限(美元)
- 返回 `hard_limit_usd` 等;无限额度 key 返回 `100000000`(一亿占位值,无参考意义)
- 受 `DisplayTokenStatEnabled` 与 `quota_display_type` 影响;与⑥相减可得剩余额度
- **本项目用途**:中——按 key 统计表的「累计剩余」列候选数据源
#### ⑥ `GET /v1/dashboard/billing/usage` — 累计已用(美分)
- 返回 `total_usage`(美分,÷100 = 美元);可与⑧的 `total_used ÷ quota_per_unit` 交叉对账(不一致 = 站点改过比率,见④)
- **本项目用途**:中——同上,对账与校验用途
#### ⑦ `GET /v1/models` — 可用模型列表
- 数据源是数据库(渠道实际配置);与 `/v1/models/:model` 单查接口数据源不同
- **本项目用途**:低——调试期验证渠道配置用
### 宽松鉴权组(TokenAuthReadOnly,sk-key)
#### ⑧ `GET /api/usage/token` — token 级用量汇总(原始 quota)
- 返回 `total_used`(累计,非当月)、`total_granted`、`total_available`、`unlimited_quota`
- **本项目用途**:**高**——按 key 统计表「全周期累计(已用/剩余)」两列的直接数据源;key 耗尽后仍可查(用完也能对账)
#### ⑨ `GET /api/log/token` — 最近 1000 条调用日志
- **硬上限 1000 条**(`common.MaxRecentItems = 1000`)、不支持任何参数、最新在前;响应里的 `id` 是每次从 1 重编的展示序号,**跨请求无意义,去重必须用 `request_id`**
- 大响应:pretty-print 后 2~4MB——本项目同步引擎需直面的单次响应体积
- **本项目用途**:**核心**——增量同步引擎的唯一数据源;本地攒全量后,任意时间范围的用量/明细/模型统计都是本地聚合查询
## 3. 范围之外(sk-key 不可达)
1. **账号级统计接口**(如 `/api/log/self/stat`,支持时间范围 + quota 汇总):需账号登录态,sk-key 访问 401——本项目以「本地攒日志 + 聚合」替代
2. **订阅信息**(订阅编号 / 生效期间 / 额度):**没有免 auth 的接口可直接查询**(作者实测,2026-09-13);登录态的**「钱包」页面**可见——显示订阅编号(形如「订阅 #N」)、状态(生效中 / 已过期 + 过期时间)、总额度与已用 / 剩余:
- 订阅编号**推测**与日志 `other.subscription_id` 为同一体系(实现期以真实数据核对)
- 对应设计:订阅信息由购买者手工录入(见 `docs/design/purchases表字段设计.md`)