local_candidate_enrollment
Plugin de postulantes - códigos de acceso, autorregistro y aislamiento para la Prueba Técnica de Selección, incorporación al equipo, creación de colaboradores y recuperación de contraseña sin correo.
local_candidate_enrollment resuelve el flujo de selección que pide el manual: un postulante entra con un código que le da Talento Humano, rinde solo la prueba de su cargo y no ve nada de la Academia. Además aloja la lógica compartida para crear colaboradores (staff_manager) y la recuperación de contraseña sin correo.
| Dato | Valor |
|---|---|
| Componente | local_candidate_enrollment (nombre visible "Auto-registro de candidatos") |
| Ruta en la imagen | /var/www/html/local/candidate_enrollment |
| Versión | 2026100700 (release 1.0.0) |
| Requiere | Moodle 4.5 (2024100700) |
| Tabla | local_candenrol_code (Base de datos) |
| Capacidad | local/candidate_enrollment:viewcandidates (Capacidades) |
| Evento | local_candidate_enrollment\event\password_selfreset |
| Depende de | Clases de local_deltamodules (builder, academy, mailer, ai_tiers) |
Estructura
Modelo de la Prueba Técnica de Selección
| Elemento | Implementación |
|---|---|
| Curso | seleccion_pruebas_tecnicas (número de ID PTS), separado de la Academia (candidates::COURSE). Lo crea create-selection-tests.php. |
| Prueba de un cargo | Un cuestionario "Prueba Técnica — Cargo" en su propia sección, con restricción por grupo del curso (el cargo) y por completar el consentimiento LOPDP (actividad Consulta / choice). |
| Postulante | Cuenta en la cohorte candidatos (candidates::COHORT) con el rol restringido delta_postulante, matriculada manualmente como estudiante y en el grupo de su cargo. Usuario cand<cédula>, contraseña aleatoria que no necesita. |
| Incorporado | Preferencia local_candenrol_hired con la fecha (candidates::HIREDPREF); sale de la cohorte candidatos. |
Códigos de acceso: codes
| Método | Qué hace |
|---|---|
generate($groupid, $days, $maxuses, $note) | Código = iniciales del cargo + 4 caracteres de un alfabeto sin 0/O ni 1/I/L (codes::ALPHABET). Usos entre 1 y 50 (1 por defecto), vigencia entre 1 y 60 días (hasta las 23:59:59). |
normalize, pretty | ac-7k4q → AC7K4Q; se muestra como AC-7K4Q. |
status, statuses | activo, usado, vencido o anulado; se calcula al leerlo (no hay tareas). |
check_code($input) | Paso 1 del registro: existe, no anulado, no vencido y la prueba sigue disponible. |
check($input, $cedula) | Paso 2: además, una cédula ya registrada solo vuelve a entrar con el mismo código que usó; un código agotado solo sirve para quien ya lo usó. |
consume($c, $userid) | Agrega al postulante a usedby (una vez por persona) y actualiza uses. |
revoke, all, of_user | Anular, listar y saber con qué código se registró alguien. |
Postulantes: candidates
| Método | Qué hace |
|---|---|
course(), is_candidate($userid) | Curso de selección y si la persona está en la cohorte candidatos. |
tests() | Pruebas del curso (cmid → cuestionario, grupo, área, número de preguntas, nota para aprobar). |
areas() | Cargos con prueba visible (groupid => cargo, sin el prefijo "Prueba Técnica —"). |
rows($f) | Postulantes con prueba, intentos, nota y estado; filtros por cargo, estado, fechas y texto (nombre, cédula o correo). |
statuses() | aprobo, no_aprobo, pendiente (de calificar), en_curso, sin_iniciar, incorporado. |
create_test($cargo, $opts) | Prueba nueva para otro cargo: grupo, sección con restricción de grupo, cuestionario con builder::create_quiz(), aviso de candidato y restricción grupo + consentimiento. |
test_defaults() | Valores para las pruebas nuevas desde test_default_time / attempts / pass (por defecto 30 min, 1 intento, 7 sobre 10). |
update_test($cmid, $time, $attempts, $pass) | Opciones permitidas: tiempo TEST_TIMES (0, 10, 15, 20, 30, 45, 60, 90), intentos TEST_ATTEMPTS (1 a 3), nota TEST_PASS (5 a 10 sobre 10). Fija la nota máxima en 10 y rehace el aviso. |
delete_test($cmid) | Borra el cuestionario (con sus intentos), su grupo y su sección vacía, y anula los códigos de ese cargo. No borra cuentas. |
export_rows, export_columns | Filas para descargar con el formato institucional. |
Flujos
Autorregistro (index.php)
Página pública, enlazada desde la portada y la pantalla de ingreso.
Código
El postulante escribe solo el código (code_form), que se guarda en $SESSION->deltacandcode.
Datos y consentimiento
Ve el cargo de su prueba y completa nombre completo, cédula (10 dígitos) y correo, con la casilla del aviso de datos (LOPDP) obligatoria (signup_form).
Cuenta
Solo reutiliza la cuenta de un postulante con la misma cédula y el mismo correo (signup_form::candidate_for); nunca entra a la cuenta de un colaborador. Crea o reutiliza la cuenta, matricula, consume el código, agrega al grupo y a la cohorte y asigna delta_postulante. Todo se hace sin cambiar de usuario.
Entrada
Comprueba que la cuenta sea solo de postulante (is_plain_candidate), inicia su sesión, registra la respuesta de la actividad de consentimiento y acepta la política del sitio vigente, y lo lleva a su prueba.
Límite anti-abuso: 10 envíos fallidos por IP cada 30 minutos (caché recoverthrottle).
Aislamiento (hook_callbacks)
| Hook | Comportamiento |
|---|---|
before_http_headers | Un postulante no incorporado solo puede estar en su prueba (mod-quiz-view, attempt, summary, startattempt), en done.php, en el login o en la política. Cualquier otra página lo lleva a su prueba (test_url()). Al terminar sin intentos abiertos, o al llegar a la revisión del intento, va a done.php (no ve sus respuestas). Para Talento Humano, la vista del cuestionario y del curso de selección redirigen a Postulantes (salvo en modo de edición o como super administrador). |
before_standard_head_html_generation | CSS que oculta al postulante la barra de navegación, el índice, el chat de IA, el pie y el menú de usuario (salvo Cerrar sesión). |
primary_extend | "Postulantes" en la barra superior (clave deltacandidates) para quien tiene viewcandidates. |
done.php agradece, informa que Talento Humano se pondrá en contacto, cierra la sesión y vuelve a la portada; si le queda un intento, puede usarlo. Al enviar la prueba, el observador mailer::on_test_submitted de local_deltamodules envía el correo "Prueba técnica recibida" (sin la nota).
Postulantes (candidates.php)
Capacidad local/candidate_enrollment:viewcandidates. Pestañas postulantes (filtros, estados, ver prueba, calificar preguntas abiertas, descargar, eliminar con local/deltamodules:managepeople y moodle/user:delete), codigos (generar, enviar por correo con mailer::candidate_code, anular) y pruebas (crear, ajustar o eliminar pruebas; cargar preguntas desde Word, Excel o XML con load_questions → academy::import_into_quiz(); editar con questions.php).
Incorporar al equipo (hire.php)
Capacidades viewcandidates y moodle/user:create. staff_manager::promote() convierte la misma cuenta en colaborador (se conservan su prueba y su nota): usuario y datos nuevos, contraseña temporal, quita delta_postulante y la cohorte candidatos, marca local_candenrol_hired, suspende la matrícula del curso de selección y aplica assign_cargo(). Si el correo está configurado envía la bienvenida y no muestra contraseña.
Crear colaborador (create_staff.php)
Usuarios → Cuentas → Crear colaborador (página externa local_candidate_enrollment_staff, moodle/user:create). settings.php oculta del menú la página nativa "Crear un nuevo usuario" (addnewuser), que sigue accesible por URL. staff_manager::create() exige correo válido y único, cédula de 10 dígitos única y nombre de usuario libre (por defecto, la parte del correo antes de @); crea la cuenta con cambio de contraseña obligatorio, aplica assign_cargo() y envía la bienvenida si hay correo. La misma función usa el agente de IA. Detalle de cargos y perfiles en Personas y perfiles.
Recuperar contraseña sin correo (recover.php)
El enlace "¿Olvidó su contraseña?" del login apunta aquí (forgottenpasswordurl, fijado por configure-forgot-password-url.php). La persona escribe su usuario (o correo) y su cédula.
| Situación | Resultado |
|---|---|
Correo configurado y tipo reset encendido | Envía el enlace de un solo uso al correo registrado (mailer::reset). La respuesta es la misma exista o no la cuenta; con la cédula correcta muestra el correo enmascarado. |
| Sin correo, datos correctos, cuenta que no es de gestión | Genera una contraseña temporal aleatoria con cambio obligatorio, la muestra una sola vez (POST/Redirect/GET), dispara password_selfreset y avisa a los administradores. |
| Datos incorrectos o cuenta de gestión | Mensaje genérico (no revela qué dato falló). |
Defensas: 6 intentos por IP y 5 por cuenta cada 30 minutos (caché recoverthrottle); solo cuentas activas con autenticación manual; un éxito no libera el contador.
Páginas heredadas
| Página | Estado |
|---|---|
candidate_link.php | Muestra el enlace público de autorregistro (Usuarios → Cuentas, moodle/user:create). admin_access no la incluye en la lista blanca, así que solo la ve el super administrador. |
ficha.php | Redirige al Historial de local_deltamodules (history.php) o a Personal. |
ai_terms_report.php | Redirige a local/deltamodules/policies.php?tab=ia. |
Privacidad
classes/privacy/provider.php es un proveedor de privacidad completo (API core_privacy: metadata\provider, request\plugin\provider y request\core_userlist_provider), en el contexto del sistema.
Los datos del postulante (nombre, cédula, correo, aceptación del aviso de datos e intentos de la prueba) viven en su cuenta de Moodle y en el cuestionario: los exportan y borran los proveedores de Moodle. El plugin solo declara, en local_candenrol_code, qué cuentas usaron cada código (usedby), quién lo creó (createdby) y la fecha de creación (timecreated).
| Operación | Comportamiento |
|---|---|
| Exportar | Lista de códigos donde aparece la persona, con su relación ("Lo usó para rendir la prueba técnica" o "Lo creó") y la fecha de creación. |
| Eliminar a una persona | Se quita su id de usedby y, si fue la autora, createdby queda en 0. El código se conserva. |
| Eliminar a todos en el contexto | usedby queda vacío y createdby en 0 en todos los códigos. |
Cómo se atiende una solicitud de datos: Políticas y privacidad.