# Buscador Multisearch — Proyecto completo Paquete de documentación técnica y entregables del proyecto de rediseño del Buscador Multisearch para CGD Formación. Fecha de empaquetado: 12 de mayo de 2026. --- ## Qué es este paquete 28 archivos organizados que cubren, en conjunto, el diseño y la especificación técnica de un sistema para detectar, clasificar, vincular y notificar convocatorias de oposiciones públicas a lo largo de su ciclo de vida completo (de la OEP a la toma de posesión). El paquete incluye: - Análisis comparativo de los dos buscadores existentes y diagnóstico de mejoras. - Diccionario maestro de 25 categorías temáticas con patrones, exclusiones y catálogo oficial de cuerpos OEP 2026. - Plan de mejora continua del sistema (cuatro bucles de aprendizaje). - Modelo de las 10 fases formales del proceso selectivo conforme al EBEP y al RD 364/1995. - Esquemas completos de base de datos PostgreSQL. - Algoritmos Python ejecutables: identificación de procesos, parser de bases con extracción de temario, diff semántico de temarios entre convocatorias, motor de reglas de notificación, generador de calendarios iCal, web watcher para monitorizar tablones electrónicos. - Plantillas HTML del email diario y del email inmediato. - Especificación completa del dashboard web con wireframes navegables. - Sistema de monitorización externa de URLs (tablones, sedes electrónicas, webs específicas) e información manual por proceso (notas, pendientes, contactos, adjuntos). Total: aproximadamente 12.000 líneas de documentación y código de referencia. --- ## Cómo está organizado Los archivos están numerados según el orden en que se desarrollaron durante el proyecto. Los números bajos (00-17) son los entregables técnicos finales; los números altos (90-93) son los documentos conceptuales iniciales que dan el contexto y la justificación. ### Bloque 1 · Documentos conceptuales (contexto del proyecto) | Archivo | Para qué sirve | |---|---| | `90_mejoras_buscador_multisearch.md` | Diagnóstico inicial del Buscador Multisearch existente: duplicación, falta de cobertura en Madrid y Cádiz, diccionario corto, sistema de confianza con 14 reglas de exclusión, ejecución 7 días/semana. Briefing original para el desarrollador. | | `91_diccionario_maestro_oposiciones.md` | Catálogo completo de patrones para las 24 categorías temáticas iniciales (administración general, hacienda, justicia, seguridad social, instituciones penitenciarias, diplomacia, informática y TIC, sanidad, educación, archivos/bibliotecas, estadística, ingenierías, medio ambiente, meteorología, transportes, agricultura, defensa, empleo, investigación, industria, habilitación nacional, entes públicos, personal laboral AGE, servicios sociales). Catálogo oficial de cuerpos OEP 2026 con códigos del BOE. | | `92_mejora_continua_buscador.md` | Plan para que el sistema mejore solo con el tiempo. Cuatro bucles encadenados (diario, semanal, mensual, trimestral), distinguiendo qué se automatiza y qué requiere validación humana. Cuándo introducir IA/LLM. | | `93_ciclo_vida_procesos_buscador.md` | Concepto del ciclo de vida del proceso selectivo. Diseño inicial con 3 fases (que luego se amplió a 10). Introducción a la vinculación de fases por `id_proceso` y a la extracción del temario con diff. | ### Bloque 2 · Implementación técnica (los 18 archivos numerados 00-17) Las cuatro intervenciones iniciales: | Archivo | Para qué sirve | |---|---| | `00_README_intervenciones.md` | Guía maestra de las cuatro intervenciones técnicas. Diagrama de flujo de cómo encajan, dependencias (PostgreSQL 14+, pdfplumber, sentence-transformers, jinja2, pgvector), orden de implementación recomendado, test de aceptación con datos reales. | | `01_fases.yaml` | **(versión inicial)** Clasificador de cuatro fases con palabras-ancla. Sustituido por `06_fases_extendido.yaml`. Se mantiene aquí por referencia histórica. | | `02_email_template.html` | Plantilla Jinja2 del email diario, organizada en cinco bloques visuales por fase con las bases destacadas arriba en verde. CSS inline para compatibilidad de clientes de email. | | `02_email_especificacion.md` | Acompaña a la plantilla anterior. Filosofía del email, lógica de orden, casos extremos (día sin hits, OEP estatal masiva, OCR roto), compatibilidad con Outlook, versión texto plano, tracking de píxel y enlaces de feedback. | | `03_catalogo_administraciones.yaml` | Catálogo normalizado de administraciones convocantes: AGE, ministerios, organismos autónomos, 17 CCAA, ciudades autónomas, servicios de salud autonómicos, diputaciones, ayuntamientos grandes, universidades. Extensible. | | `03_catalogo_cuerpos.yaml` | Catálogo de cuerpos, escalas y categorías profesionales con código oficial XXXX. Todos los cuerpos de la OEP estatal 2026 (Anexos I, II, III, IV) más categorías comunes en autonomías y ayuntamientos más cuerpos sanitarios. | | `03_db_procesos_schema.sql` | Esquema PostgreSQL completo para procesos selectivos: tablas `procesos`, `eventos_proceso`, `tribunales`, `fechas_clave`, `usuarios`, `suscripciones`, `alertas`, `hit_feedback`, `resumenes_enviados`, más vistas `procesos_huerfanos` y `procesos_activos_resumen`. | | `03_id_proceso.py` | Algoritmo de generación determinista del `id_proceso` (formato `admin__cuerpo__año__turno`). Clase `IdentificadorProceso` con métodos para detectar administración, cuerpo, año y turno a partir del texto del boletín. | | `04_db_temarios_schema.sql` | Esquema PostgreSQL para temarios históricos. Usa pgvector para embeddings de 384 dimensiones. Tablas `temarios`, `temas`, `diff_temarios`, función SQL `buscar_temas_similares` para búsqueda semántica. | | `04_parser_bases.py` | Parser de bases de convocatoria. Usa pdfplumber. Extrae plazas por turno, sistema selectivo, descripción de ejercicios, tasa de examen, composición del tribunal, requisitos de titulación, y el temario completo estructurado por parte general/específica. | | `04_diff_temarios.py` | Diff semántico entre temarios de convocatorias distintas. Usa sentence-transformers con modelo multilingüe. Asignamiento bipartito greedy. Clasifica cada tema como idéntico, reformulado, nuevo o eliminado. | El sistema de notificaciones: | Archivo | Para qué sirve | |---|---| | `05_README_notificaciones.md` | Guía maestra del sistema de notificaciones. Diez fases formales del proceso selectivo. Cuatro canales (email diario, email inmediato, dashboard, calendario iCal). Matriz fase × canal × público objetivo. Tres niveles de reglas configurables. | | `06_fases_extendido.yaml` | **(versión final, sustituye a `01_fases.yaml`)** Clasificador con las 10 fases formales del EBEP. Cada fase con su urgencia, público objetivo, prioridad de email, canales preferidos y palabras-ancla. Más modificadores cruzados (corrección de errores, ampliación de plazo, composición de tribunal). | | `07_db_alertas_y_reglas.sql` | Esquema PostgreSQL para alertas, reglas y suscripciones. Siete tablas nuevas: `suscripciones_proceso`, `preferencias_notificacion`, `reglas_notificacion`, `eventos_notificacion`, `notificaciones_enviadas`, `silenciados`. Función SQL `evaluar_destinatarios`. | | `08_email_alerta_template.html` | Plantilla Jinja2 del email inmediato (mucho más concisa que el diario). Un solo evento, dos botones, enlace para silenciar futuras alertas similares. Tablas anidadas para máxima compatibilidad con Outlook. | | `09_dashboard_especificacion.md` | Especificación completa del dashboard web. Stack recomendado FastAPI/Django con HTMX o Alpine. Nueve pantallas detalladas. Endpoints API mínimos. Roles soportados. MVP por sprints. | | `10_calendario_ics.py` | Generador de calendarios iCalendar (.ics) suscriptibles desde Google Calendar, Outlook o Apple Calendar. URL única por usuario con token aleatorio. Recordatorios automáticos por tipo de fecha (7 días y 1 día antes para fin de plazo; 30, 7 y 1 día para exámenes). | | `11_motor_reglas.py` | Motor de evaluación de reglas con mini-DSL declarativo (operadores `equals`, `in`, `gt`, `contains`, `between`, `regex`; combinadores `all`, `any`, `not`; notación punto para campos anidados). Clase `MotorReglas` con antispam, idempotencia, persistencia. **18 tests unitarios** que pasan todos. | | `12_dashboard_wireframes.html` | Wireframes navegables del dashboard como HTML estático autónomo (se abre con doble clic). Nueve páginas conectadas con mini-router en JavaScript. Diseño minimalista con paleta neutra. | | `13_diccionario_deporte.yaml` | Categoría DEPORTE completa (la 25ª, core business de la academia). Patrones de alta confianza (técnicos deportivos, monitores especialistas, profesores de EF, socorristas, personal del CSD), patrones acotados, seis exclusiones específicas, administraciones relevantes (CSD, AEPSAD, IMD, patronatos). | La monitorización externa: | Archivo | Para qué sirve | |---|---| | `14_README_monitorizacion_externa.md` | Concepto y justificación: el art. 16 del RD 364/1995 permite que los anuncios sucesivos al iniciar el proceso vayan al tablón, no al BOE. Sin monitorizar tablones se pierde toda la cola del proceso. | | `15_db_enlaces_y_notas_schema.sql` | Esquema PostgreSQL para enlaces externos monitorizados, snapshots de URL, archivos detectados, notas manuales (tipos: nota, pendiente, contacto, observación), etiquetas y adjuntos manuales. | | `16_web_watcher.py` | Motor de monitorización web. Clase `WebWatcher`. Frecuencia adaptativa según fase. Respeto a servidores (User-Agent identificable, rate limit, robots.txt). Normalización de HTML antes de hashear. Detección de archivos PDF/DOCX nuevos. Integración con parser y clasificador. | | `17_dashboard_enlaces_notas.md` | Especificación de las dos nuevas secciones del dashboard en el detalle del proceso: "Enlaces monitorizados" e "Información manual" (con pestañas: notas / pendientes / contactos / adjuntos). Permisos y visibilidad. | --- ## Cómo se relacionan entre sí ``` ┌──────────────────────────────────────────┐ │ FUENTES DE DATOS │ │ │ │ Boletines oficiales (BOE, │ │ autonómicos, provinciales) │ │ + │ │ URLs externas monitorizadas │ │ (tablones, sedes, web del proceso) │ │ + │ │ Adjuntos manuales subidos al sistema │ └─────────────────┬────────────────────────┘ ↓ ┌──────────────────────────────────────────┐ │ PIPELINE COMÚN DE PROCESAMIENTO │ │ │ │ 1. Clasificador de fases (06_fases_*) │ │ 2. Identificador de proceso (03_id_*) │ │ 3. Parser de bases (04_parser_*) │ │ 4. Diff de temarios (04_diff_*) │ │ 5. Motor de reglas (11_motor_*) │ └─────────────────┬────────────────────────┘ ↓ ┌──────────────────────────────────────────┐ │ ALMACENAMIENTO (PostgreSQL) │ │ │ │ procesos, eventos_proceso, temarios, │ │ fechas_clave, tribunales, enlaces, │ │ archivos_detectados, notas, alertas, │ │ reglas, notificaciones, snapshots... │ └─────────────────┬────────────────────────┘ ↓ ┌──────────────────────────────────────────┐ │ CANALES DE SALIDA │ │ │ │ Email diario Email inmediato │ │ (02_email_*) (08_email_*) │ │ │ │ Dashboard web Calendario iCal │ │ (09, 12, 17) (10_calendario_*) │ └──────────────────────────────────────────┘ ``` --- ## Stack técnico necesario - **Backend**: Python 3.10+ - **Base de datos**: PostgreSQL 14+ con extensiones `uuid-ossp`, `pg_trgm`, `vector` (pgvector) - **PDF**: pdfplumber + pdfminer.six - **Embeddings semánticos**: sentence-transformers con modelo `paraphrase-multilingual-MiniLM-L12-v2` (118 MB, CPU suficiente) - **Email**: jinja2 para renderizado de plantillas - **Web scraping**: requests + beautifulsoup4 - **Calendarios**: icalendar (Python) - **Web app** (recomendado): FastAPI o Django + HTMX, Alpine.js o Vue 3. No es necesario un SPA pesado tipo React. `requirements.txt` propuesto en `00_README_intervenciones.md`. --- ## Orden recomendado de implementación Por sprints incrementales: **Sprint 1 — Mínimo viable mejorado (2 semanas):** - Crear las dos BD base (`03_db_procesos_schema.sql`, `04_db_temarios_schema.sql`). - Cargar catálogos YAML como configuración. - Implementar clasificador de fases con `06_fases_extendido.yaml`. - Integrar plantilla del email diario reorganizado (`02_email_template.html`). Con esto ya tienes una mejora cualitativa sobre el buscador actual. **Sprint 2 — Vinculación de procesos (2 semanas):** - Implementar `03_id_proceso.py` para empezar a generar `id_proceso` y poblar la tabla de procesos. - Dashboard mínimo con vista de inicio y detalle de proceso (timeline de 10 fases). **Sprint 3 — Extracción de temario (3 semanas, es lo más complejo):** - Implementar `04_parser_bases.py` cuando aparezca la primera convocatoria con bases tras desplegar. - Implementar `04_diff_temarios.py` una vez haya un temario histórico. - Añadir vista de temarios al dashboard. **Sprint 4 — Sistema de notificaciones (2 semanas):** - Crear esquema `07_db_alertas_y_reglas.sql`. - Implementar `11_motor_reglas.py` con sus 18 tests. - Plantilla del email inmediato (`08_email_alerta_template.html`). - Pantalla de preferencias en el dashboard. **Sprint 5 — Calendario y reglas avanzadas (1-2 semanas):** - Implementar `10_calendario_ics.py`. - Editor YAML de reglas avanzadas en el dashboard. **Sprint 6 — Monitorización externa (3-4 semanas):** - Crear esquema `15_db_enlaces_y_notas_schema.sql`. - CRUD de notas, pendientes, contactos en dashboard. - Implementar `16_web_watcher.py` con rate limit y respeto a robots.txt. - Vista de enlaces monitorizados en el detalle de proceso. Total estimado: 13-16 semanas para el proyecto completo. El sprint 1 ya es desplegable de forma autónoma y aporta valor diferencial sobre lo que hay ahora. --- ## Cómo abrir cada tipo de archivo | Extensión | Cómo abrirlo | |---|---| | `.md` | Cualquier editor de texto o visor de Markdown (VS Code, Typora, GitHub, GitLab) | | `.yaml` | Editor de texto (VS Code con extensión YAML recomendado) | | `.sql` | Editor SQL o de texto (DBeaver, pgAdmin, VS Code) | | `.py` | Editor de Python (VS Code, PyCharm). Ejecutable con `python3 archivo.py` | | `.html` | Navegador web (doble clic). Especialmente `12_dashboard_wireframes.html` que es navegable | El archivo `12_dashboard_wireframes.html` es autónomo: se abre con doble clic en cualquier navegador (no necesita servidor ni dependencias) y permite recorrer las nueve pantallas del dashboard para validar UX antes de programar nada. --- ## Para validar antes de empezar a desarrollar Tres pruebas de aceptación recomendadas con datos reales: 1. **OEP estatal 2026** (BOE-A-2026-9946, RD 387/2026 de 7-may-2026): debe clasificarse como fase **OEP** en todas las categorías relevantes y crear los procesos correspondientes en estado "OEP publicada". 2. **Bases de una convocatoria pasada** (cualquier convocatoria reciente de Inspector de Hacienda, TAG municipal, enfermera, etc.): el parser debe extraer plazas, ejercicios, tasa, tribunal y temario completo. El temario debe poder compararse con la convocatoria anterior del mismo cuerpo. 3. **Apertura de plazo en BOE reciente**: debe clasificarse como fase **presentación de solicitudes** y vincularse al `id_proceso` correcto (la administración + cuerpo + año coincide con un proceso ya existente). Debe extraer la fecha fin de plazo y generar evento de calendario. Si los tres pasan, el ciclo completo funciona correctamente. --- ## Contacto y referencias Proyecto desarrollado para CGD Formación (oposicionesdeporte.com). Material complementario en el repositorio: estructura de carpetas, historial de decisiones de diseño, documentación adicional de cada componente. Para dudas técnicas durante la implementación, los archivos `.md` incluyen secciones de "comentarios de uso" y los archivos `.py` traen ejemplos en su `__main__` y, en el caso del motor de reglas, 18 tests unitarios que sirven como documentación viva del comportamiento esperado.