# desktop_app Aplicación de escritorio Electron + React de **Flujo IPS** para interactuar con el stack de servicios. Permite seleccionar carpetas locales, contar servicios en facturas médicas, revisar resultados y lanzar extracciones LLM. --- ## Flujos principales ### Conteo de facturas 1. Seleccionar carpeta con PDFs. 2. Los PDFs se envían en lotes de 10 a `POST /count/v1/count` (count-api). 3. Los resultados se guardan en PostgreSQL vía `POST /count-jobs` (extraction). 4. El usuario revisa y marca archivos como válidos/inválidos. ### Extracción desde conteo 1. Desde el wizard de conteo, clic en "Extraer archivos válidos". 2. Se llama `POST /tasks/extraction/from-count` con el `counting_task_id`. 3. El servicio extraction lee los PDFs desde el volumen `/data` y los procesa con LLM. ### Extracción directa 1. Seleccionar carpeta → discovery de campos → seleccionar campos → estimar costo. 2. Subir PDFs en lotes a `/tasks/{id}/ingest-many`. 3. Polling de progreso vía `GET /tasks/{id}`. 4. Exportar resultados como CSV. --- ## Arquitectura técnica | Capa | Tecnología | |------|-----------| | Shell | Electron 35+ | | UI | React 19 + TypeScript | | Bundler | Vite | | Estilos | CSS custom (sin framework UI) | | IPC | `contextBridge` (preload.cjs) | ### Comunicación con el backend Toda la comunicación pasa por el API Gateway. | Entorno | URL por defecto | |---------|-----------------| | Desarrollo (`npm run dev`) | `http://127.0.0.1:8189` | | Instalador (build producción) | `https://pys1.builker.xyz` | El cliente HTTP es [`src/renderer/lib/apiClient.ts`](src/renderer/lib/apiClient.ts). ### Indexación de carpetas El proceso principal (Electron) indexa carpetas locales con [`electron/folderIndex.cjs`](electron/folderIndex.cjs): - Modo `general`: lista todos los PDFs/TIFFs de la carpeta. - Modo `radicados`: busca un PDF por tipo de documento dentro de subdirectorios con nombre de radicado. --- ## Estructura del código ``` electron/ main.cjs — proceso principal Electron preload.cjs — bridge seguro main ↔ renderer (contextBridge) folderIndex.cjs — indexación de carpetas locales src/ renderer/ App.tsx — root: navegación y estado global components/ CountingWizard.tsx — wizard de conteo en 3 pasos CountResultsTable.tsx — tabla de resultados con validación CountingStepper.tsx — indicador de progreso ExtractionWizard.tsx — wizard de extracción en 4 pasos ExtractionStepper.tsx — indicador de progreso lib/ apiClient.ts — cliente HTTP hacia el API Gateway payloads.ts — builders de FormData y JSON pathMapping.ts — mapeo rutas locales ↔ contenedor csv.ts — exportación CSV styles.css — estilos globales shared/ types.ts — tipos compartidos main/renderer ``` --- ## Variables de configuración (runtime) | Variable | Default | Descripción | |----------|---------|-------------| | `API Gateway URL` | Ver tabla arriba | Configurable en la pantalla de Configuración | | Ruta local de documentos | — | Seleccionada con el explorador de archivos | | Ruta en contenedor | `/data` | Prefijo donde Docker monta los documentos | --- ## Arrancar en desarrollo ```bash cd services/desktop_app npm install npm run dev ``` ## Build para producción ```bash # 1) Sube la versión en package.json (ej. 1.0.1) # 2) Configura credenciales una vez: copia .env.minio.example → .env.minio # 3) Genera el instalador y súbelo a MinIO automáticamente: npm run dist ``` El instalador queda en `%LOCALAPPDATA%\IPSExtractor-desktop-release\` (fuera de Documents/OneDrive, para evitar bloqueos de `app.asar` en Windows) y se publica en: `s3.builker.xyz/apps-versions/IPSExtractor/{version}/` La fecha de release (UI, `latest.json`, `DATA.txt`) es **el día del build/publish**, salvo que pases `RELEASE_DATE=DD/MM/YYYY`. Se escribe en `version.json` antes de `vite build` (la UI la inyecta en compile-time). Si solo quieres el `.exe` local **sin** subir a MinIO: ```bash npm run dist:local ``` ### Versión de la app | Campo | Archivo | |-------|---------| | Número (`1.0.0`) | `package.json` → `version` | | Fecha de release | MinIO (`latest.json` / `DATA.txt` de la versión); fallback local de `version.json` | La versión se muestra en el menú lateral y en la esquina superior derecha. Al arrancar, la app lee la fecha desde MinIO para la versión instalada (si coincide con `latest.json`, o desde `{version}/DATA.txt`). ### Auto-update (MinIO) Al iniciar la app **instalada**, consulta: `https://s3.builker.xyz/apps-versions/IPSExtractor/latest.json` Si hay una versión mayor, pregunta al usuario, descarga el Setup.exe, verifica `sha256` y lanza el instalador NSIS. Layout en el bucket `apps-versions`: ```text IPSExtractor/ latest.json versions.json ← catálogo de todas las versiones publicadas 1.0.1/Flujo-IPS-1.0.1-Setup.exe 1.0.1/DATA.txt ← fecha DD/MM/YYYY, ej. 06/07/2026 ``` **Requisito:** el prefijo `IPSExtractor/` debe permitir `GetObject` anónimo en la API (`s3.builker.xyz`). La política se configura en la consola (`minio.builker.xyz`). Credenciales de publicación (solo en tu PC): ```bash cp .env.minio.example .env.minio # Edita MINIO_ACCESS_KEY y MINIO_SECRET_KEY ``` `npm run dist` las usa automáticamente al final. También puedes republicar sin rebuild: ```bash npm run publish:minio ```