Archived
feat(api): 实装三个公开接口——groups/perf-metrics/rankings(全站视角数据)
- 新增 /api/user/groups:用户分组与倍率(未启用分组时为空对象),与 /api/pricing group_ratio 互补 - 新增 /api/perf-metrics/summary:全站模型服务质量(延迟/成功率/TPS/小时级序列),hours 参数;对拼车工具补「模型健康度」视角 - 新增 /api/rankings:全站模型用量排行(名次/份额/环比增长),period 参数;车长选主推模型的数据依据 - 三者均 authMode none,公开接口组置于清单最前;/api/status 的「唯一」表述改为公开接口组之一 - spec 断言 6→9(路径顺序、鉴权分布 none×4+strict×3+lenient×2);交互设计文档 §1 清单重排补全站视角定位说明;README 计数更新 - 验证:test 89/89 + type-check + lint + build 四绿
This commit is contained in:
@@ -3,17 +3,20 @@ import { describe, expect, it } from 'vitest';
|
||||
import { endpointList, findEndpointByPath } from './endpoints';
|
||||
|
||||
describe('endpointList 数据完整性', () => {
|
||||
it('恰好 6 个接口(设计文档 §1 定案的对接清单)', () => {
|
||||
expect(endpointList).toHaveLength(6);
|
||||
it('恰好 9 个接口(设计文档 §1 定案的对接清单)', () => {
|
||||
expect(endpointList).toHaveLength(9);
|
||||
});
|
||||
|
||||
it('路径唯一(path 是 tab / queryKey 的唯一标识)', () => {
|
||||
const pathList = endpointList.map((endpoint) => endpoint.path);
|
||||
expect(new Set(pathList).size).toBe(6);
|
||||
expect(new Set(pathList).size).toBe(9);
|
||||
});
|
||||
|
||||
it('顺序与用户指定清单一致', () => {
|
||||
expect(endpointList.map((endpoint) => endpoint.path)).toEqual([
|
||||
'/api/user/groups',
|
||||
'/api/perf-metrics/summary',
|
||||
'/api/rankings',
|
||||
'/api/status',
|
||||
'/v1/dashboard/billing/subscription',
|
||||
'/v1/dashboard/billing/usage',
|
||||
@@ -31,8 +34,11 @@ describe('endpointList 数据完整性', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('鉴权模式分布正确(公开 1 + 严格 3 + 宽松 2)', () => {
|
||||
it('鉴权模式分布正确(公开 4 + 严格 3 + 宽松 2)', () => {
|
||||
expect(endpointList.map((endpoint) => endpoint.authMode)).toEqual([
|
||||
'none',
|
||||
'none',
|
||||
'none',
|
||||
'none',
|
||||
'strict',
|
||||
'strict',
|
||||
|
||||
+80
-1
@@ -2,6 +2,9 @@
|
||||
* 对接接口的静态元数据
|
||||
* 数据源:docs/NewAPI-sk-key接口文档.md(源码实证调研)
|
||||
* 顺序即 sider / tab 展示顺序(设计文档 §1 定案,不分组不编号)
|
||||
*
|
||||
* 鉴权三态:none = 完全公开(无需任何凭证)→ strict = TokenAuth → lenient = TokenAuthReadOnly
|
||||
* 公开接口组(/api/user/groups、/api/perf-metrics/summary、/api/rankings、/api/status)排在清单最前
|
||||
*/
|
||||
|
||||
export type AuthMode = 'strict' | 'lenient' | 'none';
|
||||
@@ -24,6 +27,82 @@ export interface EndpointDefinition {
|
||||
}
|
||||
|
||||
export const endpointList: readonly EndpointDefinition[] = [
|
||||
{
|
||||
path: '/api/user/groups',
|
||||
method: 'GET',
|
||||
authMode: 'none',
|
||||
authMiddlewareName: '无(公开接口)',
|
||||
responseSummary: '用户分组与倍率列表(未启用分组时为空对象)',
|
||||
notes: [
|
||||
'完全公开:无任何鉴权中间件(本工具对接清单中三个免凭证接口之一)',
|
||||
'返回站点配置的用户分组(default / vip 等)及其倍率;站点未启用分组时 data 为空对象',
|
||||
'用途:解释「同一模型为什么计费不同」——分组倍率会影响同一模型的实际消耗',
|
||||
'与 /api/pricing 的 group_ratio 字段互补:本接口是分组清单,pricing 是模型定价',
|
||||
],
|
||||
sampleResponse: { success: true, message: '', data: {} },
|
||||
},
|
||||
{
|
||||
path: '/api/perf-metrics/summary',
|
||||
method: 'GET',
|
||||
authMode: 'none',
|
||||
authMiddlewareName: 'HeaderNavModulePublicOrUserAuth(默认公开)',
|
||||
responseSummary: '全站模型服务质量汇总(延迟/成功率/TPS)',
|
||||
notes: [
|
||||
'公开接口:管理员未在 HeaderNav 中开启 pricing 模块的 requireAuth 时无需任何凭证',
|
||||
'query 参数 hours:统计窗口小时数(默认 24)',
|
||||
'返回每个模型的 avg_latency_ms(平均延迟)、success_rate(成功率 %)、avg_tps(每秒 token 数)、recent_success_series(按小时采样的成功率时间序列)',
|
||||
'对拼车工具的意义:单个 sk-key 日志看不到全局服务质量,本接口补上「模型当前健康度」视角——伙伴反馈「慢/报错多」时用它定位是模型问题还是自身问题',
|
||||
'明细版 /api/perf-metrics?model=xxx 需 query 参数(model 必填,另支持 group/hours),面板暂不支持 query 输入,可用上方注意事项了解参数后经代理手动拼接',
|
||||
],
|
||||
sampleResponse: {
|
||||
success: true,
|
||||
data: {
|
||||
models: [
|
||||
{
|
||||
model_name: 'gpt-5.6-sol',
|
||||
avg_latency_ms: 16823,
|
||||
success_rate: 94.73,
|
||||
avg_tps: 25.81,
|
||||
recent_success_series: [
|
||||
{ ts: 1788872400, success_rate: 100 },
|
||||
{ ts: 1788876000, success_rate: 99.16 },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/api/rankings',
|
||||
method: 'GET',
|
||||
authMode: 'none',
|
||||
authMiddlewareName: 'HeaderNavModulePublicOrUserAuth(默认公开)',
|
||||
responseSummary: '全站模型用量排行(名次/份额/增长)',
|
||||
notes: [
|
||||
'公开接口:同 perf-metrics,受 HeaderNav 模块开关控制,默认无需凭证',
|
||||
'query 参数 period:统计周期(默认 week)',
|
||||
'返回每个模型的 rank(名次)、previous_rank(上期名次)、total_tokens(总用量)、share(份额)、growth_pct(环比增长 %)',
|
||||
'对拼车工具的意义:看全站都在用什么模型——车长选「主推模型」(便宜且稳定)的数据依据;配合 perf-metrics 的成功率可识别衰退模型',
|
||||
],
|
||||
sampleResponse: {
|
||||
success: true,
|
||||
data: {
|
||||
models: [
|
||||
{
|
||||
rank: 1,
|
||||
previous_rank: 2,
|
||||
model_name: 'gpt-5.6-sol',
|
||||
vendor: 'OpenAI',
|
||||
vendor_icon: 'OpenAI',
|
||||
category: 'all',
|
||||
total_tokens: 1583845480,
|
||||
share: 0.6549,
|
||||
growth_pct: 60.4253,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/api/status',
|
||||
method: 'GET',
|
||||
@@ -31,7 +110,7 @@ export const endpointList: readonly EndpointDefinition[] = [
|
||||
authMiddlewareName: '无(公开接口)',
|
||||
responseSummary: '站点配置与计费参数(含 quota_per_unit)',
|
||||
notes: [
|
||||
'完全公开:无任何鉴权,不持有 sk-key 也能访问(本工具对接清单中唯一)',
|
||||
'完全公开:无任何鉴权,不持有 sk-key 也能访问(对接清单公开接口组之一)',
|
||||
'quota_per_unit 是 QuotaPerUnit 当前生效值(默认 500000,NewAPI 以 $0.002 / 1K tokens 的基准定价为锚点设计)——quota ÷ 该值 = 美元,换算比率的唯一权威来源,管理员可改,不要硬编码',
|
||||
'想用 billing 接口(subscription / usage)反推换算比率不可靠:它们内部就是拿 quota ÷ QuotaPerUnit 换算的,站点改了配置它们会跟着变,永远「吻合」——比率唯一权威只有本接口的 quota_per_unit',
|
||||
'quota_display_type 影响 /v1/dashboard/billing/subscription 与 /v1/dashboard/billing/usage 的语义:USD 直接是美元;CNY 先 ÷QuotaPerUnit 再 ×usd_exchange_rate;TOKENS 是原始 token 数',
|
||||
|
||||
Reference in New Issue
Block a user