Archived
feat(api): 实装 /api/status 接口——无鉴权公开接口,换算比率权威来源
- endpoints:AuthMode 扩展 'none'(完全公开),追加 /api/status 定义(考证实证文案 + 实测示例响应),置于列表首位 - endpoint-info-line:鉴权徽标三态化(公开/宽松/严格,map 驱动 + none 中性样式) - endpoint-panel:requiresKey——无鉴权接口隐藏 sk-key 输入行、按钮不因空 key 禁用、空态文案区分 - spec:接口数 5→6、顺序、鉴权分布(none+strict×3+lenient×2)断言更新 - docs:接口文档同步 479 行新版(/api/status 详解 + QuotaPerUnit 考证);交互设计 §1 清单加第 0 行;README 与 side-nav 计数更新 - 验证:test 64/64 + type-check + lint + build 四绿
This commit is contained in:
@@ -3,17 +3,18 @@ import { describe, expect, it } from 'vitest';
|
||||
import { endpointList, findEndpointByPath } from './endpoints';
|
||||
|
||||
describe('endpointList 数据完整性', () => {
|
||||
it('恰好 5 个接口(设计文档 §1 定案的对接清单)', () => {
|
||||
expect(endpointList).toHaveLength(5);
|
||||
it('恰好 6 个接口(设计文档 §1 定案的对接清单)', () => {
|
||||
expect(endpointList).toHaveLength(6);
|
||||
});
|
||||
|
||||
it('路径唯一(path 是 tab / queryKey 的唯一标识)', () => {
|
||||
const pathList = endpointList.map((endpoint) => endpoint.path);
|
||||
expect(new Set(pathList).size).toBe(5);
|
||||
expect(new Set(pathList).size).toBe(6);
|
||||
});
|
||||
|
||||
it('顺序与用户指定清单一致', () => {
|
||||
expect(endpointList.map((endpoint) => endpoint.path)).toEqual([
|
||||
'/api/status',
|
||||
'/v1/dashboard/billing/subscription',
|
||||
'/v1/dashboard/billing/usage',
|
||||
'/v1/models',
|
||||
@@ -25,13 +26,14 @@ describe('endpointList 数据完整性', () => {
|
||||
it('全部为 GET 且带鉴权元数据', () => {
|
||||
for (const endpoint of endpointList) {
|
||||
expect(endpoint.method).toBe('GET');
|
||||
expect(['strict', 'lenient']).toContain(endpoint.authMode);
|
||||
expect(['strict', 'lenient', 'none']).toContain(endpoint.authMode);
|
||||
expect(endpoint.authMiddlewareName).toBeTruthy();
|
||||
}
|
||||
});
|
||||
|
||||
it('严格/宽松鉴权分布正确(前 3 严格,后 2 宽松)', () => {
|
||||
it('鉴权模式分布正确(公开 1 + 严格 3 + 宽松 2)', () => {
|
||||
expect(endpointList.map((endpoint) => endpoint.authMode)).toEqual([
|
||||
'none',
|
||||
'strict',
|
||||
'strict',
|
||||
'strict',
|
||||
|
||||
+32
-3
@@ -1,17 +1,17 @@
|
||||
/**
|
||||
* 5 个对接接口的静态元数据
|
||||
* 对接接口的静态元数据
|
||||
* 数据源:docs/NewAPI-sk-key接口文档.md(源码实证调研)
|
||||
* 顺序即 sider / tab 展示顺序(设计文档 §1 定案,不分组不编号)
|
||||
*/
|
||||
|
||||
export type AuthMode = 'strict' | 'lenient';
|
||||
export type AuthMode = 'strict' | 'lenient' | 'none';
|
||||
|
||||
export interface EndpointDefinition {
|
||||
/** 接口路径(唯一标识,同时用作 tab 标签与 queryKey 组成部分) */
|
||||
readonly path: string;
|
||||
/** HTTP 方法(当前全部为 GET,保留扩展位) */
|
||||
readonly method: 'GET';
|
||||
/** 鉴权模式:strict = TokenAuth(key 无效/过期/耗尽直接被拒);lenient = TokenAuthReadOnly(宽松,废 key 也能查) */
|
||||
/** 鉴权模式:strict = TokenAuth(key 无效/过期/耗尽直接被拒);lenient = TokenAuthReadOnly(宽松,废 key 也能查);none = 完全公开(无需任何凭证) */
|
||||
readonly authMode: AuthMode;
|
||||
/** 鉴权中间件名(展示用) */
|
||||
readonly authMiddlewareName: string;
|
||||
@@ -24,6 +24,35 @@ export interface EndpointDefinition {
|
||||
}
|
||||
|
||||
export const endpointList: readonly EndpointDefinition[] = [
|
||||
{
|
||||
path: '/api/status',
|
||||
method: 'GET',
|
||||
authMode: 'none',
|
||||
authMiddlewareName: '无(公开接口)',
|
||||
responseSummary: '站点配置与计费参数(含 quota_per_unit)',
|
||||
notes: [
|
||||
'完全公开:无任何鉴权,不持有 sk-key 也能访问(本工具对接清单中唯一)',
|
||||
'quota_per_unit 是 QuotaPerUnit 当前生效值(默认 500000,源码 $0.002 / 1K tokens 锚点)——quota ÷ 该值 = 美元,换算比率的唯一权威来源,管理员可改,不要硬编码',
|
||||
'接口①④交叉实测吻合验证不了管理员是否改过此值:billing 接口内部就是拿 quota ÷ QuotaPerUnit 换算,同一常量自证',
|
||||
'quota_display_type 影响 billing 接口语义:USD 直接是美元;CNY 先 ÷QuotaPerUnit 再 ×usd_exchange_rate;TOKENS 是原始 token 数',
|
||||
'返回 60+ 字段(版本、登录方式、前端模块开关、公告等),解析时只取计费相关字段,其余忽略;字段集合随版本演进,需容忍未知字段',
|
||||
],
|
||||
sampleResponse: {
|
||||
success: true,
|
||||
message: '',
|
||||
data: {
|
||||
quota_per_unit: 500000,
|
||||
quota_display_type: 'USD',
|
||||
usd_exchange_rate: 6.8,
|
||||
display_in_currency: true,
|
||||
custom_currency_symbol: '¤',
|
||||
custom_currency_exchange_rate: 1,
|
||||
price: 6.8,
|
||||
system_name: 'AI Gateway',
|
||||
version: 'v1.0.0-rc.35',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/v1/dashboard/billing/subscription',
|
||||
method: 'GET',
|
||||
|
||||
Reference in New Issue
Block a user