Apariencia
Gestión de usuarios
/admin/usuarios es la pantalla central para administrar a las personas que tienen cuenta en HUMAE: candidatos, reclutadores, empresas y otros admins. Desde aquí se invita gente nueva, se reenvían invitaciones expiradas, se eliminan cuentas y — desde Fase 16 — se aprueba o rechaza a quienes se registraron por su cuenta como reclutador o empresa.
Listado y filtros
La página muestra una lista paginada con filtros combinables:
- Buscador por nombre o email (server-side, parámetro
q). - Rol (
admin,recruiter,company_user,candidate). - Estado:
- Activos — cuentas operativas (
status=active). - Invitados — admins crearon su cuenta vía
Invitar usuario; aún no aceptaron el link. - Pendientes de aprobación — auto-registrados que esperan la decisión de un admin.
- Suspendidos y Inactivos — cuentas bloqueadas (manual o tras un rechazo).
- Activos — cuentas operativas (
Acceso directo desde correo
Los correos PendingUserRegistrationNotification que reciben los admins llevan un CTA a https://app.humae.com.mx/admin/usuarios?status=pending_approval. La página inicializa el filtro desde el query param y deja la lista lista para revisar.
Cada fila muestra avatar (iniciales), nombre, email, rol primario, empresa asociada (si aplica), fecha relevante (alta / expiración de invitación / fecha de solicitud) y badges contextuales: Pendiente de aprobación, Invitado, Suspendido, Inactivo.
Aprobar o rechazar un auto-registro
Cuando un usuario se registra en /register/reclutador o /register/empresa, su User queda con status=pending_approval. En la pantalla aparece con badge ámbar y dos botones inline:
- Aprobar (
CheckCircle2) → llamaPOST /api/v1/admin/users/{user}/approve. - Rechazar (
XCircle) → abre el dialogRejectUserDialog.
Aprobación
Es de un solo clic. El backend:
- Verifica que el usuario sigue en
pending_approval(responde409si no — defensa contra doble click). - Pone
status=active. - Carga el primer rol del usuario y manda
AccountApprovedNotification(roleLabel)(mail + database). - Devuelve el
AdminUserResourceactualizado y la lista se invalida automáticamente (TanStack Query key["admin","users"]).
Resultado al usuario:
- Recibe correo "Tu cuenta HUMAE fue aprobada" con CTA al login.
- Su próximo
POST /auth/logindevuelve200con token.
Rechazo (con motivo opcional)
El click en Rechazar abre un dialog modal con:
- Resumen de la solicitud ("Vas a rechazar la solicitud de {nombre} ({email})…").
- Textarea de motivo opcional, máx. 500 caracteres.
- Botones Cancelar y Rechazar solicitud.
Al confirmar:
POST /api/v1/admin/users/{user}/rejectcon{reason?: string}.- Backend valida pending → setea
status=inactive. - Manda
AccountRejectedNotification(reason). - La fila desaparece del filtro
pending_approvaly aparece bajoInactivos.
Resultado al usuario:
- Recibe correo "No pudimos aprobar tu cuenta HUMAE" + el motivo (si se capturó).
- Su login devuelve
403 errors.code = account_inactive.
El rechazo no es destructivo
El User queda en DB con status=inactive (puedes reactivarlo manualmente desde Tinker si fue un error). No usamos delete() en el reject porque el rastro auditable es valioso.
Invitar usuarios manualmente (flujo paralelo)
Además del self-service, los admins pueden invitar directamente reclutadores, empresas u otros admins desde el botón "Invitar usuario". Este flujo no pasa por pending_approval:
- Crea el
Userconstatus='invited', sin password (se genera un hash aleatorio temporal). - Manda
UserInvitationNotificationcon un token firmado de 7 días. - El invitado abre
/onboard?token=..., define su contraseña y acepta.accepted_atse setea y el user pasa aactive.
Es el patrón previo, pensado para casos donde el admin ya conoce a la persona y quiere acelerar el alta.
Eliminar usuarios
El botón papelera al final de cada fila confirma con window.confirm() y manda DELETE /api/v1/admin/users/{user}. El backend impide que un admin se elimine a sí mismo (422 "No puedes eliminar tu propia cuenta").
No es soft-delete
Esta acción borra el registro. Si necesitas conservar histórico, prefiere rechazar o suspender (cambiar status manualmente) antes de eliminar.
Endpoints involucrados
| Endpoint | Método | Cuándo |
|---|---|---|
/api/v1/admin/users | GET | Listar/filtrar (acepta q, role, status) |
/api/v1/admin/users | POST | Invitar nuevo usuario |
/api/v1/admin/users/{user}/resend-invitation | POST | Reenviar mail de invitación expirada |
/api/v1/admin/users/{user}/approve | POST | Aprobar auto-registro |
/api/v1/admin/users/{user}/reject | POST | Rechazar auto-registro ({reason?}) |
/api/v1/admin/users/{user} | DELETE | Eliminar cuenta |
Todos requieren auth:sanctum + rol admin (verificación en UserController::ensureAdmin()).
Tests automatizados de respaldo
El backend tiene cobertura Pest para esta página:
tests/Feature/Api/V1/Admin/ApproveRejectTest.php— happy paths + 409 si no está pending + 403 si quien llama no es admin + filtro de listado porpending_approval.tests/Feature/Api/V1/Auth/RegisterRecruiterTest.phpyRegisterCompanyTest.php— verifican que el alta efectivamente notifica a los admins.
Siguiente
Para revisar las decisiones de configuración global del sistema: Configuración →.

