librechat-analytics/routes/api.js
DJP e74f21d57e feat: Add Conversations tab with user drill-down
New tab showing most expensive conversations with title, user, models,
and token breakdown. Clicking a user name in the Users tab filters
conversations to that user. Includes CSV export.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 15:16:49 -04:00

80 lines
2.3 KiB
JavaScript

const express = require('express');
const router = express.Router();
const analytics = require('../services/analytics');
router.get('/summary', async (req, res) => {
try {
const data = await analytics.getSummary(req.db, req.query);
res.json(data);
} catch (err) {
console.error('Summary error:', err);
res.status(500).json({ error: err.message });
}
});
router.get('/top-users', async (req, res) => {
try {
const limit = parseInt(req.query.limit) || 10;
const data = await analytics.getTopUsers(req.db, req.query, limit);
res.json(data);
} catch (err) {
console.error('Top users error:', err);
res.status(500).json({ error: err.message });
}
});
router.get('/top-models', async (req, res) => {
try {
const limit = parseInt(req.query.limit) || 10;
const data = await analytics.getTopModels(req.db, req.query, limit);
res.json(data);
} catch (err) {
console.error('Top models error:', err);
res.status(500).json({ error: err.message });
}
});
router.get('/top-agents', async (req, res) => {
try {
const limit = parseInt(req.query.limit) || 10;
const data = await analytics.getTopAgents(req.db, req.query, limit);
res.json(data);
} catch (err) {
console.error('Top agents error:', err);
res.status(500).json({ error: err.message });
}
});
router.get('/cost-breakdown', async (req, res) => {
try {
const data = await analytics.getCostBreakdown(req.db, req.query);
res.json(data);
} catch (err) {
console.error('Cost breakdown error:', err);
res.status(500).json({ error: err.message });
}
});
router.get('/usage-over-time', async (req, res) => {
try {
const data = await analytics.getUsageOverTime(req.db, req.query);
res.json(data);
} catch (err) {
console.error('Usage over time error:', err);
res.status(500).json({ error: err.message });
}
});
router.get('/top-conversations', async (req, res) => {
try {
const limit = parseInt(req.query.limit) || 20;
const userId = req.query.userId || null;
const data = await analytics.getTopConversations(req.db, req.query, limit, userId);
res.json(data);
} catch (err) {
console.error('Top conversations error:', err);
res.status(500).json({ error: err.message });
}
});
module.exports = router;