Se integraron correctamente los cambios realizados. Sin pendientes identificados.
- "Ejecutar Análisis IA" — Job en segundo plano implementado.
POST /candidates/ethics/batchcrea unBatchJobProgress(job_type: 'etico_analysis'), responde202 AcceptedconjobIdy procesa de forma asíncrona. El Hub (EticoModule.jsx) tiene el botón "Ejecutar Análisis IA", polling viaGET /batch-jobs/etico_analysis/latesty estado "Analizando…" mientras corre. - Buscador via API ✓
- Ordenamiento via API ✓ (
sort_by+sort_dir) - Paginación via API ✓ (
page+limit) - Filtros via API ✓ (
role,branch_id,company_id,flag_severity,has_flags)
- El análisis ético invoca un LLM (Anthropic Claude o OpenAI GPT-4o). Sin
ANTHROPIC_API_KEYuOPENAI_API_KEYen el entorno, el batch falla con "No hay proveedor de IA configurado". Pendiente de pruebas locales una vez que el cliente provea la key de producción.
Sin observaciones del cliente.
Sin observaciones del cliente.
Sin observaciones del cliente. Ver ítem 24 para requerimientos de fase 2.
Alertas cargando desde API. Dropdowns con label predeterminado y ordenamiento por columna habilitado.
- Alertas se muestran correctamente desde la API. ✓
- Dropdowns "Todos los tipos" / "Todas las severidades" visibles. ✓ — commit
3f171e8 - Ordenamiento columnas Alerta y Tipo. ✓ — commits
a24b683/c55ea21 - Dropdowns alineados a la izquierda (quitado
ml: "auto"). ✓ — commit2b5a9c0
Sin observaciones del cliente.
Sin observaciones del cliente.
- Corregir el flujo completo del módulo.
- Reorganizar y ajustar los endpoints para mantener consistencia con el resto del sistema.
- Buscador por API
- Ordenamiento por API
- Paginación por API
- Filtros por API
Búsqueda, ordenamiento, paginación y filtros via API implementados y estandarizados en todos los módulos.
- Buscador siempre visible y alineado a la izquierda en todos los módulos. ✓ — commit
2b5a9c0 - Búsqueda server-side con debounce — Motor Ético, Scorecard, Seguimiento, Vacantes, Empleados, Usuarios, Predicción, Auditoría. ✓
- Ordenamiento server-side — todos los módulos (ver ítem 18). ✓
- Paginación server-side — todos los módulos. ✓
- Filtros server-side — todos los módulos. ✓
- Implementación anterior revertida (
7db4834) y re-implementada de forma estable por módulo. ✓
- Detalle del empleado —
EmployeeProfile.jsx(1 672 líneas) con tabs y secciones. ✓ - Ligar al candidato —
candidate_iden BD con datos reales; panel de búsqueda en UI. ✓ - Buscador, paginación, filtros, sort — todo server-side ya implementado. Sort por Score fixeado (
sequelize.literal NULLS LAST). ✓ - StatusMap — sincronizado con BD (
active / terminated). Dropdowns condisplayEmpty + renderValue. ✓
- Desarrollar el Reporte Anual completo.
- Incluir toda la información y métricas correspondientes de acuerdo con los requerimientos funcionales.
- Buscador por API
- Ordenamiento por API
- Paginación por API
- Filtros por API
- Incorporar la funcionalidad de Pensión Alimenticia conforme al alcance definido.
- Buscador por API
- Ordenamiento por API
- Paginación por API
- Filtros por API
- ✓ user_roles: un usuario puede tener múltiples roles (admin, gerente, reclutador). La unión de permisos de todos los roles activos define el acceso funcional.
- ✓ user_scopes: tabla
(user_id, company_id, branch_id)define sobre qué datos puede actuar el usuario.(NULL, NULL)= acceso global (admin). - ✓ scopeBranch middleware: inyecta filtro
branch_id IN (...)automáticamente en todas las queries; admins con isGlobalScope lo omiten. - ✓ Gerente y Reclutador solo ven candidatos, vacantes, expedientes y solicitudes de sus sucursales autorizadas.
- ✓ UI de asignación: panel "Editar usuario" con árbol empresa → sucursales; el admin asigna acceso visual e intuitivamente.
- ✓ Panel "Editar usuario": layout dividido — datos del perfil + roles a la izquierda (sticky), árbol de acceso por empresa/sucursal a la derecha.
- ✓ Multi-rol: chips de roles con toggle. La unión de permisos de todos los roles asignados define el acceso funcional del usuario.
- ✓ Árbol de acceso (
SimpleTreeView): muestra todas las empresas; seleccionar una la agrega como acceso; las sucursales se pueden afinar individualmente. Sin formulario "agregar empresa" — el árbol completo siempre visible. - ✓ Guardado unificado: un solo botón "Guardar cambios" persiste perfil, roles y scopes en paralelo.
- ✓ JWT + permissions_version: sesiones activas reciben
stale_permissionsal cambiar roles o accesos y son forzadas a re-autenticar. - ✓ Capa de overrides eliminada: tabla
user_permissionseliminada; modelo simplificado a roles + scopes únicamente. - ✓ Trazabilidad: auditoría de LOGIN, cambio de roles y asignación de accesos.
- ⏳ Menú dinámico derivado de permisos (ítem separado).
Sync job activo. 7 entrevistas sincronizadas con candidate_id, vacancy_id, duration_minutes, score e interviewers (JSONB). Tab de Entrevistas en Detalle del Candidato muestra historial completo con las nuevas columnas. JOS-26 resuelto.
API: https://api.tuvanosa.net/WS/TuvanosaReclutamiento/api/applications/
Sync job activo. 81,307 postulaciones sincronizadas. candidate_id 100%, vacancy_id 99.97%, status 100%. company_id: 4,374 → 62,410 (76.8%) — fix en syncBranchMap() propaga company_id a branches pre-existentes vía COALESCE. Columnas muertas stages/timeline/progress eliminadas de schema y sync. Integridad referencial garantizada por reconciliation passes idempotentes. Log de ejecución con logger.info/error en cada ciclo. JOS-21 resuelto.
Sort server-side, paginación y filtros ya implementados en todos los módulos. Fix displayEmpty + renderValue aplicado en cada dropdown con valor inicial vacío.
- Motor Ético — filtros Rol/Sucursal/Empresa/Alertas + sort Rol y Alertas + buscador siempre visible alineado a la izquierda (sin gap). ✓ — commits
c5e93a1/eabb8c6 - Predicción de Cierres — sort server-side + status filter + sort columnas Empresa y Sucursal + toolbar reemplazado por buscador visible siempre + dropdown Estado, consistente con todos los módulos. ✓ — commit
eeab728 - Scorecard Predictivo — sort + pagination server-side. ✓
- Expediente Digital — dropdowns Estatus/Seniority/CV fixeados. ✓
- Alertas Operativas — sort columnas Alerta y Tipo + dropdowns fixeados. ✓
- Gestión de Empleados — sort/filtros/paginación + score sort
NULLS LASTfixeado + sort Puesto y Estado agregados. ✓ - Gestión de Usuarios — bug raíz corregido (
sort/dir→sort_by/sort_diren hook); sort por Nombre, Rol, Sucursal, Estado y Registro funcionando. ✓ - Seguimiento — sort + filtros + displayEmpty + buscador siempre visible a la izquierda. ✓ — commit
2b5a9c0 - Vacantes — sort server-side + displayEmpty. ✓
- Auditoría Nacional — dropdowns Sucursal/Compañía/Departamento fixeados. ✓
- Gestión de Créditos — sort + displayEmpty. ✓
- Botón Exportar Excel (filtrado activo) + Exportar Todo (sin filtros) en los 5 módulos: Motor Ético, Predicción de Cierres, Alertas, Seguimiento WhatsApp, Scorecard.
- API:
GET /candidates/export(Etico + Scorecard),GET /reports/alerts/export,GET /whatsapp/conversations/export(cap 5 000 filas + fila sentinel),GET /vacancies/export?view=predictivo. - Hub: helper compartido
downloadBlob.js; truncación WhatsApp muestra toast de advertencia. - Rutas registradas antes del wildcard
/:id;branchScopey guards de permiso preservados.
- El buscador debe realizar búsquedas considerando todas las opciones disponibles seleccionadas dentro de cada apartado.
- Permitir múltiples filtros simultáneos y una búsqueda dentro de ese filtrado.
Implementado en todos los módulos — free-text multi-columna combinable con filtros dropdown simultáneamente. Búsqueda SQL con unaccent. Validado 2026-08-23.
| Módulo | Campos de búsqueda | +Filtros |
|---|---|---|
| Motor Ético | name, last_name, mother_name, email, phone, target_role | ✓ |
| Scorecard | Ídem Motor Ético (mismo endpoint) | ✓ |
| Vacantes | title, code, job_function, department + nombres de candidatos vinculados | ✓ |
| Predictivo | Ídem Vacantes (mismo servicio) | ✓ |
| Seguimiento | fullName, phone, whatsapp_number (in-memory) | ✓ |
| Alertas | title, description, entity (in-memory) | ✓ |
| Empleados | name, last_name, email, email_corporate, employee_number, position_title | ✓ |
| Usuarios | name, last_name, email | ✓ |
Incorporar los placeholders correspondientes en los filtros predeterminados de tipo de severidad y estado del candidato.
Implementado — fix displayEmpty + renderValue.
- Eliminar el indicador de Vacantes abiertas duplicado. ✓ Resuelto — commit
499bd65. - Incorporar la columna Responsable de la Vacante en el listado de predicción por vacante. ✓ Resuelto — commit
834278b.
Incorporar la columna Responsable en el listado de candidatos.
Implementado — commit 834278b.
- Permitir la carga del CV del candidato y realizar la extracción automática de información para completar datos faltantes del perfil.
- En el detalle del candidato, permitir consultar la información almacenada en OneDrive únicamente cuando el candidato tenga estatus Contratable, mostrando su expediente completo.
- En el apartado de documentos: mostrar la fecha de carga de cada documento y permitir su visualización.
- Mostrar todos los documentos cargados por el personal de Recursos Humanos.
- Incorporar el checklist completo de documentación requerida (formato a proporcionar por Nancy).
- Habilitar la captura del checklist únicamente cuando el candidato cambie a estatus Contratable.
- Una vez Contratable, habilitar desde el listado una opción para generar el documento de contratación.
- Incorporar los formatos de contratación por empresa (información a proporcionar por Nancy).
- Una vez generado el documento, permitir que el personal valide la información antes de dar de alta al empleado en Nomipaq y demás sistemas.
- Configurar permisos específicos por apartado del perfil del candidato — el administrador tiene acceso completo.
Incorporar los placeholders correspondientes en los filtros disponibles del módulo.
Implementado — fix displayEmpty + renderValue.
- Resolución de identidad RFC-first → CURP fallback con normalización UPPER(TRIM()). Servicio único (
employee-identity.service.js) usado por sync, create() y promoteFromCandidate(). - Motor de merge Union-Find (
employee-merge.service.js): agrupa duplicados transitivos, elige canónico (más reciente activo), reasigna FKs en 11 tablas, registra enemployee_merge_audit. - Backfill ejecutado: 2,260 empleados procesados → 21 grupos colapsados → 77 filas mergeadas, 0 errores. Migraciones M1–M4 aplicadas.
- Sync rewrite (G5d): match-before-insert con dedup, democión de is_current,
employee_position_historypoblada (2,208 registros). - Timeline multi-empresa en perfil del empleado: sección "Trayectoria Multi-empresa" con historial cronológico inverso y chip "Actual".
Verificado: 33/33 tests verdes. Backfill corrido en local. Timeline visible en Hub. Commit: feat/employee-dedup-m26 — 2026-08-25.
Permitir asignar a los usuarios a una o más empresas, según corresponda.
Implementado — header de empresa clickeable selecciona/deselecciona todas sus sucursales.
- Incorporar una pantalla de configuración que permita administrar y personalizar las plantillas de los mensajes enviados a los candidatos.
Pantalla /dashboard/plantillas con 4 tarjetas editables (recordatorio entrevista, carta oferta, solicitud documentos, recordatorio examen). Placeholder {{nombre}} sustituido al momento de envío. Botón "Restaurar default" para volver al texto original sin deploy. Accesible desde el ícono ⚙ en el módulo de Seguimiento. Validado 2026-08-24.
- Incorporar la columna Reclutador en el listado de vacantes.
- Mostrar el estatus actual de la vacante y una línea de tiempo que identifique la etapa actual del proceso.
- En el detalle de la vacante: permitir visualizar el CV de los candidatos.
- Permitir descargar el CV del candidato.
- Permitir reenviar el CV por correo electrónico al personal correspondiente.
- Permitir acceder directamente al perfil completo del candidato desde el detalle de la vacante.
- Generar una alerta para el personal correspondiente cuando un empleado de la organización se postule a una vacante.
- Campo
is_activeenCandidatecon hooksbeforeSave,beforeBulkCreate,beforeBulkUpdate. Migración con backfill e índice compuesto(is_active, created_at).candidatos.totalfiltrado poris_active = true. - Índice de rotación — Fórmula A:
(bajas / plantilla_fin_período) × 100. Plantilla fin = empleados activos al cierre del periodo víastart_date + termination_date. Versión de fórmula expuesta en footer del PDF. - Top antigüedad — endpoint acepta
top_n(default 10, máx 50). Tabla en Hub con nombre, sucursal, departamento y tenure en meses. - Comparativo YoY —
compare_yearreconstruye snapshot histórico sin tabla adicional. Card "Comparativo Anual" en Hub visible sólo cuando hay año previo. - Fechas de baja consideradas en todos los filtros de periodo:
termination_date IS NULL OR termination_date > endDate.
Verificado: SDD cycle completo. Commits 591483c, 2eb0b4e (API) · 94034f8 (Hub) — 2026-08-25.
- Implementar un mecanismo para solicitar la autorización del candidato antes de realizar consultas sobre su información.
- Enviar la solicitud de autorización mediante el chatbot.
- Una vez obtenida la autorización, permitir la consulta de: IMSS, Fonacot, Infonavit y Pensiones registradas.
- Permitir que los usuarios de Tuvanosa generen requisiciones de personal mediante un formulario.
- El formulario debe permitir especificar: Empresa, Sucursal, Departamento y Necesidad de talento.
- Implementar un flujo de aprobación para las requisiciones.
- Una vez autorizada una requisición, generar automáticamente la vacante correspondiente.
- Permitir asignar un responsable para cubrir la vacante generada.
- Al publicar una vacante: permitir seleccionar al responsable del proceso de reclutamiento.
- Permitir configurar un responsable predeterminado para la vacante.
- Permitir agregar responsables adicionales.
- Los responsables configurados deben utilizarse como contactos para las fuentes de publicación de la vacante.
- Crear un apartado para administrar la configuración de salarios.
- Permitir establecer rangos salariales de acuerdo con: Empresa, Sucursal y Departamento.
- Utilizar el tabulador configurado para establecer un rango inicial al publicar una vacante.
- En el Expediente Digital y en el detalle del perfil, agregar una acción para contratar al candidato.
- Al contratar, inyectar automáticamente la información del candidato en los templates de Tuvanosa correspondientes a la empresa a la que aplicó.
- Una vez completado y autorizado el template, inyectar los datos en Nomipaq.
- Instalar/configurar el proceso en el servidor donde reside la base de datos que conecta con Nomipaq (según guía provista por el cliente).