Saltar al contenido principal
Version: Siguiente

Arquitectura del Sistema

Este documento proporciona una visión arquitectónica de alto nivel del sistema de Lana Bank, describiendo la arquitectura de tres capas (cliente, gateway de API, backend), los componentes principales en cada capa y cómo interactúan.

Visión General de las Capas del Sistema

Lana Bank sigue una arquitectura en capas que separa responsabilidades entre presentación del cliente, seguridad del gateway de API, orquestación de la aplicación, lógica de dominio, servicios de infraestructura y persistencia de datos.

┌─────────────────────────────────────────────────────────────────┐
│ Capa de Cliente │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ admin-panel │ │ customer-portal │ │
│ │ (Next.js) │ │ (Next.js) │ │
│ │ Puerto 3001 │ │ Puerto 3002 │ │
│ └─────────────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│ Capa de Gateway de API │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Oathkeeper │ │ Keycloak │ │
│ │ Puerto 4455 │ │ Puerto 8081 │ │
│ └─────────────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│ Capa de Aplicación (Rust) │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ admin-server │ │ customer-server │ │
│ │ Puerto 5253 │ │ Puerto 5254 │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ ┌─────────────────────┐ │
│ │ lana-app │ │
│ │ (Orquestador) │ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────────┐
│ Capa de Datos │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ PostgreSQL │ │ cala-ledger │ │
│ │ (Base de datos) │ │ (Libro mayor) │ │
│ └─────────────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘

Capa de Cliente

La capa de cliente consiste en dos aplicaciones web separadas que atienden a diferentes perfiles de usuario:

AplicaciónTecnologíaPuertoPropósito
admin-panelNext.js 15 + Apollo Client3001Interfaz administrativa para operaciones bancarias
customer-portalNext.js 15 + NextAuth3002Interfaz orientada al cliente para gestión de cuentas

Ambas aplicaciones se comunican con el backend a través del gateway de API Oathkeeper, que maneja la validación de tokens de autenticación antes de enrutar las solicitudes al servidor GraphQL correspondiente.

Capa de Gateway de API

La capa de gateway de API proporciona autenticación centralizada y enrutamiento.

Oathkeeper (Puerto 4455)

Oathkeeper actúa como un proxy inverso que:

  • Valida tokens JWT en las solicitudes entrantes
  • Delega la autenticación a Keycloak vía endpoint JWKS
  • Enruta solicitudes autenticadas a admin-server o customer-server
  • Aplica políticas CORS

Keycloak (Puerto 8081)

Keycloak funciona como proveedor de identidad:

  • Emite tokens JWT tras autenticación exitosa
  • Gestiona cuentas de usuario y credenciales
  • Expone un endpoint JWKS para distribución de claves públicas
  • Soporta tanto ámbitos internos (admin) como de clientes

Capa de Aplicación

La capa de aplicación está implementada en Rust y consiste en el orquestador y los servidores GraphQL.

lana-cli

El binario lana-cli sirve como punto de entrada principal y orquestador:

  • Inicializa el pool de conexiones a la base de datos
  • Crea la instancia LanaApp que agrega todos los servicios de dominio
  • Lanza admin-server y customer-server en tareas separadas de tokio
  • Maneja apagado elegante ante señales SIGTERM/SIGINT
  • Gestiona recursos compartidos (pool de base de datos, estado de la aplicación)

admin-server

Servidor de API GraphQL para operaciones administrativas:

  • Expone consultas y mutaciones administrativas
  • Valida tokens JWT mediante RemoteJwksDecoder
  • Extrae el ID de usuario administrador de las claims del JWT
  • Crea AdminAuthContext para verificaciones de autorización
  • Sirve GraphQL Playground en /admin/graphql
  • Maneja endpoints de webhook para integraciones externas

customer-server

Servidor de API GraphQL para operaciones de clientes:

  • Expone consultas para clientes
  • Valida tokens JWT mediante RemoteJwksDecoder
  • Extrae el ID de usuario cliente de las claims del JWT
  • Crea CustomerAuthContext para verificaciones de autorización
  • Sirve GraphQL Playground en /customer/graphql

lana-app

El crate lana-app sirve como la fachada de la lógica de negocio central:

  • Agrega todos los servicios de dominio (core-credit, core-deposit, core-customer, etc.)
  • Inicializa infraestructura compartida (pool de base de datos, sistema de jobs, outbox)
  • Proporciona una interfaz unificada para los resolvers de GraphQL
  • Gestiona ciclos de vida y dependencias de servicios

Capa de Dominio

Los servicios de dominio implementan la lógica de negocio siguiendo principios de Domain-Driven Design (DDD):

MóduloCratePropósito
Moneycore-moneyTipos de moneda, importes monetarios y conversión
Customercore-customerEntidades de clientes, perfiles y relaciones
Creditcore-creditFacilidades de crédito, desembolsos, obligaciones
Depositcore-depositCuentas de depósito, depósitos y retiros
Accountingcore-accountingPlan de cuentas, balance de comprobación
Custodycore-custodyBilleteras e integración con custodios externos
Applicantcore-applicantFlujos KYC/AML e integración con Sumsub
Accesscore-accessUsuarios, roles y control de acceso

Capa de Infraestructura

Los servicios de infraestructura proporcionan capacidades transversales:

ServicioCratePropósito
AuditoríaauditRegistro inmutable de acciones para cumplimiento
AutorizaciónauthzControl de acceso basado en roles (RBAC) con Casbin
OutboxoutboxEntrega confiable de eventos mediante patrón outbox
JobsjobProcesamiento de tareas en segundo plano
Trazabilidadtracing-utilsTrazado distribuido con OpenTelemetry

Capa de Datos

PostgreSQL

Base de datos relacional principal que almacena:

  • Eventos de entidades (event sourcing)
  • Estado proyectado de entidades
  • Configuración del sistema
  • Datos de auditoría

cala-ledger

Libro mayor de contabilidad de partida doble:

  • Cuentas y conjuntos de cuentas
  • Transacciones y asientos
  • Historial de saldos
  • Plantillas de transacciones

BigQuery (Analítica)

Almacén de datos para análisis:

  • Datos extraídos mediante Meltano
  • Modelos transformados con dbt
  • Reportes e inteligencia de negocio

Modelo de Despliegue

El sistema puede desplegarse como:

  • Desarrollo local: Docker Compose con Tilt para orquestación
  • Producción: Kubernetes con Helm charts

Stack Tecnológico

CapaTecnología
FrontendNext.js 15, React, Apollo Client
APIGraphQL (async-graphql)
BackendRust, Tokio (async runtime)
Base de datosPostgreSQL
Libro mayorCala Ledger
AutenticaciónKeycloak, OAuth 2.0/OIDC
GatewayOathkeeper
ObservabilidadOpenTelemetry
BuildNix, Cargo
OrquestaciónKubernetes, Helm

Decisiones arquitectónicas clave

Event sourcing

Todos los cambios de estado se capturan como eventos:

  • Registro de auditoría completo
  • Consultas temporales
  • Capacidad de reproducción de eventos

Arquitectura hexagonal

Separación clara de responsabilidades:

  • Lógica de dominio aislada de la infraestructura
  • Patrón adaptador para servicios externos
  • Lógica de negocio testeable

Patrón CQRS

Segregación de responsabilidad de comandos y consultas:

  • Rutas de lectura optimizadas
  • Operaciones de escritura separadas
  • Consistencia eventual cuando sea apropiado

Segregación de responsabilidad de comandos y consultas:

  • Rutas de lectura optimizadas
  • Operaciones de escritura separadas
  • Consistencia eventual cuando sea apropiado

Segregación de responsabilidad de comandos y consultas:

  • Rutas de lectura optimizadas
  • Operaciones de escritura separadas
  • Consistencia eventual cuando sea apropiado

Segregación de responsabilidad de comandos y consultas:

  • Rutas de lectura optimizadas
  • Operaciones de escritura separadas
  • Consistencia eventual cuando sea apropiado

Segregación de responsabilidad de comandos y consultas:

  • Rutas de lectura optimizadas
  • Operaciones de escritura separadas
  • Consistencia eventual cuando sea apropiado

Segregación de responsabilidad de comandos y consultas:

  • Rutas de lectura optimizadas
  • Operaciones de escritura separadas
  • Consistencia eventual cuando sea apropiado

Segregación de responsabilidad de comandos y consultas:

  • Rutas de lectura optimizadas
  • Operaciones de escritura separadas
  • Consistencia eventual cuando sea apropiado

Segregación de responsabilidad de comandos y consultas:

  • Rutas de lectura optimizadas
  • Operaciones de escritura separadas
  • Consistencia eventual cuando sea apropiado