IPSExtractor Microservices

Monorepo con servicios separados como si fueran repos independientes. Cada servicio tiene su propia API, dependencias, Dockerfile, codigo de dominio e infraestructura local. No hay paquetes compartidos entre servicios.

services/
  extraction/        Repo/servicio de extraccion
    api/             API FastAPI
    domain/          Dominio propio de extraccion y normalizacion
    core/            Utilidades propias para PDF, texto y filas
    infrastructure/  Persistencia propia del servicio
    requirements.txt
    Dockerfile

  cleaning/          Repo/servicio de limpieza
    api/             API FastAPI
    domain/          Reglas propias de limpieza
    infrastructure/  Persistencia propia del servicio
    requirements.txt
    Dockerfile

  api_gateway/       API central opcional
    api/             Proxy HTTP hacia extraction y cleaning
    requirements.txt
    Dockerfile

  desktop_app/       App desktop Windows/Mac
    electron/        Main process, preload y dialogos nativos
    src/             React UI, cliente API y export CSV
    package.json

La base de datos Postgres es compartida como contrato de integracion, pero el codigo de acceso a datos esta duplicado dentro de cada servicio para que puedan vivir por separado.

Puertos

Servicio Puerto Uso
api_gateway 8000 API central opcional
extraction 8001 API propia de extraccion
cleaning 8002 API propia de limpieza
database 5432 Postgres
desktop_app local App desktop fuera de Docker

Documentacion interactiva:

  • http://localhost:8000/docs
  • http://localhost:8001/docs
  • http://localhost:8002/docs

Variables

IPS_DOCUMENT_ROOT=C:/ruta/a/documentos

# Ejemplo: extraccion con Grok/xAI
EXTRACTOR_PROVIDER=xai
EXTRACTOR_BASE_URL=https://api.x.ai/v1
EXTRACTOR_API_KEY=tu_xai_api_key
EXTRACTOR_MODEL=grok-tu-modelo
EXTRACTOR_TIMEOUT_S=120

# Ejemplo: normalizacion con OpenAI
NORMALIZER_PROVIDER=openai
NORMALIZER_BASE_URL=https://api.openai.com/v1
NORMALIZER_API_KEY=tu_openai_api_key
NORMALIZER_MODEL=gpt-tu-modelo
NORMALIZER_TIMEOUT_S=120

PDF_DPI=600
PDF_THREAD_COUNT=10
CONCURRENCY_LIMIT=4
ALLOWED_DOCUMENT_TYPES=CC,TI,CE,RC,PA,PPT,PEP,EPT,NUIP

Si NORMALIZER_BASE_URL o NORMALIZER_API_KEY se dejan vacios, el servicio usa el mismo backend configurado en EXTRACTOR_BASE_URL y EXTRACTOR_API_KEY.

Dentro de Docker, IPS_DOCUMENT_ROOT se monta como /data.

Levantar

docker compose up --build

Health checks:

curl http://localhost:8000/health
curl http://localhost:8001/health
curl http://localhost:8002/health

Flujo Directo Por Servicio

  1. Ver modelos disponibles en extraccion:
curl http://localhost:8001/models
  1. Descubrir campos:
curl -X POST http://localhost:8001/schemas \
  -H "Content-Type: application/json" \
  -d '{"document_path": "/data/radicado-1/factura.pdf"}'
  1. Ejecutar extraccion:
curl -X POST http://localhost:8001/batches \
  -H "Content-Type: application/json" \
  -d '{
    "root_path": "/data",
    "keywords": ["factura"],
    "fields": ["numero_factura", "items/*/codigo", "items/*/valor"],
    "alias_map": {
      "numero_factura": "factura",
      "items/*/codigo": "codigo",
      "items/*/valor": "valor"
    },
    "structure_mode": "radicados"
  }'

La respuesta devuelve id; ese valor es el batch_id.

  1. Consultar filas extraidas:
curl http://localhost:8001/batches/{batch_id}/rows
  1. Ver reglas de limpieza:
curl http://localhost:8002/rules
  1. Analizar columnas extraidas:
curl http://localhost:8002/batches/{batch_id}/analysis
  1. Ejecutar limpieza:
curl -X POST http://localhost:8002/jobs \
  -H "Content-Type: application/json" \
  -d '{
    "extraction_batch_id": "{batch_id}",
    "rules_per_column": {
      "valor": ["to_integer"],
      "fecha": ["date_to_ddmmyyyy"]
    }
  }'

La respuesta devuelve id; ese valor es el job_id.

  1. Consultar filas limpias:
curl http://localhost:8002/jobs/{job_id}/rows

Flujo Por API Gateway

El gateway no importa codigo interno de los servicios; solo enruta HTTP.

curl http://localhost:8000/models
curl http://localhost:8000/config
curl http://localhost:8000/extraction/batches/{batch_id}/rows
curl http://localhost:8000/cleaning/jobs/{job_id}/rows

Para llamar cualquier endpoint propio de un servicio:

  • http://localhost:8000/extraction/...
  • http://localhost:8000/cleaning/...

Desarrollo Independiente

Extraccion como repo aparte:

cd services/extraction
pip install -r requirements.txt
uvicorn api.main:app --host 0.0.0.0 --port 8001

Limpieza como repo aparte:

cd services/cleaning
pip install -r requirements.txt
uvicorn api.main:app --host 0.0.0.0 --port 8002

Gateway como repo aparte:

cd services/api_gateway
pip install -r requirements.txt
uvicorn api.main:app --host 0.0.0.0 --port 8000

App desktop como repo aparte:

cd services/desktop_app
npm install
npm run dev

La app usa http://localhost:8000 por defecto y traduce rutas locales dentro de IPS_DOCUMENT_ROOT hacia /data para llamar al API. La pantalla principal solo pide seleccionar la carpeta a procesar; los resultados se guardan en base de datos y la exportacion CSV es opcional.

Contrato De Base De Datos

Los servicios se integran por Postgres:

  • extraction_batches
  • extraction_rows
  • tasks
  • cleaning_jobs
  • cleaned_rows

Cada servicio mantiene su propia copia del modelo SQLAlchemy para no depender de un paquete comun.

S
Description
No description provided
Readme
10 MiB
Languages
Python 56.7%
TypeScript 31.3%
CSS 5.5%
JavaScript 3.7%
Go 2%
Other 0.8%