fix(ui): tighten analytics session and query contracts

This commit is contained in:
Tam Nhu Tran committed 2026-04-27 12:30:56 -04:00
1 parent e95b354297
commit b2e4be310d
9 files changed
+162 -106

No files matched your search

@@ -175,94 +175,98 @@ describe('cliproxy usage syncer', () => {
});
});
it('migrates legacy v2 snapshots forward before merging new history', async () => {
await runWithScopedConfigDir(ccsDir, async () => {
const snapshotPath = path.join(ccsDir, 'cache', 'cliproxy-usage', 'latest.json');
fs.mkdirSync(path.dirname(snapshotPath), { recursive: true });
fs.writeFileSync(
snapshotPath,
JSON.stringify({
version: 2,
timestamp: Date.now() - 60_000,
daily: [
{
date: '2026-03-01',
source: 'cliproxy',
inputTokens: 100,
outputTokens: 20,
cacheCreationTokens: 0,
cacheReadTokens: 10,
cost: 0.2,
totalCost: 0.2,
modelsUsed: ['gemini-2.5-pro'],
modelBreakdowns: [
{
modelName: 'gemini-2.5-pro',
inputTokens: 100,
outputTokens: 20,
cacheCreationTokens: 0,
cacheReadTokens: 10,
cost: 0.2,
},
],
},
],
hourly: [
{
hour: '2026-03-01 12:00',
source: 'cliproxy',
requestCount: 7,
inputTokens: 100,
outputTokens: 20,
cacheCreationTokens: 0,
cacheReadTokens: 10,
cost: 0.2,
totalCost: 0.2,
modelsUsed: ['gemini-2.5-pro'],
modelBreakdowns: [
{
modelName: 'gemini-2.5-pro',
inputTokens: 100,
outputTokens: 20,
cacheCreationTokens: 0,
cacheReadTokens: 10,
cost: 0.2,
},
],
},
],
monthly: [
{
month: '2026-03',
source: 'cliproxy',
inputTokens: 100,
outputTokens: 20,
cacheCreationTokens: 0,
cacheReadTokens: 10,
totalCost: 0.2,
modelsUsed: ['gemini-2.5-pro'],
modelBreakdowns: [
{
modelName: 'gemini-2.5-pro',
inputTokens: 100,
outputTokens: 20,
cacheCreationTokens: 0,
cacheReadTokens: 10,
cost: 0.2,
},
],
},
],
}),
'utf-8'
);
it('migrates legacy v1 and v2 snapshots forward before merging new history', async () => {
for (const version of [1, 2]) {
await runWithScopedConfigDir(ccsDir, async () => {
const snapshotPath = path.join(ccsDir, 'cache', 'cliproxy-usage', 'latest.json');
fs.mkdirSync(path.dirname(snapshotPath), { recursive: true });
fs.writeFileSync(
snapshotPath,
JSON.stringify({
version,
timestamp: Date.now() - 60_000,
daily: [
{
date: '2026-03-01',
source: 'cliproxy',
inputTokens: 100,
outputTokens: 20,
cacheCreationTokens: 0,
cacheReadTokens: 10,
cost: 0.2,
totalCost: 0.2,
modelsUsed: ['gemini-2.5-pro'],
modelBreakdowns: [
{
modelName: 'gemini-2.5-pro',
inputTokens: 100,
outputTokens: 20,
cacheCreationTokens: 0,
cacheReadTokens: 10,
cost: 0.2,
},
],
},
],
hourly: [
{
hour: '2026-03-01 12:00',
source: 'cliproxy',
requestCount: 7,
inputTokens: 100,
outputTokens: 20,
cacheCreationTokens: 0,
cacheReadTokens: 10,
cost: 0.2,
totalCost: 0.2,
modelsUsed: ['gemini-2.5-pro'],
modelBreakdowns: [
{
modelName: 'gemini-2.5-pro',
inputTokens: 100,
outputTokens: 20,
cacheCreationTokens: 0,
cacheReadTokens: 10,
cost: 0.2,
},
],
},
],
monthly: [
{
month: '2026-03',
source: 'cliproxy',
inputTokens: 100,
outputTokens: 20,
cacheCreationTokens: 0,
cacheReadTokens: 10,
totalCost: 0.2,
modelsUsed: ['gemini-2.5-pro'],
modelBreakdowns: [
{
modelName: 'gemini-2.5-pro',
inputTokens: 100,
outputTokens: 20,
cacheCreationTokens: 0,
cacheReadTokens: 10,
cost: 0.2,
},
],
},
],
}),
'utf-8'
);
await syncCliproxyUsage(() => Promise.resolve(buildResponse(200, '2026-03-02T12:00:00.000Z')));
await syncCliproxyUsage(() =>
Promise.resolve(buildResponse(200, '2026-03-02T12:00:00.000Z'))
);
const cached = await loadCachedCliproxyData();
expect(cached.daily.map((entry) => entry.date)).toEqual(['2026-03-02', '2026-03-01']);
expect(cached.hourly.find((entry) => entry.hour === '2026-03-01 12:00')?.requestCount).toBe(7);
});
const cached = await loadCachedCliproxyData();
expect(cached.daily.map((entry) => entry.date)).toEqual(['2026-03-02', '2026-03-01']);
expect(cached.hourly.find((entry) => entry.hour === '2026-03-01 12:00')?.requestCount).toBe(7);
});
}
});
it('prunes history details older than the configured retention window', async () => {