// FILE: backend/src/routes/rbac_admin.js import { Router } from "express"; import { Role, Permission, UserProjectRole, Project } from "../db/sequelize.js"; import { authJwt } from "../middleware/authJwt.js"; import { loadPrincipalMw } from "../middleware/loadPrincipal.js"; // แก้ไข: import ให้ถูกต้อง import { requirePerm } from "../middleware/requirePerm.js"; const router = Router(); // Middleware Chain ที่ถูกต้อง 100% ตามสถาปัตยกรรมของคุณ router.use(authJwt(), loadPrincipalMw()); // == ROLES Management == router.get("/roles", requirePerm("roles.manage"), async (req, res, next) => { try { const roles = await Role.findAll({ include: [{ model: Permission, attributes: ["id", "name"], through: { attributes: [] } }], order: [["name", "ASC"]], }); res.json(roles); } catch (error) { next(error); } }); router.post("/roles", requirePerm("roles.manage"), async (req, res, next) => { const { name, description } = req.body; if (!name) return res.status(400).json({ message: "Role name is required." }); try { const newRole = await Role.create({ name, description }); res.status(201).json(newRole); } catch (error) { if (error.name === "SequelizeUniqueConstraintError") { return res.status(409).json({ message: `Role '${name}' already exists.` }); } next(error); } }); router.put("/roles/:id/permissions", requirePerm("roles.manage"), async (req, res, next) => { const { permissionIds } = req.body; if (!Array.isArray(permissionIds)) return res.status(400).json({ message: "permissionIds must be an array." }); try { const role = await Role.findByPk(req.params.id); if (!role) return res.status(404).json({ message: "Role not found." }); await role.setPermissions(permissionIds); const updatedRole = await Role.findByPk(req.params.id, { include: [{ model: Permission, attributes: ['id', 'name'], through: { attributes: [] } }] }); res.json(updatedRole); } catch (error) { next(error); } }); // == USER-PROJECT-ROLES Management == router.get("/user-project-roles", requirePerm("users.manage"), async (req, res, next) => { const { userId } = req.query; if (!userId) return res.status(400).json({ message: "userId query parameter is required." }); try { const assignments = await UserProjectRole.findAll({ where: { user_id: userId }, include: [ { model: Project, attributes: ["id", "name"] }, { model: Role, attributes: ["id", "name"] } ], }); res.json(assignments); } catch (error) { next(error); } }); router.post("/user-project-roles", requirePerm("users.manage"), async (req, res, next) => { const { userId, projectId, roleId } = req.body; if (!userId || !projectId || !roleId) return res.status(400).json({ message: "userId, projectId, and roleId are required." }); try { const [assignment, created] = await UserProjectRole.findOrCreate({ where: { user_id: userId, project_id: projectId, role_id: roleId }, defaults: { user_id: userId, project_id: projectId, role_id: roleId }, }); if (!created) return res.status(409).json({ message: "This assignment already exists." }); res.status(201).json(assignment); } catch (error) { next(error); } }); router.delete("/user-project-roles", requirePerm("users.manage"), async (req, res, next) => { const { userId, projectId, roleId } = req.body; if (!userId || !projectId || !roleId) return res.status(400).json({ message: "userId, projectId, and roleId are required." }); try { const deletedCount = await UserProjectRole.destroy({ where: { user_id: userId, project_id: projectId, role_id: roleId } }); if (deletedCount === 0) return res.status(404).json({ message: 'Assignment not found.' }); res.status(204).send(); } catch (error) { next(error); } }); export default router;