12 KiB
管理与展示 UI 模块
1. 定位
UI 模块负责把数据、计费、Key 路由、配额和诊断能力投影成可使用的页面。信息架构和统计展示主要参考 cpa-usage-keeper,Key 套餐与金额操作参考 cpa-plugin-key-billing。
UI 不计算价格、不重新聚合账本、不保存业务真相。页面中的所有数字都来自 api.md 定义的权限化查询 API;UI 不直接读取 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 已阻断、未定价事件、采集延迟告警。
参考组件:StatCards、RecentActivityPanel、OverviewRealtimePanel。
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 Files:OAuth/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 topology(callback-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 的 KeyOverviewPage、StatCards、RecentActivityPanel 与 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、
nosniff和no-store(敏感接口)。
resource 只支持 exact GET,因此前端构建必须遵守:
- Vite 使用相对
base,build manifest 中每个 JS/CSS/font 都注册成独立 ResourceRoute; - 页面路由使用 HashRouter,不依赖 history fallback;
- 第一版不注册 service worker,避免公开资源或敏感 JSON 被离线缓存;
- CSP 禁止 inline 时使用独立资源或固定 hash;
- 用户 JSON 设置
Cache-Control: no-store和Vary: 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 页面:
- 用户金额总览;
- 管理员 Overview;
- 下游账户/Key/套餐/账户路由;
- 请求明细;
- 上游 Codex 账户与配额;
- 价格;
- 系统诊断。
后续补齐 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.tsx、OverviewRealtimePanel.tsx;RequestEventsDetailsCard.tsx;analysis/AnalysisPanel.tsx;credentials/;PriceSettingsCard.tsx、ApiKeySettingsCard.tsx;web/src/lib/api.ts、types.ts。
cpa-plugin-key-billing 参考:
internal/plugin/ui.html;internal/plugin/management.go;internal/billing/keys.go、log.go。
10. 验收标准
- 用户登录后只能看到本账户且只有金额计费单位;
- 管理员能完成 Key、套餐、余额、路由、价格和上游账户管理;
- Overview、Events、上游配额与账本数字一致;
- 历史金额不因当前价格变化而改变;
- 权限校验在服务端执行;
- 页面不泄露下游/上游秘密、Prompt 或完整 Response;
- Management Key/用户 Key 只驻留当前页面内存,刷新失效,用户 JSON 不缓存;
- exact resource assets、HashRouter、CSP 和 entity-decode 往返测试通过;
- Home 模式由 readiness 明确拒绝,不显示误导性的空页面;
- 大数据量下使用分页和聚合,UI 不冻结;
- 关键动作有确认、审计、错误反馈和可恢复路径。