Shows users below 1M/2M/3M/4M/5M tokens with filter buttons. Sorted lowest first so admins can quickly find and top up users running low. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
112 lines
3.1 KiB
JavaScript
112 lines
3.1 KiB
JavaScript
const { Router } = require('express');
|
|
const balanceService = require('../services/balance');
|
|
|
|
const router = Router();
|
|
|
|
router.get('/stats', async (req, res) => {
|
|
try {
|
|
const stats = await balanceService.getStats(req.db);
|
|
res.json(stats);
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
|
|
router.get('/balances', async (req, res) => {
|
|
try {
|
|
const { page = 1, limit = 50 } = req.query;
|
|
const result = await balanceService.getAllBalances(req.db, parseInt(page), parseInt(limit));
|
|
res.json(result);
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
|
|
router.get('/balances/low', async (req, res) => {
|
|
try {
|
|
const { threshold = 1000000 } = req.query;
|
|
const users = await balanceService.getLowBalances(req.db, parseInt(threshold));
|
|
res.json({ users });
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
|
|
router.get('/balances/search', async (req, res) => {
|
|
try {
|
|
const { q } = req.query;
|
|
if (!q || q.length < 2) {
|
|
return res.json({ users: [] });
|
|
}
|
|
const users = await balanceService.searchUsers(req.db, q);
|
|
res.json({ users });
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
|
|
router.get('/balances/:userId', async (req, res) => {
|
|
try {
|
|
const balance = await balanceService.getUserBalance(req.db, req.params.userId);
|
|
if (!balance) {
|
|
return res.status(404).json({ error: 'User not found' });
|
|
}
|
|
res.json(balance);
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
|
|
router.post('/balances/:userId/set', async (req, res) => {
|
|
try {
|
|
const { amount } = req.body;
|
|
if (typeof amount !== 'number' || amount < 0) {
|
|
return res.status(400).json({ error: 'Invalid amount' });
|
|
}
|
|
const result = await balanceService.setBalance(req.db, req.params.userId, amount);
|
|
res.json(result);
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
|
|
router.post('/balances/:userId/add', async (req, res) => {
|
|
try {
|
|
const { amount } = req.body;
|
|
if (typeof amount !== 'number' || amount === 0) {
|
|
return res.status(400).json({ error: 'Invalid amount' });
|
|
}
|
|
const result = await balanceService.addBalance(req.db, req.params.userId, amount);
|
|
res.json(result);
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
|
|
router.post('/balances/bulk/add', async (req, res) => {
|
|
try {
|
|
const { amount } = req.body;
|
|
if (typeof amount !== 'number' || amount === 0) {
|
|
return res.status(400).json({ error: 'Invalid amount' });
|
|
}
|
|
const result = await balanceService.addToAll(req.db, amount);
|
|
res.json(result);
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
|
|
router.post('/balances/bulk/set', async (req, res) => {
|
|
try {
|
|
const { amount } = req.body;
|
|
if (typeof amount !== 'number' || amount < 0) {
|
|
return res.status(400).json({ error: 'Invalid amount' });
|
|
}
|
|
const result = await balanceService.setAll(req.db, amount);
|
|
res.json(result);
|
|
} catch (err) {
|
|
res.status(500).json({ error: err.message });
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|