Connect
ixiclinic Connect — agente local de hardware en la LAN de la sucursal. Se conecta saliente al cloud y ejecuta los trabajos de impresión sobre impresoras de red y USB.
ixiclinic Connect (@ixiclinic/connect, en bridge/) es el agente local de hardware. Se instala en
una máquina dentro de la red (LAN) de la sucursal y es la única pieza que alcanza el hardware
del laboratorio (impresoras de red en el puerto 9100, impresoras USB del SO, cajón de dinero).
Se conecta saliente al cloud por Socket.IO (atraviesa NAT, sin abrir puertos) y ejecuta los
trabajos de impresión que el API le enruta.
| Stack | TypeScript, socket.io-client; tsx en dev, Bun para compilar el binario |
| Ubicación | bridge/ (raíz del repo) |
| Paquete | @ixiclinic/connect |
Nota: Connect no forma parte del workspace de pnpm. El workspace solo incluye
apps/*ypackages/*(pnpm-workspace.yaml);bridge/es un proyecto hermano en la raíz con su propiobun.lock. Por eso no se levanta conpnpm devni con Turbo.
Ver también la guía completa de Impresión y Bridge.
Por qué existe
El cloud no alcanza la LAN del cliente: una impresora térmica en el mostrador no es accesible desde
api.ixiclinic.com. Connect cierra esa brecha conectándose hacia afuera y haciendo de puente entre el
cloud y el hardware físico.
Arquitectura (bridge/src/)
| Archivo | Responsabilidad |
|---|---|
index.ts | Entrypoint: orquesta config, registro, socket, poll de trabajos y descubrimiento. |
config.ts | Carga/persiste la configuración (env + ~/.ixiclinic-bridge/config.json). |
api.ts | Cliente HTTP del API del bridge (BridgeApi): registro, heartbeat, poll, resultado. |
socket.ts | Conexión Socket.IO saliente; recibe los eventos job:new y printers:rescan. |
discovery.ts | Descubre impresoras: escaneo de subred al puerto 9100 + impresoras del SO. |
escpos.ts | Construye comandos ESC/POS (impresión térmica, apertura de cajón). |
printing.ts | Envía el documento a la impresora (TCP 9100 / spooler del SO). |
queue.ts | Lógica de cola de trabajos. |
logger.ts | Logging. |
Enrolamiento por token
- En el admin: Hardware → Nuevo agente y se copia su token.
- El agente se autentica enviando ese token en el header
x-bridge-tokenen cada llamada HTTP (BridgeApi); el socket lo pasa enauth: { token }. - El token puede venir por env (
IXICLINIC_BRIDGE_TOKEN), por flag (--token) o guardarse en la config local (~/.ixiclinic-bridge/config.json) para los próximos arranques.
Endpoints del bridge (todos autenticados por el token): POST /api/bridge/register,
POST /api/bridge/heartbeat, POST /api/bridge/printers, GET /api/bridge/jobs,
POST /api/bridge/jobs/{id}/result, GET /api/bridge/latest.
Flujo de trabajos: poll + push
El diseño separa la fuente de verdad de la señal:
- El poll
GET /api/bridge/jobses la fuente de verdad. El agente consulta cadaIXICLINIC_POLL_MS(default 15 s); aunque el socket se caiga, el poll recupera los trabajos. - El push por socket (evento
job:new) es solo un "despertador": al recibirlo, el agente dispara un poll inmediato en lugar de esperar el intervalo.printers:rescanfuerza un re-descubrimiento. - El servidor maneja los reintentos: un trabajo fallido vuelve a
pendingy reaparece en el siguiente poll. El agente reporta el estado conPOST /api/bridge/jobs/{id}/result(printing/done/failed).
Variables de entorno
| Variable | Default | Descripción |
|---|---|---|
IXICLINIC_API_URL | https://api.ixiclinic.com | URL del API. |
IXICLINIC_BRIDGE_TOKEN | — | Token del agente (del admin). |
IXICLINIC_POLL_MS | 15000 | Intervalo de poll de trabajos. |
IXICLINIC_HEARTBEAT_MS | 30000 | Intervalo de heartbeat. |
IXICLINIC_RESCAN_MS | 600000 | Intervalo de re-descubrimiento de impresoras. |
IXICLINIC_BRIDGE_DIR | ~/.ixiclinic-bridge | Carpeta de configuración. |
Desarrollo
En dev el agente corre con tsx (no con Bun):
cd bridge
bun install
IXICLINIC_API_URL=https://api.ixiclinic.com IXICLINIC_BRIDGE_TOKEN=<token> bun run dev
# bun run dev === "tsx watch src/index.ts"; también vale Node ≥ 18Probar la impresión desde el admin o por API:
POST /api/printing/jobs
{ "role": "test", "documentType": "test" }Instalación en producción
Tras crear el agente en el admin y copiar su token, en la máquina con la impresora se ejecuta una
vez el instalador (bridge/install/install.sh en macOS/Linux, bridge/install/install.ps1 en
Windows). El instalador descarga el binario del último Release, lo registra como servicio
(systemd / launchd / tarea de Windows) y lo arranca. El agente avisa en sus logs cuando hay una
versión nueva (GET /api/bridge/latest).
Empaquetado y release
Bun se usa para compilar el agente a un binario único (no como runtime de dev):
bun build src/index.ts --compile --outfile dist/ixiclinic-connectEl workflow .github/workflows/connect-release.yml (disparado por un tag connect-v* o manual)
hace que Bun cross-compile desde un solo runner los binarios para Linux, Windows y macOS
(Apple Silicon + Intel) y los adjunta a un GitHub Release.
Pendiente
- Firma de binarios (notarization de Apple / Authenticode).
- Self-update del binario en ejecución (hoy avisa para reinstalar).
- Descubrimiento por mDNS/Bonjour y estado por SNMP (papel, online).
- Conector de instrumentos de laboratorio (serial/TCP → resultados).
Mobile
App móvil de ixiclinic — React Native 0.79 + Expo 54 con expo-router. Estructura inicial con pantallas de catálogo, resultados y sucursales.
Desktop
ixiclinic Desktop — shell de escritorio nativo (Tauri) que carga admin.ixiclinic.com con sesión persistente, audio/voz nativos y el agente ixiclinic Connect empaquetado como sidecar.