erp-construccion/docs/02-definicion-modulos/MAI-001-fundamentos/requerimientos/RF-AUTH-001-roles-construccion.md
rckrdmrd 7f422e51db
Some checks failed
CI Pipeline / Lint & Type Check (push) Has been cancelled
CI Pipeline / Validate SSOT Constants (push) Has been cancelled
CI Pipeline / Backend Tests (push) Has been cancelled
CI Pipeline / Frontend Tests (push) Has been cancelled
CI Pipeline / Build (push) Has been cancelled
CI Pipeline / Docker Build (push) Has been cancelled
feat: Documentation and orchestration updates
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 05:35:28 -06:00

569 lines
18 KiB
Markdown

# RF-AUTH-001: Sistema de Roles de Construcción
## 📋 Metadata
| Campo | Valor |
|-------|-------|
| **ID** | RF-AUTH-001 |
| **Módulo** | Autenticación y Autorización |
| **Prioridad** | P0 - Crítica |
| **Estado** | 🚧 Planificado |
| **Versión** | 1.0 |
| **Fecha creación** | 2025-11-17 |
| **Última actualización** | 2025-11-17 |
## 🔗 Referencias
### Especificación Técnica
📐 [ET-AUTH-001: RBAC Implementation](../especificaciones/ET-AUTH-001-rbac.md)
### Implementación DDL
🗄️ **ENUM Canónico:**
- **Ubicación:** `apps/database/ddl/00-prerequisites.sql:30-39`
- **Tipo:** `auth_management.construction_role`
- **Valores:** `director`, `engineer`, `resident`, `purchases`, `finance`, `hr`, `post_sales`
🗄️ **Tablas que usan el ENUM:**
1. `auth_management.profiles``apps/database/ddl/schemas/auth_management/tables/03-profiles.sql:15`
2. `auth.users``apps/database/ddl/schemas/auth/tables/01-users.sql:15`
3. `constructoras.user_constructoras``apps/database/ddl/schemas/constructoras/tables/02-user_constructoras.sql:20`
### Backend
💻 **Implementación:**
- **Enum:** `apps/backend/src/shared/enums/construction-role.enum.ts`
- **Guard:** `apps/backend/src/shared/guards/roles.guard.ts`
- **Decorator:** `@Roles('engineer', 'director')`
### Frontend
🎨 **Componentes:**
- **Types:** `apps/frontend/src/types/auth.types.ts`
- **Componentes:**
- `apps/frontend/src/components/auth/RoleBasedRoute.tsx`
- `apps/frontend/src/components/ui/UserRoleBadge.tsx`
- `apps/frontend/src/components/admin/AdminPanel.tsx`
### Reutilización de Catálogo
♻️ **Componente base:** `shared/catalog/auth/` *(Patrón de roles RBAC)*
**Adaptación:** 3 roles base → 7 roles específicos de construcción
---
## 📝 Descripción del Requerimiento
### Contexto
El Sistema de Administración de Obra necesita diferenciar entre **7 tipos de usuarios** con permisos y funcionalidades específicas para la gestión de proyectos de construcción. Esta diferenciación es crítica para:
- Proteger datos sensibles de obras y presupuestos
- Permitir gestión efectiva de recursos por perfil especializado
- Cumplir con segregación de funciones (SOD - Separation of Duties)
- Garantizar trazabilidad de acciones por responsable
### Necesidad del Negocio
**Problema:**
En proyectos de construcción, diferentes actores tienen responsabilidades y necesidades de información distintas:
- **Dirección** necesita visión global de márgenes y riesgos
- **Ingeniería** necesita control de presupuestos y programación
- **Residentes** necesitan capturar avances desde campo
- **Compras** necesita gestionar proveedores e inventarios
- **Finanzas** necesita controlar flujo de efectivo
- **RRHH** necesita gestionar nómina y asistencias
- **Postventa** necesita atender incidencias y garantías
Sin un sistema de roles bien definido, todos tendrían el mismo nivel de acceso, lo cual:
- Comprometería la confidencialidad de datos financieros
- Dificultaría la asignación de responsabilidades
- Impediría auditorías efectivas
- Generaría confusión en permisos
**Solución:**
Implementar un sistema de roles con **7 niveles especializados** de autorización que permita acceso granular basado en función y responsabilidad en la obra.
---
## 🎯 Requerimiento Funcional
### RF-AUTH-001.1: Roles Disponibles
El sistema **DEBE** soportar exactamente 7 roles de usuario especializados en construcción:
#### 1. Director (`director`)
**Descripción:** Director general o de proyectos con visión estratégica
**Permisos:**
- ✅ Visión global de todos los proyectos de la constructora
- ✅ Acceso a márgenes de utilidad y rentabilidad
- ✅ Ver todos los reportes financieros
- ✅ Aprobar presupuestos y modificaciones mayores
- ✅ Acceso a analytics y dashboards ejecutivos
- ✅ Gestionar equipo de proyecto (asignar responsables)
- ✅ Aprobar estimaciones mayores
- ❌ NO edita datos operativos (lo hace ingeniería)
- ❌ NO captura avances (lo hacen residentes)
**Restricciones RLS (Row Level Security):**
```sql
-- Política: Director ve todos los proyectos de su constructora
CREATE POLICY "directors_view_all_projects" ON projects.projects
FOR SELECT
TO authenticated
USING (
constructora_id = get_current_constructora_id()
AND get_current_user_role() = 'director'
);
```
**Casos de Uso:**
- Revisar estado financiero de todas las obras
- Analizar desviaciones de costos
- Tomar decisiones estratégicas (cancelar/continuar obras)
- Aprobar órdenes de cambio mayores
---
#### 2. Ingeniero (`engineer`)
**Descripción:** Ingeniero de planeación, control de obra, o jefe de proyecto
**Permisos:**
- ✅ Todos los permisos de residente
- ✅ Crear y editar presupuestos
- ✅ Gestionar catálogo de conceptos de obra
- ✅ Ver y ajustar programación de obra
- ✅ Generar reportes de avance y desviaciones
- ✅ Revisar estimaciones antes de aprobar
- ✅ Asignar cuadrillas a frentes de trabajo
- ✅ Acceso a módulo de planeación
- ❌ NO puede aprobar estimaciones (solo director/finanzas)
- ❌ NO puede ver márgenes de utilidad detallados
- ❌ NO gestiona compras (lo hace departamento de compras)
**Restricciones RLS:**
```sql
-- Política: Ingeniero ve proyectos donde es responsable o de su área
CREATE POLICY "engineers_view_assigned_projects" ON projects.projects
FOR SELECT
TO authenticated
USING (
get_current_user_role() = 'engineer'
AND (
id IN (
SELECT project_id
FROM projects.project_team_assignments
WHERE user_id = get_current_user_id()
AND role IN ('engineer', 'project_manager')
)
OR constructora_id = get_current_constructora_id()
)
);
```
**Casos de Uso:**
- Elaborar presupuestos por prototipo
- Ajustar precios unitarios
- Revisar avances vs programado
- Generar curva S
- Revisar checklists de calidad
---
#### 3. Residente (`resident`)
**Descripción:** Residente de obra o supervisor de campo
**Permisos:**
- ✅ Capturar avances físicos de obra (desde app móvil)
- ✅ Registrar incidencias y no conformidades
- ✅ Tomar evidencias fotográficas geolocalizadas
- ✅ Completar checklists de actividades
- ✅ Ver programación de su obra
- ✅ Registrar asistencia de empleados (app móvil con biométrico)
- ✅ Solicitar materiales (requisiciones)
- ✅ Ver inventario de su almacén de obra
- ❌ NO puede editar presupuestos
- ❌ NO puede aprobar órdenes de compra
- ❌ NO puede ver datos financieros (costos, márgenes)
- ❌ NO puede ver otras obras (solo las asignadas)
**Restricciones RLS:**
```sql
-- Política: Residente solo ve su(s) obra(s) asignada(s)
CREATE POLICY "residents_view_own_projects" ON projects.projects
FOR SELECT
TO authenticated
USING (
get_current_user_role() = 'resident'
AND id IN (
SELECT project_id
FROM projects.project_team_assignments
WHERE user_id = get_current_user_id()
AND role = 'resident'
AND active = true
)
);
```
**Casos de Uso:**
- Capturar avance de cimentación al 80%
- Registrar incidencia de filtración en lote 23
- Tomar foto de avance con GPS
- Completar checklist de instalaciones hidrosanitarias
- Registrar asistencia de cuadrilla de albañiles con huella dactilar
---
#### 4. Compras (`purchases`)
**Descripción:** Encargado de compras y almacén
**Permisos:**
- ✅ Ver requisiciones de todas las obras
- ✅ Crear y gestionar órdenes de compra
- ✅ Comparar cotizaciones de proveedores
- ✅ Gestionar catálogo de proveedores
- ✅ Autorizar entregas parciales/completas
- ✅ Gestionar movimientos de inventario (entradas, salidas, traspasos)
- ✅ Ver kardex de materiales
- ✅ Configurar alertas de stock mínimo
- ❌ NO puede editar presupuestos
- ❌ NO puede ver márgenes de utilidad
- ❌ NO puede aprobar estimaciones
**Restricciones RLS:**
```sql
-- Política: Compras ve requisiciones de todas las obras de la constructora
CREATE POLICY "purchases_view_all_requisitions" ON purchases.purchase_requisitions
FOR SELECT
TO authenticated
USING (
get_current_user_role() = 'purchases'
AND constructora_id = get_current_constructora_id()
);
```
**Casos de Uso:**
- Comparar 3 cotizaciones de cemento
- Generar orden de compra por $50,000
- Autorizar entrega parcial de acero
- Traspasar materiales entre obras
- Alertar por stock bajo de alambrón
---
#### 5. Finanzas (`finance`)
**Descripción:** Administración, contabilidad o finanzas
**Permisos:**
- ✅ Ver presupuestos y costos reales de todas las obras
- ✅ Aprobar estimaciones hacia clientes
- ✅ Aprobar estimaciones hacia subcontratistas
- ✅ Ver flujo de efectivo de obra
- ✅ Gestionar pagos y cobranzas
- ✅ Ver reportes financieros detallados
- ✅ Exportar datos contables
- ✅ Configurar centros de costo
- ❌ NO puede editar avances físicos
- ❌ NO puede crear órdenes de compra (solo autorizar pagos)
**Restricciones RLS:**
```sql
-- Política: Finanzas ve datos financieros de toda la constructora
CREATE POLICY "finance_view_all_financials" ON budgets.budgets
FOR SELECT
TO authenticated
USING (
get_current_user_role() = 'finance'
AND constructora_id = get_current_constructora_id()
);
```
**Casos de Uso:**
- Revisar desviaciones de presupuesto por obra
- Aprobar estimación 3 de obra A por $2M
- Ver flujo de efectivo proyectado
- Generar reporte de cartera vencida
- Exportar pólizas contables
---
#### 6. RRHH (`hr`)
**Descripción:** Recursos Humanos y nómina
**Permisos:**
- ✅ Gestionar empleados y cuadrillas
- ✅ Ver asistencias de todas las obras
- ✅ Generar reportes de nómina
- ✅ Exportar datos para IMSS/INFONAVIT
- ✅ Ver costeo de mano de obra por obra
- ✅ Gestionar oficios y categorías
- ✅ Configurar parámetros de nómina
- ❌ NO puede ver presupuestos completos
- ❌ NO puede aprobar estimaciones
- ❌ NO puede ver márgenes de utilidad
**Restricciones RLS:**
```sql
-- Política: RRHH ve datos de empleados de toda la constructora
CREATE POLICY "hr_view_all_employees" ON hr.employees
FOR SELECT
TO authenticated
USING (
get_current_user_role() = 'hr'
AND constructora_id = get_current_constructora_id()
);
```
**Casos de Uso:**
- Dar de alta nuevo empleado en IMSS
- Generar archivo SUA mensual
- Revisar asistencias de obra B
- Calcular costeo de mano de obra por partida
- Exportar nómina semanal
---
#### 7. Postventa (`post_sales`)
**Descripción:** Coordinador de postventa y garantías
**Permisos:**
- ✅ Ver viviendas entregadas
- ✅ Gestionar tickets de postventa
- ✅ Registrar incidencias de clientes
- ✅ Dar seguimiento a garantías
- ✅ Programar visitas de reparación
- ✅ Gestionar cuadrillas de postventa
- ✅ Ver historial completo de vivienda
- ❌ NO puede ver presupuestos
- ❌ NO puede ver datos de obras en ejecución
- ❌ NO puede gestionar compras
**Restricciones RLS:**
```sql
-- Política: Postventa solo ve viviendas entregadas
CREATE POLICY "post_sales_view_delivered_units" ON projects.housing_units
FOR SELECT
TO authenticated
USING (
get_current_user_role() = 'post_sales'
AND status = 'delivered'
AND constructora_id = get_current_constructora_id()
);
```
**Casos de Uso:**
- Registrar incidencia de filtración en vivienda entregada
- Programar reparación de grieta en muro
- Ver historial de tickets de lote 45
- Generar reporte de garantías vencidas
- Asignar cuadrilla de plomería para reparación
---
### RF-AUTH-001.2: Asignación de Roles
**Reglas de Asignación:**
1. **Al registrarse (self-service):**
- Usuarios nuevos reciben rol `resident` por defecto
- No es posible auto-asignarse otros roles
- Registro requiere invitación de constructora
2. **Promoción a otros roles:**
- Solo `director` puede asignar/cambiar roles
- Requiere justificación documentada en audit_logs
- Cambio de rol envía notificación por email
3. **Relación con Constructoras:**
- Un usuario puede pertenecer a múltiples constructoras (diferentes roles)
- Ejemplo: Juan es `engineer` en Constructora A y `resident` en Constructora B
- Usuario selecciona constructora activa al login
4. **Degradación de rol:**
- `director` puede degradar cualquier rol
- Usuario puede solicitar cambio de rol
- Cambio de rol no elimina acceso histórico (solo auditoría)
---
### RF-AUTH-001.3: Validación de Roles
El sistema **DEBE** validar roles en 3 capas:
1. **Backend (Guards):**
```typescript
// apps/backend/src/modules/budgets/budgets.controller.ts
@Roles('director', 'engineer', 'finance')
@Get('budgets/:id')
getBudget(@Param('id') id: string) {
// Solo director, engineer y finance pueden ver presupuestos
}
```
2. **Database (RLS Policies):**
```sql
-- Cada tabla sensible debe tener políticas RLS por rol
-- Ejemplo: presupuestos solo visibles por director, engineer, finance
CREATE POLICY "budgets_select_by_role" ON budgets.budgets
FOR SELECT
TO authenticated
USING (
get_current_user_role() IN ('director', 'engineer', 'finance')
AND constructora_id = get_current_constructora_id()
);
```
3. **Frontend (Routing y UI):**
```typescript
// apps/frontend/src/routes/ProtectedRoute.tsx
<RoleBasedRoute allowedRoles={['engineer', 'director']}>
<BudgetManagement />
</RoleBasedRoute>
```
---
## 📊 Matriz de Permisos por Módulo
| Módulo | director | engineer | resident | purchases | finance | hr | post_sales |
|--------|----------|----------|----------|-----------|---------|----|-----------:|
| **Proyectos** |
| Ver todos los proyectos | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
| Ver proyectos asignados | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
| Crear proyecto | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Editar proyecto | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| **Presupuestos** |
| Ver presupuestos | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
| Crear presupuesto | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Editar presupuesto | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Ver márgenes | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
| **Compras** |
| Ver requisiciones | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| Crear requisición | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| Crear orden de compra | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Aprobar orden | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
| **Inventarios** |
| Ver inventario | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| Movimientos | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| **Control de Obra** |
| Capturar avances | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Ver avances | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
| Editar avances | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| **RRHH** |
| Ver empleados | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| Gestionar empleados | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
| Ver asistencias | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| Registrar asistencia | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
| Exportar IMSS/INFONAVIT | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ |
| **Postventa** |
| Ver tickets | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ |
| Crear ticket | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ |
| Asignar cuadrilla | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
| **Reportes** |
| Dashboard ejecutivo | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
| Reportes de obra | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
| Reportes financieros | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
---
## ✅ Criterios de Aceptación
### AC-001: Roles Implementados
- [ ] ENUM `construction_role` existe en DDL con 7 valores
- [ ] Backend tiene enum TypeScript espejo
- [ ] Frontend tiene types TypeScript
- [ ] Documentación de cada rol completa
### AC-002: RLS Policies Activas
- [ ] Tabla `projects.projects` tiene policies por rol
- [ ] Tabla `budgets.budgets` tiene policies por rol
- [ ] Tabla `hr.employees` tiene policies por rol
- [ ] 10+ tablas críticas con RLS implementado
### AC-003: Guards Funcionales
- [ ] `@Roles()` decorator implementado en backend
- [ ] Endpoints sensibles protegidos con guards
- [ ] Tests E2E validan autorización por rol
### AC-004: UI Adapta por Rol
- [ ] Dashboard muestra diferentes opciones según rol (7 variantes)
- [ ] Menú de navegación adapta según rol
- [ ] Componentes restringidos no se muestran a roles no autorizados
### AC-005: Auditoría
- [ ] Cambios de rol se auditan en `audit_logs`
- [ ] Timestamp, admin que realizó cambio, y justificación registrados
---
## 🧪 Testing
### Test Case 1: Residente NO puede ver presupuestos
```typescript
test('Resident cannot view budgets', async () => {
const resident = await createUser({ role: 'resident' });
const project = await createProject();
await loginAs(resident);
const response = await api.get(`/budgets/project/${project.id}`);
expect(response.status).toBe(403); // Forbidden
});
```
### Test Case 2: Ingeniero puede crear presupuesto
```typescript
test('Engineer can create budget', async () => {
const engineer = await createUser({ role: 'engineer' });
const project = await createProject();
await loginAs(engineer);
const response = await api.post('/budgets', {
project_id: project.id,
name: 'Presupuesto base',
total: 1000000
});
expect(response.status).toBe(201);
expect(response.data.budget.id).toBeDefined();
});
```
### Test Case 3: Director tiene acceso completo
```typescript
test('Director can access all projects', async () => {
const director = await createUser({ role: 'director' });
await createMultipleProjects(5);
await loginAs(director);
const response = await api.get('/projects');
expect(response.status).toBe(200);
expect(response.data.projects.length).toBe(5);
});
```
---
## 📚 Referencias Adicionales
### Documentos Relacionados
- 📄 [RF-AUTH-002: Estados de Cuenta de Usuario](./RF-AUTH-002-estados-cuenta.md)
- 📄 [RF-AUTH-003: Multi-tenancy por Constructora](./RF-AUTH-003-multi-tenancy.md)
- 📐 [ET-AUTH-001: RBAC Implementation](../especificaciones/ET-AUTH-001-rbac.md)
### Estándares de Industria
- [NIST RBAC Model](https://csrc.nist.gov/projects/role-based-access-control)
- [OWASP: Authorization Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html)
---
## 📅 Historial de Cambios
| Versión | Fecha | Autor | Cambios |
|---------|-------|-------|---------|
| 1.0 | 2025-11-17 | Tech Lead | Creación inicial basada en EAI-001/RF-AUTH-001 de GAMILIT |
---
**Documento:** `docs/01-fase-alcance-inicial/MAI-001-fundamentos/requerimientos/RF-AUTH-001-roles-construccion.md`
**Ruta relativa:** `MAI-001-fundamentos/requerimientos/RF-AUTH-001-roles-construccion.md`
**Épica:** MAI-001
**Sprint:** Sprint 1 (Semanas 2-3)