# Cuatro intervenciones implementadas — Guía maestra Paquete técnico que materializa las cuatro intervenciones del documento `ciclo_vida_procesos_buscador.md`. Cada intervención llega con sus archivos listos para integrar en el proyecto. --- ## Mapa de archivos | # | Intervención | Archivos | Lenguaje/Formato | |---|---|---|---| | 1 | Clasificador de fases | `01_fases.yaml` | YAML | | 2 | Email reorganizado | `02_email_template.html` + `02_email_especificacion.md` | HTML + Markdown | | 3 | Vinculación de fases | `03_catalogo_administraciones.yaml` + `03_catalogo_cuerpos.yaml` + `03_db_procesos_schema.sql` + `03_id_proceso.py` | YAML + SQL + Python | | 4 | Extracción de temario | `04_db_temarios_schema.sql` + `04_parser_bases.py` + `04_diff_temarios.py` | SQL + Python | Total: 9 archivos. Todos los Python son **referencia ejecutable** con las dependencias claras al inicio de cada uno. --- ## Cómo se integran entre sí ``` ┌─────────────────────────────────────────────────────────────┐ │ MOTOR DEL BUSCADOR (existente, a ampliar) │ │ │ │ 1. Descarga boletines del día │ │ 2. Aplica los patrones del diccionario maestro │ │ 3. Para cada hit candidato: │ │ ↓ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ INTERVENCIÓN 1: clasificador de fases │ │ │ │ Carga `01_fases.yaml` y etiqueta el hit con: │ │ │ │ - fase: oep | bases | apertura | subfase | desconocida │ │ │ - subtipo (si aplica): lista_admitidos, ... │ │ │ └─────────────────────────────────────────────────────┘ │ │ ↓ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ INTERVENCIÓN 3: vinculación de fases │ │ │ │ Usa `03_id_proceso.py` con los catálogos: │ │ │ │ - identifica administración convocante │ │ │ │ - identifica cuerpo/escala/categoría │ │ │ │ - genera id_proceso determinista │ │ │ │ - persiste en BD `03_db_procesos_schema.sql` │ │ │ └─────────────────────────────────────────────────────┘ │ │ ↓ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ INTERVENCIÓN 4: si fase == bases │ │ │ │ Ejecuta `04_parser_bases.py` sobre el PDF: │ │ │ │ - extrae datos estructurados (plazas, tasas, ...) │ │ │ │ - extrae temario completo │ │ │ │ - persiste en BD `04_db_temarios_schema.sql` │ │ │ │ - ejecuta `04_diff_temarios.py` contra anterior │ │ │ └─────────────────────────────────────────────────────┘ │ │ ↓ │ │ 4. Agrupa hits del día por categoría y por proceso │ │ 5. Genera email con `02_email_template.html` │ │ ↓ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ INTERVENCIÓN 2: email enviado al usuario │ │ │ │ Bloque BASES arriba (destacado) │ │ │ │ Bloque OEP │ │ │ │ Bloque apertura plazo │ │ │ │ Bloque sub-fases (plegado) │ │ │ │ Bloque FP (plegado) │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Dependencias técnicas mínimas - **Backend**: Python 3.10+ - **Base de datos**: PostgreSQL 14+ (los esquemas usan `JSONB`, `tsvector` y `pgvector`) - **PDF**: `pdfplumber` (mejor que `pypdf2` para tablas) + `pdfminer.six` como fallback - **Embeddings semánticos**: `sentence-transformers` con modelo `paraphrase-multilingual-MiniLM-L12-v2` (multilingüe, 118 MB, CPU ok) - **Email**: `jinja2` para renderizado de plantilla, cualquier librería SMTP para envío - **YAML**: `pyyaml` - **Normalización de texto**: `unidecode` para acentos, `re` para expresiones regulares `requirements.txt` propuesto: ``` pdfplumber>=0.10 pdfminer.six>=20221105 sentence-transformers>=2.6 psycopg2-binary>=2.9 pgvector>=0.2 jinja2>=3.1 pyyaml>=6.0 unidecode>=1.3 python-dateutil>=2.8 ``` --- ## Orden de implementación recomendado 1. **Crear las tablas** (`03_db_procesos_schema.sql` y `04_db_temarios_schema.sql`). 2. **Cargar los catálogos** YAML como configuración del aplicativo. 3. **Implementar el clasificador de fases** usando `01_fases.yaml`. Este es el cambio mínimo viable: solo con esto y la reorganización del email ya tienes el Sprint 1 cerrado. 4. **Implementar `03_id_proceso.py`** para empezar a generar `id_proceso` y poblar la tabla de procesos. 5. **Implementar `04_parser_bases.py`** para extraer datos y temario cuando aparezcan bases. 6. **Implementar el diff de temarios** una vez haya al menos un temario histórico para comparar. 7. **Integrar la plantilla del email** con los datos enriquecidos. --- ## Test de aceptación con datos reales Cuando todo esté en marcha, validar con tres documentos del histórico: 1. **OEP estatal**: `BOE-A-2026-9946` (Real Decreto 387/2026, 7-mayo-2026). - Debe clasificarse como **fase: oep** en todas las categorías. - Debe crear ~50 procesos (uno por cuerpo del Anexo I). - Cada proceso queda en estado "esperando bases". 2. **Bases de una convocatoria autonómica o local**: cualquier convocatoria pasada de Inspector de Hacienda, TAG municipal, enfermero/a, etc. - Debe clasificarse como **fase: bases**. - El parser debe extraer plazas, ejercicios, tasa, tribunal y temario completo. - El temario debe poder compararse contra el de la convocatoria anterior del mismo cuerpo. 3. **Apertura de plazo en BOE**: convocatoria reciente del BOE que llame a un proceso ya con bases publicadas. - Debe clasificarse como **fase: apertura**. - Debe vincularse al `id_proceso` correcto (la administración + cuerpo + año coincide con uno ya existente). - Debe extraer fecha fin de plazo y generar evento de calendario. Si los tres pasan, el ciclo completo funciona.