Apariencia
Roles y usuarios
HUMAE modela un único tipo de usuario (User) con cuatro roles asignables. Un mismo correo puede tener uno o varios roles, aunque lo normal es un rol por cuenta.
Los cuatro roles
| Rol | Código | ¿Quién es? | ¿Qué puede hacer? |
|---|---|---|---|
| Candidato | candidate | Persona que busca empleo y paga membresía | Construye su perfil, hace tests, descarga su CV. Ve solo sus datos y sus asignaciones. |
| Reclutador HUMAE | recruiter | Colaborador interno de HUMAE | Busca en el directorio, asigna candidatos a vacantes, agenda y gestiona entrevistas, descarga CVs. |
| Usuario de empresa | company_user | Contacto designado por la empresa cliente | Gestiona sus vacantes (crear, publicar, cerrar), revisa candidatos presentados por HUMAE, confirma entrevistas. |
| Administrador | admin | Staff HUMAE con privilegios totales | Configura catálogos, lee reportes, administra usuarios, edita plantillas, gestiona pagos. |
Los roles están definidos como enum PHP App\Enums\UserRole y persisten en la tabla model_has_roles (Spatie Permission).
Jerarquía implícita
admin → puede todo lo de recruiter + configuración global
recruiter → HUMAE interno, opera el pipeline
company_user → cliente externo, acceso solo a SU empresa y vacantes
candidate → acceso solo a SUS datosEl rol admin tiene "before bypass" en las Policies de Laravel: si el método before() devuelve true, el admin puede ejecutar cualquier acción. Esto está implementado explícitamente en cada Policy — nunca implícito.
¿Puede un usuario cambiar de rol?
No desde la UI pública. El rol se fija al momento del registro:
- Candidato: se autoregistra en
/registery queda con rolcandidate. - Reclutador: lo crea manualmente un
admindesde el panel de administración. - Company user: lo crea un
adminy se asocia a unaCompanyespecífica (tablacompany_members). - Admin: lo crea otro
admin(o se siembra conRolesAndPermissionsSeeder).
Un admin puede reasignar roles desde el panel si es necesario (ej. promover un recruiter a admin).
Relaciones con otras entidades
User (1) ─── (0..1) CandidateProfile ← si el user es candidato
User (1) ─── (0..n) CompanyMember ← si el user es company_user
User (1) ─── (0..n) Membership ← historial de membresías (candidatos)
User (1) ─── (0..n) Payment ← historial de pagos
User (1) ─── (0..n) DatabaseNotification ← notificaciones in-appUn company_user es siempre miembro de al menos una Company (con rol interno owner, manager o viewer dentro de esa empresa). Ver Empresa cliente.
Estados de cuenta
Independientemente del rol, cada User tiene un campo status:
| Estado | Descripción |
|---|---|
pending_verification | Recién registrado, falta verificar correo |
active | Cuenta funcional |
suspended | Temporalmente bloqueado (ej. falta de pago, infracción) |
banned | Bloqueo permanente |
Un usuario con status != active no puede hacer login. El middleware de auth lo rechaza con 401.
Verificación de correo
- Al registrarse, el candidato recibe un correo con una URL firmada con expiración (
VerifyEmail::createUrlUsing). - Hasta que la URL se visita, el endpoint
GET /meresponde conemail_verified_at: nully ciertas acciones (como iniciar el checkout de membresía) están bloqueadas. - Los correos del verificación se reenvían con
POST /auth/verify-email/resend(rate limit: 3 por minuto).
Multi-dispositivo
Un mismo usuario puede tener múltiples tokens Sanctum activos (laptop + móvil). El logout desde un dispositivo no cierra la sesión en los demás. El endpoint POST /auth/logout solo revoca el token actual. Para cerrar todas las sesiones se usa POST /auth/logout-all (admin-only por ahora).
Siguiente paso
Ve cómo se encadenan las acciones de cada rol en el día a día: Flujos principales →

