Files
Horux360/docs/SAT-SYNC-IMPLEMENTATION.md
Consultoria AS dcc33af523 feat: SAT sync improvements and documentation
- Add custom date range support for SAT synchronization
- Fix UUID cast in SQL queries for sat_sync_job_id
- Fix processInitialSync to respect custom dateFrom/dateTo parameters
- Add date picker UI for custom period sync
- Add comprehensive documentation for SAT sync implementation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 03:01:27 +00:00

7.1 KiB

Implementación de Sincronización SAT

Resumen

Sistema de sincronización automática de CFDIs con el SAT (Servicio de Administración Tributaria de México) para Horux360.

Componentes Implementados

1. Backend (API)

Servicios

Archivo Descripción
src/services/fiel.service.ts Gestión de credenciales FIEL (e.firma)
src/services/sat/sat-client.service.ts Cliente para el servicio web del SAT
src/services/sat/sat.service.ts Lógica principal de sincronización
src/services/sat/sat-crypto.service.ts Encriptación AES-256-GCM para credenciales
src/services/sat/sat-parser.service.ts Parser de XMLs de CFDI

Controladores

Archivo Descripción
src/controllers/fiel.controller.ts Endpoints para gestión de FIEL
src/controllers/sat.controller.ts Endpoints para sincronización SAT

Job Programado

Archivo Descripción
src/jobs/sat-sync.job.ts Cron job para sincronización diaria (3:00 AM)

2. Frontend (Web)

Componentes

Archivo Descripción
components/sat/FielUploadModal.tsx Modal para subir certificado y llave FIEL
components/sat/SyncStatus.tsx Estado de sincronización con selector de fechas
components/sat/SyncHistory.tsx Historial de sincronizaciones

Página

Archivo Descripción
app/(dashboard)/configuracion/sat/page.tsx Página de configuración SAT

3. Base de Datos

Tabla Principal (schema public)

-- sat_sync_jobs: Almacena los trabajos de sincronización
CREATE TABLE sat_sync_jobs (
  id UUID PRIMARY KEY,
  tenant_id UUID NOT NULL,
  type VARCHAR(20) NOT NULL,  -- 'initial' | 'daily'
  status VARCHAR(20) NOT NULL, -- 'pending' | 'running' | 'completed' | 'failed'
  date_from TIMESTAMP NOT NULL,
  date_to TIMESTAMP NOT NULL,
  cfdi_type VARCHAR(20),
  sat_request_id VARCHAR(100),
  sat_package_ids TEXT[],
  cfdis_found INTEGER DEFAULT 0,
  cfdis_downloaded INTEGER DEFAULT 0,
  cfdis_inserted INTEGER DEFAULT 0,
  cfdis_updated INTEGER DEFAULT 0,
  progress_percent INTEGER DEFAULT 0,
  error_message TEXT,
  started_at TIMESTAMP,
  completed_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW(),
  retry_count INTEGER DEFAULT 0
);

-- fiel_credentials: Almacena las credenciales FIEL encriptadas
CREATE TABLE fiel_credentials (
  id UUID PRIMARY KEY,
  tenant_id UUID UNIQUE NOT NULL,
  rfc VARCHAR(13) NOT NULL,
  cer_data BYTEA NOT NULL,
  key_data BYTEA NOT NULL,
  key_password_encrypted BYTEA NOT NULL,
  encryption_iv BYTEA NOT NULL,
  encryption_tag BYTEA NOT NULL,
  serial_number VARCHAR(100),
  valid_from TIMESTAMP NOT NULL,
  valid_until TIMESTAMP NOT NULL,
  is_active BOOLEAN DEFAULT true,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

Columnas agregadas a tabla cfdis (por tenant)

ALTER TABLE tenant_xxx.cfdis ADD COLUMN xml_original TEXT;
ALTER TABLE tenant_xxx.cfdis ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE tenant_xxx.cfdis ADD COLUMN last_sat_sync TIMESTAMP;
ALTER TABLE tenant_xxx.cfdis ADD COLUMN sat_sync_job_id UUID;
ALTER TABLE tenant_xxx.cfdis ADD COLUMN source VARCHAR(20) DEFAULT 'manual';

Dependencias

{
  "@nodecfdi/sat-ws-descarga-masiva": "^2.0.0",
  "@nodecfdi/credentials": "^2.0.0",
  "@nodecfdi/cfdi-core": "^1.0.1"
}

Flujo de Sincronización

1. Usuario configura FIEL (certificado .cer + llave .key + contraseña)
   ↓
2. Sistema valida y encripta credenciales (AES-256-GCM)
   ↓
3. Usuario inicia sincronización (manual o automática 3:00 AM)
   ↓
4. Sistema desencripta FIEL y crea cliente SAT
   ↓
5. Por cada mes en el rango:
   a. Solicitar CFDIs emitidos al SAT
   b. Esperar respuesta (polling cada 30s)
   c. Descargar paquetes ZIP
   d. Extraer y parsear XMLs
   e. Guardar en BD del tenant
   f. Repetir para CFDIs recibidos
   ↓
6. Marcar job como completado

API Endpoints

FIEL

Método Ruta Descripción
GET /api/fiel/status Estado de la FIEL configurada
POST /api/fiel/upload Subir nueva FIEL
DELETE /api/fiel Eliminar FIEL

Sincronización SAT

Método Ruta Descripción
POST /api/sat/sync Iniciar sincronización
GET /api/sat/sync/status Estado actual
GET /api/sat/sync/history Historial de syncs
GET /api/sat/sync/:id Detalle de un job
POST /api/sat/sync/:id/retry Reintentar job fallido

Parámetros de sincronización

interface StartSyncRequest {
  type?: 'initial' | 'daily';  // default: 'daily'
  dateFrom?: string;           // ISO date, ej: "2025-01-01T00:00:00"
  dateTo?: string;             // ISO date, ej: "2025-12-31T23:59:59"
}

Configuración

Variables de entorno

# Clave para encriptar credenciales FIEL (32 bytes hex)
FIEL_ENCRYPTION_KEY=tu_clave_de_32_bytes_en_hexadecimal

# Zona horaria para el cron
TZ=America/Mexico_City

Límites del SAT

  • Antigüedad máxima: 6 años
  • Solicitudes por día: Limitadas (se reinicia cada 24h)
  • Tamaño de paquete: Variable

Errores Comunes del SAT

Código Mensaje Solución
5000 Solicitud Aceptada OK - esperar verificación
5002 Límite de solicitudes agotado Esperar 24 horas
5004 No se encontraron CFDIs Normal si no hay facturas en el rango
5005 Solicitud duplicada Ya existe una solicitud pendiente
- Información mayor a 6 años Ajustar rango de fechas
- No se permite descarga de cancelados Facturas canceladas no disponibles

Seguridad

  1. Encriptación de credenciales: AES-256-GCM con IV único
  2. Almacenamiento seguro: Certificado, llave y contraseña encriptados
  3. Autenticación: JWT con tenantId embebido
  4. Aislamiento: Cada tenant tiene su propio schema en PostgreSQL

Servicios Systemd

# API Backend
systemctl status horux-api

# Web Frontend
systemctl status horux-web

Comandos Útiles

# Ver logs de sincronización SAT
journalctl -u horux-api -f | grep "\[SAT\]"

# Estado de jobs
psql -U postgres -d horux360 -c "SELECT * FROM sat_sync_jobs ORDER BY created_at DESC LIMIT 5;"

# CFDIs sincronizados por tenant
psql -U postgres -d horux360 -c "SELECT COUNT(*) FROM tenant_xxx.cfdis WHERE source = 'sat';"

Changelog

2026-01-25

  • Implementación inicial de sincronización SAT
  • Integración con librería @nodecfdi/sat-ws-descarga-masiva
  • Soporte para fechas personalizadas en sincronización
  • Corrección de cast UUID en queries SQL
  • Agregadas columnas faltantes a tabla cfdis
  • UI para selección de periodo personalizado
  • Cambio de servicio web a modo producción (next start)

Próximos Pasos

  • Implementar reintentos automáticos para errores temporales
  • Notificaciones por email al completar sincronización
  • Dashboard con estadísticas de CFDIs por periodo
  • Soporte para filtros adicionales (RFC emisor/receptor, tipo de comprobante)