# 需求清单 > 平台的需求权威索引与裁决档案:以「**不依赖 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),倾向手动拉起步、导出与推送逻辑分离留升级口子