Modelo de Datos
Distribución por base de datos
- PostgreSQL — 40 tablas con datos estructurados, JOINs frecuentes, ACL, embeddings RAG (
pgvector). - MongoDB — 6 collections con schemas dinámicos (expedientes, documentos, comentarios, walks de doc-flow Layer 2, tareas, timeline de tareas).
- MinIO — archivos binarios identificados por SHA-256 (content-addressed).
- Typesense — replica indexada para búsqueda full-text typo-tolerant.
- Redis — sesiones, parámetros en caché (TTL 3600s), colas BullMQ.
Tablas PostgreSQL (40)
Identidad y multitenancy
| Tabla | Descripción |
|---|---|
tenants | Multi-tenancy: 1 fila por organismo, 1 realm Keycloak asociado |
users | Perfiles locales — caché de usuarios validados en Keycloak |
service_clients | Clientes M2M (machine-to-machine) con credenciales OAuth client-credentials |
Permisos (RBAC)
| Tabla | Descripción |
|---|---|
modules | Catálogo de módulos del sistema (dossier, flow, share, etc.) |
permissions | 132 permisos granulares organizados por módulo |
roles | Roles por tenant (tenant_admin, manager, etc.) |
role_permissions | Assignment role→permission |
user_roles | Caché de roles del user (fuente: claim realm_access.roles del JWT) |
Cuentas y expedientes (lado relacional)
| Tabla | Descripción |
|---|---|
account_types | Esquemas + metadata por tipo de cuenta |
accounts | Cuentas titulares/firmantes/deudores |
account_links | Vínculos entre cuentas (ej. titular ↔ firmante) |
dossier_types | Templates de expediente con metadata schemas y campos por estado |
document_types | Tipos de documento con MIME asociados y metadata schemas |
dossier_accounts | Vinculación expediente ↔ cuentas |
dossier_audits | Auditoría de cambios sobre expedientes |
dossier_documents | Vinculación expediente ↔ documentos (con tipo y estado) |
document_audits | Auditoría de cambios sobre documentos |
Configuración del sistema
| Tabla | Descripción |
|---|---|
parameter_definitions | Definición de parámetros globales y por tenant |
parameter_values | Valores efectivos (con caché Redis 3600s) |
Integraciones
| Tabla | Descripción |
|---|---|
external_systems | Sistemas externos (URL base + credencial) |
credentials | Credenciales cifradas AES-256-GCM. direction=OUTBOUND (Kuatia llama afuera) o INBOUND (afuera llama a Kuatia, ej. para Shares) |
endpoints | Operaciones REST/SOAP configurables (métodos, paths, schemas, retries) |
endpoint_executions | Log de ejecuciones de endpoints (request/response truncados) |
ui_endpoints | Integraciones de UI embebida (iframe/popup/redirect/internal) con SSO |
Flujos
| Tabla | Descripción |
|---|---|
flow_versions | Versionado de definiciones de flujo por DossierType y por DocumentType (doc-flows Layer 2) |
flow_waits | Pausas de flujo por webhook/tiempo, con token único — barridas por la cola flow-timeout |
Tareas y bulk
| Tabla | Descripción |
|---|---|
task_reminders | Recordatorios + escalation, cola task-lifecycle |
bulk_import_jobs | Tracking de imports CSV/XLSX, cola bulk-operations |
data_export_jobs | Tracking de exports tenant-wide, cola bulk-operations |
MIME y procesamiento
| Tabla | Descripción |
|---|---|
mime_handlers | Extractores + visores custom por tenant (WEBHOOK / ENDPOINT / REACT_COMPONENT / IFRAME_URL) |
Shares (acceso filesystem-like)
| Tabla | Descripción |
|---|---|
shares | Configuración de share con toggles por protocolo (WebDAV/SFTP/FTPS/SMB/S3), scope (TENANT/ACCOUNT/DOSSIER), mapeo MIME→DocumentType |
Reportes
| Tabla | Descripción |
|---|---|
scheduled_reports | Reportes cron-driven con distribución por email, cola scheduled-reports |
ACL fino
| Tabla | Descripción |
|---|---|
access_rules | Reglas finas a nivel Account/Dossier/Document |
access_rule_audits | Audit chain de cambios sobre access_rules |
acl_denial_log | Registro de denegaciones para análisis y troubleshooting |
Asistente AI + RAG
| Tabla | Descripción |
|---|---|
ai_conversations | Historial del Asistente AI por user/tenant |
document_chunks | Chunks vectorizados con columna embedding (pgvector) para búsqueda semántica RAG |
Bandeja, indexación y procesadores
| Tabla | Descripción |
|---|---|
inbox_saved_views | Vistas guardadas per-user en la bandeja (filtros + nombre + orden) |
indexation_tasks | Cola de re-indexación tiered por MIME para el MimeIndexerService |
specialized_processors | Catálogo de procesadores invocables desde el nodo extract_with_processor (con outputSchema Ajv) |
Collections MongoDB (6)
| Collection | Schema | Notas |
|---|---|---|
dossiers | Dossier | Jerárquicos (parentId + path[]), schema variable por dossierTypeId, contiene instanceData del flow |
documents | Document | _id = SHA-256 del contenido (deduplicación nativa). Versiones via versionHistory[] |
document_comments | DocumentComment | Comentarios anclados a documentos |
document_flow_walks | DocumentWalk | Estado del walk del doc-flow Layer 2 (currentNodeId + context + tasks[] + history[]) |
tasks | Task | Tareas humanas + sistema, schema variable por taskType, incluye uiEndpointId para tareas con UI embebida |
task_activities | TaskActivity | Timeline append-only de la tarea (create/claim/attach/comment/complete/…) |
Reglas de distribución
| Si... | Va a... |
|---|---|
| El schema varía por tipo o tenant | MongoDB |
| Estructura fija con JOINs frecuentes | PostgreSQL |
| Archivo binario | MinIO |
| Requiere búsqueda full-text | Typesense (réplica) |
| Requiere búsqueda semántica | pgvector (vía RAG) |
| Estado efímero / caché | Redis |
Document — Content-addressed storage
El campo _id de Document en MongoDB es el hash SHA-256 del contenido del archivo, no un UUID generado. Esto permite deduplicación automática:
El métrico kuatia_document_dedup_hits_total mide cuántas subidas evitaron almacenamiento por dedup.
Dossier — Jerarquía
Los dossiers son jerárquicos: cada uno puede tener un parentId apuntando a otro dossier. El campo path[] contiene todos los ancestros para queries eficientes de árbol completo. Contenedores (sub-dossiers) son la base de doc-flows Layer 2.
Cuenta Corriente #123
├── Depósito Enero 2026
│ ├── comprobante.pdf
│ └── recibo.pdf
└── Depósito Febrero 2026
└── comprobante.pdf
Indexación
Toda consulta se diseña para escalar a millones de filas por tenant. Reglas:
- Todo índice empieza con
tenantId. - Si además se filtra por otro campo (
accountId,state, etc.), el índice es compuesto(tenantId, campo). - Sin excepciones: si una query nueva no tiene índice apropiado, no se mergea.
Cifrado de credenciales
credentials.config se cifra con AES-256-GCM usando una key de env (sin fallback). Los GET nunca devuelven el ciphertext ni el plaintext — solo hasSecret: boolean. La key vive en CRYPTO_KEY y el sistema NO arranca si falta.