MF.
ESEN
Volver al portfolio

Estudio de caso / Automatización · Búsqueda de empleo

Kairo

De fuentes dispersas a oportunidades con contexto.

Plataforma de descubrimiento, monitorización y gestión de oportunidades laborales con matching explicable y candidaturas supervisadas.

Tecnologías utilizadas
Next.js · React · NestJS · TypeScript · PostgreSQL · Prisma · Redis · BullMQ · OpenAI · Playwright

El problema

Buscar empleo exige revisar fuentes repetidas, eliminar duplicados, detectar cambios y preparar documentos. Kairo convierte ese trabajo en procesos con estados y validaciones, manteniendo las decisiones de candidatura bajo control del usuario.

Mi participación

Desarrollo el frontend Next.js, la API NestJS y un worker BullMQ independiente. Implemento ingestión, adapters ATS, matching, presupuesto de IA y el dominio de oportunidades y candidaturas con materiales privados y versionados.

Qué permite hacer

Descubrir y mantener un universo de fuentes

Discovery registra candidatos y evidencia antes de incorporarlos. Monitoring consulta fuentes conocidas como Lever, Greenhouse y Ashby mediante adapters; normaliza ofertas, detecta cambios y conserva ejecuciones y errores.

Priorizar con una explicación

Perfil y preferencias alimentan validación y matching determinista. Los atributos desconocidos se distinguen de incompatibilidades. El usuario gestiona el estado de cada oportunidad sin que una puntuación cambie su decisión automáticamente.

Preparar y autorizar una candidatura

CV, cartas y respuestas se preparan desde fuentes explícitas, con revisión humana. Aplicar autoriza una candidatura y un paquete concreto. Los runners de formularios compatibles piden intervención ante CAPTCHA, preguntas o controles no soportados.

Cómo encajan las piezas

Un monorepo con workspaces separa Web, API y Worker. PostgreSQL/Prisma almacena fuentes, ofertas, perfiles, oportunidades y paquetes. Redis/BullMQ ejecuta discovery, monitoring, validación y matching mediante jobs y scheduler. OpenAI se utiliza en tareas delimitadas; normalización, validación y scoring determinista permanecen fuera del modelo.

Relaciones entre componentes del MVP
  1. Next.js Web
    Perfil · oportunidades · autorizaciones
    NestJS API
  2. API → Redis / BullMQ
    Discovery · Monitoring · validación
    Worker → ATS
  3. Worker
    Normalización · matching · historial
    PostgreSQL / Prisma
  4. Paquete revisado + Aplicar
    Versión · checksum · autorización
    Runner supervisado

Decisiones de ingeniería

Separar evidencia externa y estado del usuario

Discovery mantiene candidatos en staging antes de la ingestión canónica. Monitoring normaliza y deduplica con adapters y sólo cierra ofertas tras una lectura completa. Validación y matching son deterministas; una puntuación o un fallo de fuente no modifica la etapa de la oportunidad elegida por el usuario.

La IA tiene presupuesto y límites

Las llamadas registran consumo en AiUsage y pasan por reservas y controles de presupuesto. Structured Outputs y validación separan una respuesta del proveedor de un dato aceptado por el dominio.

Autorizar materiales inmutables

ApplicationPackage congela perfil, oferta, respuestas y documentos. Un cambio material invalida la autorización. El runner consume el paquete revisado sin generar nuevos textos con IA durante el envío.

Dificultades resueltas

Evitar envíos duplicados e inciertos

Antes del único envío final se registra submitIntentAt. Una respuesta ambigua deja SUBMISSION_UNKNOWN y no se reintenta automáticamente. La compatibilidad del formulario se inspecciona y caduca; no basta con reconocer el ATS.

Preparar documentos sin inventar experiencia

Los materiales conservan fuentes y hashes. La generación semántica se valida y revisa antes de autorizar; el modo extractivo local ofrece una alternativa sin llamadas de IA.

Capacidades demostrables

Automatización con estado de dominio

Las ejecuciones persistidas permiten seguir errores de fuentes y cambios de ofertas hasta su priorización.

Asistencia bajo control humano

Un paquete revisado y una autorización por candidatura delimitan lo que el runner puede enviar. La compatibilidad sigue limitada a formularios soportados.