95 lines
2.2 KiB
JavaScript
95 lines
2.2 KiB
JavaScript
const mongoose = require('mongoose');
|
|
|
|
const auditLogSchema = new mongoose.Schema({
|
|
action: {
|
|
type: String,
|
|
required: true,
|
|
enum: [
|
|
'CREATE', 'UPDATE', 'DELETE', 'RESTORE',
|
|
'LOGIN', 'LOGOUT', 'LOGIN_FAILED',
|
|
'IMPORT', 'EXPORT', 'BULK_UPDATE', 'BULK_DELETE',
|
|
'PASSWORD_RESET', 'PASSWORD_CHANGE'
|
|
],
|
|
index: true
|
|
},
|
|
resource: {
|
|
type: String,
|
|
required: true,
|
|
enum: ['User', 'Config', 'Admin', 'Stoeberhundefuehrer'],
|
|
index: true
|
|
},
|
|
resourceId: {
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
index: true
|
|
},
|
|
resourceName: {
|
|
type: String,
|
|
default: null
|
|
},
|
|
adminId: {
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
ref: 'Admin',
|
|
index: true
|
|
},
|
|
adminUsername: {
|
|
type: String,
|
|
index: true
|
|
},
|
|
// Pre-change snapshot (UPDATE only)
|
|
before: {
|
|
type: mongoose.Schema.Types.Mixed,
|
|
default: null
|
|
},
|
|
// Post-change snapshot (UPDATE only)
|
|
after: {
|
|
type: mongoose.Schema.Types.Mixed,
|
|
default: null
|
|
},
|
|
// Field-level diff: { fieldName: { before, after } }
|
|
changes: {
|
|
type: mongoose.Schema.Types.Mixed,
|
|
default: null
|
|
},
|
|
// HTTP context
|
|
requestMethod: { type: String },
|
|
requestPath: { type: String },
|
|
statusCode: { type: Number, index: true },
|
|
duration: { type: Number }, // ms
|
|
// Extra context: import stats, export format, bulk count, etc.
|
|
metadata: {
|
|
type: mongoose.Schema.Types.Mixed,
|
|
default: null
|
|
},
|
|
ipAddress: {
|
|
type: String,
|
|
index: true
|
|
},
|
|
userAgent: String,
|
|
success: {
|
|
type: Boolean,
|
|
default: true,
|
|
index: true
|
|
},
|
|
errorMessage: String
|
|
}, {
|
|
timestamps: true
|
|
});
|
|
|
|
auditLogSchema.index({ createdAt: -1 });
|
|
auditLogSchema.index({ adminId: 1, createdAt: -1 });
|
|
auditLogSchema.index({ resource: 1, action: 1, createdAt: -1 });
|
|
auditLogSchema.index({ success: 1, createdAt: -1 });
|
|
auditLogSchema.index({ adminUsername: 1, createdAt: -1 });
|
|
|
|
auditLogSchema.statics.log = async function(data) {
|
|
try {
|
|
return await this.create(data);
|
|
} catch (error) {
|
|
const logger = require('../utils/logger');
|
|
logger.error('Failed to create audit log:', error);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
module.exports = mongoose.model('AuditLog', auditLogSchema);
|