feat(analytics): add usage analytics page with caching layer

- Add Analytics page with usage trends, model breakdown, sessions table
- Add server-side caching layer for better-ccusage data (TTL-based)
- Add request coalescing to prevent duplicate concurrent API calls
- Add /api/usage/refresh endpoint to manually clear cache
- Add date-range filter, summary cards, trend charts components
- Fix API parameter mismatch (since/until in YYYYMMDD format)
- Wire up Refresh button with loading state animation
This commit is contained in:
kaitranntt
2025-12-08 21:47:36 -05:00
parent 57032eec5e
commit a721af3cf3
17 changed files with 1961 additions and 2 deletions
+75
View File
@@ -2,6 +2,81 @@
* Type shims for incomplete external dependencies
*/
// better-ccusage types (package has JS exports but incomplete TS subpath support)
declare module 'better-ccusage/data-loader' {
export interface ModelBreakdown {
modelName: string;
inputTokens: number;
outputTokens: number;
cacheCreationTokens: number;
cacheReadTokens: number;
cost: number;
}
export interface DailyUsage {
date: string;
source: string;
inputTokens: number;
outputTokens: number;
cacheCreationTokens: number;
cacheReadTokens: number;
cost: number;
totalCost: number;
modelsUsed: string[];
modelBreakdowns: ModelBreakdown[];
}
export interface MonthlyUsage {
month: string;
source: string;
inputTokens: number;
outputTokens: number;
cacheCreationTokens: number;
cacheReadTokens: number;
totalCost: number;
modelsUsed: string[];
modelBreakdowns: ModelBreakdown[];
}
export interface SessionUsage {
sessionId: string;
projectPath: string;
inputTokens: number;
outputTokens: number;
cacheCreationTokens: number;
cacheReadTokens: number;
cost: number;
totalCost: number;
lastActivity: string;
versions: string[];
modelsUsed: string[];
modelBreakdowns: ModelBreakdown[];
source: string;
}
export interface DataLoaderOptions {
mode?: 'calculate' | 'cached';
claudePaths?: string[];
}
export function loadDailyUsageData(options?: DataLoaderOptions): Promise<DailyUsage[]>;
export function loadMonthlyUsageData(options?: DataLoaderOptions): Promise<MonthlyUsage[]>;
export function loadSessionData(options?: DataLoaderOptions): Promise<SessionUsage[]>;
}
declare module 'better-ccusage/calculate-cost' {
export interface Totals {
inputTokens: number;
outputTokens: number;
cacheCreationTokens: number;
cacheReadTokens: number;
costUSD: number;
}
export function calculateTotals(entries: unknown[]): Totals;
export function getTotalTokens(entries: unknown[]): number;
}
declare module 'cli-table3' {
interface TableOptions {
head?: string[];