Dealer_Onboarding_Backend/src/modules/admin/admin.controller.ts

243 lines
8.3 KiB
TypeScript

import { Request, Response } from 'express';
import db from '../../database/models/index.js';
const { Role, Permission, RolePermission, User, DealerCode, AuditLog } = db;
import { AUDIT_ACTIONS } from '../../common/config/constants.js';
import { AuthRequest } from '../../types/express.types.js';
// --- Roles Management ---
export const getRoles = async (req: Request, res: Response) => {
try {
const roles = await Role.findAll({
include: [
{
model: Permission,
as: 'permissions',
through: { attributes: [] }
},
{
model: User,
as: 'users',
attributes: ['id']
}
],
order: [['roleName', 'ASC']]
});
// Map to include userCount
const result = roles.map((r: any) => ({
...r.toJSON(),
userCount: r.users?.length || 0
}));
res.json({ success: true, data: result });
} catch (error) {
console.error('Get roles error:', error);
res.status(500).json({ success: false, message: 'Error fetching roles' });
}
};
export const createRole = async (req: AuthRequest, res: Response) => {
try {
const { roleCode, roleName, description, permissionIds } = req.body; // permissionIds: string[]
const role = await Role.create({ roleCode, roleName, description });
if (permissionIds && permissionIds.length > 0) {
for (const pid of permissionIds) {
await RolePermission.create({
roleId: role.id,
permissionId: pid
});
}
}
await AuditLog.create({
userId: req.user?.id,
action: AUDIT_ACTIONS.CREATED,
entityType: 'role',
entityId: role.id,
newData: req.body
});
res.status(201).json({ success: true, data: role, message: 'Role created successfully' });
} catch (error) {
console.error('Create role error:', error);
res.status(500).json({ success: false, message: 'Error creating role' });
}
};
export const updateRole = async (req: AuthRequest, res: Response) => {
try {
const { id } = req.params;
const { roleName, description, permissionIds, isActive } = req.body;
const role = await Role.findByPk(id);
if (!role) return res.status(404).json({ success: false, message: 'Role not found' });
await role.update({ roleName, description, isActive });
if (permissionIds) {
// Remove existing permissions and re-add new ones
await RolePermission.destroy({ where: { roleId: id } });
for (const pid of permissionIds) {
await RolePermission.create({
roleId: id,
permissionId: pid
});
}
}
await AuditLog.create({
userId: req.user?.id,
action: AUDIT_ACTIONS.UPDATED,
entityType: 'role',
entityId: id,
newData: req.body
});
res.json({ success: true, message: 'Role updated successfully' });
} catch (error) {
console.error('Update role error:', error);
res.status(500).json({ success: false, message: 'Error updating role' });
}
};
// --- Permissions Management ---
export const getPermissions = async (req: Request, res: Response) => {
try {
const permissions = await Permission.findAll({ order: [['module', 'ASC']] });
res.json({ success: true, data: permissions });
} catch (error) {
console.error('Get permissions error:', error);
res.status(500).json({ success: false, message: 'Error fetching permissions' });
}
};
// --- User Management (Admin) ---
export const getAllUsers = async (req: Request, res: Response) => {
try {
const users = await User.findAll({
attributes: { exclude: ['password'] },
include: [
{
model: Role,
as: 'role',
include: [
{
model: Permission,
as: 'permissions',
through: { attributes: [] }
}
]
},
{ model: db.Zone, as: 'zone' },
{ model: db.Region, as: 'region' },
{ model: db.Area, as: 'area' }
],
order: [['createdAt', 'DESC']]
});
res.json({ success: true, data: users });
} catch (error) {
console.error('Get users error:', error);
res.status(500).json({ success: false, message: 'Error fetching users' });
}
};
export const updateUserStatus = async (req: AuthRequest, res: Response) => {
try {
const { id } = req.params;
const { status, isActive } = req.body;
const user = await User.findByPk(id);
if (!user) return res.status(404).json({ success: false, message: 'User not found' });
await user.update({ status, isActive });
await AuditLog.create({
userId: req.user?.id,
action: AUDIT_ACTIONS.UPDATED,
entityType: 'user',
entityId: id,
newData: { status, isActive }
});
res.json({ success: true, message: 'User status updated' });
} catch (error) {
console.error('Update user status error:', error);
res.status(500).json({ success: false, message: 'Error updating user status' });
}
};
export const updateUser = async (req: AuthRequest, res: Response) => {
try {
const { id } = req.params;
const {
fullName, email, roleCode, status, isActive, employeeId,
mobileNumber, department, designation,
zoneId, regionId, stateId, districtId, areaId
} = req.body;
const user = await User.findByPk(id);
if (!user) return res.status(404).json({ success: false, message: 'User not found' });
const oldData = user.toJSON();
await user.update({
fullName: fullName || user.fullName,
email: email || user.email,
roleCode: roleCode || user.roleCode,
status: status || user.status,
isActive: isActive !== undefined ? isActive : user.isActive,
employeeId: employeeId || user.employeeId,
mobileNumber: mobileNumber || user.mobileNumber,
department: department || user.department,
designation: designation || user.designation,
zoneId: zoneId !== undefined ? zoneId : user.zoneId,
regionId: regionId !== undefined ? regionId : user.regionId,
stateId: stateId !== undefined ? stateId : user.stateId,
districtId: districtId !== undefined ? districtId : user.districtId,
areaId: areaId !== undefined ? areaId : user.areaId
});
await AuditLog.create({
userId: req.user?.id,
action: AUDIT_ACTIONS.UPDATED,
entityType: 'user',
entityId: id,
oldData,
newData: req.body
});
res.json({ success: true, message: 'User updated successfully', data: user });
} catch (error) {
console.error('Update user error:', error);
res.status(500).json({ success: false, message: 'Error updating user' });
}
};
// --- Dealer Codes ---
export const generateDealerCode = async (req: AuthRequest, res: Response) => {
try {
const { regionId, stateId, channel } = req.body;
// Logic to generate unique code based on format (e.g., RE-[Region]-[State]-[Seq])
// This is a placeholder for the actual business logic
const timestamp = Date.now().toString().slice(-6);
const code = `DLR-${timestamp}`;
const dealerCode = await DealerCode.create({
code,
isUsed: false,
generatedBy: req.user?.id
});
res.status(201).json({ success: true, data: dealerCode });
} catch (error) {
console.error('Generate dealer code error:', error);
res.status(500).json({ success: false, message: 'Error generating dealer code' });
}
};