feat(billing): add usage analytics charts and summary totals
Add daily usage trend charts with multi-metric toggles, overview vs user analysis views, date-range filtering, and usage summary API for interval and all-time totals. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+31
-1
@@ -4,7 +4,7 @@ import path from 'node:path';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import express from 'express';
|
||||
import { listUsagePaged, listLedgerPaged } from './pagination.mjs';
|
||||
import { listUsagePaged, listLedgerPaged, getUsageStats, getUsageSummary } from './pagination.mjs';
|
||||
|
||||
const projectRoot = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
|
||||
@@ -307,7 +307,29 @@ export function createAdminApp(services) {
|
||||
res.json({ user: result.user });
|
||||
});
|
||||
|
||||
async function handleUsageStats(req, res) {
|
||||
try {
|
||||
const result = await getUsageStats(pool, req.query);
|
||||
res.json(result);
|
||||
} catch (err) {
|
||||
if (err?.code === 'INVALID_TIME_RANGE') {
|
||||
return res.status(400).json({ message: '无效的时间范围' });
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
adminApi.get('/usage/summary', requireAdmin, async (req, res) => {
|
||||
const result = await getUsageSummary(pool, req.query);
|
||||
res.json(result);
|
||||
});
|
||||
|
||||
adminApi.get('/usage/stats', requireAdmin, handleUsageStats);
|
||||
|
||||
adminApi.get('/usage', requireAdmin, async (req, res) => {
|
||||
if (req.query.stats === '1' || req.query.stats === 'true') {
|
||||
return handleUsageStats(req, res);
|
||||
}
|
||||
const result = await listUsagePaged(pool, req.query);
|
||||
res.json(result);
|
||||
});
|
||||
@@ -399,6 +421,14 @@ export function createAdminApp(services) {
|
||||
res.json(result);
|
||||
});
|
||||
|
||||
adminApi.get('/memory-v2/runtime', requireAdmin, async (_req, res) => {
|
||||
if (!memoryV2ConfigService?.getRuntimeState) {
|
||||
return res.status(503).json({ message: 'Memory V2 配置服务未启用' });
|
||||
}
|
||||
const result = await memoryV2ConfigService.getRuntimeState();
|
||||
return res.json(result);
|
||||
});
|
||||
|
||||
adminApi.get('/mindsearch/config', requireAdmin, async (_req, res) => {
|
||||
if (!mindSearchConfigService?.getAdminConfig) return res.status(503).json({ message: 'MindSearch 配置未启用' });
|
||||
res.json(await mindSearchConfigService.getAdminConfig());
|
||||
|
||||
Reference in New Issue
Block a user