ADR 0008 — Caché, archivos, colas, rutas HTTP e integraciones con ORMs
- Estado: aceptada
- Fecha: 2026-09-25
Decisiones
- Mismo patrón para cada recurso. Un puerto crudo que no conoce tenants (
CacheStore,StorageDriver,QueueDriver) y un envoltorio que aísla por tenant (TenantCache→tenant:{id}:,TenantStorage→{id}/, trabajos contenantId). Los drivers de memoria vienen en el núcleo; Redis/Valkey, S3 y BullMQ son paquetes aparte. Cada driver pasa la misma suite de contrato (@tenancy-node/testing). - Rutas de archivo seguras.
normalizeStoragePathrechaza.., rutas absolutas,\y bytes nulos, y el driver local verifica además que la ruta final quede dentro de su raíz. - Colas.
tenancy.jobs.define/dispatchytenancy.worker(). Cada trabajo corre en el contexto de su tenant. Los intentos con reintentos pendientes quedan comowarny el último intento fallido comoerror(operation: queue.job). El modoqueuede los eventos es un trabajo internoevent:<nombre>: la petición espera solo a que quede encolado. - Rutas HTTP opcionales independientes del framework.
TenancyHttpRoutesdevuelve{ status, headers, body }y los adaptadores solo la conectan. Todas apagadas por defecto;/tenancy/healthresponde en cualquier host (balanceadores); las rutas de tenant nunca responden en el contexto central;/tenancy/mesolo muestrapublicFields. - ORMs.
tenancy.knex()ytenancy.prisma(): una instancia por conexión de tenant en un LRU (TenantInstances); al descartarla se cierra después de un tiempo de gracia para no cortar consultas en curso.tenancy.drizzle()reutiliza el pool nativo del tenant (no abre conexiones). La app pasa sus propias funciones (drizzle,migrate,PrismaClient), así los tipos del ORM quedan del lado de la app y el paquete no fija versiones. - Migradores externos. El puerto
TenancyMigratorrecibe unMigrationContext(conexión, URL y pool nativo del tenant) para Knex, Drizzle y Prisma (prisma migrate deploycon laDATABASE_URLdel tenant). - Errores de pools. Los pools de
pg/mysql2tienen manejador de'error'(sin él, un reinicio de la base tumba el proceso); el error queda comodb.pool.error. tenancy schemagenera modelos Prisma, Drizzle o TypeORM leyendoinformation_schemade la base real (en MariaDB, JSON se reconoce porCHECK (json_valid(...))).
Pendiente
- Colas separadas por tenant (hoy: una cola compartida con
tenantIden cada trabajo). - Probar
orm-prismacontra un Prisma generado real (hoy: cliente de reemplazo y migrador con un proceso real). - La imagen
minio/minioya no se publica: los tests de S3 usan SeaweedFS.