Cliente: Centrica
Proyecto: Nebula ERP
Versión: 1.0
Fecha: 29 de Diciembre, 2025
Autor: Carlos Torres (Arquitecto de Software - CatcSoft)
Estado: VIGENTE - Documento Maestro de Arquitectura
- Introducción y Contexto
- C4 Level 1 - System Context Diagram
- C4 Level 2 - Container Diagram
- C4 Level 3 - Component Diagram
- C4 Level 4 - Code Diagram
- Architecture Decision Records (ADRs)
- Quality Attributes
- Deployment View
- Data Architecture
- Security Architecture
- Technology Stack
- Migration Strategy
Este documento describe la arquitectura de software completa de Nebula ERP, el nuevo sistema de gestión empresarial que Centrica construirá sobre el framework Simappe (licenciado de CatcSoft).
Este es el documento maestro que consolida todas las decisiones arquitectónicas, patrones, diagramas C4 y especificaciones técnicas del proyecto.
Nebula ERP es un sistema ERP modular, multi-tenant, construido sobre el stack Simappe que soporta:
- Gestión Financiera: Contabilidad general, plan de cuentas, tesorería
- Facturación Electrónica: Facturación con integración DIAN, validación de documentos
- Gestión de Impuestos: IVA, retenciones, declaraciones tributarias
- Presupuestos: Control presupuestal, seguimiento y análisis de desviaciones
- Gestión de Nómina: Cálculo y generación de nóminas con cumplimiento DIAN
- Talento Humano: Contratación, evaluación de desempeño, capacitación
- Gestión de Inventarios: Control de stock, bodegas, movimientos, kardex
- Activos Fijos: Registro, depreciación, mantenimiento de activos
- Reportería Avanzada: BI, dashboards, reportes regulatorios
Relación Simappe - Nebula:
- Simappe = Framework/stack desarrollado por CatcSoft (Carlos Torres)
- Centrica = Cliente que licencia Simappe para construir Nebula
- Nebula = Producto ERP construido SOBRE Simappe (NO reemplazo)
CatcSoft (Carlos)
↓ licencia
Simappe Framework (Core/Base)
↓ usa como base
Centrica
↓ construye
Nebula ERP (Producto Final)
Diagrama de Relación:
flowchart LR
CatcSoft[CatcSoft - Carlos Torres]
Simappe[Simappe Framework]
Centrica[Centrica - Cliente]
Nebula[Nebula ERP]
CatcSoft -->|Desarrolla| Simappe
CatcSoft -->|Licencia a| Centrica
Centrica -->|Usa como base| Simappe
Centrica -->|Construye| Nebula
Nebula -->|Ejecuta sobre| Simappe
style Simappe fill:#ff9,stroke:#333,stroke-width:2px
style Nebula fill:#9f9,stroke:#333,stroke-width:3px
Arquitectura Base: Simappe provee:
- Multi-tenancy DATABASE-BASED
- Microservicios base (Gateway, Admin, Client, OAuth2)
- Clases base (SimappeController, SimappeService, SimappeRepository)
- Infraestructura de datos (TenantAwareDataSource, HikariCP)
Arquitectura de Negocio: Nebula añade:
- Microservicios de dominio (Accounting, Payroll, Inventory, etc.)
- Lógica de negocio específica de ERP
- Integraciones con DIAN, bancos, entidades externas
| Rol |
Nombre |
Responsabilidad |
| Arquitecto de Software |
Carlos Torres (CatcSoft) |
Decisiones arquitectónicas, diseño técnico |
| Product Owner |
[Centrica - COMPLETAR] |
Requisitos de negocio, priorización |
| Jefe de Infraestructura |
[Centrica - COMPLETAR] |
Provisión de recursos, ambientes |
| Jefe de RRHH |
[Centrica - COMPLETAR] |
Reclutamiento equipo desarrollo |
| Equipo de Desarrollo |
10 personas (2 Sr Backend, 2 Sr Frontend, 4 Jr, 1 DevOps, 1 QA) |
Implementación |
graph TB
subgraph External["Actores Externos"]
User["👤 Usuario Final<br/>(Contador, Gerente, RRHH)"]
Admin["👨💼 Administrador Sistema<br/>(IT Centrica)"]
Dev["👨💻 Desarrollador<br/>(Equipo Nebula)"]
end
subgraph Systems["Sistemas Externos"]
DIAN["🏛️ DIAN<br/>(Facturación Electrónica)"]
Banks["🏦 Bancos<br/>(Pagos, Conciliación)"]
Email["📧 Proveedores Email<br/>(AWS SES, MailerSend)"]
Storage["☁️ Storage<br/>(MinIO S3-compatible)"]
end
Nebula["🏢 NEBULA ERP<br/>(Sistema Central)"]
User -->|Usa vía Web| Nebula
Admin -->|Configura| Nebula
Dev -->|Desarrolla módulos| Nebula
Nebula -->|Reporta facturas| DIAN
Nebula -->|Solicita pagos| Banks
Nebula -->|Envía notificaciones| Email
Nebula -->|Almacena documentos| Storage
Banks -->|Confirma transacciones| Nebula
DIAN -->|Valida documentos| Nebula
style Nebula fill:#f96,stroke:#333,stroke-width:4px
style User fill:#9cf
style Admin fill:#fc9
style Dev fill:#9f9
style DIAN fill:#fcc
style Banks fill:#cfc
Usuarios Finales:
- Contadores: Registran facturas, gestionan tesorería
- Gerentes: Consultan reportes, aprueban gastos
- RRHH: Gestionan nómina, contratos
Administradores:
- Configuran tenants (nuevos clientes)
- Gestionan usuarios y permisos
- Monitorean sistema
Desarrolladores:
- Crean nuevos módulos de negocio
- Extienden funcionalidad base de Simappe
| Sistema |
Integración |
Protocolo |
Criticidad |
| DIAN |
Facturación electrónica |
SOAP/REST |
ALTA |
| Bancos |
Pagos PSE, conciliación |
REST |
ALTA |
| AWS SES |
Emails transaccionales |
SMTP/API |
MEDIA |
| MinIO |
Almacenamiento documentos |
S3 API |
MEDIA |

Identity Provider (Keycloak/OAuth2 Server)
- Responsabilidad: Autenticación y autorización
- Tecnología: Spring Authorization Server / Keycloak
- Puerto: 9999
- Endpoints:
/oauth2/token, /oauth2/authorize
API Gateway
- Responsabilidad: Routing, rate limiting, CORS
- Tecnología: Spring Cloud Gateway (WebFlux)
- Puerto: 8080
- Features: Circuit breaker, retry, timeout
Static Content (Nginx)
- Responsabilidad: Servir frontend Angular
- Tecnología: Nginx
- Puerto: 80/443
SimappeAdmin
- Responsabilidad: Gestión centralizada (usuarios, roles, configuración, notificaciones)
- Puerto: 9010 | Context-path:
/simappe-admin
- Base de Datos: PostgreSQL (users, roles, companies)
- Dependencias: MongoDB (audit), Kafka (events)
SimappeClient
- Responsabilidad: Configuraciones client-side (menús, consecutivos, perfiles)
- Puerto: 9020 | Context-path:
/simappe-client
- Base de Datos: PostgreSQL (menu_customization, consecutive_config)
- Cache: Redis (menu cache, 30 min TTL)
Microservicios de Dominio Nebula (Futuros):
nebula-accounting (8100): Contabilidad general y plan de cuentas
nebula-payroll (8101): Nómina y gestión de empleados
nebula-billing (8102): Facturación electrónica y DIAN
nebula-budgets (8103): Presupuestos y control financiero
nebula-taxes (8104): Impuestos (IVA, retenciones, declaraciones)
nebula-inventory (8105): Inventarios y bodegas
nebula-assets (8106): Activos fijos y depreciación
nebula-hr (8107): Talento humano (contratación, evaluación, capacitación)
nebula-reports (8108): Reportería avanzada y BI
SimappeCommons (JAR)
- Clases base:
SimappeController, SimappeService, SimappeRepository
- Multi-tenancy:
TenantAwareDataSource, TenantContext
- Anotaciones:
@ConnectionContext, @EntityIdSupport, @IgnoreTenant
- Clientes HTTP: Feign/WebClient para inter-service communication
SimappeModel (JAR)
- DTOs compartidos (242 DTOs en 8 dominios)
- Enums de negocio
- Constantes
SimappeArchetype (Maven Archetype)
- Generador de microservicios con estructura estándar
- Comando:
mvn archetype:generate -DarchetypeArtifactId=simappe-archetype
NebulaModel (JAR)
- DTOs específicos de Nebula ERP (contabilidad, nómina, inventarios, etc.)
- Extiende SimappeModel con dominios de negocio
- Enums específicos:
TaxType, InvoiceStatus, PayrollStatus, etc.
NebulaShared (JAR)
- Utilidades compartidas entre microservicios Nebula
- Validadores de negocio (RUT, NIT, DIAN)
- Formateadores (moneda, fechas, reportes)
- Integraciones comunes (DIAN, bancos)
Service Discovery (Eureka Server)
- Puerto: 8761
- Responsabilidad: Registro y descubrimiento de microservicios
Config Server
- Puerto: 8890
- Responsabilidad: Configuración centralizada
- Backend: Git repository
Kafka (Event Bus)
- Puertos: 9092 (broker), 2181 (zookeeper)
- Topics:
user-events, email-notifications, audit-log
- Retención: 30 días
Databases
- PostgreSQL 16+: Datos transaccionales (multi-tenant vía schemas)
- MongoDB 7+: Audit logs, documentos flexibles
- Redis 7+: Caché distribuido, sesiones
Portainer
- Puerto: 9000
- Responsabilidad: Gestión de contenedores Docker
flowchart TB
GW[API Gateway]
UserCtrl[UserController]
UserSvc[UserService]
UserComp[UserComponent - Business Logic]
UserRepo[UserRepository]
TenantCtx[TenantContext]
DataSource[TenantAwareDataSource]
DB1[(PostgreSQL acme)]
DB2[(PostgreSQL beta)]
Mongo[(MongoDB)]
KafkaProd[Kafka]
GW --> UserCtrl
UserCtrl --> UserSvc
UserSvc --> UserComp
UserComp --> UserRepo
UserRepo --> TenantCtx
TenantCtx --> DataSource
DataSource --> DB1
DataSource -.-> DB2
UserComp --> KafkaProd
KafkaProd --> Mongo
style UserComp fill:#9f9,stroke:#060,stroke-width:3px
style TenantCtx fill:#ff9,stroke:#333,stroke-width:2px
style DataSource fill:#ff9,stroke:#333,stroke-width:2px
// Controller extends SimappeController
@RestController
@RequestMapping("/api/v1/menu-configuration")
public class MenuConfigurationController extends SimappeController {
private final MenuConfigurationService menuConfigurationService;
@GetMapping("/read")
public ResponseEntity<List<MenuCustomizationDTO>> read(HttpServletRequest request) {
var list = menuConfigurationService.read(request);
return new ResponseEntity<>(list, HttpStatus.OK);
}
}
// Service (simple delegador)
@Service
public class MenuConfigurationService {
private final MenuConfigurationComponent menuConfigurationComponent;
public List<MenuCustomizationDTO> read(HttpServletRequest request) {
return menuConfigurationComponent.read(request); // Solo delega
}
}
// Component extends SimappeService - LÓGICA DE NEGOCIO AQUÍ
@Component
@ConnectionContext // Activa multi-tenancy
@EntityIdSupport // Soporte LongId
public class MenuConfigurationComponent extends SimappeService
implements CrudHttpServletRequestComponent<MenuCustomizationDTO, Long> {
private final MenuCustomizationRepository menuCustomizationRepository;
private final AuditLogService auditLogService;
@Override
public List<MenuCustomizationDTO> read(HttpServletRequest request) {
// LÓGICA DE NEGOCIO: El tenant se resuelve automáticamente
List<MenuCustomization> list = menuCustomizationRepository.findAll();
List<MenuCustomizationDTO> listReturn = this.loadForListEntity(list);
// Enviar evento de auditoría
auditLogService.sendMessage(SimappeUtilities.createAuditLogMessage(
"read", "List generated", EventType.READ,
this.getClass().getCanonicalName(),
request.getHeader(SimappeConstant.AUTHORIZATION)
));
return listReturn;
}
}
// Repository extends SimappeRepository
public interface MenuCustomizationRepository
extends SimappeRepository<MenuCustomization, LongId> {
// Custom query con filtro automático de tenant
@Query("SELECT m FROM MenuCustomization m WHERE m.levelType = :levelType")
List<MenuCustomization> findByLevelType(@Param("levelType") CustomizationLevelType levelType);
}
- Request llega al Gateway (puerto 8090)
- Gateway enruta a
MenuConfigurationController (SimappeClient, puerto 9020)
- Controller llama a
MenuConfigurationService.read()
- Service delega a
MenuConfigurationComponent.read()
- Component ejecuta lógica de negocio:
- Extrae
tenantId del JWT (vía @ConnectionContext)
- Repository consulta con filtro automático de tenant
- Repository obtiene datos filtra dos por tenant
- Component mapea Entity → DTO
- Component envía evento de auditoría a Kafka
- Service retorna DTO al Controller
- Controller serializa como JSON
- Gateway envía respuesta HTTP 200
Fecha: 20-Dic-2025
Estado: APROBADO
Contexto:
Nebula debe soportar múltiples clientes (tenants) con aislamiento de datos estricto.
Opciones Evaluadas:
- APPLICATION-LEVEL: Columna
tenantId en cada tabla
- DATABASE-LEVEL (database-per-tenant): Cada tenant = 1 schema aislado
- DATABASE-PER-TENANT: Cada tenant = 1 base de datos física
Decisión: OPCIÓN 2 - DATABASE-LEVEL (database-per-tenant)
Justificación:
- ✅ Aislamiento fuerte: Error en query NO afecta otros tenants
- ✅ Compliance: Facilita auditorías (datos claramente separados)
- ✅ Performance: Índices por schema (no toda la BD)
- ✅ Escalabilidad: Soporta hasta 500 tenants por BD física
- ❌ Contra: Más complejo que APPLICATION-LEVEL
Implementación:
TenantAwareDataSource en SimappeCommons
- Routing automático vía
TenantContext (ThreadLocal)
- Anotación
@ConnectionContext activa resolución de tenant
Consecuencias:
- Cada microservicio debe usar
@ConnectionContext
- Migraciones deben aplicarse a TODOS los schemas
- Backup/restore por schema (no por tabla)
Fecha: 22-Dic-2025
Estado: APROBADO
Contexto:
Necesitamos separación clara de responsabilidades en cada microservicio.
Decisión: Controller → Service → Component (+ Repository)
Justificación:
- Controller: Solo HTTP, NO lógica
- Service: Orquestación, NO lógica directa
- Component: TODA la lógica de negocio (extends SimappeService)
- Repository: Solo acceso a datos
Por qué NO Service con lógica:
- Services deben orquestar MÚLTIPLES Components
- Lógica en Service = acoplamiento, difícil testing
- Component con
@ConnectionContext = multi-tenancy automático
Fecha: 23-Dic-2025
Estado: APROBADO
Decisión:
- Síncrona (Feign/WebClient): Para consultas que requieren respuesta inmediata
- Asíncrona (Kafka): Para eventos, auditoría, notificaciones
Matriz de Decisión:
| Caso de Uso |
Patrón |
Razón |
| Obtener menú de usuario |
Síncrono (WebClient) |
Usuario espera respuesta |
| Registrar auditoría |
Asíncrono (Kafka) |
No afecta UX, eventual consistency OK |
| Enviar email notificación |
Asíncrono (Kafka) |
Retry automático, decoupling |
| Validar permisos |
Síncrono (Feign) |
Decisión inmediata requerida |
Fecha: 21-Dic-2025
Estado: APROBADO
Contexto:
Necesitamos soporte multi-motor SQL (PostgreSQL, Oracle, SQL Server).
Decisión: Oracle XE 21c como BD de negocio (Nebula), PostgreSQL para configuración interna (Simappe)
Justificación:
- ✅ Open Source: Sin costos de licenciamiento
- ✅ ACID completo: Transacciones robustas
- ✅ JSON support: Columnas JSONB para flexibilidad
- ✅ Performance: Índices avanzados (GIN, GIST, BRIN)
- ✅ Schemas nativos: Ideal para multi-tenancy
- ⚠️ Oracle/SQL Server: Soportados vía JPA (pero PostgreSQL preferido)
Implementación:
- Hibernate con dialecto auto-detecta BD
- Tests con TestContainers (PostgreSQL)
- Producción: Cliente elige PostgreSQL/Oracle/SQL Server
Fecha: 24-Dic-2025
Estado: APROBADO
Decisión: Apache Kafka como event bus principal
Por qué NO RabbitMQ:
- Kafka = Log-based, retención configurable (30 días)
- RabbitMQ = Queue-based, mensajes se consumen y eliminan
- Auditoría requiere retención: Kafka gana
Topics Definidos:
user-events: Cambios en usuarios
email-notifications: Emails a enviar
audit-log: Log de auditoría completo
Fecha: 27-Dic-2025
Estado: APROBADO
Decisión: Angular 21 (última versión estable)
Justificación:
- ✅ Signals: Reactividad mejorada (menos RxJS boilerplate)
- ✅ Standalone Components: NO necesita NgModules
- ✅ SSR mejorado: Performance inicial
- ✅ TypeScript nativo: Type safety end-to-end
- ✅ CLI potente: Generación de código estándar
Tecnologías Frontend:
- Angular 21
- RxJS (solo donde sea necesario)
- Reactive Forms (preferido sobre Template-driven)
- Angular Material (componentes UI)
Fecha: 23-Ene-2026
Estado: APROBADO
Contexto:
Se debe decidir la granularidad del despliegue para los módulos de Nebula (Contabilidad, Nómina, etc.).
Decisión: ARQUITECTURA DE MICROSERVICIOS.
Justificación:
- ✅ Aislamiento de fallos: Un error en el módulo de Nómina no detiene la facturación.
- ✅ Escalabilidad independiente: Permite asignar más recursos a procesos pesados (ej. cierres contables) sin sobrecostos en otros módulos.
- ✅ Alineación con Simappe: El framework base ya está orquestado como microservicios; un monolito crearía una inconsistencia arquitectónica.
Consecuencias:
- Mayor complejidad en el despliegue y monitoreo (mitigado por Jenkins/Portainer).
Fecha: 23-Ene-2026
Estado: APROBADO
Contexto:
Necesidad de manejar diferentes tipos de datos con requisitos de consistencia y volumen dispares. Complementa el ADR-004.
Decisión: USO DE POSTGRESQL (ADMINISTACIÓN), ORACLE (NEGOCIO) Y MONGODB (AUDITORÍA).
Justificación:
- ✅ PostgreSQL: Ideal para la gestión multi-tenant global por su robustez en schemas y configuración de sistema.
- ✅ Oracle: Estándar corporativo para transacciones financieras de Nebula que requieren máxima consistencia y soporte PL/SQL complejo.
- ✅ MongoDB: Almacenamiento eficiente para logs de auditoría asíncronos de alto volumen.
Consecuencias:
- Requiere mantenimiento de tres motores de BD por parte de Infraestructura Céntrica.
Fecha: 23-Ene-2026
Estado: APROBADO
Contexto:
Decisión sobre la soberanía de los datos y la facilidad de despliegue (On-premise vs Cloud).
Decisión: ENFOQUE HÍBRIDO BASADO EN IMÁGENES OCI (DOCKER).
Justificación:
- ✅ Gobernanza: Permite a Centrica mantener la soberanía de los datos en servidores propios (On-premise).
- ✅ Portabilidad: Facilita una futura migración a Cloud (AWS/Azure) sin refactorización de código.
Consecuencias:
- Exige que los nodos de infraestructura (NODE-01..03) tengan runtime de Docker/Containerd actualizado.
Fecha: 23-Ene-2026
Estado: APROBADO
Contexto:
Decidir entre integrar módulos de un ERP comercial existente o construir una solución nativa.
Decisión: DESARROLLO 100% GREENSFIELD SOBRE SIMAPPE.
Justificación:
- ✅ IP Propia: Centrica es dueña del producto final Nebula, eliminando pagos de licencias recurrentes a terceros.
- ✅ Flexibilidad: Control total sobre la hoja de ruta funcional sin depender de limitaciones de software cerrado.
Fecha: 23-Ene-2026
Estado: APROBADO
Contexto:
Definir el balance entre reactividad de interfaz y consistencia de sistemas. Complementa ADR-003.
Decisión: REST (WEBCLIENT) PARA EXPERIENCIA DE USUARIO / KAFKA PARA INTEGRACIÓN DE SISTEMAS.
Justificación:
- ✅ REST: Respuestas inmediatas y síncronas para el frontend Angular.
- ✅ Kafka: Desacoplamiento total para orquestación de procesos largos (Nómina, DIAN) y replicación de auditoría.
Targets:
| Métrica |
Objetivo |
Medición |
| Response Time (P95) |
< 500ms |
API Gateway logs |
| Throughput |
1000 req/s por microservicio |
Load testing (JMeter) |
| Database Query Time |
< 100ms (P95) |
Hibernate statistics |
| Frontend Load Time |
< 2s (First Contentful Paint) |
Lighthouse |
Estrategias:
- Caching: Redis (30 min TTL para menús)
- Connection Pooling: HikariCP (max 10 conexiones por tenant)
- Lazy Loading: Angular modules cargados on-demand
- CDN: Static assets en Nginx con cache headers
Horizontal Scaling:
- Microservicios: Stateless, escalan con Docker replicas
- Base de Datos: Read replicas para queries (PostgreSQL streaming replication)
- Kafka: Partitions por throughput
Vertical Scaling:
- DEV: 4 vCPU, 16GB RAM
- PROD: 8 vCPU, 32GB RAM (escalable a 16 vCPU, 64GB)
Límites:
- Tenants por BD física: 500 (validado en Simappe)
- Concurrent users por tenant: 100
Target: 99.5% uptime (43.8 horas downtime/año permisible)
Estrategias:
- Health Checks: Spring Actuator (
/actuator/health)
- Circuit Breakers: Resilience4j (3 fallos → OPEN, 30s HALF_OPEN)
- Retry: 3 intentos con backoff exponencial
- Monitoring: Prometheus + Grafana
Autenticación:
- OAuth2 + JWT (JJWT library)
- Tokens con TTL 3600s (1 hora)
- Refresh tokens con TTL 7 días
Autorización:
- RBAC (Role-Based Access Control)
- Permisos granulares por endpoint
Datos:
- Passwords: BCrypt (strength 12)
- Datos sensibles: Ofuscación con
@Obfuscated annotation
- Audit logs: Inmutables en MongoDB
Network:
- TLS 1.3 obligatorio
- Certificados
*.centrica.com
- VPN para acceso DevOps
¶ 7.5. Maintainability
Code Quality:
- SonarQube: Quality Gate (A rating mínimo)
- Test Coverage: >80% para Components
- Documentation: JavaDoc en clases públicas
Deployments:
- Blue-Green Deployment: Zero downtime
- Rollback automático: Si health check falla
graph TB
subgraph Internet["🌐 Internet"]
Users["Usuarios Finales"]
Devs["Desarrolladores"]
end
subgraph VLAN_Tools["VLAN Gestión (NODE-00)"]
GitLab["GitLab CE<br/>gitlab.centrica.com"]
Jenkins["Jenkins<br/>jenkins.centrica.com"]
Nexus["Nexus<br/>nexus.centrica.com"]
end
subgraph VLAN_Dev["VLAN Fábrica (NODE-01 DEV)"]
DevServices["Microservicios DEV<br/>*.dev.centrica.com"]
DevDB["PostgreSQL DEV"]
end
subgraph VLAN_QA["VLAN Fábrica (NODE-02 QA)"]
QAServices["Microservicios QA<br/>*.qa.centrica.com"]
QADB["PostgreSQL QA"]
end
subgraph VLAN_Prod["VLAN Producción (NODE-03 PROD)"]
ProdServices["Microservicios PROD<br/>*.nebula.centrica.com"]
ProdDB["PostgreSQL PROD<br/>(Multi-Tenant)"]
end
Users -->|HTTPS 443| ProdServices
Devs -->|VPN WireGuard| GitLab
Devs -->|VPN| DevServices
Jenkins -->|CI/CD Deploy| DevServices
Jenkins -->|CI/CD Deploy| QAServices
Jenkins -->|Release Deploy| ProdServices
DevServices --> DevDB
QAServices --> QADB
ProdServices --> ProdDB
style ProdServices fill:#f96,stroke:#333,stroke-width:3px
style ProdDB fill:#fcc,stroke:#333,stroke-width:3px
| Nodo |
CPU |
RAM |
Disco |
SO |
Servicios |
| NODE-00 (Tools) |
4 vCPU |
16GB |
200GB SSD |
Ubuntu 22.04 |
GitLab, Jenkins, Nexus, Nginx PM |
| NODE-01 (DEV) |
4 vCPU |
32GB |
200GB SSD |
Ubuntu 22.04 |
Todos los microservicios, PostgreSQL, MongoDB, Kafka, Redis, Eureka |
| NODE-02 (QA) |
4 vCPU |
32GB |
200GB SSD |
Ubuntu 22.04 |
Todos los microservicios, PostgreSQL, MongoDB, Kafka, Redis, Eureka |
| NODE-03 (PROD) |
8 vCPU |
48GB |
500GB SSD |
Ubuntu 22.04 |
Todos los microservicios, PostgreSQL (multi-tenant), MongoDB, Kafka, Redis, Eureka |
| Servicio |
Puerto |
Protocolo |
Acceso |
| Nginx (Frontend) |
80, 443 |
HTTP/HTTPS |
Público |
| API Gateway |
8090 |
HTTP |
Interno |
| OAuth2 Server |
8787 |
HTTP |
Interno |
| Eureka Server |
8761 |
HTTP |
Interno |
| Config Server |
8890 |
HTTP |
Interno |
| SimappeAdmin |
9010 |
HTTP |
Interno |
| SimappeClient |
9020 |
HTTP |
Interno |
| PostgreSQL |
5432 |
TCP |
Interno + VPN |
| MongoDB |
27017 |
TCP |
Interno |
| Kafka |
9092 |
TCP |
Interno |
| Redis |
6379 |
TCP |
Interno |
| GitLab |
22, 80, 443 |
SSH/HTTP |
VPN |
| Jenkins |
8081 |
HTTP |
VPN |
| Portainer |
9000 |
HTTP |
VPN |
Estrategia: Database-per-Tenant en PostgreSQL
Database: nebula_prod
├── Schema: default (metadata global)
│ ├── database_config_v2 (configuración de conexiones)
│ └── audit_log_summary (resumen auditoría)
├── Schema: acme (Tenant "ACME Corp")
│ ├── users
│ ├── menu_customization
│ ├── invoices
│ └── ...
└── Schema: beta (Tenant "Beta Inc")
├── users
├── menu_customization
├── invoices
└── ...
Routing Automático:
TenantContext.setCurrentTenant("acme"); // Desde JWT
// Todas las queries subsecuentes usan schema "acme"
repository.findAll(); // SELECT * FROM acme.users
SimappeAdmin:
User, Role, Company, Subsidiary
NotificationTemplate, EmailFeedback
SimappeClient:
MenuCustomization, ConsecutiveConfiguration
DocumentBase64, UserProfile
Nebula (Futuros):
Invoice, InvoiceLine, Tax
Payroll, PayrollItem, Employee
Product, Inventory, Movement
Herramienta: Flyway
Estrategia:
- Migración corre en schema
default primero
- Script itera por TODOS los tenant schemas
- Aplica migración a cada tenant
- Rollback automático si falla en algún tenant
Ejemplo:
-- V1__create_invoices.sql
CREATE TABLE invoices (
id BIGSERIAL PRIMARY KEY,
invoice_number VARCHAR(50) NOT NULL,
tenant_id BIGINT NOT NULL,
-- ...
);
-- Flyway crea tabla en CADA base de datos de tenant: acme_prod.invoices, beta_prod.invoices, ...
graph LR
User["Usuario"] -->|1. Login| OAuth2["OAuth2 Server"]
OAuth2 -->|2. JWT Token| User
User -->|3. Request + JWT| Gateway["API Gateway"]
Gateway -->|4. Valida Token| Gateway
Gateway -->|5. Extrae Claims| Gateway
Gateway -->|6. Inyecta Headers| Microservicio["Microservicio"]
Microservicio -->|7. Resuelve Tenant| TenantContext["TenantContext"]
TenantContext -->|8. Filtra Datos| Database["Database"]
{
"sub": "usuario@centrica.com",
"roles": ["ROLE_ADMIN", "ROLE_ACCOUNTANT"],
"tenantId": "acme_prod",
"companyId": 123,
"subsidiaryId": 456,
"iat": 1703876400,
"exp": 1703880000
}
| Rol |
Permisos |
| SUPER_ADMIN (Centrica IT) |
Gestión de tenants, configuración global |
| ADMIN (Cliente) |
Gestión usuarios del tenant, configuración tenant |
| ACCOUNTANT |
CRUD facturas, reportes financieros |
| HR_MANAGER |
CRUD nómina, reportes RRHH |
| USER |
Solo lectura |
| Componente |
Tecnología |
Versión |
| Lenguaje |
Java |
25 |
| Framework |
Spring Boot |
3.5.11 |
| Cloud |
Spring Cloud |
2025.0.0 |
| Build Tool |
Maven |
3.9+ |
| ORM |
Hibernate / JPA |
6.x |
| Mapping |
ModelMapper |
3.2.1 |
| Validation |
Jakarta Bean Validation |
3.0 |
| Security |
Spring Security + OAuth2 |
6.x |
| JWT |
JJWT |
0.12.6 |
| API Docs |
SpringDoc OpenAPI |
2.8.5 |
| Testing |
JUnit 5, Mockito, TestContainers |
- |
| Componente |
Tecnología |
Versión |
| Framework |
Angular |
21 |
| Lenguaje |
TypeScript |
5.x |
| HTTP Client |
Angular HttpClient |
- |
| Forms |
Reactive Forms |
- |
| Reactive |
RxJS |
7.x |
| UI Components |
Angular Material |
21 |
| Build |
Vite |
- |
| Testing |
Jasmine, Karma |
- |
| Componente |
Tecnología |
Versión |
| Contenedores |
Docker |
24+ |
| Orquestación |
Docker Compose |
2.x |
| Service Discovery |
Eureka |
- |
| API Gateway |
Spring Cloud Gateway |
- |
| Config Server |
Spring Cloud Config |
- |
| Message Broker |
Apache Kafka |
3.6+ |
| Cache |
Redis |
7+ |
| Databases |
PostgreSQL 16+, MongoDB 7+ |
- |
| CI/CD |
Jenkins |
2.x |
| VCS |
GitLab CE |
- |
| Artifacts |
Nexus |
3.x |
| Monitoring |
Prometheus, Grafana |
- |
| Logs |
ELK Stack |
- |
Fase 0 - PoCs (Enero 2025):
- PoC Multi-Motor SQL (5 días)
- PoC Multi-Tenancy Performance (3 días)
- PoC Integración DIAN (5 días)
- PoC Event-Driven Kafka (3 días)
- PoC Frontend Performance (2 días)
Fase 1 - Módulos Financieros Core (Febrero-Mayo 2025):
- Módulo Contabilidad (8 sprints)
- Módulo Facturación + DIAN (6 sprints)
- Módulo Impuestos (4 sprints)
- Módulo Presupuestos (3 sprints)
Fase 2 - Módulos RRHH y Activos (Junio-Septiembre 2025):
- Módulo Nómina (6 sprints)
- Módulo Talento Humano (4 sprints)
- Módulo Activos Fijos (4 sprints)
Fase 3 - Módulos Operativos (Octubre-Diciembre 2025):
- Módulo Inventarios (5 sprints)
- Módulo Reportería Avanzada (4 sprints)
Fase 4 - Integrations & Production (Enero-Marzo 2026):
- Integración Bancos (3 sprints)
- Integración Pago Seguro Online (2 sprints)
- Pilot con 3 clientes (1 mes)
- General Availability (GA) (1 mes)
NO es migración de datos (Nebula es producto nuevo)
Onboarding de Clientes:
- Creación de tenant (base de datos PostgreSQL independiente)
- Configuración inicial (usuarios, permisos)
- Carga de maestros (plan de cuentas, empleados)
- Parametrización (consecutivos, plantillas)
- Go-Live
- Simappe como base: Nebula se construye SOBRE Simappe (NO lo reemplaza)
- Multi-Tenancy DATABASE: Database-per-tenant (1 BD completa por cliente)
- Microservicios: Arquitectura modular y escalable
- Patrón 3 capas: Controller → Service → Component (lógica en Component)
- Event-Driven: Kafka para auditoría y eventos asíncronos
| Riesgo |
Probabilidad |
Impacto |
Mitigación |
| Retraso reclutamiento |
ALTA |
ALTO |
Proceso acelerado, headhunters |
| Complejidad multi-tenant |
MEDIA |
ALTO |
PoCs extensivos, validación temprana |
| Performance con 100+ tenants |
MEDIA |
MEDIO |
Load testing, tuning BD |
| Integración DIAN |
ALTA |
ALTO |
PoC específico, experto DIAN |
- ✅ Aprobar este documento (stakeholders)
- ✅ Provisionar infraestructura DEV (10-Ene)
- ✅ Completar reclutamiento equipo (31-Ene)
- ✅ Ejecutar PoCs (Fase 0)
- ✅ Desarrollar Módulo Contabilidad (Fase 1 - primer sprint)
Documento aprobado por:
Última revisión: 29-Dic-2025
Próxima revisión: 31-Ene-2026 (post Fase 0)
| Version |
Fecha |
Autor |
Descripcion |
| 1.1.0 |
2026-03-04 |
Carlos Torres |
Revision, sanitizacion y publicacion en Wiki Arquitectura Centrica. |
| 1.0.0 |
2025-12-29 |
Carlos Torres |
Creacion del documento. |