mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-08-04 13:51:50 +00:00
* feat(dashboard): add granular usage timelines * fix(dashboard): readable timeline legend and month-scale buckets Session legend labels now use the real projectPath's last two segments (app/web) instead of the sanitized project dir, which rendered as an unreadable -Users-name-... dump and truncated in the legend. Hourly buckets now cap at 8 days; longer ranges bucket daily. A 30-day window rendered 720 overlapping hourly spikes, unreadable as a chart. The browser no longer gives the backend session_other/model_other aggregate a top-N slot, which rendered two identical Other legend entries whenever the backend fold out-ranked a real series. --------- Co-authored-by: AgentSeal <hello@agentseal.org>
27 lines
1.4 KiB
TypeScript
27 lines
1.4 KiB
TypeScript
import { describe, expect, it, beforeAll } from 'vitest'
|
|
import { buildMenubarPayloadForRange } from '../src/usage-aggregator.js'
|
|
import { getDateRange } from '../src/cli-date.js'
|
|
import { loadPricing } from '../src/models.js'
|
|
|
|
describe('buildMenubarPayloadForRange', () => {
|
|
beforeAll(async () => {
|
|
await loadPricing()
|
|
})
|
|
|
|
it('returns a valid payload and skips optimize findings when optimize:false', async () => {
|
|
const payload = await buildMenubarPayloadForRange(getDateRange('today'), { provider: 'all', optimize: false })
|
|
expect(typeof payload.current.label).toBe('string')
|
|
expect(payload.current.cost).toBeGreaterThanOrEqual(0)
|
|
expect(Array.isArray(payload.current.topProjects)).toBe(true)
|
|
expect(Array.isArray(payload.current.topModels)).toBe(true)
|
|
expect(Array.isArray(payload.history.daily)).toBe(true)
|
|
expect(payload.history.timeline?.bucketMinutes).toBe(15)
|
|
expect(Array.isArray(payload.history.timeline?.points)).toBe(true)
|
|
expect(payload.current.retryTax.totalUSD).toBeGreaterThanOrEqual(0)
|
|
// Codex credits are always present in the payload (display gates them); 0 with no data.
|
|
expect(typeof payload.current.codexCredits).toBe('number')
|
|
expect(payload.current.codexCredits).toBeGreaterThanOrEqual(0)
|
|
// optimize:false => scanAndDetect skipped => empty optimize block regardless of data
|
|
expect(payload.optimize).toEqual({ findingCount: 0, savingsUSD: 0, topFindings: [] })
|
|
})
|
|
})
|