- Configure workspace Git repository with comprehensive .gitignore - Add Odoo as submodule for ERP reference code - Include documentation: SETUP.md, GIT-STRUCTURE.md - Add gitignore templates for projects (backend, frontend, database) - Structure supports independent repos per project/subproject level Workspace includes: - core/ - Reusable patterns, modules, orchestration system - projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.) - knowledge-base/ - Reference code and patterns (includes Odoo submodule) - devtools/ - Development tools and templates - customers/ - Client implementations template 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
12 KiB
RF-AUTH-001: Sistema de Roles de Usuario
📋 Metadata
| Campo | Valor |
|---|---|
| ID | RF-AUTH-001 |
| Módulo | Autenticación y Autorización |
| Prioridad | Alta |
| Estado | ✅ Implementado |
| Versión | 1.0 |
| Fecha creación | 2025-11-07 |
| Última actualización | 2025-11-07 |
🔗 Referencias
Especificación Técnica
📐 ET-AUTH-001: RBAC (Role-Based Access Control)
Implementación DDL
🗄️ ENUM Canónico:
- Ubicación:
apps/database/ddl/00-prerequisites.sql:30-32 - Tipo:
auth_management.gamilit_role - Valores:
student,admin_teacher,super_admin
🗄️ Tablas que usan el ENUM:
auth_management.profiles→apps/database/ddl/schemas/auth_management/tables/03-profiles.sql:15auth.users→apps/database/ddl/schemas/auth/tables/01-users.sql:15system_configuration.feature_flags→apps/database/ddl/schemas/system_configuration/tables/02-feature_flags.sql:20
Backend
💻 Implementación:
- Enum:
apps/backend/src/shared/enums/gamilit-role.enum.ts - Guard:
apps/backend/src/shared/guards/roles.guard.ts - Decorator:
@Roles('admin_teacher', 'super_admin')
Frontend
🎨 Componentes:
- Types:
apps/frontend/src/types/auth.types.ts - Componentes:
apps/frontend/src/components/auth/RoleBasedRoute.tsxapps/frontend/src/components/ui/UserRoleBadge.tsxapps/frontend/src/components/admin/AdminPanel.tsx
Mapeo Completo
📊 Ver mapeo completo: Requerimientos → Implementación
📝 Descripción del Requerimiento
Contexto
El sistema educativo Gamilit necesita diferenciar entre tres tipos de usuarios con permisos y funcionalidades distintas. Esta diferenciación es crítica para:
- Proteger datos sensibles de estudiantes
- Permitir gestión efectiva de aulas por profesores
- Facilitar administración del sistema completo
Necesidad del Negocio
Problema: Sin un sistema de roles bien definido, todos los usuarios tendrían el mismo nivel de acceso, lo cual:
- Comprometería la privacidad de datos de estudiantes
- Dificultaría la gestión de contenido educativo
- Impediría la administración centralizada del sistema
Solución: Implementar un sistema de roles con 3 niveles de autorización que permita acceso granular basado en responsabilidades.
🎯 Requerimiento Funcional
RF-AUTH-001.1: Roles Disponibles
El sistema DEBE soportar exactamente 3 roles de usuario:
1. Estudiante (student)
Descripción: Usuario regular que accede al sistema para aprender
Permisos:
- ✅ Acceder a ejercicios asignados
- ✅ Ver su propio progreso y estadísticas
- ✅ Interactuar con sistema de gamificación personal
- ✅ Participar en funcionalidades sociales (amigos, equipos)
- ✅ Ver contenido publicado
- ❌ NO puede ver datos de otros estudiantes (excepto amigos)
- ❌ NO puede crear o editar contenido educativo
- ❌ NO puede acceder a panel de administración
Restricciones RLS (Row Level Security):
-- Política típica para estudiantes
CREATE POLICY "students_view_own_data" ON progress_tracking.module_progress
FOR SELECT
TO authenticated
USING (
user_id = gamilit.get_current_user_id()
AND gamilit.get_current_user_role() = 'student'
);
2. Profesor/Admin (admin_teacher)
Descripción: Profesor o administrador de aula con capacidades de gestión
Permisos:
- ✅ Todos los permisos de estudiante
- ✅ Crear y editar contenido educativo
- ✅ Ver progreso de estudiantes en sus aulas
- ✅ Revisar ejercicios de respuesta abierta
- ✅ Asignar ejercicios a estudiantes/aulas
- ✅ Generar reportes de aula
- ✅ Gestionar aulas (crear, editar, archivar)
- ❌ NO puede acceder a datos de todas las aulas (solo las asignadas)
- ❌ NO puede modificar configuración del sistema
- ❌ NO puede gestionar usuarios a nivel sistema
Restricciones RLS:
-- Política para profesores (ver estudiantes de sus aulas)
CREATE POLICY "teachers_view_classroom_students" ON progress_tracking.module_progress
FOR SELECT
TO authenticated
USING (
gamilit.get_current_user_role() = 'admin_teacher'
AND user_id IN (
SELECT cm.user_id
FROM social_features.classroom_members cm
WHERE cm.classroom_id IN (
SELECT classroom_id
FROM social_features.classroom_members
WHERE user_id = gamilit.get_current_user_id()
AND role = 'teacher'
)
)
);
3. Super Admin (super_admin)
Descripción: Administrador del sistema con acceso completo
Permisos:
- ✅ Acceso completo a todos los datos
- ✅ Gestionar usuarios (crear, suspender, banear)
- ✅ Modificar configuración del sistema
- ✅ Aprobar/rechazar contenido en revisión
- ✅ Ver estadísticas globales del sistema
- ✅ Gestionar integraciones externas
- ✅ Acceder a logs de auditoría
- ✅ Exportar datos del sistema
- ⚠️ Sin restricciones RLS (bypass con
USING (true))
Nota de Seguridad:
⚠️ El rol
super_admindebe asignarse con extremo cuidado. Idealmente limitado a 2-3 usuarios del equipo técnico.
RF-AUTH-001.2: Asignación de Roles
Reglas de Asignación:
-
Al registrarse:
- Usuarios nuevos reciben rol
studentpor defecto - No es posible auto-asignarse
admin_teacherosuper_admin
- Usuarios nuevos reciben rol
-
Promoción a admin_teacher:
- Solo
super_adminpuede promover usuarios aadmin_teacher - Requiere justificación documentada en audit_logs
- Solo
-
Promoción a super_admin:
- Solo
super_adminexistente puede promover a otrosuper_admin - Requiere aprobación de 2 super_admins (proceso manual)
- Requiere justificación documentada
- Solo
-
Degradación de rol:
super_adminpuede degradar cualquier roladmin_teacherNO puede cambiar roles- Usuario puede solicitar degradación voluntaria
RF-AUTH-001.3: Validación de Roles
El sistema DEBE validar roles en:
- Backend (Guards):
// apps/backend/src/shared/guards/roles.guard.ts
@Roles('admin_teacher', 'super_admin')
@Get('admin/dashboard')
getAdminDashboard() {
// Solo accesible por admin_teacher y super_admin
}
- Database (RLS Policies):
- Cada tabla sensible debe tener políticas RLS por rol
- Triggers verifican permisos antes de INSERT/UPDATE
- Frontend (Routing):
// apps/frontend/src/routes/ProtectedRoute.tsx
<RoleBasedRoute allowedRoles={['admin_teacher', 'super_admin']}>
<AdminDashboard />
</RoleBasedRoute>
📊 Casos de Uso
UC-STU-001: Estudiante accede a sus ejercicios
Actor: Estudiante
Precondiciones: Usuario autenticado con rol student
Flujo:
- Estudiante navega a "Mis Ejercicios"
- Sistema consulta
progress_tracking.module_progresscon RLS - RLS filtra solo ejercicios donde
user_id = current_user_id - Sistema muestra ejercicios propios del estudiante
Resultado: Estudiante ve solo sus datos, no puede acceder a datos de otros.
UC-TEACHER-001: Profesor ve progreso de sus estudiantes
Actor: Profesor (admin_teacher)
Precondiciones: Usuario autenticado con rol admin_teacher, asignado a al menos 1 aula
Flujo:
- Profesor navega a "Mis Aulas"
- Sistema obtiene aulas donde profesor tiene rol
teacher - Profesor selecciona un aula
- Sistema consulta progreso de todos los estudiantes del aula
- RLS valida que profesor tiene acceso a esa aula
Resultado: Profesor ve progreso de estudiantes en sus aulas, no de otras aulas.
UC-ADMIN-001: Super admin gestiona sistema completo
Actor: Super Admin
Precondiciones: Usuario autenticado con rol super_admin
Flujo:
- Admin navega a "Panel de Administración"
- Sistema valida rol =
super_admin - Admin accede a:
- Gestión de usuarios (todos)
- Configuración del sistema
- Logs de auditoría
- Estadísticas globales
Resultado: Admin tiene visibilidad completa del sistema.
🔐 Consideraciones de Seguridad
1. Principio de Menor Privilegio
- Cada rol tiene únicamente los permisos necesarios para su función
- No hay roles "comodín" con permisos arbitrarios
2. Defense in Depth (Defensa en Profundidad)
Validación en 3 capas:
- Frontend: Oculta UI no autorizada (seguridad visual)
- Backend: Guards verifican roles antes de ejecutar lógica
- Database: RLS policies bloquean acceso a nivel de datos
3. Auditoría de Cambios de Rol
Toda asignación/cambio de rol se audita en audit_logging.audit_logs:
-- Trigger automático
INSERT INTO audit_logging.audit_logs (
user_id, action, resource_type, resource_id, details
) VALUES (
current_admin_id,
'update',
'user_role',
target_user_id,
jsonb_build_object(
'old_role', 'student',
'new_role', 'admin_teacher',
'reason', 'Promoted to manage classroom XYZ'
)
);
✅ Criterios de Aceptación
AC-001: Roles Implementados
- ENUM
gamilit_roleexiste en DDL con 3 valores - Backend tiene enum TypeScript espejo
- Frontend tiene types TypeScript
AC-002: RLS Policies Activas
- Tabla
progress_tracking.module_progresstiene policies por rol - Tabla
educational_content.modulestiene policies por rol - Tabla
social_features.classroom_memberstiene policies por rol - 7+ 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
- 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: Estudiante NO puede ver datos de otros
test('Student cannot view other students progress', async () => {
const student1 = await createUser({ role: 'student' });
const student2 = await createUser({ role: 'student' });
await loginAs(student1);
const response = await api.get(`/progress/${student2.id}`);
expect(response.status).toBe(403); // Forbidden
});
Test Case 2: Profesor puede ver progreso de su aula
test('Teacher can view classroom students progress', async () => {
const teacher = await createUser({ role: 'admin_teacher' });
const classroom = await createClassroom({ teacherId: teacher.id });
const student = await addStudentToClassroom(classroom.id);
await loginAs(teacher);
const response = await api.get(`/classrooms/${classroom.id}/progress`);
expect(response.status).toBe(200);
expect(response.data.students).toContainEqual(
expect.objectContaining({ id: student.id })
);
});
Test Case 3: Super admin tiene acceso completo
test('Super admin can access all data', async () => {
const admin = await createUser({ role: 'super_admin' });
await loginAs(admin);
const response = await api.get('/admin/users');
expect(response.status).toBe(200);
expect(response.data.users.length).toBeGreaterThan(0);
});
📚 Referencias Adicionales
Documentos Relacionados
- 📄 RF-AUTH-002: Estados de Cuenta de Usuario
- 📄 RF-SOC-001: Sistema de Aulas
- 📐 ADR-003: Decisión de usar RLS en lugar de app-level auth
Estándares de Industria
📅 Historial de Cambios
| Versión | Fecha | Autor | Cambios |
|---|---|---|---|
| 1.0 | 2025-11-07 | Database Team | Creación inicial del requerimiento |
Documento: docs/01-requerimientos/01-autenticacion-autorizacion/RF-AUTH-001-roles.md
Ruta relativa desde docs/: 01-requerimientos/01-autenticacion-autorizacion/RF-AUTH-001-roles.md