Files
cpa-plugin/docs/modules/ui.md
T

12 KiB
Raw Blame History

管理与展示 UI 模块

1. 定位

UI 模块负责把数据、计费、Key 路由、配额和诊断能力投影成可使用的页面。信息架构和统计展示主要参考 cpa-usage-keeperKey 套餐与金额操作参考 cpa-plugin-key-billing

UI 不计算价格、不重新聚合账本、不保存业务真相。页面中的所有数字都来自 api.md 定义的权限化查询 APIUI 不直接读取 Repository 或 CPA Auth 原文。

2. 两种视图必须分离

2.1 用户视图

用户通过自己的 API Key 登录,只能看到与该 Key 所属账户有关的数据。根据已经确定的产品原则,用户可见的计费核心单位只有金额:

  • 总额度;
  • 已消费金额;
  • 剩余金额;
  • 本周期起止;
  • 今日/本月消费;
  • 按日金额趋势;
  • 最近请求的模型、时间、状态和最终金额;
  • Key 状态和到期时间。

用户界面不显示 Token 数、credits、倍率、每百万 Token 价格、上游账户配额或内部核算字段。金额统一显示 settlement currency,并使用服务器返回的格式化字符串/定点值,不能由浏览器 float 重算。

2.2 管理员视图

管理员拥有完整运维与审计能力,可以查看:

  • 金额及 Token 明细;
  • 价格和 Fast/long-context 规则;
  • 下游账户、Key、套餐和余额;
  • 上游账号、订阅、配额和健康状态;
  • 请求/执行、重试、实际路由与失败;
  • 统计分析、同步状态、数据库和插件诊断。

管理员页面中的“用户花费”和“上游配额”必须视觉与命名分离,避免把两种额度混为一谈。

本项目采用请求结束后结算的软金额额度。用户页必须写“软额度/请求后结算”,不得宣传“绝不超额”;余额很低时仍可能由最后一个在途请求产生有限负余额。

3. 管理员信息架构

主要沿用 usage-keeper 的七个区域,并加入本项目的计费/路由管理:

3.1 总览 Overview

首屏回答“现在系统是否正常、花了多少钱、谁在使用”:

  • 今日/本周期总金额、请求数、成功率;
  • RPM、金额/分钟;管理员可切换查看 TPM/Token;
  • 日均请求、日均金额;
  • 金额、请求、缓存命中率时间序列;
  • Recent Activity 活动格;
  • 实时请求速率、金额速率、TTFT/Latency P50/P95
  • 当前模型、下游账户/Key、上游账户 Top;
  • 上游账户即将耗尽、Key 已阻断、未定价事件、采集延迟告警。

参考组件:StatCardsRecentActivityPanelOverviewRealtimePanel

3.2 分析 Analysis

  • 金额和 Token 时间序列;
  • 金额分项:输入、cache read、cache write、output
  • 模型效率:每请求金额、输出量、缓存率;
  • Top models
  • TTFT/Latency 分布和异常点;
  • 下游账户/Key、模型、Auth File、AI Provider 构成;
  • Key×模型热力图;
  • Fast 使用金额与占比;
  • strict/preferred 路由命中和 fallback 分析。

参考 analysis/AnalysisPanel.tsx。金额始终使用已经入账的 ChargedAmount,不能按当前价格重算历史。

3.3 请求 Events

可分页、筛选、排序和导出。管理员可配置显示列:

  • 时间、RequestID、Key/账户;
  • requested/upstream/billing model 与 alias
  • requested/reported/effective service tier
  • success/failure/canceled/rejected
  • endpoint、stream、reasoning effort
  • TTFT、Latency、速度;
  • Token 各分项与缓存率;
  • 最终金额、价格版本、倍率、核算质量;
  • 期望上游账户、实际账户、retry/fallback
  • 请求日志受控查看/下载入口。

参考 RequestEventsDetailsCard 的列偏好、分页、筛选、导出和 request log 交互。默认不展示 Prompt/Response;查看 CPA 请求日志必须显式授权、短期 token、审计记录和脱敏。

3.4 下游账户与 Key

这是本项目相对 keeper 的核心新增页:

  • 账户名称、状态、套餐、本期额度/已用/剩余金额;
  • 所属 Key、preview、alias、状态、有效期、最近使用;
  • 创建/轮换/禁用/撤销 Key
  • 绑定/解绑套餐、充值、扣减、重置周期;
  • 模型、endpoint、Fast 使用权限;
  • route mode 与指定上游账户/池;
  • 实际路由与 fallback 最近记录;
  • 批量操作和 CPA Key 同步。

额度操作必须二次确认,并展示变更前后金额及将写入的账本原因。

3.5 上游账户 Auth Files / Providers

沿用 usage-keeper 两个独立 tab

  • Auth FilesOAuth/Codex 账户;
  • AI Provider:配置型 API Key provider。

展示身份别名、provider、状态、priority、disabled、订阅层级/有效期、首次/最近使用、成功失败、用量、当前配额窗口和重置时间。支持:

  • provider 筛选、分页、排序;
  • 编辑本地别名;
  • 刷新单个或当前页配额;
  • Codex quota inspection
  • 可用时执行 quota reset
  • 查看哪些下游 Key 严格/优先绑定到该账户。
  • 显示 scheduler-visible/bindable;MVP 阻止绑定不在最高可用 priority tier 的 Auth,并解释当前 CPA scheduler 只能看到该 tier。

不要在 UI 返回上游 token、完整文件内容或 API Key。

3.6 价格与套餐 Settings

  • 模型价格目录、来源、版本和生效时间;
  • 同步预览、确认发布、管理员覆盖;
  • Fast 2.5x、long-context 和条件规则;
  • 未定价模型告警;
  • 套餐金额、周期、绑定账户数量;
  • 安全/readiness 设置、数据库备份和保留策略;当前无插件管理 session,不把 Management Key 持久化。

参考 keeper 的 PriceSettingsCard、pricing rules,以及 key-billing 的 Plans/Prices 页面。禁止后台同步后无确认地改变生产计价。

3.7 系统诊断

  • 插件版本、CPA ABI/RPC schema 与兼容状态;
  • SQLite 路径、大小、WAL、最近备份和 integrity
  • runtime topologycallback-driven/sidecar/worker soak status)、required-plugin readiness 和 sentinel/gateway 状态(不显示 secret);
  • pending request 数、采集/写入队列深度;
  • 各 aggregation checkpoint lag
  • 未定价、missing、partial、inconsistent 计数;
  • CPA identity/model/quota 最近同步结果;
  • 插件运行事件和错误。

诊断日志与账本分开;清理诊断日志不会清除金额、请求事实或累计。

4. 用户页面布局

用户页面保持极简:

[当前 Key / 状态]                         [退出]

[本周期额度 $20.00] [已消费 $7.25] [剩余 $12.75] [周期结束 8/31]

[金额趋势:今天 / 7 天 / 本月 / 自定义]

[最近请求]
时间 | 模型 | 状态 | 金额

可以参考 usage-keeper 的 KeyOverviewPageStatCardsRecentActivityPanel 与 realtime 交互,但将 Token/RPM/TPM/cache 等内容替换成用户需要的金额、请求和可用状态。

5. 交互原则

  • 时间范围统一支持 today、yesterday、7/30 天、本月和自定义;
  • Overview 可在页面可见时每 10 秒刷新,隐藏时暂停;
  • Events 第一页可自动刷新,其他页保持稳定;
  • 大表支持列显示/排序偏好、分页和导出;
  • 空状态、加载、部分加载、数据延迟和价格不可用必须分别表达;
  • Analysis 的慢查询分区并行加载,某一区失败不遮挡其他已完成卡片;
  • 桌面和移动端都可用,表格横向滚动、tooltip 可键盘访问;
  • 支持明暗主题和中英文,但第一版中文优先;
  • 金额、时间、百分比由统一 formatter 处理。

6. 技术承载方式

第一版建议构建静态 React/Vite bundle,使用 go:embed 打入动态库,通过 CPA management_api 注册:

  • 受 CPA Management Key 保护的 JSON API 位于 /v0/management/plugins/<plugin-id>/...
  • browser resource 位于 /v0/resource/plugins/<plugin-id>/...;CPA 当前只支持未经过 Management Key 的精确 GET resource 路径;
  • 管理员数据必须由受保护 Management API 获取,不能嵌入公开 resource HTML
  • MVP 用户页只注册少量只读 resource GET JSON 路径,由插件自行校验 Authorization: Bearer <downstream-key> 并按 Credential scope 返回金额投影;
  • 用户 Key 只保存在页面内存,不进入 URL、cookie 日志或 localStorage;刷新后需要重新输入;
  • 当前 CPA plugin route 不足以安全实现完整的用户 POST API 和 HttpOnly 登录 session。需要这些能力时应增加独立 sidecar/public API 或扩展 CPA 的 authenticated user plugin routes
  • HTML/JSON/CSV 导出全部转义,响应设置 CSP、nosniffno-store(敏感接口)。

resource 只支持 exact GET,因此前端构建必须遵守:

  • Vite 使用相对 basebuild manifest 中每个 JS/CSS/font 都注册成独立 ResourceRoute
  • 页面路由使用 HashRouter,不依赖 history fallback
  • 第一版不注册 service worker,避免公开资源或敏感 JSON 被离线缓存;
  • CSP 禁止 inline 时使用独立资源或固定 hash;
  • 用户 JSON 设置 Cache-Control: no-storeVary: Authorization

公开 resource shell 不会自动获得 CPA Management Key。管理员首次进入时手工输入 Key,只保存在当前页面 JS 内存,刷新即失效;不得读取或复用 CPA 控制面板的 localStorage/sessionStorage。用户 Key 采用相同的“当前页面内存”原则,但只调用用户只读 resource GET。

当前 CPA Management adapter 会对 JSON 字符串做 HTML entity 转义。客户端对服务端 JSON 字符串最多执行一次兼容性 entity decode,然后仍由 React text node 渲染;禁止 dangerouslySetInnerHTML。测试必须覆盖 A & B <x> 写入/读取往返。CSV 导出还要防 = + - @ 开头的公式注入,不能把 HTML escape 当成 CSV 安全。

不能照搬 key-billing 在浏览器 session state 中借用 Management Key 的方式作为最终安全模型。

CPA home.enabled 时 Management 和 resource route 都返回 404,因此 cpa-ext 第一版整体不支持 Home;页面不能把它表现成普通“暂无数据”。

7. API 投影原则

  • 用户 API 只返回自己的金额投影,不先返回管理员对象再让前端隐藏字段;
  • 管理员 API 返回 Token/价格/上游身份等完整审计字段;
  • 所有列表使用服务端分页、筛选和稳定游标;
  • 图表 API 返回预聚合,不把几十万条事件交给浏览器计算;
  • API 金额返回 currency + micros + display,前端不得自行从 Token 算钱;
  • realtime、overview、analysis、events 独立接口,避免一个慢请求阻塞整个页面。

8. MVP 与后续

MVP 页面:

  1. 用户金额总览;
  2. 管理员 Overview
  3. 下游账户/Key/套餐/账户路由;
  4. 请求明细;
  5. 上游 Codex 账户与配额;
  6. 价格;
  7. 系统诊断。

后续补齐 Analysis、复杂热力图、排名、更多 provider、导出与 request log。底层数据/API 契约从第一版就应容纳它们。

9. 参考路径

cpa-usage-keeper 为主要 UI 参考:

  • web/src/pages/UsagePage.tsx
  • web/src/pages/KeyOverviewPage.tsx
  • web/src/components/usage/StatCards.tsx
  • RecentActivityPanel.tsxOverviewRealtimePanel.tsx
  • RequestEventsDetailsCard.tsx
  • analysis/AnalysisPanel.tsx
  • credentials/
  • PriceSettingsCard.tsxApiKeySettingsCard.tsx
  • web/src/lib/api.tstypes.ts

cpa-plugin-key-billing 参考:

  • internal/plugin/ui.html
  • internal/plugin/management.go
  • internal/billing/keys.golog.go

10. 验收标准

  • 用户登录后只能看到本账户且只有金额计费单位;
  • 管理员能完成 Key、套餐、余额、路由、价格和上游账户管理;
  • Overview、Events、上游配额与账本数字一致;
  • 历史金额不因当前价格变化而改变;
  • 权限校验在服务端执行;
  • 页面不泄露下游/上游秘密、Prompt 或完整 Response
  • Management Key/用户 Key 只驻留当前页面内存,刷新失效,用户 JSON 不缓存;
  • exact resource assets、HashRouter、CSP 和 entity-decode 往返测试通过;
  • Home 模式由 readiness 明确拒绝,不显示误导性的空页面;
  • 大数据量下使用分页和聚合,UI 不冻结;
  • 关键动作有确认、审计、错误反馈和可恢复路径。