Architecture - TomasPosada2/talent-matchmaker-ai GitHub Wiki
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
| 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 |
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.