Files
new-api-key-usage/docs/design/需求清单.md
T
skycurtain 867bb7d566 docs: 命令登记与 SK_KEY_ENCRYPTION_SECRET 命名对齐
AGENTS 命令表、会话留档约定;骨架搭建指南与设计文档键名对齐代码。
2026-10-06 01:30:52 +08:00

20 KiB
Raw Blame History

需求清单

平台的需求权威索引与裁决档案:以「不依赖 NewAPI 平台管理员与用户体系的独立计费平台」为定位,按功能域记录平台做什么、不做什么、为什么(裁决脉络见 §9)。后续专门设计文档(API 契约 / 交互 / 引擎)回答「怎么做」;R 编号体系是被引用的锚点。R3 / R4 延后项存档于 §9,核心功能实现后重启;新需求按 R 体系增补。

项目 内容
状态 定稿(2026-10-01)
关联 README.md(项目沿革与动因)· 七篇表字段设计(定稿)· docs/references/NewAPI-接口范围.md(可用接口参考)
取代 《设计议题》(2026-09-29 由本清单取代;其中双形态裁决与 CFW 调研结论已并入本文 §5/§7)

0. 平台定位与背景

定位:不依赖 NewAPI 平台管理员与用户体系的独立计费平台。上游只提供 sk-key 级接口——没有账单、没有分摊、没有历史回填,一切计费性质的能力(采集、归集、折算、分摊、账单)都必须由平台自身承载。上游接口的完整实证见 docs/references/NewAPI-接口范围.md。

平台哲学(2026-09-29 裁决):平台不做价值判断,只提供事实服务——「谁该付谁多少钱」的分摊口径是人和人之间的事;平台提供分账所需的全部原材料(用量事实、来源标注、支付记录、多维统计),数字全部客观中立。

背景(三类问题促成当前设计阶段):

  1. 迭代部署成本:服务器部署形态下每次迭代都需实例运营方手工升级,测试阶段迭代频繁而运营方无暇跟随 → 双形态交付(R13,已裁决)
  2. 初版设计刻意收缩的部分:管理面固定口令不妥(R11)、充值折算(R7)、多订阅处理(R8)
  3. 已知设计问题:错误行 request_id 去重(R15 必修项)

1. 数据采集域

# 需求 说明 状态
R1 sk-key 轮询采集与攒库 定时轮询 key 级接口、request_id 去重、全量日志入库——架构动因(上游无时间范围过滤接口)是物理约束,实现细节开放讨论 已裁决(2026-10-01,随 R15 表设计审阅定稿)
R2 key 登记与生命周期 管理通道登记、手动启停(status 纯手动开关,引擎只读);401 等持续失败经引擎日志与数据截止显形,停用由作者手动执行(不做自动摘除——引擎记录、不决策) 已裁决(2026-09-29,随 R15 审阅)

2. 数据资产域(新增)

本地库是全量日志的唯一副本(上游不提供回填);上游窗口仅最近 1000 条(实测当前速率 ≈ 3 天),同步停摆超过窗口即永久丢数据。「不依赖上游」的直接推论:资产保护是平台自己的责任。

# 需求 说明 状态
R3 数据资产保护 备份 / 导出 / 恢复策略——平台核心资产不能只有单副本 延后(2026-09-29 裁决:核心功能实现后再议;提案存档见裁决记录)
R4 采集健康与告警 同步停摆告警、数据连续性校验——3 天窗口的不可逆风险需要可观测兜底 延后(2026-09-29 裁决:核心功能实现后再议;提案存档见裁决记录)

3. 计费域

# 需求 说明 状态
R5 用量查询 时间范围 / 明细与汇总;查询入口已归位——成员视图(令牌)与管理面总览/下钻(口令),「凭 sk-key 的开放查询」已裁撤(见裁决记录 2026-09-29);统计维度含按 key / 成员 / 计费来源 / 模型(见 R9) 已裁决(2026-10-01,数据层随表设计定稿;查询口径细节归 API 契约)
R6 美元换算与支付记录 重定义(2026-09-29):① quota → 额度美元换算(÷ quota_per_unit,qpu_history 时间线服务它)——纯客观单位换算,保留;② 裁撤每行日志的实付分摊金额(amount_rmb,「quota 占比 × 实付」)——它是分摊口径的派生值,随购买记录漂移,违反事实服务原则;③ 支付记录登记:支付金额 ↔ 额度的比率关系(币种无关——系统不预设币种,见 R9) 已裁决(2026-09-29,重定义)
R7 充值登记 重定义(2026-09-29):充值与订阅同构——支付记录(金额 + 额度 + 比率)+ 日志来源标注(billing_source)+ 按来源统计;同样不做充值用量的金额分摊(原「池子加权平均」方案裁撤) 已裁决(2026-09-29,重定义)
R8 多订阅并行处理 重定义(2026-09-29):① 支付记录允许多订阅期间重叠(不设互斥约束)② 日志-支付记录按 subscription_id 直连(上游标注的客观事实,不推算)——「整笔订阅一把尺」原则已随 amount_rmb 裁撤消亡,订阅维度无需任何「尺」③ 按订阅分组的统计为查询时聚合输出(非物理表——账本只存事实行,统计是随查随算的派生视图);「未关联订阅」为 LEFT JOIN 未匹配集的透明分组(无新字段,正常时恒为零——非零即异常信号:缺登记或上游行为变化),兼作数据健康指示器;扣费顺序(先旧后新等)是上游策略,日志忠实记录,平台不管 已裁决(2026-09-29,重定义)
R9 分摊原材料与多维统计 重定义(2026-09-29):平台不做应付款计算、不做分摊口径(闲置额度归谁之类是社交层问题)——只提供原材料:计费来源标注(billing_source:订阅 / 充值)、支付记录(币种无关:支付金额与额度之间的比率关系,不预设币种)、任意时段多维聚合(按 key / 成员 / 来源 / 模型) 已裁决(2026-09-29,重定义)
R10 计费周期与账单 已裁撤(2026-09-29):周期 = 任意查询时段(订阅期间为预置选项);无平台侧账单(应付款不计算,期末快照无对象)。保留行以维持编号连续 已裁撤

4. 使用者域

平台自身的身份体系——实际使用者 ≈ 作者(管理)+ 若干分摊成员(查询)+ 运营方(信任模型内,本就能看到一切)。这不是多租户产品。

# 需求 说明 状态
R11 平台身份体系与鉴权 访问主体 = 作者 + 成员(运营方完全信任,不设身份)。成员身份与管理面鉴权均已裁决(2026-09-29,见裁决记录) 已裁决(2026-09-29)
R12 成员自助视图 令牌进成员视图:名下 key 的模型调用日志——每条记录额外携带所属订阅/充值的信息(具体携带形态待核查后设计)+ 用量聚合(quota / 美元,按来源分解);完全公开透明(订阅与支付参数对成员可见);无「应付」概念(分摊是社交层问题);登录壳交互(输令牌 → sessionStorage,关标签失效) 已裁决(2026-09-29)

5. 交付域(已裁决)

# 需求 说明 状态
R13 双形态交付 完整前后端(先行,母体):服务器部署的前后端分离应用 + PostgreSQL(后端单进程承载 API 路由与同步引擎),功能全集在此形态上设计与实现;CFW 抽取版(后续,衍生):Cloudflare Workers(API + Cron Triggers 轮询)+ D1 攒库 + 前端静态资产托管,从母体中抽取业务核心、替换基础设施层——承载「部署权归作者」的目标形态 已裁决(2026-09-29)
R14 可移植性分层 R13 的横切约束:业务核心(轮询逻辑 / request_id 去重 / 折算链计算 / 加密体系 / API 语义)与形态耦合面(HTTP 框架 / 调度器 / 数据库驱动 / 托管部署)分离;数据访问层隔离 PostgreSQL 与 SQLite/D1 方言(jsonb → TEXT + SQLite JSON 函数、类型与索引映射);轮次语义统一(幂等、错过即补——每轮全量拉最近 1000 条天然补偿) 已裁决(2026-09-29)

6. 数据模型

# 需求 说明 状态
R15 数据模型修订 七篇表设计(api_keys · usage_logs · payments · qpu_history · members · users · sessions)经作者逐篇审阅定稿:四张基线表复审落点 + payments 重定义(订阅/充值同构、币种无关、只存事实)+ 访问主体三新表 + usage_logs 来源提列(billing_source / subscription_id)与错误行去重修订(非消费行 dedupe_key 追加含 content 的指纹)+ api_keys.member_id 归属列 + 401 自动摘除状态机裁撤(引擎记录不决策);方言映射归数据访问层设计 定稿(2026-10-01)

7. R13 的支撑材料:CFW 可行性调研(2026-09-29,developers.cloudflare.com 官方文档核实,五项全部无阻断)

# 调研点 结论(Workers Free / Paid)
1 Cron 粒度与补偿 */5 * * * * 支持(最小每分钟);UTC 执行;单次执行上限 15 分钟;controller.scheduledTime 可检测延迟;失败重试机制存在(noRetry() 可关);Cron Events 留存最近 100 次调用(可观测)
2 D1 限制 单库 500 MB / 10 GB;每 Worker 调用查询数 50 / 1000;单条 SQL ≤ 100 KB、绑定参数 ≤ 100/语句;库为单线程(写入串行)——本项目低频批量写入无碍
3 Workers 运行时 CPU:10 ms(网络等待不计)/ 30 s(<1h 间隔 cron;≥1h 为 15 min);外网子请求 50 / 1000 每调用;出站并发 6;Cron Triggers 每账号 5 / 250
4 免费额度 Workers Free:10 万请求/天;D1 Free:读 500 万行/天、写 10 万行/天、存储 5 GB;静态资产请求免费无限(前端托管零成本)
5 加密体系 Workers 完整实现 Web Crypto:HKDF ✓ / AES-256-GCM ✓ / HMAC-SHA256 ✓(原生加速)——SK_KEY_ENCRYPTION_SECRET 体系可平移

负载画像对照(key 数按 10–25 估):

  • 每轮 cron:外网子请求 = 2 × key 数(Free 上限 50 → 最多 25 key);CPU 主要花在 1000 条 JSON 解析 + SHA-256 指纹 + AES-GCM 解密——Free 10 ms 是唯一贴线风险点(实现期实测,超限则升 Paid)
  • D1 写入:5 分钟一批、日增千行级 ≪ 10 万行/天;存储日增 MB 级 → Free 500 MB 可撑约两年,Paid 10 GB 富余
  • 查询面:个人低频聚合查询 ≪ 500 万行读/天(时间范围需走索引避免全表扫描)
  • 同步引擎防重入:D1 单线程天然串行化写入,多 cron 并发触发无竞态风险;每轮幂等(request_id 去重),失败重试零副作用

8. 推进方式

需求阶段收官(2026-10-01):15 项全部有归宿——R1 / R2 / R5 / R6 / R7 / R8 / R9 / R11 / R12 / R13 / R14 / R15 已裁决关闭,R10 裁撤,R3 / R4 延后(提案存档见 §9)。七篇表设计、八篇交互设计均经作者逐篇审阅定稿。剩余专门设计文档:API 契约 → 同步引擎设计(双形态架构下,逐篇立稿、逐篇审阅)。

9. 裁决记录

2026-09-29 · 访问主体模型(R11 · R12 · 关联 R5)

访问主体 = 作者 + 成员,一个模型两种凭证(运营方完全信任,不设身份;CFW 版可将来叠加 Cloudflare Access 作为前置纵深,不作鉴权主体)。

成员侧(成员视图):

  • 成员实体(新增):基本用户字段(id / name 显示名 / remark 备注 / status 启停 / created_at)+ 受管理凭证(token_hash 哈希存储 + token_issued_at;生成时明文展示一次,可吊销、可重发)+ key 归属(api_keys.member_id,1:N,允许空——未归属 key 存在)
  • 一层成员模型:key 创建权始终在作者(唯一 NewAPI 账号持有人);归属登记即层级——成员向下拼车 = 作者开新 key 挂其名下,平台不感知下级;算账口径 = 成员名下全部 key 的计费总和
  • 成员视图:登录壳(输入令牌 → sessionStorage,关标签失效)→ 自己关联的 key 列表 + 每 key 计费 + 聚合(应付部分随 R9 裁决展开)
  • 成员侧无注册、无密码、无会话;令牌泄露处置 = 作者吊销重发(朋友信任关系下凭证事务经作者,路径短于自助改密)

管理面侧(作者,唯一管理员)——最小登录体系:

  • users 表(单行:作者 username + password_hash)+ sessions 表(随机 256bit 令牌哈希存储、expires_at 如 7 天、登出即删,随时可踢)
  • 密码哈希 = PBKDF2-SHA256(WebCrypto 原生,高迭代)——Workers runtime 无 argon2/bcrypt,PBKDF2 是两形态统一实现(R14 的落地细节)
  • 浏览器侧:HttpOnly + Secure + SameSite=Lax cookie,路径限管理面——替代手动凭证管理
  • 部署期初始化(空库双通道):初始用户名/密码经 env(母体)/ wrangler secret(CFW)传入;管理面入口幂等三态判断——非空 → 登录页;空库 + env 凭证在 → 静默落库(部署完成即就绪,无抢注窗口;母体启动 / 首次请求检查,CFW 首次请求 / 首次 Cron 检查);空库 + env 凭证无 → 引导页设新密码(重置兜底通道)
  • 初始凭证为引导性质:仅空库时生效,此后改 env 不改密;改密走登录后的表单(旧密码验证 → 落库,登录体系的基本配套);env 凭证可留可删、无依赖——留着:删 users 行即静默重建;删了:引导页当场设新密码(见 users表字段设计.md 3.1);抢注窗口仅存在于「删 env + 删行」的重置瞬间
  • 无注册、无找回(忘记密码 = 服务器改库,管理员特权);登录节流为最小实现(失败延迟/计数)
  • 基线三件套状态修正:作者侧登录页与会话解禁(最小形态);admin 角色不做(单管理员无角色引擎用武之地);成员侧维持令牌无会话

开放查看面裁撤(同日裁决):「凭 sk-key 查」入口取消——sk-key 明文从 web 界面消失(仅登记时输入一次、随即加密);场景归位:成员 → 令牌视图;作者 → 管理面(key 清单下钻 + 全员总览面板,总览为新增设计项)

审计日志(独立需求,与鉴权方案正交):管理面写操作(key 登记/启停、购买记录增删改、成员开户/停用、令牌签发/吊销、改密)逐条留痕:操作类型、时间、操作者(前向兼容多管理员扩展——审计是不可变历史,归属不能事后补写;系统触发事件如空库重建为 NULL)、关键内容摘要;属业务核心层,两形态共有。同理正交的还有同步引擎运行日志——记录语义两形态一致,落盘通道随形态(母体 stdout/journald,CFW Workers Logs)

2026-09-29 · 分摊哲学与原材料(R9 重定义 · R10 裁撤 · R6/R7 重定义 · R12 形态修正)

平台不做价值判断,只提供事实服务——「谁该付谁多少钱」是人和人之间的社交问题;平台提供分账所需的全部原材料,数字全部客观中立。

裁掉:

  • 应付款计算与分摊口径——「闲置额度归谁」这类没有客观答案的问题,平台不回答(「按占额度分摊」vs「按占总用量分摊」的口径之争随之消失)
  • 期末账单快照与周期管理(R10 裁撤)——周期 = 任意查询时段(订阅期间为预置选项),无平台侧账单
  • 每行日志的实付分摊金额(amount_rmb)——「quota 占比 × 实付」是分摊口径的派生值而非事实,且随购买记录修订漂移;明细行金额回归 quota + 额度美元(÷ quota_per_unit,qpu_history 时间线,纯客观单位换算);基线「查看面金额口径 = 折算实付人民币」的设计作废

保留与新增:

  • 支付记录(订阅与充值同构):支付金额 ↔ 额度的比率关系——币种无关(系统不预设人民币或其他币种,币种是使用者之间的约定);订阅与充值两类支付事件统一建模(表结构与命名随 R15)
  • 计费来源标注为一等维度:billing_source(订阅 / 充值)随日志解析存储;按来源 / 成员 / key / 模型的任意时段多维聚合
  • 充值登记(R7 重定义):与订阅同构——不做充值用量的金额分摊(原「池子加权平均」方案裁撤)
  • 成员视角(R12 形态修正):名下 key 的模型调用日志,每条记录额外携带所属订阅/充值的信息(具体携带形态待核查后设计)、完全公开透明(订阅与支付参数对成员可见)、无「应付」概念

2026-10-01 · R15 审阅定稿

七篇表设计经作者逐篇审阅,全部定稿。审阅期实质修订:key_id → api_key_id、note → remark、401 自动摘除状态机裁撤(api_keys 3.6——引擎记录不决策,status 纯手动开关)、管理员初始化与重置改为空库双通道(users 3.1——env 静默重建 / 引导页兜底,env 凭证降级为可弃);另有多处语义辨析随文入档(错误行去重指纹、量与换算率、sessions 与 members 零关系、QPU 存在必要性裁决保留)。

2026-10-01 · 交互设计八篇定稿

八篇交互设计(共性 / 登录 / 总览 / key / 支付 / 成员 / 审计 / 成员视图)经作者逐篇审阅,全部定稿。审阅期修订:

  • 纯用量模式(共性 §3.8,部门实例场景触发):无支付记录 = 完整可用子集——参数卡中性空态、展开行降级、核对提示全空静默、订阅期间快捷项隐藏
  • 响应式范围收缩(作者裁决):只做布局响应,不做组件响应与移动端 UI 重设计
  • 组件能力需求清单(共性 §3.7):组件库与前端框架归实现期自由度,本清单为选型验收标准
  • 审计日志保留操作者列:前向兼容多管理员——审计是不可变历史,操作者归属不能事后补写;系统触发事件为 NULL
  • 其余:成员视图「移动端优先级」随响应式裁决改为「窄屏说明」;Key 登记对话框补「+ 新建成员」快捷入口;统计容器表述「桶」统一为「分组」

2026-09-29 · 多订阅并行(R8 重定义)

  • 「一把尺」原则已随 amount_rmb 裁撤消亡——其唯一客户是分摊金额计算;quota → 美元走 QPU(站点参数),订阅维度无需任何「尺」
  • 日志归属 = 上游事实,非推算:日志 other.subscription_id 直接关联支付记录(实现期核查项:登录态钱包页的订阅编号与日志 subscription_id 是否同一体系——基线草案既有推测,与 R12 携带形态并作一批真实数据核查)
  • 未关联分组 = 查询层产物(LEFT JOIN 未匹配集,无新字段),正常时恒为零,非零即异常信号;两种未关联(日志缺 ID / 有 ID 无登记)的展示区分留设计期
  • 统计 = 派生视图:数据库只存事实行,一切分组/分解/汇总为查询时聚合,无预计算存储

2026-09-29 · 数据资产域延后(R3 / R4)

裁决:不纳入现阶段(锦上添花能力,核心功能实现后再议)。提案存档如下,供重启讨论时作起点:

  • R4 采集健康与告警(三层提案):① 同步健康面板(数据截止 / 轮次成败 / 引擎状态——即管理面总览的一部分)② 缺口检测与留痕(停摆恢复轮检测时间缝隙,落「数据缺口事件」记录——丢了多少无法精确知道,但「丢过」可精确留痕)③ 主动告警(webhook 推送,作者自配钉钉/企微/TG bot;停摆判定 = 连续 N 轮失败或数据截止落后超阈值;不做邮件、不做分级路由)
  • R3 资产保护(导出 + 备份 + 异地性提案):① 管理面一键导出(全量日志 JSONL + 支付记录 + 归属)② 形态差异——母体 pg_dump 定时 + 作者定期拉取;CFW 版 D1 Time Travel(PITR:付费 30 天 / 免费 7 天)+ wrangler d1 export ③ 异地性三选(作者手动拉起步 / 推 R2 对象存储 / 只信 Time Travel),倾向手动拉起步、导出与推送逻辑分离留升级口子