File size: 2,685 Bytes
9a92a42 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | import UserActivity, { ActivityAction, ActivityCategory } from '../model/userActivity.model';
import { Types } from 'mongoose';
import { Request } from 'express';
interface LogActivityParams {
userId: Types.ObjectId | string;
action: ActivityAction;
category: ActivityCategory;
description: string;
metadata?: {
ipAddress?: string;
userAgent?: string;
eventId?: Types.ObjectId;
formId?: Types.ObjectId;
organizationId?: Types.ObjectId;
trainerId?: Types.ObjectId;
changes?: Record<string, any>;
errorMessage?: string;
statusCode?: number;
location?: {
type: "Point";
coordinates: [number, number];
};
duration?: number;
method?: string;
endpoint?: string;
queryParams?: Record<string, any>;
responseSize?: number;
};
sessionId?: string;
success?: boolean;
}
/**
* Log user activity to the database
*/
export const logActivity = async (params: LogActivityParams): Promise<void> => {
try {
await UserActivity.create({
user: params.userId,
action: params.action,
category: params.category,
description: params.description,
metadata: params.metadata || {},
sessionId: params.sessionId,
success: params.success !== undefined ? params.success : true,
timestamp: new Date()
});
} catch (error) {
console.error('Error logging activity:', error);
// Don't throw - activity logging should not break the main flow
}
};
/**
* Extract metadata from Express request
*/
export const extractRequestMetadata = (req: Request) => {
return {
ipAddress: req.ip || req.socket.remoteAddress,
userAgent: req.get('user-agent'),
method: req.method,
endpoint: req.originalUrl || req.url
};
};
/**
* Log activity from Express request
*/
export const logActivityFromRequest = async (
req: Request,
action: ActivityAction,
category: ActivityCategory,
description: string,
additionalMetadata?: Record<string, any>,
success: boolean = true
): Promise<void> => {
if (!req.user) {
console.warn('Cannot log activity: No user in request');
return;
}
const metadata = {
...extractRequestMetadata(req),
...additionalMetadata
};
await logActivity({
userId: req.user._id,
action,
category,
description,
metadata,
success
});
};
export default {
logActivity,
extractRequestMetadata,
logActivityFromRequest
};
|