Conectividad
Ping barato contra cada servicio — no confirma que un job real vaya a funcionar de punta a punta, solo que el servicio responde.
Resend no tiene un ping gratis sin mandar un email real — mandá un código de prueba a una dirección y validalo acá para confirmar credenciales y entrega.
Historial de descargas (compartir archivos)
Accesos a la API machine-to-machine. Informa: quién pidió qué, si terminó ok, y cuánto tardó.
Lista blanca de IPs (Comparte Archivos)
Mejora de seguridad sobre el token compartido (VRAG_TOKEN) de /api/share/* — con al menos
una IP acá, cualquier otra queda bloqueada en los 3 endpoints (listado y descarga), aunque tenga el token correcto.
Vacía = sin restricción de IP, como hasta ahora. El "nombre de usuario" es solo para identificar en el historial de
arriba quién es cada IP — no es una credencial.
Ojo: detrás de un proxy (Nginx Proxy Manager), esta IP es la IP pública del llamador, no una máquina física — varias PCs detrás del mismo router comparten la misma IP pública.
Lista blanca de IPs (Buscador)
Protege el login de las cuentas con rol usuario al Buscador/Asesor — con al menos una IP acá,
cualquier cuenta usuario que intente entrar desde otra IP queda rechazada en el login mismo
(nunca llega a crear sesión). El rol admin nunca queda bloqueado por esto — tiene su propio control
de acceso vía /admin/*. Lista separada de la de Comparte Archivos (arriba): son casos distintos,
autorizar acá no habilita la API machine-to-machine ni viceversa. Vacía = sin restricción, como hasta ahora.
Accesos al Buscador (login)
Todo intento de login, de cualquier rol — aceptado o rechazado, y por qué (credenciales inválidas o IP no autorizada).
Reprocesar documentos con espaciado dañado
Documentos ya cargados que quedaron con palabras pegadas por un bug de extracción ya corregido (ver CLAUDE-memory.md 2026-08-05). Se re-extraen desde /backup (o MinIO si falta) — no hace falta volver a subir nada.
El resumen de "Historial de carga" (/admin/carga) cuenta estos documentos por una columna que no se completa sola para lo cargado antes de este fix — actualizala acá si el conteo no coincide con "Ver candidatos".
Segunda pasada con IA de visión
Documentos que ni el OCR mecánico pudo leer (manuscritos, fotocopias sin tinta, sellos/firmas) — se reprocesan con el modelo de visión configurado en el servidor (VRAG_VISION_*). Sin esas variables configuradas, el reproceso falla explícito por documento en vez de fingir éxito.
Referencia de Adjudicatarios
Importa Adj.csv (expediente ↔ contrato ↔ titular) como tabla de referencia completa en SQLite, y agrega al
grafo del Asesor 2 datos por expediente ya cargado: DNI y nombre del titular. El resto de las columnas queda solo en SQL.
El archivo no se sube por acá — copialo por SCP/WinSCP a ${VIVIRAG_PATH}/data/Adj.csv en el
servidor antes de importar.
Consultando estado…
Control contra la referencia
Archivos que las columnas de rutas de Adj.csv nombran para cada expediente y que todavía no figuran
cargados. Match por nombre de archivo exacto — no se normaliza (principio "nombre de archivo intacto").
Conversión de Archivos (Etapa 37)
Reconstruye, por expediente, un PDF por cada categoría de Adj.csv con hojas asignadas (más Sin_clasificar.pdf
para las que no quedan en ninguna) a partir de las hojas sueltas (lee de /backup,
nunca pide el archivo de nuevo) y sustituye las hojas sueltas en MinIO por el documento fusionado —
las citas de búsqueda ya indexadas se re-apuntan solas, no hace falta re-cargar nada. Un expediente con datos
inconsistentes en Adj.csv (ninguna categoría asignada, una hoja en 2 categorías, una hoja que falta, o con más de
1 página) se informa como error y no se toca. Se puede volver a correr las veces que haga falta: lo que no cambió
se saltea solo.
Consultando estado…
⚠ Borrar historial de carga con error
Borra únicamente las filas de historial con status "error". Los documentos ya cargados (done/duplicate) nunca se tocan acá — son el inventario que usa la API de compartir archivos.
⚠ Limpieza total
Vacía MinIO y Qdrant por completo, y borra el historial/registro de SQLite. Irreversible. No toca /backup en disco.