Este servicio sincroniza automáticamente las facturas aprobadas desde Supabase hacia la base de datos Firebird SAIDB.
- Sincronización en tiempo real usando Supabase Realtime
- Recuperación automática de facturas pendientes al iniciar el servicio
- Mapeo automático de datos entre estructuras diferentes
- Manejo de transacciones para garantizar integridad de datos
- Gestión automática de consecutivos en TIPDOC
- Sincronización automática de terceros en segundo plano
- API de control para monitoreo y sincronización manual
- Logging completo para monitoreo y debugging
- Manejo robusto de errores
- 🔧 Configuración centralizada en Supabase con caché local encriptado
- 🔐 Seguridad mejorada con credenciales encriptadas y RLS
- 👥 Multi-tenant con configuración por usuario
- 📦 Instalador automático para Windows con wizard gráfico
- 🔄 Puertos alternativos para evitar conflictos
- 🔌 Incluye fbclient.dll para Firebird 2.5
- Node.js 18 o superior
- Acceso a base de datos Supabase
- Acceso a base de datos Firebird SAIDB
- Permisos de lectura en Supabase y escritura en Firebird
- Node.js 18 o superior
- Inno Setup 6 (para compilar el instalador)
- PKG (instalado automáticamente con npm install)
- Windows 7 o superior
- Permisos de administrador
- Firebird instalado y configurado
- Clonar el repositorio
git clone <repository-url>
cd supabase-firebird-sync- Instalar dependencias
npm install-
Configurar base de datos
Ejecutar la migración para crear la tabla de configuración:
# En Supabase SQL Editor, ejecutar: database/migrations/create_invoice_config_table.sql -
Configurar credenciales
Copiar y editar el archivo
.env:cp .env.example .env # Editar .env con tus credencialesEl archivo
.envahora contiene SOLO credenciales sensibles:# Credenciales de Supabase SUPABASE_URL=https://tu-proyecto.supabase.co SUPABASE_ANON_KEY=tu_anon_key_aqui # Usuario del servicio USER_UUID=uuid-del-usuario-en-invoice_user # Contraseña para encriptar caché de configuración CONFIG_CACHE_PASSWORD=password_seguro_para_cache
IMPORTANTE: Las credenciales de Firebird (host, puerto, base de datos, usuario, contraseña) se configuran en Supabase en la tabla
invoice_config, NO en el archivo.env.📖 Ver Configuración Centralizada para más detalles.
-
Insertar configuración operativa en Supabase
Editar y ejecutar el script de configuración:
# 1. Editar database/migrations/insert_default_config.sql # 2. Reemplazar 'TU_USER_UUID_AQUI' con tu UUID real # 3. Ejecutar en Supabase SQL Editor
Nota: La configuración operativa (intervalos, rangos, preferencias) ahora se gestiona desde la tabla
invoice_configen Supabase. Ver docs/CONFIGURACION_CENTRALIZADA.md para más detalles. -
Encriptar el archivo .env
node scripts/encrypt-env.js
.\scripts\build-all.ps1Este script compila automáticamente:
- El ejecutable con PKG (
dist/supabase-firebird-sync.exe) - El instalador con Inno Setup (
installer/Output/InstaladorSyncFirebird-v1.0.0.exe)
npm run build:legacyGenera: dist/supabase-firebird-sync.exe (~50 MB)
.\scripts\build-installer.ps1Genera: installer/Output/InstaladorSyncFirebird-v1.0.0.exe (~50 MB)
Ver GUIA_COMPILACION_COMPLETA.md para:
- Requisitos previos
- Encriptación del archivo .env
- Opciones avanzadas de compilación
- Solución de problemas
npm run devnpm startUsar el instalador gráfico:
- Ejecutar
InstaladorSyncFirebird-v1.0.0.execomo administrador - Seguir el wizard de instalación
- Ingresar:
- Nombre del servicio (sin espacios)
- Contraseña ENV_PASSWORD
- Contraseña CONFIG_CACHE_PASSWORD
- El servicio se instala y arranca automáticamente
Documentación para implementadores:
NOTA: Los métodos antiguos (Método A y B) están obsoletos. Usar el instalador gráfico. npm run install-service
O usar el script batch:
```bash
install-windows-service.bat
Para distribuir el servicio sin requerir Node.js instalado, usamos Node.js SEA (Single Executable Applications):
# Compilar todos los ejecutables (servicio + instaladores)
npm run build:complete
# O directamente:
.\build-sea.batEjecutables generados en dist/:
supabase-firebird-sync.exe- Servicio principal (~85 MB)install-service.exe- Instalador del serviciouninstall-service.exe- Desinstaladorencrypt-env.exe- Encriptador de .env
Método: Node.js 22+ SEA (incluye Node.js completo embebido)
📚 Documentación detallada: Compilación de Ejecutables SEA
📚 Documentación completa:
Para Desarrolladores:
Para Implementadores (Técnicos de Campo):
🎯 NUEVO: Instalador Wizard (Recomendado)
- 📦 Instalador con Inno Setup - Instalación con wizard gráfico
- Solo 3 preguntas al usuario
- Instalación automática completa
- No requiere conocimientos técnicos
- Tiempo: 2-3 minutos
📖 Documentación de Instalación Manual:
- 📘 Guía de Instalación para Implementadores - Documento principal
- ✅ Checklist de Instalación - Lista de verificación
- ⚡ Referencia Rápida - Comandos esenciales
- ❓ Preguntas Frecuentes - FAQ para implementadores
Gestión del servicio:
# Detener
net stop SupabaseFirebirdSync
# Iniciar
net start SupabaseFirebirdSync
# Desinstalar
npm run uninstall-serviceSi el servicio no inicia o presenta errores:
-
Ejecutar diagnóstico automático:
diagnose.bat
-
Probar en modo consola:
test-console.bat
-
Revisar logs:
type logs\error.log
📚 Guía completa: TROUBLESHOOTING.md
# Sincronización incremental (solo cambios nuevos)
npm run sync-thirds
# Sincronización completa (todos los registros)
npm run sync-thirds-full
# Ver estadísticas de sincronización
npm run sync-thirds-stats# Sincronización de cuentas (según rangos configurados)
npm run sync-accounts
# Sincronización completa de cuentas
npm run sync-accounts-full
# Ver estadísticas de sincronización de cuentas
npm run sync-accounts-stats
# Ver configuración de sincronización de cuentas
npm run sync-accounts-config# Sincronización incremental de productos (solo cambios nuevos)
npm run sync-products
# Sincronización completa de productos
npm run sync-products-full
# Ver estadísticas de sincronización de productos
npm run sync-products-stats
# Ver configuración de sincronización de productos
npm run sync-products-config# Probar la funcionalidad de recuperación de facturas pendientes
npm run test-recovery# Probar la configuración del campo INVC en CARPRODE
npm run test-invc-config# Probar el manejo correcto de fechas sin cambios de zona horaria
npm run test-dates# Probar la configuración de códigos predeterminados de proyecto y actividad
npm run test-project-activity# Probar la configuración del tipo de documento
npm run test-document-type# Probar el filtro por UUID de usuario
npm run test-user-filter# Probar la exclusión de rangos de cuentas
npm run test-account-exclusion# Diagnosticar problemas de duplicados y facturas pendientes
npm run diagnostic# Probar configuración de Pinecone y embeddings
npm run test-pinecone
# Sincronizar todos los productos a Pinecone
npm run sync-products-to-pinecone
# Buscar productos por similitud semántica
npm run search-products -- tornillo acero inoxidableE, S = 1, 1(valores fijos)TIPO = configurable(tipo de documento, por defecto "FIA")BATCH = secuencial automáticoID_N = num_identificacionFECHA = date(fecha exacta de la factura, sin cambios de zona horaria)DUEDATE = date(fecha de vencimiento = fecha de la factura)TOTAL = totalLETRAS = conversión automática a letras
TIPO = configurable(tipo de documento, por defecto "FIA")CRUCE = configurable(mismo valor que TIPO)BATCH = mismo del encabezadoACCT = account_codeDEBIT = debitCREDIT = creditDESCRIPCION = descriptionINVC = configurable(ver configuración INVC)FECHA = entry_date(fecha de la entrada contable)DUEDATE = invoice.date(fecha de vencimiento = fecha de la factura)PROYECTO = configurable(código de proyecto predeterminado)ACTIVIDAD = configurable(código de actividad predeterminado)
El campo INVC en la tabla CARPRODE de Firebird puede configurarse para usar diferentes valores:
Opción 1: Usar número de batch/FIA (por defecto)
USE_INVOICE_NUMBER_FOR_INVC=false- Envía el número consecutivo de FIA generado automáticamente
- Comportamiento actual del sistema
- Garantiza unicidad numérica secuencial
Opción 2: Usar invoice_number de Supabase
USE_INVOICE_NUMBER_FOR_INVC=true- Envía el número de factura original de Supabase
- Mantiene la referencia directa al número de factura
- Útil para trazabilidad y reconciliación
- El campo
INVCtiene un límite de 15 caracteres - Los valores se truncan automáticamente si exceden este límite
- El cambio de configuración afecta solo a las nuevas facturas procesadas
- Se recomienda mantener consistencia en la configuración
El sistema requiere configurar un UUID de usuario para filtrar todos los datos y operaciones:
# UUID del usuario para filtrar todos los datos del sistema
# Este campo es OBLIGATORIO y debe ser un UUID válido
USER_UUID=550e8400-e29b-41d4-a716-446655440000- Validación al inicio: El sistema valida que el UUID esté configurado y sea válido
- Filtro automático: Todas las consultas se filtran automáticamente por
user_id - Inserción automática: Todos los nuevos registros incluyen el
user_idconfigurado - Realtime filtrado: Solo las facturas del usuario configurado activan el listener
- Aislamiento completo: Cada usuario ve únicamente sus propios datos
Todas las tablas principales incluyen el campo user_id:
invoices- Facturasinvoice_items- Items de facturasaccounting_entries- Entradas contablesinvoice_third_parties- Terceros sincronizadosinvoice_chart_of_accounts- Plan de cuentas sincronizadoinvoice_products- Productos sincronizados
- Obligatorio: El sistema no inicia sin un UUID válido configurado
- Validación: Se valida el formato UUID v4
- Filtro automático: Imposible acceder a datos de otros usuarios
- Logging: Se registra el UUID configurado al iniciar
- Obtener UUID del usuario desde tu sistema de autenticación
- Configurar en .env:
USER_UUID=tu-uuid-de-usuario-aqui
- Reiniciar el servicio para aplicar la configuración
- Verificar con el script de prueba:
npm run test-user-filter
El tipo de documento determina cómo se clasifican las facturas en el sistema Firebird:
# Tipo de documento para CARPROEN, CARPRODE y TIPDOC
DOCUMENT_TYPE=FIA # Por defecto: FIA (Factura IA)- Creación automática: Si el tipo no existe en TIPDOC, se crea automáticamente
- Consecutivos independientes: Cada tipo tiene su propio consecutivo
- Validación: Se trunca automáticamente a 3 caracteres máximo
- Consistencia: TIPO y CRUCE en CARPRODE siempre tienen el mismo valor
| Código | Descripción | Uso Típico |
|---|---|---|
FIA |
Factura IA | Facturas por pagar (por defecto) |
FAC |
Factura de Venta | Facturas de venta |
CXP |
Cuenta por Pagar | Cuentas por pagar |
CXC |
Cuenta por Cobrar | Cuentas por cobrar |
REC |
Recibo de Caja | Recibos |
COM |
Comprobante | Comprobantes contables |
NOT |
Nota Contable | Notas contables |
CARPROEN.TIPO: CHAR(3) - Tipo de documentoCARPRODE.TIPO: CHAR(3) - Tipo de documento (mismo que CARPROEN)CARPRODE.CRUCE: CHAR(3) - Referencia cruzada (mismo que TIPO)TIPDOC.CLASE: CHAR(3) - Clasificación en tabla de tipos
# Ejemplo 1: Facturas IA (por defecto)
DOCUMENT_TYPE=FIA
# Resultado: Facturas por pagar IA
# Ejemplo 2: Facturas de venta
DOCUMENT_TYPE=FAC
# Resultado: Facturas de venta
# Ejemplo 3: Tipo personalizado
DOCUMENT_TYPE=MIS
# Resultado: Documento tipo MIS (se crea automáticamente)Los campos PROYECTO y ACTIVIDAD en la tabla CARPRODE pueden configurarse con valores predeterminados:
# Códigos predeterminados para todos los registros CARPRODE
DEFAULT_PROJECT_CODE=PROJ001 # Máximo 10 caracteres
DEFAULT_ACTIVITY_CODE=ACT # Máximo 3 caracteresAdemás de los rangos de inclusión (ACCOUNT_SYNC_RANGES), puedes configurar rangos de cuentas que deseas excluir de la sincronización:
# Rangos de cuentas a EXCLUIR de la sincronización
# Formato: cuenta1-cuenta2,cuenta3-cuenta4 o cuenta_individual-cuenta_individual
ACCOUNT_EXCLUDE_RANGES=# Excluir cuentas específicas individuales
ACCOUNT_EXCLUDE_RANGES=53159502-53159502,53959501-53959501
# Excluir rangos completos
ACCOUNT_EXCLUDE_RANGES=60000000-69999999,80000000-89999999
# Mezcla de cuentas individuales y rangos
ACCOUNT_EXCLUDE_RANGES=12345678-12345678,50000000-59999999,70000000-79999999
# No excluir nada (por defecto)
ACCOUNT_EXCLUDE_RANGES=- Primero se aplican los rangos de inclusión (
ACCOUNT_SYNC_RANGES) - Después se excluyen las cuentas especificadas en
ACCOUNT_EXCLUDE_RANGES - El resultado final son las cuentas que están en los rangos de inclusión PERO NO en los rangos de exclusión
# Incluir cuentas del 11000000 al 11999999
ACCOUNT_SYNC_RANGES=11000000-11999999
# Pero excluir algunas cuentas específicas de ese rango
ACCOUNT_EXCLUDE_RANGES=11050000-11059999,11500000-11500000Resultado: Se sincronizarán todas las cuentas del 11000000 al 11999999, EXCEPTO las del 11050000 al 11059999 y la cuenta 11500000.
# Probar la configuración de exclusión
npm run test-account-exclusion
# Ver análisis completo de rangos
npm run test-account-ranges- Si están configurados: Todos los registros CARPRODE tendrán estos valores
- Si están vacíos: Los campos se envían como cadenas vacías
- Truncamiento automático: Los valores se truncan si exceden los límites
- Consistencia: Todos los registros de una factura tendrán los mismos valores
PROYECTO: CHAR(10) - Código de proyecto (máximo 10 caracteres)ACTIVIDAD: CHAR(3) - Código de actividad (máximo 3 caracteres)
# Ejemplo 1: Sin configuración
DEFAULT_PROJECT_CODE=
DEFAULT_ACTIVITY_CODE=
# Resultado: campos vacíos
# Ejemplo 2: Configuración normal
DEFAULT_PROJECT_CODE=PROJ001
DEFAULT_ACTIVITY_CODE=ACT
# Resultado: PROYECTO="PROJ001", ACTIVIDAD="ACT"
# Ejemplo 3: Con truncamiento
DEFAULT_PROJECT_CODE=PROYECTO_MUY_LARGO
DEFAULT_ACTIVITY_CODE=ACTIVIDAD_LARGA
# Resultado: PROYECTO="PROYECTO_M", ACTIVIDAD="ACT"El sistema incluye integración con Pinecone para búsqueda semántica de productos usando embeddings vectoriales. Esto permite:
- 🔎 Búsqueda por similitud: Encuentra productos similares aunque no coincidan exactamente las palabras
- 🤖 Embeddings con IA: Usa el servicio de embeddings de chatbotstools.asistentesautonomos.com
- 📊 Sincronización automática: Los productos se sincronizan automáticamente a Pinecone
- 🎯 Búsqueda inteligente: "tornillo acero" encuentra "tornillos de acero inoxidable"
- Regístrate en https://app.pinecone.io/
- Crea un nuevo índice con estas configuraciones:
- Dimensión: 512 (para embeddings CLIP)
- Métrica: cosine
- Nombre: elige un nombre descriptivo (ej:
saidb-products)
- En Pinecone Dashboard → API Keys
- Copia tu API Key
- Anota el Environment (ej:
us-east-1-aws)
- Regístrate en https://chatbotstools.asistentesautonomos.com/
- Crea una API Key en tu dashboard
- Suscríbete al servicio de "CLIP Embeddings"
# Pinecone
PINECONE_API_KEY=tu-api-key-de-pinecone
PINECONE_INDEX_NAME=saidb-products
PINECONE_ENVIRONMENT=us-east-1-aws
PINECONE_NAMESPACE= # Opcional, usa USER_UUID por defecto
# Servicio de Embeddings
EMBEDDINGS_API_KEY=tu-api-key-de-embeddings
EMBEDDINGS_API_URL=https://chatbotstools.asistentesautonomos.com/api/embeddings
EMBEDDINGS_DIMENSION=512
# Sincronización
ENABLE_PINECONE_SYNC=true
PINECONE_SYNC_INTERVAL=60 # minutos
PINECONE_BATCH_SIZE=50npm run test-pineconeEste comando:
- ✅ Verifica que todas las variables estén configuradas
- ✅ Prueba la conexión con el servicio de embeddings
- ✅ Prueba la conexión con Pinecone
- ✅ Inserta un vector de prueba
- ✅ Realiza una búsqueda de prueba
- ✅ Limpia el vector de prueba
npm run sync-products-to-pineconeEste comando:
- Obtiene todos los productos del usuario desde Supabase
- Genera embeddings para cada producto (código + descripción)
- Los almacena en Pinecone con metadata completa
- Procesa en lotes para optimizar rendimiento
npm run search-products -- <texto de búsqueda>Ejemplos:
# Buscar tornillos
npm run search-products -- tornillo acero inoxidable
# Buscar cables
npm run search-products -- cable electrico calibre 12
# Buscar por código
npm run search-products -- 12345-
Generación de embeddings:
- Se combina el código y descripción del producto
- Se envía al servicio de embeddings
- Se obtiene un vector de 512 dimensiones
-
Almacenamiento en Pinecone:
- Cada producto se almacena con ID único:
product_{item_code} - Se incluye metadata: código, descripción, user_id, fecha
- Se usa namespace por usuario para aislamiento
- Cada producto se almacena con ID único:
-
Búsqueda:
- Se genera embedding para el texto de búsqueda
- Se buscan los vectores más similares en Pinecone
- Se retornan los productos ordenados por similitud
Cada vector en Pinecone incluye:
{
"item_code": "12345",
"description": "Tornillo acero inoxidable 1/4",
"supabase_id": "uuid-del-registro",
"user_id": "uuid-del-usuario",
"synced_at": "2025-12-12T10:30:00Z"
}Si ENABLE_PINECONE_SYNC=true, el sistema:
- Sincroniza productos nuevos automáticamente
- Actualiza productos modificados
- Ejecuta sincronización cada
PINECONE_SYNC_INTERVALminutos
- Pinecone: Plan gratuito incluye 1 índice y 100K vectores
- Embeddings: $10/mes por servicio en chatbotstools.asistentesautonomos.com
Si ves errores como estos:
Error: duplicate key value violates unique constraint "invoice_third_parties_id_n_key"
Error: duplicate key value violates unique constraint "invoice_products_item_code_key"
Causa: Las restricciones UNIQUE en Supabase no incluyen el user_id, causando conflictos entre usuarios.
Solución:
-
Ejecuta el script de diagnóstico:
npm run diagnostic
-
Ejecuta el SQL de corrección en Supabase SQL Editor:
- Abre el archivo
database/fix_unique_constraints.sql - Copia todo el contenido
- Pégalo en Supabase SQL Editor y ejecútalo
- Abre el archivo
-
Reinicia el servicio
Qué hace el script SQL:
- Elimina restricciones UNIQUE simples (
id_n,item_code,account_code) - Crea restricciones UNIQUE compuestas (
id_n + user_id, etc.) - Permite que múltiples usuarios tengan los mismos códigos
Si había facturas en estado APROBADO antes de iniciar el servicio y no se sincronizaron:
Causa: El sistema tiene recuperación automática pero puede estar deshabilitada o fallar.
Diagnóstico:
npm run diagnosticSoluciones:
-
Verificar configuración:
ENABLE_INVOICE_RECOVERY=true RECOVERY_BATCH_SIZE=10
-
Reiniciar el servicio: Al iniciar, el sistema busca y procesa facturas pendientes automáticamente
-
Verificar logs: Busca mensajes como:
Verificando facturas aprobadas pendientes de sincronización... Encontradas X facturas aprobadas pendientes -
Procesar manualmente: Si la recuperación automática falla, usa:
npm run test-recovery
Cómo funciona la recuperación:
- Al iniciar, el sistema busca facturas con
estado=APROBADOyservice_response != 'Ok' - Las procesa en lotes (tamaño configurable)
- Actualiza el estado a
SINCRONIZADOoERRORsegún el resultado
Síntomas:
- Ves datos de otros usuarios
- Errores de permisos
Solución:
- Verifica que
USER_UUIDesté configurado en.env - Ejecuta el test de filtro:
npm run test-user-filter
- Verifica que todas las tablas tengan el campo
user_id - Reinicia el servicio
# Diagnóstico completo
npm run diagnostic
# Verificar filtro de usuario
npm run test-user-filter
# Probar recuperación de facturas
npm run test-recovery
# Ver estadísticas de sincronización
npm run sync-third-parties-stats
npm run sync-accounts-stats
npm run sync-products-stats- Detección: Supabase Realtime detecta cambio en
invoices.estado = "APROBADO" - Obtención: Se obtienen datos completos (invoice + items + entries)
- Validación: Se verifica que exista tipo FIA en TIPDOC
- Mapeo: Se transforman los datos al formato Firebird
- Inserción: Se insertan datos en CARPROEN y CARPRODE
- Actualización: Se actualiza consecutivo en TIPDOC si es necesario
Al iniciar el servicio, se ejecuta automáticamente un proceso de recuperación que:
- Búsqueda: Identifica facturas con
estado = "APROBADO"yservice_response != "Ok" - Procesamiento por lotes: Procesa las facturas en grupos configurables (por defecto 10)
- Sincronización: Aplica el mismo flujo de procesamiento que las facturas en tiempo real
- Pausa entre lotes: Incluye pausas para no sobrecargar el sistema
- Reporte: Genera un reporte final con facturas procesadas y errores
Configuración de recuperación:
ENABLE_INVOICE_RECOVERY=true # Habilitar/deshabilitar recuperación
RECOVERY_BATCH_SIZE=10 # Número de facturas por loteLos logs se guardan en:
logs/combined.log- Todos los logslogs/error.log- Solo errores- Consola - Logs con colores para desarrollo
- Transacciones: Rollback automático en caso de error
- Reconexión: Reintentos automáticos de conexión
- Logging: Registro detallado de todos los errores
- Graceful shutdown: Cierre limpio con Ctrl+C
src/
├── config/ # Configuración
├── database/ # Clientes de BD
├── services/ # Lógica de negocio
├── utils/ # Utilidades
└── index.js # Punto de entrada
El servicio registra:
- Facturas procesadas exitosamente
- Errores de conexión o procesamiento
- Estadísticas de rendimiento
- Estado de las conexiones
- Verificar credenciales en
.env - Confirmar que el puerto 3050 esté abierto
- Validar permisos del usuario
- Verificar URL y clave anónima
- Confirmar que Realtime esté habilitado
- Validar permisos en la tabla invoices
- Verificar que el estado sea exactamente "APROBADO"
- Confirmar que existan entradas contables
- Revisar logs para errores específicos
MIT License - Ver archivo LICENSE para detalles.