Prashikshak / API /src /model /userActivity.model.ts
Abhisingh-18's picture
Initial commit: Prashikshak - disaster management training platform
9a92a42
Raw
History Blame Contribute Delete
4.68 kB
import { Schema, model, Document, Types } from 'mongoose';
// Enum for action types
export enum ActivityAction {
// Authentication
LOGIN = 'login',
LOGOUT = 'logout',
SIGNUP = 'signup',
PASSWORD_CHANGE = 'password_change',
PASSWORD_RESET = 'password_reset',
// Profile Management
PROFILE_UPDATE = 'profile_update',
PROFILE_PHOTO_UPLOAD = 'profile_photo_upload',
LOCATION_UPDATE = 'location_update',
// Event Management
EVENT_CREATE = 'event_create',
EVENT_UPDATE = 'event_update',
EVENT_DELETE = 'event_delete',
EVENT_JOIN = 'event_join',
EVENT_LEAVE = 'event_leave',
EVENT_CHECKIN = 'event_checkin',
EVENT_VIEW = 'event_view',
EVENT_SEARCH = 'event_search',
// Form Management
FORM_CREATE = 'form_create',
FORM_UPDATE = 'form_update',
FORM_DELETE = 'form_delete',
FORM_SUBMIT = 'form_submit',
FORM_VIEW = 'form_view',
FORM_EXPORT = 'form_export',
// Verification Actions
TRAINER_VERIFY = 'trainer_verify',
TRAINER_REJECT = 'trainer_reject',
ORG_VERIFY = 'organization_verify',
ORG_REJECT = 'organization_reject',
// Document Actions
DOCUMENT_UPLOAD = 'document_upload',
DOCUMENT_VIEW = 'document_view',
// Analytics
ANALYTICS_VIEW = 'analytics_view',
REPORT_EXPORT = 'report_export',
// API Actions
API_ERROR = 'api_error',
UNAUTHORIZED_ACCESS = 'unauthorized_access'
}
export enum ActivityCategory {
AUTH = 'authentication',
PROFILE = 'profile',
EVENT = 'event',
FORM = 'form',
VERIFICATION = 'verification',
ANALYTICS = 'analytics',
SYSTEM = 'system'
}
interface IActivityMetadata {
// Request details
ipAddress?: string;
userAgent?: string;
device?: string;
browser?: string;
// Resource references
eventId?: Types.ObjectId;
formId?: Types.ObjectId;
organizationId?: Types.ObjectId;
trainerId?: Types.ObjectId;
// Action-specific data
changes?: Record<string, any>; // For updates
errorMessage?: string; // For errors
statusCode?: number;
// Geographic data
location?: {
type: "Point";
coordinates: [number, number];
};
// Additional context
duration?: number; // milliseconds
method?: string; // HTTP method
endpoint?: string; // API endpoint
queryParams?: Record<string, any>;
responseSize?: number; // bytes
}
export interface IUserActivity extends Document {
user: Types.ObjectId;
action: ActivityAction;
category: ActivityCategory;
description: string;
metadata: IActivityMetadata;
timestamp: Date;
sessionId?: string; // Track user sessions
success: boolean;
createdAt: Date;
}
const UserActivitySchema = new Schema<IUserActivity>({
user: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true,
index: true
},
action: {
type: String,
enum: Object.values(ActivityAction),
required: true,
index: true
},
category: {
type: String,
enum: Object.values(ActivityCategory),
required: true,
index: true
},
description: {
type: String,
required: true
},
metadata: {
ipAddress: String,
userAgent: String,
device: String,
browser: String,
eventId: {
type: Schema.Types.ObjectId,
ref: 'Event'
},
formId: {
type: Schema.Types.ObjectId,
ref: 'Form'
},
organizationId: {
type: Schema.Types.ObjectId,
ref: 'User'
},
trainerId: {
type: Schema.Types.ObjectId,
ref: 'User'
},
changes: Schema.Types.Mixed,
errorMessage: String,
statusCode: Number,
location: {
type: {
type: String,
enum: ['Point']
},
coordinates: [Number]
},
duration: Number,
method: String,
endpoint: String,
queryParams: Schema.Types.Mixed,
responseSize: Number
},
timestamp: {
type: Date,
default: Date.now,
index: true
},
sessionId: {
type: String,
index: true
},
success: {
type: Boolean,
default: true,
index: true
}
}, {
timestamps: { createdAt: true, updatedAt: false }
});
// Compound indexes for common queries
UserActivitySchema.index({ user: 1, timestamp: -1 });
UserActivitySchema.index({ user: 1, category: 1, timestamp: -1 });
UserActivitySchema.index({ user: 1, action: 1, timestamp: -1 });
UserActivitySchema.index({ sessionId: 1, timestamp: -1 });
UserActivitySchema.index({ 'metadata.eventId': 1 });
UserActivitySchema.index({ 'metadata.formId': 1 });
// TTL index - automatically delete logs older than 2 years
UserActivitySchema.index({ timestamp: 1 }, { expireAfterSeconds: 63072000 });
export default model<IUserActivity>('UserActivity', UserActivitySchema);