diff --git a/backend/src/routes/admin.js b/backend/src/routes/admin.js index 3de8d2a..acfd7c2 100644 --- a/backend/src/routes/admin.js +++ b/backend/src/routes/admin.js @@ -4,7 +4,7 @@ const { authenticate } = require('../middleware/auth'); const { requireAdmin } = require('../middleware/admin'); const matchingService = require('../services/matching'); const { SUGGESTION_STATUS } = require('../constants'); -const { ACTIONS, log: activityLog } = require('../services/activityLog'); +const { ACTIONS, log: activityLog, queryLogs, getActionTypes, getStats } = require('../services/activityLog'); const { getClientIP } = require('../utils/request'); const router = express.Router(); @@ -237,3 +237,98 @@ router.get('/events/:slug/matching-runs/:runId/suggestions', authenticate, requi next(error); } }); + +// ================================================================== +// ACTIVITY LOGS ENDPOINTS +// ================================================================== + +// GET /api/admin/activity-logs - Query activity logs with filters +router.get('/activity-logs', authenticate, requireAdmin, async (req, res, next) => { + try { + const { + startDate, + endDate, + action, + category, + username, + userId, + success, + limit = 100, + offset = 0, + } = req.query; + + // Parse query parameters + const filters = { + startDate: startDate ? new Date(startDate) : null, + endDate: endDate ? new Date(endDate) : null, + action: action || null, + category: category || null, + username: username || null, + userId: userId ? parseInt(userId) : null, + success: success !== undefined ? success === 'true' : null, + limit: parseInt(limit), + offset: parseInt(offset), + }; + + // Query logs + const result = await queryLogs(filters); + + // Log admin viewing activity logs + activityLog({ + userId: req.user.id, + username: req.user.username, + ipAddress: getClientIP(req), + action: ACTIONS.ADMIN_VIEW_LOGS, + method: req.method, + path: req.path, + metadata: { + filters: { + startDate, + endDate, + action, + category, + username, + userId, + success, + }, + resultCount: result.logs.length, + }, + }); + + res.json({ + success: true, + data: result, + }); + } catch (error) { + next(error); + } +}); + +// GET /api/admin/activity-logs/actions - Get unique action types +router.get('/activity-logs/actions', authenticate, requireAdmin, async (req, res, next) => { + try { + const actions = await getActionTypes(); + + res.json({ + success: true, + count: actions.length, + data: actions, + }); + } catch (error) { + next(error); + } +}); + +// GET /api/admin/activity-logs/stats - Get activity log statistics +router.get('/activity-logs/stats', authenticate, requireAdmin, async (req, res, next) => { + try { + const stats = await getStats(); + + res.json({ + success: true, + data: stats, + }); + } catch (error) { + next(error); + } +});