Flujo de Negocio
El flujo de negocio de GM Fiscal cubre seis fases secuenciales que llevan al contador desde el acceso al sistema hasta la obtención del reporte Excel listo para presentar al SAT. Cada fase es atómica: si falla, el estado de la solicitud refleja el error y el sistema permite reintentar sin pérdida de datos.
Diagrama del flujo completo
flowchart TD
START([Contador accede al sistema]) --> LOGIN
subgraph AUTH["FASE 1 — Autenticación"]
LOGIN["Ingresa usuario, contraseña y RFC"]
VALIDATE["GM Servicios valida credenciales"]
TOKEN["Se emiten tokens JWT (24h acceso / 30d renovable)"]
EMPRESA["Se registra la empresa si es la primera vez"]
end
subgraph REQUEST["FASE 2 — Crear solicitud"]
NEW_SOL["Selecciona empresa, período y tipo de facturas"]
ESTADO1["Solicitud creada: Listo para conciliar"]
end
subgraph FETCH["FASE 3 — Obtener facturas"]
FETCH_ERP["Consulta ERP: facturas registradas en contabilidad"]
FETCH_SAT["Consulta SAT vía Prodigia o Hades Bóveda Fiscal"]
PARSE["Parseo y normalización de XMLs CFDI"]
end
subgraph CONCILIA["FASE 4 — Conciliación"]
MATCH["Cruce ERP vs SAT por UUID (strings.EqualFold)"]
RESULT_A["AMBOS: presente en ERP y en SAT"]
RESULT_B["SOLO ERP: en contabilidad, sin timbre SAT"]
RESULT_C["SOLO SAT: timbrado, no registrado en ERP"]
RESULT_D["CANCELADO: fecha de cancelación en ERP"]
ESTADO2["Solicitud: Conciliada (estado final)"]
end
subgraph REPORT["FASE 5 — Generar reporte"]
TRIGGER["Solicitud de reporte R21 / RAMCI"]
ASYNC["Worker asincrónico procesa en segundo plano"]
EXCEL["Excel generado con formato SAT"]
AZURE["Subida a Azure Blob Storage"]
NOTIF["Notificación en tiempo real vía WebSocket"]
end
subgraph DOWNLOAD["FASE 6 — Descarga"]
DOWNLOAD_REPORT["Contador descarga el Excel para presentar al SAT"]
end
LOGIN --> VALIDATE --> TOKEN --> EMPRESA
EMPRESA --> NEW_SOL --> ESTADO1
ESTADO1 --> FETCH_ERP
ESTADO1 --> FETCH_SAT
FETCH_ERP --> PARSE
FETCH_SAT --> PARSE
PARSE --> MATCH
MATCH --> RESULT_A & RESULT_B & RESULT_C & RESULT_D
RESULT_A & RESULT_B & RESULT_C & RESULT_D --> ESTADO2
ESTADO2 --> TRIGGER --> ASYNC
ASYNC --> EXCEL --> AZURE --> NOTIF --> DOWNLOAD_REPORT
Fase 1 — Autenticación
El login valida las credenciales del usuario contra GM Servicios, el sistema centralizado de autenticación del ecosistema GM Transporte. Si la validación es exitosa, se emiten dos tokens JWT:
- Access token: vigencia de 24 horas. Se envía en el encabezado
Authorization: Bearer <token>en todas las peticiones posteriores. - Refresh token: vigencia de 30 días. Se usa para obtener un nuevo access token sin requerir credenciales.
La sesión se persiste en la tabla sesiones_usuario con IP, user-agent y fechas para auditoría. Si la empresa asociada al RFC del usuario no existe en el sistema, EmpresaAutoRegistrationAdapter la registra automáticamente con los datos del token.
Fase 2 — Creación de solicitud
El contador crea una Solicitud especificando el RFC de la empresa, el período fiscal (fecha inicio y fecha fin) y el tipo de facturas a conciliar. La solicitud nace en estado Listo para conciliar y recibe un UUID único que la identifica durante todo el flujo.
POST /api/solicitudesEl tipo de facturas puede incluir emitidas, recibidas, pagos, nómina o una combinación de ellas. Este parámetro determina los filtros aplicados en las consultas posteriores al SAT y al ERP.
Fase 3 — Obtención de facturas
Esta fase es la de mayor complejidad técnica. Las facturas se obtienen de dos fuentes en paralelo:
Desde el ERP. El gateway erp/facturas_client.go consulta el sistema de contabilidad interno de GM Transporte para obtener las facturas registradas en el período. Los datos provienen del QueryGatewayService de Hades (MSSQL multi-empresa) cuando el provider es Hades, o del endpoint HTTP directo del ERP cuando el provider es Prodigia.
Desde el SAT. El gateway activo —Prodigia o Hades— entrega los CFDIs oficiales en formato ZIP. Los XMLs se extraen, se limpian de namespaces con RemoveNamespaces() y se parsean con xml.Unmarshal hacia las estructuras CFDI.
El parseo aplica 50 goroutines concurrentes para procesar los XMLs en paralelo. Los UUIDs se comparan siempre con strings.EqualFold para manejar la insensibilidad a mayúsculas/minúsculas de los UUIDs SAT.
Fase 4 — Conciliación
La conciliación la ejecuta MakeConciliacion, una función pura del dominio. No tiene efectos secundarios, no accede a base de datos ni a HTTP. Recibe las listas de facturas de ambas fuentes y produce un resultado determinístico clasificando cada factura en una de cuatro categorías:
| Categoría | Condición |
|---|---|
AMBOS | UUID presente en ERP y en SAT, estatus vigente |
ERP | UUID en ERP, ausente en SAT |
PRODIGIA | UUID en SAT, ausente en ERP |
CANCELADO | UUID presente en ERP con fecha de cancelación |
Al finalizar, la solicitud pasa a estado Conciliada, que es el único estado final e inmutable del sistema.
Fase 5 — Generación de reportes
El endpoint POST /api/reporte persiste el reporte con estado Pendiente y responde 202 Accepted de forma inmediata. El procesamiento real ocurre en el ReporteWorker, que corre con un ticker cada 10 segundos.
El worker toma los reportes pendientes y los procesa con un semáforo de máximo 3 simultáneos. Para cada reporte:
R21Processorclasifica las facturas conciliadas y calcula IVA Causado, IVA Acreditable, IVA Retenido e ISR Retenido con redondeo half-up SAT.RAMCIProcessorclasifica los comprobantes en categorías R/A/M/C/I para el reporte anual.excelizegenera el archivo Excel con las hojas del R21 y el RAMCI.- El archivo se sube a Azure Blob Storage y se genera una URL SAS con vigencia configurable.
- El sistema notifica al cliente mediante WebSocket que el reporte está disponible.
Fase 6 — Descarga
El cliente recibe la notificación WebSocket con la URL del Excel en Azure Blob. La URL incluye un token SAS con vigencia de 1440 minutos (24 horas) por defecto, configurable mediante AZURE_SAS_EXPIRY_MINUTES. Pasado ese tiempo, el cliente puede solicitar una nueva URL sin regenerar el archivo.
Contrato HTTP del flujo principal
Las rutas principales que cubren el flujo de negocio son:
POST /api/auth/login # AutenticaciónPOST /api/solicitudes # Crear solicitudGET /api/solicitudes/uuid/{uuid} # Consultar estadoPOST /api/conciliacion # Ejecutar conciliaciónGET /api/conciliacion/{uuid} # Ver resultadoPOST /api/reporte # Solicitar reporteGET /api/reporte/{uuid} # Consultar estado del reporteWS /api/ws/notificaciones/{rfc} # Canal WebSocket por RFCTodas las rutas bajo /api/* requieren el encabezado Authorization: Bearer <token> excepto /api/auth/login y /api/auth/refresh.
Pre-conciliación autónoma (solo con Hades)
Cuando el proveedor activo es Hades, el sistema puede ejecutar un pipeline de pre-conciliación en segundo plano antes de que el contador lo solicite explícitamente. Dos goroutines independientes sincronizadas con sync.WaitGroup procesan simultáneamente:
- Rama SAT: descarga y caché de todos los CFDIs del período en PostgreSQL 5434 + Azure Blob.
- Rama ERP: obtención y caché de las facturas del ERP para el mismo período.
El resultado queda almacenado como SolicitudAsset. Cuando el contador inicia la conciliación, el sistema usa los datos precacheados y el proceso es prácticamente instantáneo.
Resumen
- El flujo completo cubre seis fases: autenticación, creación de solicitud, obtención de facturas, conciliación, generación de reporte y descarga.
- La conciliación la ejecuta
MakeConciliacion, una función pura sin efectos secundarios, completamente testeable sin infraestructura. - Los reportes se generan de forma asincrónica con notificación WebSocket en tiempo real; el endpoint responde 202 inmediatamente.
- La pre-conciliación autónoma con Hades descarga y cachea facturas SAT y ERP en segundo plano para acelerar el proceso cuando el contador lo solicite.
- El estado
Conciliadaes el único estado final e inmutable; ninguna transición puede salir de él.