New role that sits between ADMIN and OPERATOR, allowing users to be assigned multiple projects instead of just one. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6.5 KiB
6.5 KiB
Plan: Agregar Rol ORGANISMOS_OPERADORES
Resumen
Agregar un nuevo rol "ORGANISMOS_OPERADORES" que:
- Se ubica entre ADMIN y OPERATOR en la jerarquía
- Permite asignar múltiples proyectos a un usuario (a diferencia de OPERATOR que solo tiene uno)
- Puede ver datos de todos sus proyectos asignados
Fase 1: Base de Datos
1.1 Crear migración SQL
Archivo nuevo: water-api/sql/add_organismos_operadores_role.sql
-- Agregar nuevo valor al enum role_name
ALTER TYPE role_name ADD VALUE 'ORGANISMOS_OPERADORES' AFTER 'ADMIN';
-- Crear tabla user_projects para relación muchos-a-muchos
CREATE TABLE user_projects (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE(user_id, project_id)
);
CREATE INDEX idx_user_projects_user_id ON user_projects(user_id);
CREATE INDEX idx_user_projects_project_id ON user_projects(project_id);
-- Insertar el nuevo rol con permisos
INSERT INTO roles (name, description, permissions) VALUES (
'ORGANISMOS_OPERADORES',
'Organismos Operadores - gestiona múltiples proyectos asignados',
'{
"users": {"create": false, "read": true, "update": false, "delete": false},
"projects": {"create": false, "read": true, "update": true, "delete": false},
"devices": {"create": true, "read": true, "update": true, "delete": false},
"meters": {"create": true, "read": true, "update": true, "delete": false},
"readings": {"create": true, "read": true, "update": false, "delete": false},
"settings": {"create": false, "read": true, "update": false, "delete": false},
"reports": {"create": true, "read": true, "export": true}
}'::JSONB
);
Fase 2: Backend
2.1 Actualizar validador de roles
Archivo: water-api/src/validators/role.validator.ts
- Línea 7: Agregar 'ORGANISMOS_OPERADORES' al enum
export const RoleNameEnum = z.enum(['ADMIN', 'ORGANISMOS_OPERADORES', 'OPERATOR', 'VIEWER']);
2.2 Actualizar tipos
Archivo: water-api/src/types/index.ts
- Agregar
projectIds?: string[]aJwtPayload - Agregar
project_ids?: string[]aUseryUserPublic
2.3 Actualizar servicio de usuarios
Archivo: water-api/src/services/user.service.ts
- Agregar funciones
getUserProjects(userId)ysetUserProjects(userId, projectIds[]) - Modificar
create()para manejarproject_idscuando rol es ORGANISMOS_OPERADORES - Modificar
update()igual - Modificar
getById()ygetAll()para incluir project_ids en respuesta
2.4 Actualizar servicio de autenticación
Archivo: water-api/src/services/auth.service.ts
- En
login(): si rol es ORGANISMOS_OPERADORES, consultaruser_projectsy agregar array al JWT - En
refresh(): mismo cambio - En
getMe(): retornarproject_idsarray
2.5 Actualizar middleware de autenticación
Archivo: water-api/src/middleware/auth.middleware.ts
- Extraer
projectIdsdel JWT y adjuntar areq.user
2.6 Actualizar validador de usuarios
Archivo: water-api/src/validators/user.validator.ts
- Agregar
project_ids: z.array(z.string().uuid()).optional()a schemas
Fase 3: Frontend
3.1 Actualizar API de autenticación
Archivo: src/api/auth.ts
- Agregar
projectIds?: string[]aJwtPayloadyAuthUser - Agregar función
getCurrentUserProjectIds(): string[] | null - Agregar función
isOrganismosOperadores(): boolean
3.2 Actualizar API de usuarios
Archivo: src/api/users.ts
- Agregar
project_ids?: string[]a interfacesUser,CreateUserInput,UpdateUserInput
3.3 Actualizar UsersPage
Archivo: src/pages/UsersPage.tsx
- Agregar
projectIds?: string[]a interfaces - Agregar componente de selección múltiple de proyectos para ORGANISMOS_OPERADORES
- Mantener selector único para OPERATOR
- Validar que se seleccione al menos un proyecto para ORGANISMOS_OPERADORES
3.4 Actualizar Sidebar
Archivo: src/components/layout/Sidebar.tsx
- Agregar
isOrganismosOperadorescheck - ORGANISMOS_OPERADORES puede ver: Dashboard, Proyectos, Medidores, Concentradores, Consumo, Analytics
- ORGANISMOS_OPERADORES NO puede ver: Users Management, Conectores, Auditoría
3.5 Actualizar páginas de datos
Archivos:
src/pages/meters/useMeters.tssrc/pages/consumption/ConsumptionPage.tsxsrc/pages/projects/ProjectsPage.tsx
Cambios en cada archivo:
- Importar
getCurrentUserProjectIds - Filtrar proyectos visibles usando array de IDs
- Permitir cambiar entre proyectos asignados
Orden de Implementación
- SQL Migration - Crear tabla y enum
- Backend Types - Actualizar tipos base
- Backend Validators - Actualizar validaciones
- Backend Services - user.service.ts, auth.service.ts
- Backend Middleware - auth.middleware.ts
- Frontend Auth API - src/api/auth.ts
- Frontend Users API - src/api/users.ts
- Frontend UsersPage - Multi-select UI
- Frontend Sidebar - Visibilidad de menús
- Frontend Data Pages - Filtrado por proyectos
Archivos a Modificar
| Archivo | Cambio |
|---|---|
water-api/sql/add_organismos_operadores_role.sql |
NUEVO - Migración |
water-api/src/validators/role.validator.ts |
Agregar enum value |
water-api/src/validators/user.validator.ts |
Agregar project_ids |
water-api/src/types/index.ts |
Agregar projectIds a tipos |
water-api/src/services/user.service.ts |
Funciones multi-proyecto |
water-api/src/services/auth.service.ts |
ProjectIds en JWT |
water-api/src/middleware/auth.middleware.ts |
Extraer projectIds |
src/api/auth.ts |
Funciones helper |
src/api/users.ts |
Actualizar interfaces |
src/pages/UsersPage.tsx |
Multi-select UI |
src/components/layout/Sidebar.tsx |
Visibilidad menús |
src/pages/meters/useMeters.ts |
Filtrado multi-proyecto |
src/pages/consumption/ConsumptionPage.tsx |
Filtrado multi-proyecto |
src/pages/projects/ProjectsPage.tsx |
Filtrado multi-proyecto |
Verificación
- Base de datos: Ejecutar migración y verificar que el rol existe
- Backend:
- Crear usuario con rol ORGANISMOS_OPERADORES y múltiples proyectos
- Verificar que JWT incluye array de projectIds
- Frontend:
- Verificar multi-select aparece solo para ORGANISMOS_OPERADORES
- Verificar que sidebar muestra/oculta elementos correctamente
- Verificar que páginas de datos filtran por proyectos asignados