Architecture - TomasPosada2/talent-matchmaker-ai GitHub Wiki

Architecture

Diagrama básico de la solución tal como está construida al cierre de Sprint 5.

flowchart TD
    Z[run_listener.py<br/>polling cada 60s] --> A
    A[Gmail real<br/>gmail_auth OAuth2] -->|gmail_inbox| B[email_detector<br/>detección de adjunto]
    A2[Bandeja simulada<br/>dev/tests] -->|correos con CV| B

    subgraph Ingesta
        B --> B2[attachment_handler<br/>validar/extraer adjunto]
        B2 --> C[malware_scanner<br/>escaneo ClamAV]
        C -->|seguro| D[text_extractor<br/>PDF / DOCX / OCR]
        C -->|inseguro| X1[Descartado]
        D --> E[profile_structurer<br/>+ evidencia textual]
        E --> F[schema<br/>validación]
        F --> G[(PostgreSQL<br/>profile_repository)]
    end

    S1[scripts/migrate_profiles_to_db.py] -.->|migración inicial| G

    subgraph Matching
        H[Vacante estructurada] --> I[Agente de matching<br/>Claude Agent SDK]
        G --> I
        I -->|tool| J[consultar_perfiles]
        I -->|tool| K[verificar_evidencia]
        I --> L[Ranking justificado<br/>+ confianza + costo]
        L --> M[Exportar CSV / PDF]
        L --> N[Notificación por correo]
    end

    subgraph API
        O[FastAPI REST] --> P[JWT por recruiter]
        O --> G
        O --> I
        Q[Job templates] --> G
    end

    R[Panel Streamlit<br/>solo pipeline de ingesta] --> E

    style X1 fill:#f8d7da
    style G fill:#d1ecf1
    style L fill:#d4edda
Loading

Componentes

Componente Responsabilidad Sprint
gmail_auth.py Flujo OAuth2 con Gmail (credentials.json / token.json, refresco automático) 5
gmail_inbox.py Leer correos reales de Gmail y reconstruir sus adjuntos MIME 5
email_polling.py + run_listener.py Listener continuo: detecta correos nuevos cada 60s y corre el pipeline sin intervención manual 5
email_detector.py Detectar correos con CV adjunto sobre la bandeja simulada (dev/tests) 1
attachment_handler.py Validar y extraer el adjunto (tamaño, corrupción) 1
malware_scanner.py Escanear adjuntos con ClamAV antes de procesarlos 5
text_extractor.py Extraer texto de PDF/DOCX, con OCR para escaneados 1, 4
profile_structurer.py Estructurar campos del perfil con evidencia textual 1, 2 (bugfix)
schema.py Validar perfil y ranking contra un schema JSON fijo 1, 3
profile_repository.py Persistencia de perfiles en PostgreSQL 5
scripts/migrate_profiles_to_db.py Migración única de perfiles ya existentes en JSON hacia Postgres 5
vacancy_structurer.py Estructurar la vacante (job description) 3
agent_tools.py Tools del agente: consultar perfiles, verificar evidencia, detectar prompt injection 3, 4
agent.py Agent loop (Thought → Action → Observation) sobre Claude Agent SDK 3, 4
ranking_exporter.py Exportar ranking a CSV/PDF 4
api.py / auth.py API REST y autenticación JWT por recruiter 5
email_notifier.py Notificar por correo cuando un ranking termina 5
job_template_repository.py Plantillas de vacante reutilizables por recruiter 5
app.py (Streamlit) Panel de prueba interno — solo del pipeline de ingesta, no del agente 3
scripts/generate_sample_inbox.py Generar la bandeja simulada de 25 correos (20 CVs + 5 casos borde) para dev/tests 1
scripts/demo_agent_error_handling.py Demo de que un fallo del framework del agente se captura sin tumbar el proceso 3

Lo que todavía no existe

No hay interfaz visual para el agente de matching: hoy solo es accesible por código o por el endpoint POST /rankings de la API (protegido por JWT). El panel Streamlit (app.py) solo sirve para probar la ingesta (Sprint 1/2/3), nunca se conectó al agente ni a la API. Construir esa interfaz (dashboard del recruiter) es el objetivo de Sprint 6.

⚠️ **GitHub.com Fallback** ⚠️