# IPSExtractor Sistema de extracción y análisis de datos desde facturas médicas PDF. Arquitectura de microservicios: cada servicio tiene su propia API, dependencias, Dockerfile y código de dominio. No hay paquetes compartidos entre servicios. --- ## Servicios | Servicio | Puerto (host) | Puerto (interno) | Tecnología | Descripción | |----------|---------------|------------------|------------|-------------| | `api_gateway` | **8189** | 8000 | Python/FastAPI | Única puerta de entrada expuesta al host | | `extraction` | — | 8001 | Python/FastAPI | Extracción LLM; solo red Docker | | `cleaning` | — | 8002 | Python/FastAPI | Limpieza; solo red Docker | | `poblacion_apta` | — | 8003 | Python/FastAPI | Población apta (Verificador ST); solo red Docker | | `count-api` | — | 8080 | Go | Conteo OCR+ONNX; solo red Docker | | `database` | — | 5432 | PostgreSQL 16 | Solo red Docker | | `redis` | — | 6379 | Redis 7 | Solo red Docker | | `desktop_app` | local | Electron + React | Aplicación de escritorio | | `bot-descarga` (API) | — | 8200 | Python/FastAPI | Control remoto de bots; solo red Docker | --- ## Bots externos (`bots/`) Agents para instalar **en PCs** (no Docker). Carpetas hermanas de `services/`. | Carpeta | Descripción | |---------|-------------| | [`bots/bot_descarga`](bots/bot_descarga) | Agent Selenium + MinIO; se conecta a la API `services/bot_descarga` vía gateway | Ver [`bots/README.md`](bots/README.md). ## Flujo principal ``` Desktop app │ ├─ Conteo (OCR + ML) │ ├─ POST /count/v1/count → count-api (lotes de 10 PDFs) │ ├─ POST /count-jobs → extraction (guarda en PostgreSQL) │ └─ PATCH /count-jobs → extraction (validación humana) │ └─ Extracción (LLM) ├─ POST /tasks/extraction/from-count → extraction (lee desde /data) ├─ POST /tasks/{id}/ingest-many → extraction (subida de PDFs) └─ GET /tasks/{id}/rows → extraction (resultados) ``` --- ## Arrancar el stack completo ```bash # Clonar y configurar cp .env.example .env # Editar .env con las API keys del LLM y la ruta de documentos docker compose up --build ``` Health checks: ```bash curl http://127.0.0.1:8189/health/live # liveness del gateway (rápido) curl http://127.0.0.1:8189/health # gateway (agrega estado de los 3 servicios) curl http://127.0.0.1:8189/jobs # lista de trabajos ``` > **Windows:** use `127.0.0.1` en lugar de `localhost` para el API Gateway. Docker publica el puerto en IPv4; `localhost` puede resolver a `::1` y la conexión queda colgada. > Los demás servicios (extraction, count-api, postgres, redis) **no** exponen puertos al host; solo el gateway en **8189**. ### Solución a fallos de build paralelo en Docker Desktop Si `docker compose up --build` falla con `frontend grpc server closed unexpectedly` al construir `count-api`, es porque Docker Desktop (Compose v2.37+) lanza todos los builds en paralelo y BuildKit se satura. Hay dos opciones: **Opción A — pre-construir count-api antes del stack completo (recomendada):** ```bash docker compose build count-api docker compose up --build ``` **Opción B — desactivar Bake y limitar el paralelismo:** ```powershell # PowerShell $env:COMPOSE_BAKE="false" $env:COMPOSE_PARALLEL_LIMIT="2" docker compose up --build ``` ```bash # bash / WSL COMPOSE_BAKE=false COMPOSE_PARALLEL_LIMIT=2 docker compose up --build ``` Ver también las variables `COMPOSE_BAKE` y `COMPOSE_PARALLEL_LIMIT` en `.env.example`. --- ## Variables de entorno principales | Variable | Descripción | |----------|-------------| | `IPS_DOCUMENT_ROOT` | Carpeta local con los documentos PDF (montada en `/data`) | | `EXTRACTOR_API_KEY` | API key del LLM (OpenAI, xAI, etc.) | | `EXTRACTOR_BASE_URL` | URL base del LLM (default: OpenAI) | | `EXTRACTOR_MODEL` | Modelo de extracción (default: `gpt-5.4-mini`) | | `WORKER_REPLICAS` | Réplicas del worker de extracción (default: `2`) | Ver `.env.example` para la lista completa. --- ## Estructura del repositorio ``` bots/ bot_descarga/ — agent Selenium para PCs (instalación externa) → README services/ api_gateway/ — proxy HTTP (Python) → README extraction/ — LLM + jobs + conteo BD (Python) → README cleaning/ — limpieza de datos (Python) → README poblacion_apta/ — población apta / Verificador ST → README bot_descarga/ — API control remoto de bots → README count-api/ — OCR + ONNX stateless (Go) → README db/ — migraciones Alembic → README desktop_app/ — app Electron + React → README docs/ database.dbml — esquema completo de la BD docker-compose.yml — stack completo .env.example — variables de entorno de referencia ``` --- ## Base de datos (esquema resumido) ``` jobs — contenedor de un trabajo del usuario tasks — módulo ejecutado (counting / extraction / cleaning / poblacion_apta) count_job_files — resultado de conteo por PDF extraction_batches — lote de extracción extraction_rows — fila extraída por documento cleaning_jobs — job de limpieza cleaned_rows — fila transformada poblacion_apta_jobs — consolidado validado (PASO_BOT) poblacion_apta_rows ``` Esquema completo: [`docs/database.dbml`](docs/database.dbml) --- ## Documentación por servicio - [`docs/MIGRACION_MICROSERVICIOS.md`](docs/MIGRACION_MICROSERVICIOS.md) — migración desde `main`, arquitectura, escalabilidad y app desktop v1.0.0 - [`services/api_gateway/README.md`](services/api_gateway/README.md) - [`services/extraction/README.md`](services/extraction/README.md) - [`services/cleaning/README.md`](services/cleaning/README.md) - [`services/poblacion_apta/README.md`](services/poblacion_apta/README.md) - [`services/services-count-facturas-medicas-serving/README.md`](services/services-count-facturas-medicas-serving/README.md) - [`services/db/README.md`](services/db/README.md) - [`services/desktop_app/README.md`](services/desktop_app/README.md) - [`services/bot_descarga/README.md`](services/bot_descarga/README.md) - [`bots/bot_descarga/README.md`](bots/bot_descarga/README.md)