Skip to content

Commit a0d165b

Browse files
committed
feat(quota): align types with coding-plan API, show boost multiplier
- types: add 4 optional fields (interval_status, weekly_status, boost_permille x 2) - render: prepend 'xN' to model name when boost_permille > 1000 - tests: add 2 cases (with boost, without boost) PR #166 missed these fields. status is not separately rendered since percent already conveys the state (1=partial, 3=full). boost informs the user about their 2x subscription multiplier.
1 parent 109287d commit a0d165b

3 files changed

Lines changed: 79 additions & 1 deletion

File tree

src/output/quota-table.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,10 @@ export function renderQuotaTable(models: QuotaModelRemain[], config: Config): vo
128128
const L = config.region === 'cn' ? LABELS_CN : LABELS_EN;
129129

130130
const rows = models.map((m) => {
131-
const displayName = displayModelName(m.model_name, config.region);
131+
const baseName = displayModelName(m.model_name, config.region);
132+
const boost = m.interval_boost_permille;
133+
const boostTag = (boost && boost > 1000) ? ` ×${boost / 1000}` : '';
134+
const displayName = baseName + boostTag;
132135
const current = renderMetric(
133136
L.current,
134137
m.current_interval_usage_count,

src/types/api.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,13 @@ export interface QuotaModelRemain {
253253
current_interval_total_count: number;
254254
current_interval_usage_count: number;
255255
current_interval_remaining_percent?: number;
256+
current_interval_status?: number;
256257
current_weekly_total_count: number;
257258
current_weekly_usage_count: number;
258259
current_weekly_remaining_percent?: number;
260+
current_weekly_status?: number;
261+
interval_boost_permille?: number;
262+
weekly_boost_permille?: number;
259263
weekly_start_time: number;
260264
weekly_end_time: number;
261265
weekly_remains_time: number;

test/output/quota-table.test.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,13 @@ function createCodingPlanModels(): QuotaModelRemain[] {
4747
current_interval_total_count: 0,
4848
current_interval_usage_count: 0,
4949
current_interval_remaining_percent: 94,
50+
current_interval_status: 1,
5051
current_weekly_total_count: 0,
5152
current_weekly_usage_count: 0,
5253
current_weekly_remaining_percent: 98,
54+
current_weekly_status: 1,
55+
interval_boost_permille: 2000,
56+
weekly_boost_permille: 2000,
5357
weekly_start_time: Date.UTC(2026, 4, 31, 0, 0, 0),
5458
weekly_end_time: Date.UTC(2026, 5, 7, 0, 0, 0),
5559
weekly_remains_time: 6 * 24 * 60 * 60 * 1000,
@@ -129,4 +133,71 @@ describe('renderQuotaTable', () => {
129133
expect(output).toContain('21 / 21');
130134
expect(output).not.toContain('0 / 3');
131135
});
136+
137+
it('renders boost multiplier when boost_permille > 1000', () => {
138+
const lines: string[] = [];
139+
const originalLog = console.log;
140+
141+
console.log = (message?: unknown) => {
142+
lines.push(String(message ?? ''));
143+
};
144+
145+
try {
146+
renderQuotaTable(createCodingPlanModels(), {
147+
...createConfig(),
148+
region: 'cn',
149+
noColor: true,
150+
});
151+
} finally {
152+
console.log = originalLog;
153+
}
154+
155+
const output = lines.join('\n');
156+
157+
// general model has interval_boost_permille=2000 => ×2 prefix
158+
expect(output).toContain('通用 ×2');
159+
// video model has no boost field => no ×2 on its row
160+
// ensure the video line is still present (so the negative check is meaningful)
161+
expect(output).toContain('视频');
162+
});
163+
164+
it('omits boost multiplier when boost_permille is missing', () => {
165+
const modelsNoBoost: QuotaModelRemain[] = [{
166+
model_name: 'general',
167+
start_time: Date.UTC(2026, 4, 31, 0, 0, 0),
168+
end_time: Date.UTC(2026, 4, 31, 2, 0, 0),
169+
remains_time: 2 * 60 * 60 * 1000,
170+
current_interval_total_count: 100,
171+
current_interval_usage_count: 50,
172+
current_interval_remaining_percent: 50,
173+
current_weekly_total_count: 1000,
174+
current_weekly_usage_count: 200,
175+
current_weekly_remaining_percent: 80,
176+
weekly_start_time: Date.UTC(2026, 4, 31, 0, 0, 0),
177+
weekly_end_time: Date.UTC(2026, 5, 7, 0, 0, 0),
178+
weekly_remains_time: 6 * 24 * 60 * 60 * 1000,
179+
}];
180+
181+
const lines: string[] = [];
182+
const originalLog = console.log;
183+
184+
console.log = (message?: unknown) => {
185+
lines.push(String(message ?? ''));
186+
};
187+
188+
try {
189+
renderQuotaTable(modelsNoBoost, {
190+
...createConfig(),
191+
region: 'cn',
192+
noColor: true,
193+
});
194+
} finally {
195+
console.log = originalLog;
196+
}
197+
198+
const output = lines.join('\n');
199+
200+
expect(output).toContain('通用');
201+
expect(output).not.toContain('×2');
202+
});
132203
});

0 commit comments

Comments
 (0)