Files
2026-10-29 17:15:12 -05:00

139 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Conexiones externas (fuentes de datos de otros sistemas)
> Leer cuando: se trabaje en traer/consultar datos de sistemas externos (pacientes, empleados de
> nómina, FoxPro u otra tecnología). No leer si: la tarea no toca datos externos.
> Contrato técnico de los conectores: [`data/conectores/README.md`](../data/conectores/README.md).
Estado (2026-10-29): **conector FoxPro 1.1.0 instalado y funcionando en Exilaser** (ver abajo).
**Módulo del sistema hecho en dev** (migración 038, `backend/src/modules/integrations`, job
`integrationSync`), sin commit ni producción.
## Arquitectura
El sistema **no se conecta directo** a las bases de origen. En cada servidor origen se instala un
**conector** (API HTTP de solo lectura) y el sistema habla con él por un contrato único (v1).
Para otra tecnología (SQL Server, Excel, etc.) se desarrolla otro conector con el mismo contrato;
el sistema no cambia. Ver decisión #2 en `DECISIONES.md`.
- Primer caso: Exilaser, Windows Server `192.168.0.253` (SAGA/SistViso en FoxPro), alcanzado por
la VPN WireGuard. Conector en `C:\api_project\foxpro`, puerto `8455`.
- Fuentes reales (revisadas por SSH, solo estructura, 2026-10-29):
| Fuente | Ruta | Tabla | Registros | Codificación | Campos útiles |
|---|---|---|---|---|---|
| Nómina | `C:\Sistema\Nomina\Datos\Exilaser` | `empleado.DBF` (VFP 0x30, sin memo) | 31 | cp1252 | `EMPCED`, `EMPAPE`, `EMPNOM`, `EMPTEL`, `EMPTEL1`, `EMPFECNAC`, `EMPCARGO`, `EMPDEPART`, `EMPINGRESO`, `EMPSALIDA`, `EMPACTIVO` |
| SAGA clientes | `C:\Sistema\Datos\exilaser` | `clientes.DBF` (VFP 0x30, sin memo, ~20 MB) | 32 985 | **cp850** | `CLICOD`, `CLIRUC`, `CLINOM`, `CLITEL`, `CLIEMAIL`, `CLIDIR`, `CLICIU`, `CLIPERSONA`, `CLITIPRUC`, `CLISEXO`, `INACTIVO`, `CLIESTADO`, `FECHAACT` |
- **No exponer** de nómina: `EMPSUELDO`, `EMPBANCO`, `EMPCUENT`, `EMPTIPOCUE`, `EMPNUMIESS`,
`EMPLET*`, `FIJO1-5`, `EMPCARGAS`, `EMPESTADO` (es estado civil) (van en `denyFields` o se usa lista de campos permitidos).
- Nómina **no tiene correo**: al crear un usuario desde nómina el correo se escribe a mano.
- Clientes: el nombre viene en **un solo campo** (`CLINOM`), sin nacimiento; incluye empresas
(RUC) — para pacientes filtrar personas naturales (`CLIPERSONA`/`CLITIPRUC`). El orden
apellidos/nombres de `CLINOM` se confirma con una muestra al instalar.
- `exilaser14`…`exilaser25` son cierres de años anteriores: **no** se exponen.
- `clientes.DBF` cambia todo el día (SAGA escribe): conviene modo **importar** o caché con
recarga mínima, para no copiar 20 MB en cada consulta.
## Requisitos acordados con el usuario
1. **Dos modos por fuente** (lo elige el superadmin): **importar** (copiar a nuestra BD) o
**consulta en vivo** (leer siempre del origen). En consulta en vivo, al agendar se guarda una
copia mínima del paciente porque las citas necesitan el registro local.
2. **Formas de conexión que no comprometan al origen** (superadmin): todo pasa por el conector de
solo lectura; el sistema no guarda credenciales del origen, solo el token del conector (cifrado
AES-256-GCM, nunca vuelve al navegador).
3. **Mapeo en dos pasos** (superadmin): 1) conexión al servidor (URL del conector + token, botón
Probar); 2) qué fuente/tabla usar y a qué destino (Pacientes, Empleados).
4. **Importación al configurar o solo consultas**: al terminar la configuración se ofrece
"Importar ahora" o dejarla solo para consultas.
5. **Diseño por drivers/conectores** con la misma interfaz (aprobado).
6. **Empleados de nómina**: se importan a una tabla local de empleados (clave: cédula; los que
desaparecen del origen quedan inactivos, no se borran). Botón **"Actualizar empleados"** a
pedido, visible para **admin y superadmin**. Debe funcionar con cualquier tipo de origen.
7. **Vista previa**: el superadmin ve las columnas y filas reales de la tabla y elige qué
columnas usar en el sistema.
8. **Crear usuario desde nómina**: en Organización → Usuarios → Nuevo, opción de elegir un empleado
de la lista importada; precarga nombre, correo, cargo y departamento si están mapeados, y deja
el usuario vinculado. No se ofrecen empleados que ya tienen usuario.
## Seguridad (resumen)
- **Regla (usuario, 2026-10-29): todo lo que se busque o traiga de SAGA es por la API del conector**,
también las búsquedas que haga Claude a pedido. El SSH al Windows es solo para administrar el
conector (instalar, actualizar, decidir qué tablas/campos expone), con permiso del usuario. Una
tabla nueva primero se agrega a `config.json` del conector con los campos mínimos; después se
consulta por la API.
- En el conector: solo `GET`, token (se guarda solo el SHA-256), IPs permitidas en el conector y en
el firewall de Windows, tablas/campos permitidos y denegados (sueldos, claves), sin rutas ni SQL
libres, límites de peticiones/concurrencia/página/tiempo, log sin tokens ni valores buscados.
- FoxPro: se lee una **copia temporal** de DBF+FPT, nunca el original (no bloquea a SAGA).
- En el sistema: configuración solo superadmin; "Actualizar empleados" admin/superadmin; auditoría
de pruebas de conexión, importaciones y consultas.
## Instalación en Exilaser (2026-10-29)
- `C:\api_project\foxpro`, Node 24 del servidor, tarea programada `LinkedCorp-Conector-FoxPro`
(al arranque, usuario SYSTEM, reinicio si cae), regla de firewall del mismo nombre: TCP 8455 solo
desde `192.168.222.3` (prod) y `192.168.222.40` (dev).
- URL desde LinkedCorp: `http://192.168.0.253:8455` (por la VPN). Token: archivo
`~/.config/linkedcorp/conector-foxpro-exilaser.token` (600) en el equipo de desarrollo; en el
Windows solo está su SHA-256.
- Probado desde dev: sin token → 401; nómina 31 empleados (11 campos permitidos); clientes 32 988
(13 campos); primera carga de clientes ~8 s, luego caché (recarga como mínimo cada 60 s);
incremental `changedField=FECHAACT` OK; tildes/ñ correctas (cp850).
- `CLINOM` viene como **APELLIDOS NOMBRES** (ej. "GONZALEZ JIMENEZ RAUL VICENTE"): al importar se
separa en las 2 primeras palabras = apellidos, resto = nombres (los apellidos compuestos se
corrigen a mano). Pacientes = `CLIPERSONA = Natural` (en una muestra de 1000: 988 naturales).
- Mejora a futuro: correr la tarea con una cuenta de dominio de solo lectura en vez de SYSTEM.
- Actualizar el conector: copiar `src/` a `C:\api_project\foxpro\src`, detener la tarea, matar el
`node` del conector y volver a iniciar la tarea.
## Decisiones del usuario sobre pacientes (2026-10-29)
- Con conexión activa **se permite crear pacientes a mano** (quedan como locales).
- Al vincular por cédula, si los datos difieren **manda SAGA** (el cambio queda en auditoría).
## Pendientes
- [x] Revisar en el server las carpetas de nómina y clientes (estructura, codificación).
- [x] Instalar el conector en `C:\api_project\foxpro` y probar desde dev.
- [x] Módulo del sistema (ver "Cómo quedó en el sistema").
- [ ] Commit, revisión y producción (migraciones 036–038, conexión y fuentes a configurar allá).
## Cómo quedó en el sistema (2026-10-29)
- **Configuración → Conexiones externas** (superadmin): conexiones (URL + token cifrado, Probar) y
fuentes Pacientes/Empleados: conexión → fuente → tabla, vista previa de 20 filas, mapeo de campos,
filtro (ej. `CLIPERSONA = Natural`), campo de cambios (`FECHAACT`) y modo (pacientes: importar o en
vivo). Botones "Traer cambios" y "Sincronización completa".
- **Programación** (job en el backend, cada 5 min revisa): pacientes en modo importar → completa
**lunes a viernes a las 05:00** (recoge borrados: quedan inactivos) e incremental cada 15 min de
06:00 a 21:00 (agregados por `_recno` + modificados por `FECHAACT`). La primera vez hace la completa.
El conector solo copia el DBF cuando el sistema le pide datos (como mínimo cada 60 s).
- **Organización → Empleados** (admin/superadmin): listado y **"Actualizar empleados"** (a pedido).
Los que salen de la nómina quedan inactivos. **Nuevo usuario → Desde nómina** precarga nombre,
cargo y departamento (si coincide por nombre) y vincula el usuario con el empleado.
- **Médicos (2026-10-29)**: casi todos facturan como **proveedores** de SAGA (`provedor.DBF`, expuesto
en el conector solo con código, nombre, RUC, teléfono, correo, ciudad, tipo e inactivo). Se cargan
como empleados con `origin=provider` con `backend/src/scripts/import-provider-employees.js` (lee
del conector por código de proveedor; sin datos personales en Git). En dev: 9 proveedores + 2 que ya
eran de nómina (Torres Palacios Nataly, Rodríguez Nava Christian). Códigos usados:
`137+031 142+033 809 234 040 794 817 565 540 405 676` (`--position=MEDICO`).
- **Médico nuevo** (desde 2026-10-29): **Organización → Empleados → "Agregar desde proveedores"**
(admin/superadmin): buscar por nombre, apellido o cédula en la fuente "Proveedores"
(Configuración → Conexiones externas, en dev: `clientes/PROVEDOR`), elegir, confirmar apellidos,
nombres y cargo (por defecto MEDICO) y guardar como empleado (`origin=provider`). Marca "Ya es
empleado" a los existentes. Luego, si entra al sistema: Nuevo usuario → Desde nómina, y Personal de
la Agenda. Los 11 médicos ya cargados se mantienen. El script queda para cargas masivas.
- **Protección**: un empleado con usuario en el sistema (p. ej. médico) **no se actualiza ni se
inactiva** al "Actualizar empleados"; los de origen proveedor tampoco los toca la nómina.
- **Agenda**: en modo importar se busca entre los importados (también por nombre de origen); en modo
en vivo el selector agrega los del origen ("Del sistema origen") y al elegir uno se trae solo ese.
El detalle del paciente muestra su origen.
- **Nombres de SAGA**: `CLINOM` no tiene orden fijo (a veces nombre primero), así que no se separa:
se guarda entero como nombre visible (`name_split=0`). Al editar el paciente, recepción separa
apellidos y nombres; desde ahí la sincronización ya no pisa su nombre (sí cédula/teléfono/correo).
- Prueba en dev con datos reales: 31 empleados (24 activos), 31 220 pacientes en 24 s; repetir la
completa sin cambios 1,7 s; 14 cédulas repetidas en SAGA quedan sin cédula en el segundo registro.