import express from 'express'; import bcrypt from 'bcryptjs'; import db from '../config/database.js'; import { authenticateToken, authorize } from '../middleware/auth.js'; const router = express.Router(); // Get all users (with filters) router.get('/', authenticateToken, async (req, res) => { try { const { role, departmentId } = req.query; let query = ` SELECT u.id, u.username, u.name, u.email, u.role, u.department_id, u.contractor_id, u.is_active, u.created_at, d.name as department_name, c.name as contractor_name FROM users u LEFT JOIN departments d ON u.department_id = d.id LEFT JOIN users c ON u.contractor_id = c.id WHERE 1=1 `; const params = []; // Supervisors can only see users in their department if (req.user.role === 'Supervisor') { query += ' AND u.department_id = ?'; params.push(req.user.departmentId); } if (role) { query += ' AND u.role = ?'; params.push(role); } if (departmentId) { query += ' AND u.department_id = ?'; params.push(departmentId); } query += ' ORDER BY u.created_at DESC'; const [users] = await db.query(query, params); res.json(users); } catch (error) { console.error('Get users error:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Get user by ID router.get('/:id', authenticateToken, async (req, res) => { try { const [users] = await db.query( `SELECT u.id, u.username, u.name, u.email, u.role, u.department_id, u.contractor_id, u.is_active, u.created_at, d.name as department_name, c.name as contractor_name FROM users u LEFT JOIN departments d ON u.department_id = d.id LEFT JOIN users c ON u.contractor_id = c.id WHERE u.id = ?`, [req.params.id] ); if (users.length === 0) { return res.status(404).json({ error: 'User not found' }); } // Supervisors can only view users in their department if (req.user.role === 'Supervisor' && users[0].department_id !== req.user.departmentId) { return res.status(403).json({ error: 'Access denied' }); } res.json(users[0]); } catch (error) { console.error('Get user error:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Create user router.post('/', authenticateToken, authorize('SuperAdmin', 'Supervisor'), async (req, res) => { try { const { username, name, email, password, role, departmentId, contractorId } = req.body; if (!username || !name || !email || !password || !role) { return res.status(400).json({ error: 'Missing required fields' }); } // Supervisors can only create users in their department if (req.user.role === 'Supervisor') { if (departmentId !== req.user.departmentId) { return res.status(403).json({ error: 'Can only create users in your department' }); } if (role === 'SuperAdmin' || role === 'Supervisor') { return res.status(403).json({ error: 'Cannot create admin or supervisor users' }); } } const hashedPassword = await bcrypt.hash(password, 10); const [result] = await db.query( 'INSERT INTO users (username, name, email, password, role, department_id, contractor_id) VALUES (?, ?, ?, ?, ?, ?, ?)', [username, name, email, hashedPassword, role, departmentId || null, contractorId || null] ); const [newUser] = await db.query( `SELECT u.id, u.username, u.name, u.email, u.role, u.department_id, u.contractor_id, u.is_active, u.created_at, d.name as department_name, c.name as contractor_name FROM users u LEFT JOIN departments d ON u.department_id = d.id LEFT JOIN users c ON u.contractor_id = c.id WHERE u.id = ?`, [result.insertId] ); res.status(201).json(newUser[0]); } catch (error) { if (error.code === 'ER_DUP_ENTRY') { return res.status(400).json({ error: 'Username or email already exists' }); } console.error('Create user error:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Update user router.put('/:id', authenticateToken, authorize('SuperAdmin', 'Supervisor'), async (req, res) => { try { const { name, email, role, departmentId, contractorId, isActive } = req.body; // Check if user exists const [existingUsers] = await db.query('SELECT * FROM users WHERE id = ?', [req.params.id]); if (existingUsers.length === 0) { return res.status(404).json({ error: 'User not found' }); } // Supervisors can only update users in their department if (req.user.role === 'Supervisor') { if (existingUsers[0].department_id !== req.user.departmentId) { return res.status(403).json({ error: 'Can only update users in your department' }); } if (role === 'SuperAdmin' || role === 'Supervisor') { return res.status(403).json({ error: 'Cannot modify admin or supervisor roles' }); } } const updates = []; const params = []; if (name !== undefined) { updates.push('name = ?'); params.push(name); } if (email !== undefined) { updates.push('email = ?'); params.push(email); } if (role !== undefined) { updates.push('role = ?'); params.push(role); } if (departmentId !== undefined) { updates.push('department_id = ?'); params.push(departmentId); } if (contractorId !== undefined) { updates.push('contractor_id = ?'); params.push(contractorId); } if (isActive !== undefined) { updates.push('is_active = ?'); params.push(isActive); } if (updates.length === 0) { return res.status(400).json({ error: 'No fields to update' }); } params.push(req.params.id); await db.query( `UPDATE users SET ${updates.join(', ')} WHERE id = ?`, params ); const [updatedUser] = await db.query( `SELECT u.id, u.username, u.name, u.email, u.role, u.department_id, u.contractor_id, u.is_active, u.created_at, d.name as department_name, c.name as contractor_name FROM users u LEFT JOIN departments d ON u.department_id = d.id LEFT JOIN users c ON u.contractor_id = c.id WHERE u.id = ?`, [req.params.id] ); res.json(updatedUser[0]); } catch (error) { console.error('Update user error:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Delete user router.delete('/:id', authenticateToken, authorize('SuperAdmin', 'Supervisor'), async (req, res) => { try { const [users] = await db.query('SELECT * FROM users WHERE id = ?', [req.params.id]); if (users.length === 0) { return res.status(404).json({ error: 'User not found' }); } // Supervisors can only delete users in their department if (req.user.role === 'Supervisor') { if (users[0].department_id !== req.user.departmentId) { return res.status(403).json({ error: 'Can only delete users in your department' }); } if (users[0].role === 'SuperAdmin' || users[0].role === 'Supervisor') { return res.status(403).json({ error: 'Cannot delete admin or supervisor users' }); } } await db.query('DELETE FROM users WHERE id = ?', [req.params.id]); res.json({ message: 'User deleted successfully' }); } catch (error) { console.error('Delete user error:', error); res.status(500).json({ error: 'Internal server error' }); } }); export default router;