243 lines
8.3 KiB
TypeScript
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' });
|
|
}
|
|
};
|