# 🇨🇴 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](https://img.shields.io/badge/Node.js-v22%20LTS-green.svg)](https://nodejs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-5.6%20Strict-blue.svg)](https://www.typescriptlang.org/) [![Fastify](https://img.shields.io/badge/Fastify-v4%2Fv5-black.svg)](https://www.fastify.io/) [![Prisma](https://img.shields.io/badge/Prisma-v5-indigo.svg)](https://www.prisma.io/) [![PostgreSQL](https://img.shields.io/badge/PostgreSQL-16%20Alpine-336791.svg)](https://www.postgresql.org/) [![React](https://img.shields.io/badge/React-18.3-61dafb.svg)](https://react.dev/) [![DIAN](https://img.shields.io/badge/DIAN-Resolución%20000165%20de%202023-emerald.svg)](https://www.dian.gov.co/) --- ## 🏛️ 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:** ```bash 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:** ```bash cd frontend npm install npm run dev ``` *Panel Administrativo disponible en:* `http://localhost:3000` 3. **Ejecutar Pruebas Unitarias de Reglas Fiscales:** ```bash cd backend npx tsx --test tests/DianFiscalRules.test.ts ``` --- ### Opción B: Ejecución Contenerizada con Docker Compose v2 ```bash 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` ```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): ```json { "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.