Initial project setup

This commit is contained in:
Gowtham M 2026-06-17 12:54:24 +05:30
commit 69588c1889
4 changed files with 36 additions and 13 deletions

View File

@ -363,12 +363,10 @@ components:
module_id: { type: integer, example: 1 }
actions:
type: object
required: [view, create, edit, delete, approve, export]
required: [view, edit, approve, export]
properties:
view: { type: boolean, example: true }
create: { type: boolean, example: true }
edit: { type: boolean, example: true }
delete: { type: boolean, example: false }
edit: { type: boolean, example: true, description: 'Add & edit (grants create + edit)' }
approve: { type: boolean, example: false }
export: { type: boolean, example: true }
@ -1619,7 +1617,7 @@ paths:
schema: { type: string }
get:
tags: [Roles]
summary: Permission matrix for role (modules x actions checkboxes)
summary: Permission matrix for role (modules x view/edit/approve/export; edit = add + edit)
responses:
"200":
description: Matrix fetched

View File

@ -23,7 +23,7 @@ router.get(
controller.list
);
router.get('/:id', authorize('ROLES', 'view'), controller.getOne);
router.post('/', authorize('ROLES', 'create'), validate(createRoleSchema), controller.create);
router.post('/', authorize('ROLES', 'edit'), validate(createRoleSchema), controller.create);
router.put('/:id', authorize('ROLES', 'edit'), validate(updateRoleSchema), controller.update);
router.put(
'/:id/permissions',
@ -38,6 +38,6 @@ router.put(
validate(permissionMatrixSchema),
controller.savePermissionMatrix
);
router.delete('/:id', authorize('ROLES', 'delete'), controller.remove);
router.delete('/:id', authorize('ROLES', 'edit'), controller.remove);
module.exports = router;

View File

@ -3,7 +3,8 @@ const ApiError = require('../../utils/ApiError');
const auditLog = require('../../utils/auditLog');
const { getPagination } = require('../../utils/pagination');
const PERMISSION_ACTIONS = ['view', 'create', 'edit', 'delete', 'approve', 'export'];
const MATRIX_ACTIONS = ['view', 'edit', 'approve', 'export'];
const MERGED_EDIT_ACTIONS = ['create', 'edit'];
const permissionSelect = {
permissions: {
@ -293,7 +294,19 @@ const getPermissionMatrix = async (id) => {
const matrix = modules.map((mod) => {
const permissions = {};
for (const action of PERMISSION_ACTIONS) {
for (const action of MATRIX_ACTIONS) {
if (action === 'edit') {
const createPerm = mod.permissions.find((p) => p.action === 'create');
const editPerm = mod.permissions.find((p) => p.action === 'edit');
const merged = [createPerm, editPerm].filter(Boolean);
permissions.edit = {
permission_id: editPerm?.id ?? createPerm?.id ?? null,
permission_ids: merged.map((p) => p.id),
granted: merged.some((p) => granted.has(p.id.toString())),
};
continue;
}
const perm = mod.permissions.find((p) => p.action === action);
permissions[action] = {
permission_id: perm?.id ?? null,
@ -310,7 +323,7 @@ const getPermissionMatrix = async (id) => {
return {
role: { id: role.id, name: role.name },
actions: PERMISSION_ACTIONS,
actions: MATRIX_ACTIONS,
modules: matrix,
};
};
@ -327,8 +340,22 @@ const savePermissionMatrix = async (id, matrix, userId, requestId) => {
const permissionIds = [];
for (const row of matrix) {
for (const action of PERMISSION_ACTIONS) {
for (const action of MATRIX_ACTIONS) {
if (!row.actions?.[action]) continue;
if (action === 'edit') {
for (const dbAction of MERGED_EDIT_ACTIONS) {
const perm = catalog.find(
(p) => p.module_id.toString() === String(row.module_id) && p.action === dbAction
);
if (!perm) {
throw new ApiError(422, `Permission not found for module ${row.module_id}:${dbAction}`);
}
permissionIds.push(perm.id);
}
continue;
}
const perm = catalog.find(
(p) => p.module_id.toString() === String(row.module_id) && p.action === action
);

View File

@ -23,9 +23,7 @@ const permissionMatrixSchema = Joi.object({
module_id: Joi.number().integer().positive().required(),
actions: Joi.object({
view: Joi.boolean().required(),
create: Joi.boolean().required(),
edit: Joi.boolean().required(),
delete: Joi.boolean().required(),
approve: Joi.boolean().required(),
export: Joi.boolean().required(),
}).required(),