Documentation Index Fetch the complete documentation index at: https://mintlify.com/emmanueljarquin-sys/GrupoMecsaCMS/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Grupo Mecsa CMS uses a flexible role-based access control (RBAC) system where each employee is assigned a role that determines their access to different modules and features. Roles are stored in the Empleados table and referenced throughout the system.
Standard Roles
The system includes six predefined standard roles that cannot be deleted:
Administrador Full system access with ability to manage users, roles, and all modules
Ventas Access to sales-related modules including clients and opportunities
Proyectos Project management access with ability to view and edit project data
Recepción Reception desk access for basic customer service features
Mercadeo Marketing team access for content, blog, and SEO management
Contabilidad Accounting access for financial modules and reports
Role Structure
Database Schema
Roles are stored in the Empleados table in the public schema:
CREATE TABLE public . "Empleados" (
id UUID PRIMARY KEY ,
nombre VARCHAR ,
apellido VARCHAR ,
email VARCHAR UNIQUE ,
rol VARCHAR , -- Role name (e.g., 'Administrador', 'Ventas')
chat_role VARCHAR ,
departamento VARCHAR ,
activo BOOLEAN DEFAULT true,
sistemas_acceso JSONB -- Array of accessible systems ['CMS', 'Chat', etc.]
);
Session Storage
Role information is stored in the session after login:
$_SESSION [ 'rol' ] = $uData [ 'rol' ] ?? '' ;
$_SESSION [ 'chat_role' ] = $uData [ 'chat_role' ] ?? '' ;
$_SESSION [ 'nombre' ] = $uData [ 'nombre' ] ?? '' ;
Role Management Interface
Administrators can manage roles through the admin_roles.php interface.
Fetching Available Roles
The system fetches roles with user counts:
admin_roles_api.php:36-72
if ( $action === 'get_roles' ) {
// Get roles with user counts from Empleados table
$res = supabase_request_service ( 'GET' ,
'Empleados?select=rol&activo=eq.true' ,
null ,
[ 'Accept-Profile: public' ]
);
$roles_raw = ( $res [ 'http' ] === 200 && is_array ( $res [ 'json' ])) ? $res [ 'json' ] : [];
// Count users per role
$counts = [];
foreach ( $roles_raw as $r ) {
$rol = strtolower ( trim ( $r [ 'rol' ] ?? '' ));
if ( $rol === '' ) continue ;
$counts [ $rol ] = ( $counts [ $rol ] ?? 0 ) + 1 ;
}
$standard = [ 'ventas' , 'proyectos' , 'administrador' , 'recepcion' , 'mercadeo' , 'contabilidad' ];
$result = [];
// Add standard roles first
foreach ( $standard as $s ) {
$result [] = [
'nombre' => $s ,
'total' => $counts [ $s ] ?? 0 ,
'is_standard' => true
];
}
// Add custom roles
foreach ( $counts as $nombre => $total ) {
if ( ! in_array ( $nombre , $standard )) {
$result [] = [
'nombre' => $nombre ,
'total' => $total ,
'is_standard' => false
];
}
}
echo json_encode ([ 'success' => true , 'roles' => $result ]);
}
Standard roles are always displayed first, followed by any custom roles that have been created.
Creating New Roles
Administrators can create custom roles:
admin_roles_api.php:117-136
if ( $action === 'create_rol' ) {
$rol_nombre = trim ( $input [ 'rol_nombre' ] ?? '' );
if ( empty ( $rol_nombre )) {
echo json_encode ([ 'success' => false , 'error' => 'Nombre de rol requerido' ]);
exit ;
}
// Define default views for new roles
$vistas = [
'dashboard' , 'usuarios' , 'categorias' , 'clientes' , 'proyectos' , 'empleados' ,
'departamentos' , 'testimoniales' , 'preguntas' , 'contenido' , 'templates' ,
'menus' , 'pages' , 'media' , 'seo' , 'blog' , 'vacantes' , 'contactos'
];
$rows = [];
foreach ( $vistas as $v ) {
$rows [] = [
'rol_nombre' => $rol_nombre ,
'vista_slug' => $v ,
'puede_ver' => false
];
}
$res = supabase_request_service ( 'POST' , 'rol_permisos' , $rows );
echo json_encode ([ 'success' => ( $res [ 'http' ] >= 200 && $res [ 'http' ] < 300 )]);
}
When a new role is created, it’s automatically assigned permission entries for all system views with puede_ver set to false. Administrators must then configure the permissions.
Deleting Custom Roles
Only custom roles without assigned users can be deleted:
admin_roles_api.php:139-149
if ( $action === 'delete_rol' ) {
$rol_nombre = trim ( $input [ 'rol_nombre' ] ?? '' );
// Check if role has assigned users
$chk = supabase_request_service ( 'GET' ,
"Empleados?rol=eq." . urlencode ( $rol_nombre ) . "&select=id&limit=1" ,
null ,
[ 'Accept-Profile: public' ]
);
if ( $chk [ 'http' ] === 200 && ! empty ( $chk [ 'json' ])) {
echo json_encode ([ 'success' => false , 'error' => 'El rol tiene usuarios asignados' ]);
exit ;
}
supabase_request_service ( ' DELETE ' , "rol_permisos?rol_nombre=eq." . urlencode ( $rol_nombre ));
echo json_encode ([ 'success' => true ]);
}
Standard roles cannot be deleted. Custom roles can only be deleted if no employees are currently assigned to them.
Assigning Roles to Users
Roles are assigned through the employee management interface:
update_employee_role.php:25-38
$id = $_POST [ 'id' ] ?? '' ;
$rol = trim ( $_POST [ 'rol' ] ?? '' );
$chat_role = trim ( $_POST [ 'chat_role' ] ?? '' );
$departamento = trim ( $_POST [ 'departamento' ] ?? '' );
if ( empty ( $id )) {
http_response_code ( 400 );
echo json_encode ([ 'success' => false , 'error' => 'ID requerido' ]);
exit ;
}
$payload = [];
if ( $rol !== '' ) $payload [ 'rol' ] = $rol ;
if ( $chat_role !== '' ) $payload [ 'chat_role' ] = $chat_role ;
if ( $departamento !== '' ) $payload [ 'departamento' ] = $departamento ;
$res = supabase_request_service ( 'PATCH' , "Empleados?id=eq. $id " , $payload , [ 'Accept-Profile: public' ]);
Role Resolution
The system uses resolve_user.php to determine the current user’s role and permissions:
// Normalize and calculate permissions
$uRole = strtolower ( trim ( $cms_user_role ));
$uEmail = strtolower ( trim ( $cms_user_email ));
// Emergency admin bypass
$isEmmanuel = (
$uEmail === 'emmanuel.jarquin@grupomecsa.net' ||
$uEmail === 'emmanueljarquin@hotmail.com' ||
$uEmail === 'emmanuelerj@gmail.com'
);
// Role mapping
$is_admin = ( $uRole === 'administrador' || $uRole === 'admin' ) || $isEmmanuel ;
$is_rrhh = ( $uRole === 'rh' || $uRole === 'rrhh' || $uRole === 'recursos humanos' );
$is_proyecto = ( $uRole === 'proyectos' || $uRole === 'proyecto' ||
$uRole === 'proyectos_edicion' || $uRole === 'proyectos_lectura' );
$is_comercial = ( $uRole === 'ventas' || $uRole === 'comercial' );
Permission Variables
The resolve script provides these boolean variables for permission checks:
Variable Description $is_adminTrue if user is administrator $is_rrhhTrue if user is Human Resources $is_proyectoTrue if user has project role $is_comercialTrue if user has sales role $is_staffTrue if user has any valid role
Role-Based Page Protection
Pages can require specific roles using the resolve script:
session_start ();
if ( ! isset ( $_SESSION [ 'token' ])) {
header ( "Location: ../login.php" );
exit ;
}
require_once __DIR__ . '/../functions/resolve_user.php' ;
if ( ! $is_admin ) {
http_response_code ( 403 );
die ( "Acceso denegado. Se requieren permisos de administrador." );
}
Include resolve_user.php
The script loads and evaluates the current user’s role.
Check permission variable
Use $is_admin, $is_rrhh, etc. to verify access.
Deny or allow access
Return 403 error or allow page to load based on role check.
Role Icons and Display
The admin interface uses icons for visual role identification:
const icons = {
'ventas' : 'fa-dollar-sign' ,
'proyectos' : 'fa-hard-hat' ,
'administrador' : 'fa-crown' ,
'recepcion' : 'fa-concierge-bell' ,
'mercadeo' : 'fa-ad' ,
'contabilidad' : 'fa-file-invoice-dollar'
};
const defaultIcon = 'fa-user-tag' ;
const roleIcon = icons [ r . nombre . toLowerCase ()] || defaultIcon ;
Systems Access
In addition to roles, users have a sistemas_acceso field that controls which systems they can access:
update_employee_role.php:45-66
if ( $activo !== null ) {
// Fetch current systems
$resGet = supabase_request_service ( 'GET' ,
"Empleados?id=eq. $id &select=sistemas_acceso" ,
null ,
[ 'Accept-Profile: public' ]
);
if ( $resGet [ 'http' ] === 200 && ! empty ( $resGet [ 'json' ])) {
$sistemas = $resGet [ 'json' ][ 0 ][ 'sistemas_acceso' ] ?? [];
if ( is_string ( $sistemas )) {
$sistemas = json_decode ( $sistemas , true ) ?: [];
}
$brand = 'CMS' ;
if ( $activo ) {
// Add CMS access
if ( ! in_array ( $brand , $sistemas ) && ! in_array ( 'cms' , $sistemas )) {
$sistemas [] = $brand ;
}
} else {
// Remove CMS access
$sistemas = array_values ( array_filter ( $sistemas ,
fn ( $s ) => strtoupper ( $s ) !== $brand
));
}
$payload [ 'sistemas_acceso' ] = $sistemas ;
$payload [ 'activo' ] = $activo ;
}
}
The sistemas_acceso field is a JSON array that can contain values like ['CMS', 'Chat', 'Portal']. Users must have ‘CMS’ in this array to access the CMS, regardless of their role.
Best Practices
Principle of Least Privilege Assign users only the roles they need to perform their job functions
Regular Audits Periodically review role assignments and remove unnecessary access
Custom Roles Create specific roles for unique access patterns rather than modifying standard roles
Documentation Document what each role can access for training and compliance