feat(activity-log): integrate logging across all endpoints (Phase 3)
Added comprehensive activity logging to 14 integration points: Auth Controller (4 actions): - AUTH_REGISTER: User registration - AUTH_LOGIN: User login - AUTH_VERIFY_EMAIL: Email verification (token & code) - AUTH_PASSWORD_RESET: Password reset Events Routes (2 actions): - EVENT_CHECKIN: User checks into event - EVENT_LEAVE: User leaves event Socket Handlers (3 actions): - EVENT_JOIN_CHAT: User joins event chat room - EVENT_LEAVE_CHAT: User leaves event chat room - CHAT_JOIN_ROOM: User joins private match chat Matches Routes (3 actions): - MATCH_CREATE: Match request created - MATCH_ACCEPT: Match request accepted - MATCH_REJECT: Match request rejected/cancelled Admin Routes (1 action + security): - ADMIN_MATCHING_RUN: Admin runs matching algorithm - Added requireAdmin middleware to all admin routes All logs include: - User ID and username (denormalized) - IP address (X-Forwarded-For aware) - Action type and resource ID - HTTP method and path (or SOCKET for WebSocket) - Contextual metadata (event slugs, match IDs, etc.) Fire-and-forget pattern ensures logging never blocks requests.
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
const express = require('express');
|
||||
const { prisma } = require('../utils/db');
|
||||
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 { getClientIP } = require('../utils/request');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// POST /api/admin/events/:slug/run-now - Trigger matching immediately for an event
|
||||
router.post('/events/:slug/run-now', authenticate, async (req, res, next) => {
|
||||
router.post('/events/:slug/run-now', authenticate, requireAdmin, async (req, res, next) => {
|
||||
try {
|
||||
const { slug } = req.params;
|
||||
|
||||
@@ -47,6 +50,23 @@ router.post('/events/:slug/run-now', authenticate, async (req, res, next) => {
|
||||
},
|
||||
});
|
||||
|
||||
// Log admin matching run activity
|
||||
activityLog({
|
||||
userId: req.user.id,
|
||||
username: req.user.username,
|
||||
ipAddress: getClientIP(req),
|
||||
action: ACTIONS.ADMIN_MATCHING_RUN,
|
||||
resource: `event:${event.id}`,
|
||||
method: req.method,
|
||||
path: req.path,
|
||||
metadata: {
|
||||
eventSlug: event.slug,
|
||||
runId: runRow.id,
|
||||
matchedCount,
|
||||
notFoundCount,
|
||||
},
|
||||
});
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
data: {
|
||||
@@ -74,7 +94,7 @@ router.post('/events/:slug/run-now', authenticate, async (req, res, next) => {
|
||||
});
|
||||
|
||||
// GET /api/admin/events/:slug/matching-runs?limit=20 - List recent runs
|
||||
router.get('/events/:slug/matching-runs', authenticate, async (req, res, next) => {
|
||||
router.get('/events/:slug/matching-runs', authenticate, requireAdmin, async (req, res, next) => {
|
||||
try {
|
||||
const { slug } = req.params;
|
||||
const limit = Math.min(parseInt(req.query.limit || '20', 10), 100);
|
||||
@@ -136,7 +156,7 @@ router.get('/events/:slug/matching-runs', authenticate, async (req, res, next) =
|
||||
module.exports = router;
|
||||
|
||||
// GET /api/admin/events/:slug/matching-runs/:runId/suggestions - List suggestions created in this run
|
||||
router.get('/events/:slug/matching-runs/:runId/suggestions', authenticate, async (req, res, next) => {
|
||||
router.get('/events/:slug/matching-runs/:runId/suggestions', authenticate, requireAdmin, async (req, res, next) => {
|
||||
try {
|
||||
const { slug, runId } = req.params;
|
||||
const onlyAssigned = String(req.query.onlyAssigned || 'true') === 'true';
|
||||
|
||||
Reference in New Issue
Block a user