Arquitectura
Stack tecnológico
| Capa | Tecnología | Rol |
|---|---|---|
| Frontend | Refine + shadcn/ui + React Flow | UI de gestión y administración |
| Backend | NestJS + TypeScript | API REST, lógica de negocio |
| Base relacional | PostgreSQL | Datos estructurados (cuentas, config, permisos) |
| Base documental | MongoDB | Datos dinámicos (expedientes, documentos, tareas) |
| Storage | MinIO | Archivos binarios (content-addressed por SHA-256) |
| Auth / IDP | Keycloak | Autenticación multi-tenant, LDAP/AD/SAML |
| Motor de flujos | WorkflowEngineService | Ejecución nativa de workflows |
| Colas | BullMQ + Redis | Jobs asíncronos, reintentos, DLQ |
| Búsqueda | Typesense | Full-text search typo-tolerant |
| Observabilidad | OTel + SigNoz + Grafana | Trazas, métricas, logs |
Diagrama de arquitectura
Principios de diseño
Separación de responsabilidades por base de datos
PostgreSQL → datos tabulares con JOINs (cuentas, usuarios, config, permisos, auditoría)
MongoDB → datos con schema variable (expedientes, documentos, tareas)
MinIO → archivos binarios, identificados por SHA-256
Redis → sesiones, parámetros en caché, colas BullMQ
Typesense → índice de búsqueda full-text (replica datos de PG + Mongo)
Multitenancy
Cada tenant tiene su propio realm en Keycloak. El tenantId viaja en el JWT
y se aplica en absolutamente todos los queries a PostgreSQL y MongoDB.
No hay excepciones.
Content-addressed storage
Los documentos se identifican por el SHA-256 de su contenido. Si el mismo archivo se sube dos veces, Kuatia lo detecta y no duplica el almacenamiento — solo crea una nueva referencia.