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

212 lines
10 KiB
Markdown

# 🇨🇴 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.