const Admin = require('../models/Admin'); const AuditLog = require('../models/AuditLog'); exports.list = async () => { return Admin.find().populate('assignedMarkets', 'name code').sort('profile.firstName'); }; exports.create = async ({ email, password, role, profile, assignedMarkets }, actorId, ip) => { if (!email || !password || !role) throw Object.assign(new Error('Email, password, and role are required.'), { statusCode: 400 }); if (password.length < 12) throw Object.assign(new Error('Password must be at least 12 characters.'), { statusCode: 400 }); const admin = await Admin.create({ email, passwordHash: password, role, profile, assignedMarkets: assignedMarkets || [], }); await admin.populate('assignedMarkets', 'name code'); await AuditLog.create({ action: 'admin_user_created', actor: actorId, targetType: 'admin', targetId: admin._id, details: { role, email }, ipAddress: ip }); return admin; }; exports.update = async (id, { role, profile, assignedMarkets, password }, actorId, ip) => { const admin = await Admin.findById(id); if (!admin) throw Object.assign(new Error('Admin user not found.'), { statusCode: 404 }); if (role) admin.role = role; if (profile) admin.profile = { ...admin.profile.toObject?.() || admin.profile, ...profile }; if (assignedMarkets) admin.assignedMarkets = assignedMarkets; if (password) { if (password.length < 12) throw Object.assign(new Error('Password must be at least 12 characters.'), { statusCode: 400 }); admin.passwordHash = password; } await admin.save(); await admin.populate('assignedMarkets', 'name code'); await AuditLog.create({ action: 'admin_user_updated', actor: actorId, targetType: 'admin', targetId: admin._id, details: { updatedFields: Object.keys({ role, profile, assignedMarkets, password }).filter(k => arguments[1][k]) }, ipAddress: ip }); return admin; }; exports.deactivate = async (id, actorId, ip) => { const admin = await Admin.findById(id); if (!admin) throw Object.assign(new Error('Admin user not found.'), { statusCode: 404 }); if (admin._id.toString() === actorId.toString()) { throw Object.assign(new Error('You cannot deactivate your own account.'), { statusCode: 400 }); } admin.accountStatus = 'deactivated'; admin.refreshToken = null; await admin.save({ validateModifiedOnly: true }); await AuditLog.create({ action: 'admin_user_deactivated', actor: actorId, targetType: 'admin', targetId: admin._id, ipAddress: ip }); }; exports.getAuditLog = async (id) => { const admin = await Admin.findById(id).select('email profile loginAudit'); if (!admin) throw Object.assign(new Error('Admin user not found.'), { statusCode: 404 }); const auditEntries = await AuditLog.find({ actor: id }).sort({ timestamp: -1 }).limit(100); return { admin: { email: admin.email, profile: admin.profile }, loginAudit: admin.loginAudit.slice(-20), auditEntries }; };