almeira-web/facturacion-dian-hub/README.md

10 KiB

🇨🇴 DIAN Electronic Invoicing Hub ("Software Propio")

Innovación & Desarrollo S.A.S. • NIT 901.554.892-9

Hub Fiscal Centralizado Multi-Tenant para DripZone y PacificTrans

Node.js TypeScript Fastify Prisma PostgreSQL React DIAN


🏛️ 1. Arquitectura de Software y Principios de Diseño (Clean Architecture & DDD)

El sistema ha sido diseñado por el equipo de Arquitectura de Software & Seguridad Cloud aplicando Clean Architecture (Uncle Bob) y Domain-Driven Design (DDD) con separación estricta de capas e inversión de dependencias:

facturacion-dian-hub/
├── backend/
│   ├── src/
│   │   ├── domain/               # Capa de Dominio (Entidades, Value Objects, Puertos, Eventos, Reglas Fiscales)
│   │   │   ├── entities/         # Factura (Aggregate Root), Cliente, ItemFactura, ResolucionDian, Tenant
│   │   │   ├── value-objects/    # Cufe (SHA-384), Nit (Módulo 11), Money, SoftwareSecurityCode, FiscalEnums
│   │   │   ├── ports/            # IFacturaRepository, ITenantRepository, IResolucionRepository, IDianClient, IXmlSigner...
│   │   │   └── exceptions/       # ValidacionFiscalException, ResolucionAgotadaException, FirmaDigitalException
│   │   ├── application/          # Capa de Aplicación (Casos de Uso, DTOs y Servicios de Orquestación)
│   │   │   ├── use-cases/        # EmitirFacturaUseCase, ConsultarFacturasUseCase...
│   │   │   ├── services/         # DianUblBuilderService (Generador UBL 2.1 estándar)
│   │   │   └── dtos/             # EmitirFacturaInputDto (Zod), FacturaResponseDto
│   │   ├── infrastructure/       # Capa de Infraestructura (Adaptadores de Frameworks y Drivers)
│   │   │   ├── database/         # Prisma Client, PostgreSQL 16 Repositorios y Store Resiliente
│   │   │   ├── security/         # XadesSigner (Firma XAdES-BES RSA-SHA256), CryptoService (AES-256-GCM)
│   │   │   ├── dian/             # DianSoapClient (SOAP VPFE y Simulador DIAN Integrado)
│   │   │   ├── qr/               # QrGeneratorService (SVG y Base64 Data URL)
│   │   │   └── printing/         # PdfGeneratorService (Representación Gráfica Oficial)
│   │   └── presentation/         # Capa de Presentación (Controladores, Rutas y Middlewares Fastify)
│   │       ├── controllers/      # InvoiceController, TenantController, ResolutionController
│   │       ├── middlewares/      # AuthenticationMiddleware (API Keys), ErrorHandlerMiddleware
│   │       ├── routes/           # /api/v1/invoices, /api/v1/tenants, /api/v1/resolutions, /health
│   │       └── server.ts         # Fastify App Builder con Helmet, CORS, Rate Limit y Swagger UI
├── frontend/                     # Panel Administrativo Web Moderno (React 18 + Vite 5 + Tailwind CSS v3.4)
│   ├── src/
│   │   ├── api/                  # Cliente HTTP con soporte Multi-Tenant
│   │   ├── store/                # Zustand Global State
│   │   ├── components/           # Navbar, KpiMetrics, InvoicesTable, InvoiceDetailModal, InvoiceEmitterModal...
│   │   └── App.tsx               # Dashboard Principal y Explorador de Facturas
├── docker-compose.yml            # Orquestación de Contenedores (Postgres 16, Backend y Frontend)
├── Dockerfile.backend            # Multi-stage Alpine con usuario no root
├── Dockerfile.frontend           # Multi-stage Nginx Alpine con compresión gzip y headers de seguridad
└── nginx.conf                    # Configuración de producción para proxy inverso y SPA

⚖️ 2. Cumplimiento Normativo DIAN Colombia (UBL 2.1)

El microservicio implementa con exactitud los requerimientos de la Resolución 000165 de 2023 y el Anexo Técnico de Factura Electrónica de Venta (Versión 1.9 vigente):

  1. Algoritmo de Dígito de Verificación (NIT):

    • Implementa el algoritmo oficial de Módulo 11 de la DIAN utilizando la serie de primos descendentes [3, 7, 13, 17, 19, 23, 29, 37, 41, 43, 47, 53, 59, 67, 71].
    • Para Innovación & Desarrollo S.A.S. (NIT 901554892), el dígito calculado es 9 (901.554.892-9).
  2. Cálculo de CUFE (Código Único de Factura Electrónica):

    • Función hash SHA-384 con formato estricto de 96 caracteres hexadecimales:
      \text{CUFE} = \text{SHA-384}(\text{NumFac} + \text{FecFac} + \text{HorFac} + \text{ValFac} + \text{CodImp1} + \text{ValImp1} + \dots + \text{ValTot} + \text{NitOFE} + \text{NumAdq} + \text{ClaveTecnica} + \text{TipoAmbiente})
  3. Código de Seguridad del Software (SoftwareSecurityCode):

    • Incrustado en sts:DianExtensions:
      \text{SoftwareSecurityCode} = \text{SHA-384}(\text{SoftwareID} + \text{SoftwarePIN} + \text{NumeroFactura})
  4. Firma Digital XAdES-BES (XMLDSig):

    • Firma electrónica enveloped con algoritmo RSA-SHA256 y Canonicalización C14N (http://www.w3.org/TR/2001/REC-xml-c14n-20010315).
    • Bloque xades:QualifyingProperties con xades:SignedProperties, SigningTime, SigningCertificate y SignaturePolicyIdentifier oficial de la DIAN (https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf).
  5. Código QR Estándar:

    • URL de validación inmediata: https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey={CUFE}
  6. Control de Consecutivos y Bloqueo Atómico:

    • La reserva de número consecutivo se ejecuta mediante transacciones ACID atómicas en PostgreSQL (dian_resolutions.currentConsecutive = currentConsecutive + 1), impidiendo saltos o colisiones en emisiones concurrentes.

🏢 3. Aislamiento Multi-Tenant (DripZone & PacificTrans)

El microservicio funciona como un Hub Fiscal Centralizado para múltiples unidades de negocio de la compañía:

Tenant Slug Caso de Uso Fiscal Prefijo Autorizado Actividad Económica (CIIU) API Key de Prueba
DripZone dripzone Venta minorista de Sneakers y Streetwear (IVA 19%) DRIP (1 al 50.000) 4771 (Prendas de vestir y calzado) dz_live_key_98f4bc12e87a
PacificTrans pacifictrans Transporte terrestre intermunicipal de pasajeros y flete de carga marítima/terrestre (Excluido IVA Art. 476 ET) PACT (1 al 50.000) 4923 (Transporte de carga por carretera) pt_live_key_33c9a184ef10

🚀 4. Guía de Ejecución Rápida

Opción A: Desarrollo Local con Node 22 (Sin Docker)

  1. Iniciar Backend:

    cd backend
    npm install
    npm run dev
    

    Servidor API disponible en: http://localhost:3001
    Swagger Docs: http://localhost:3001/api/docs
    Health Check: http://localhost:3001/health

  2. Iniciar Frontend Panel:

    cd frontend
    npm install
    npm run dev
    

    Panel Administrativo disponible en: http://localhost:3000

  3. Ejecutar Pruebas Unitarias de Reglas Fiscales:

    cd backend
    npx tsx --test tests/DianFiscalRules.test.ts
    

Opción B: Ejecución Contenerizada con Docker Compose v2

docker compose up -d --build

Servicios desplegados:

  • Base de Datos: PostgreSQL 16 Alpine en localhost:5432 con volumen persistente dian_hub_pgdata.
  • Backend API: Fastify en http://localhost:3001.
  • Frontend Panel: Nginx en http://localhost:3000.

📡 5. Catálogo de Endpoints de la API (REST / JSON)

Todas las peticiones a la API protegida requieren la cabecera x-api-key.

Emitir Factura Electrónica

POST /api/v1/invoices
Headers: x-api-key: dz_live_key_98f4bc12e87a, Content-Type: application/json

{
  "operationType": "10",
  "paymentType": "1",
  "paymentMethodCode": "10",
  "customer": {
    "identificationType": "13",
    "identificationNumber": "1144987654",
    "legalOrFullName": "Juan David Gómez",
    "email": "juan.gomez@gmail.com",
    "address": "Carrera 100 # 16-20",
    "cityName": "Cali",
    "departmentCode": "76",
    "cityCode": "76001",
    "taxRegime": "49"
  },
  "items": [
    {
      "sku": "DZ-AIR-JORDAN-01",
      "description": "Air Jordan 1 Retro High OG Lost and Found (Talla 42)",
      "quantity": 1,
      "unitPrice": 890000,
      "taxPercentage": 19,
      "taxTypeCode": "01",
      "discountAmount": 0
    }
  ]
}

Respuesta Exitosa (201 Created):

{
  "success": true,
  "data": {
    "id": "e4f876c1-...",
    "fullNumber": "DRIP-1043",
    "cufe": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855...",
    "subtotal": 890000,
    "taxTotal": 169100,
    "grandTotal": 1059100,
    "dianStatus": "ACEPTADA",
    "dianStatusCode": "00",
    "dianStatusDescription": "Procesado y Validado con Éxito por la DIAN (VPFE Validación Previa).",
    "xmlSignedUrl": "/api/v1/invoices/e4f876c1-.../xml",
    "pdfUrl": "/api/v1/invoices/e4f876c1-.../pdf"
  }
}

Otros Endpoints:

  • GET /api/v1/invoices: Listado con filtros por estado, tenant y búsqueda.
  • GET /api/v1/invoices/metrics: Métricas consolidadas (Total Facturado, IVA, % Aprobación).
  • GET /api/v1/invoices/:id/xml: Descarga el archivo XML UBL 2.1 con la firma digital XAdES-BES.
  • GET /api/v1/invoices/:id/pdf: Visualiza o descarga la representación gráfica oficial en PDF.
  • GET /api/v1/tenants: Listado de tenants autorizados.
  • GET /api/v1/resolutions: Control de numeración autorizada y alertas de vencimiento.

🔒 6. Directrices de Despliegue en VPS (Coolify)

Important

De conformidad con las políticas operativas del sistema, los despliegues en el servidor VPS de producción se administran exclusivamente a través de Coolify. No se deben levantar contenedores manuales fuera de Coolify para garantizar la integridad del enrutamiento de Traefik y evitar duplicidades de puertos o instancias.