Files
new-api-key-usage/README.md
T
skycurtain e4d25526f3 docs: 设计阶段定稿——需求清单(15 项全定案)与七篇表设计定稿
- 需求清单:独立计费平台定位,R1-R15 全部定案(12 项裁决 + R10 裁撤 + R3/R4 延后),裁决档案含访问主体模型(作者登录体系 + 成员长期令牌)、分摊哲学(平台不做价值判断只提供事实服务)、双形态交付(完整前后端先行,CFW 抽取版后续)
- 数据模型定稿(一表一文档):api_keys(16 列,401 状态机裁撤——引擎记录不决策)/ usage_logs(25 列,billing_source 与 subscription_id 提列,非消费行去重含 content 指纹)/ payments(币种无关支付记录,只存事实)/ qpu_history(按日志时刻取值)/ members(成员实体与长期令牌)/ users(空库双通道初始化与重置)/ sessions(服务端会话,否决 JWT)
- 接口参考:NewAPI-接口范围融合字段级实证,定位 docs/references/(计费平台可用接口参考,唯一上游参考)
- README / AGENTS:新版设计语境(项目沿革、重开设计动因、协作约定、文档自立原则)
2026-10-01 14:54:06 +08:00

80 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# new-api-key-usage
> 针对 NewAPI 平台的 key 用量统计工具
定时用每个 sk-key 轮询网关日志接口,按 `request_id` 去重,攒全量日志到数据库;任意时间范围的用量查询,即一条本地聚合查询。
| 项目 | 内容 |
|------|------|
| 当前状态 | **新版设计阶段**(`design` 分支,文档中心)——详细设计推进中 |
| 技术栈 | 服务器形态栈待架构设计评估(双形态交付已裁决,见 [`docs/design/需求清单.md`](docs/design/需求清单.md) R13/R14) |
## 项目沿革
| 阶段 | 形态 | 结局 |
|------|------|------|
| 初版方案 | Cloudflare Workers | 弃——当时运营方愿意提供服务器资源 |
| 新版设计(当前) | **本分支,设计进行中** | 捡回 Cloudflare Workers(**serverless 后端**:Cron 定时轮询 + 云端数据库攒库,非初版原案复刻)与完整前后端方案并列评估;同时解决管理面鉴权、充值折算、多订阅等设计问题 |
**当前设计阶段的直接动因**:服务器部署形态下,每次迭代都需实例运营方在服务器上手工升级,测试阶段迭代频繁而运营方无暇跟随;若部署到作者自控的 Cloudflare 账号(Workers + Pages),迭代部署权回到作者手里。
## 文档地图
| 文档 | 什么时候读 | 状态 |
|------|-----------|------|
| [`docs/design/需求清单.md`](docs/design/需求清单.md) | **需求权威索引与裁决档案**——R1–R15 全部定案(含裁撤与延后),R 编号体系为后续设计文档的引用锚点 | 定稿(2026-10-01) |
| [`docs/design/api_keys表字段设计.md`](docs/design/api_keys表字段设计.md) | 数据模型第一张表:key 登记、生命周期与成员归属 | 定稿(2026-10-01) |
| [`docs/design/usage_logs表字段设计.md`](docs/design/usage_logs表字段设计.md) | 数据模型第二张表:日志明细、来源提列、去重与写入策略 | 同上 |
| [`docs/design/payments表字段设计.md`](docs/design/payments表字段设计.md) | 数据模型第三张表:支付记录(订阅/充值同构,币种无关,只存事实) | 同上 |
| [`docs/design/qpu_history表字段设计.md`](docs/design/qpu_history表字段设计.md) | 数据模型第四张表:换算参数时间线(自动采样、只读) | 同上 |
| [`docs/design/members表字段设计.md`](docs/design/members表字段设计.md) | 数据模型新增表:成员实体——key 归属、成员视图身份与按成员统计的锚点 | 定稿(2026-10-01) |
| [`docs/design/users表字段设计.md`](docs/design/users表字段设计.md) | 数据模型新增表:管理员(单行)——登录体系的身份落点 | 同上 |
| [`docs/design/sessions表字段设计.md`](docs/design/sessions表字段设计.md) | 数据模型新增表:管理面会话——cookie 令牌的服务端对应物 | 同上 |
| [`docs/references/NewAPI-接口范围.md`](docs/references/NewAPI-接口范围.md) | 计费平台在 NewAPI 中可用的接口参考:鉴权档位、请求与返回结构、字段语义、实测行为、源码出处(**唯一上游参考**) | 事实依据 |
- 命名与分区:**目录用英文、文档名用中文**;`docs/design/`(我们定的方案与决策)· `docs/references/`(平台可用接口参考——实证事实,不做设计决策)
- 生命周期:设计文档定稿后不搬家、只改状态(草案 → 讨论中 → 待审阅 → 定稿(日期) → 已实现);被取代时删除(git 历史即考古)
## 这是什么项目
- 名字直述用途:NewAPI 网关下按 key 查询用量(key usage)
- 全场景统一小写 kebab-case:仓库名 / 包名 / 文档标题一致,无大写变体
## 背景故事
- 本工具源于一个真实场景:[NewAPI](https://github.com/QuantumNous/new-api)(Go + GORM 的开源 LLM 网关)实例提供订阅服务,多个使用者通过分发 API key 共享同一份订阅额度
- 项目作者是该实例的**普通用户**:购买了订阅额度,创建多个 sk- API key 分发给多名使用者分摊使用成本——**非商业,纯成本分担**
- 关键身份约束:项目作者**只有 sk-key,没有实例的管理员账号**。因此:
- 一切数据获取只能走 key 级接口(账号级接口用 sk-key 访问会 401)
- 部署形态已裁决为**双形态并行**:完整前后端部署在实例运营方提供的服务器上(作者不接触服务器)+ Cloudflare Workers 抽取版部署在作者自控账号(见 [`docs/design/需求清单.md`](docs/design/需求清单.md) R13)
## 核心需求(基线草案,待复审;完整范围见需求清单)
| # | 需求 | 说明 |
|---|------|------|
| 1 | key 用量查询 | 按时间范围查模型请求日志与用量;作者的全员视角经管理面总览实现——「凭 sk-key 的开放查询」与「多 key 合并查询」机制已裁撤(见需求清单裁决记录) |
| 2 | key 登记 | 管理通道手动登记:登记后入库并加入轮询;查看面凭已登记的 key 查询(纯只读) |
基线刻意收缩的部分(费用分摊计算、计费周期管理、多组支持、登录页、admin 角色、会话记忆)与新增域(数据资产保护等)的完整需求盘点见 [`docs/design/需求清单.md`](docs/design/需求清单.md)。
## 架构的根本动因:为什么必须攒数据
这不是优化选项,是上游接口的物理约束决定的**唯一路径**(不随部署形态改变):
1. sk-key 可用的接口(`/api/usage/token`、`/api/log/token` 等)返回的都是**累计值**或**最近 1000 条**,没有任何接口支持时间范围过滤
2. 真正适合算“当月用量”的接口(`/api/log/self/stat`,支持时间范围 + quota 汇总)需要账号登录态,sk-key 访问 401——这是“按时间段统计用量”无法纯客户端实现的**核心障碍**
3. `/api/log/token` 硬上限 1000 条、不支持任何参数(分页 / limit / 时间过滤全被忽略)
→ 结论:轮询同步 + `request_id` 去重入库 + 数据库。**部署形态可以变(运营方服务器 / Cloudflare Workers),攒库架构不变。**上游接口完整实证(含源码出处)见 [`docs/references/NewAPI-接口范围.md`](docs/references/NewAPI-接口范围.md)。
## 关键事实清单(实测 / 源码确认,设计时不得违反)
> 出处均见 [`docs/references/NewAPI-接口范围.md`](docs/references/NewAPI-接口范围.md),此处仅索引。
1. **`QuotaPerUnit = 500000`**:quota ÷ 500000 = 额度美元——**它不是实付金额**:折算到实付人民币还需乘「购买汇率」(由运营方定价、可变,历史上调整过一次)
2. **去重必须用 `request_id`**:`/api/log/token` 返回的 `id` 是每次从 1 重编的展示序号,绝不能用于去重
3. **`created_at` 是 UTC Unix 秒**(三字段交叉实测),北京时间输入需转换
4. **1000 条硬上限**:窗口只保留最近 1000 条——实测当前站点的日志速率下约等于 3 天;5 分钟级同步余量充分,但同步停摆超过约 3 天会永久丢数据
5. **`TokenAuthReadOnly`**:用量/日志接口用宽松鉴权,key 过期 / 额度耗尽仍可查询(用完也能对账);**显式禁用会被 401 拒绝**
6. **`DisplayTokenStatEnabled` 已开启**:billing 接口返回 token 级额度