Skip to content

ADR-007: Storage como Adapter en Provider Gateway

Estado: Aceptada
Fecha: 2026-05-18
Autor: Equipo de Arquitectura

Contexto

Multiples servicios de la plataforma necesitan almacenamiento de archivos:

  • ImagFlow: imagenes biometricas capturadas durante validacion de identidad
  • ImagSign: documentos PDF generados y firmados
  • ImagLend: comprobantes de desembolso, recibos, documentos del solicitante
  • ImagGuard: logs de auditoria exportados, reportes de compliance

Las opciones evaluadas son:

  1. Un servicio centralizado de storage (imagy-storage)
  2. Cada servicio gestiona su propio bucket S3 directamente
  3. Storage como un adapter dentro del patron Provider Gateway existente

Adicionalmente, algunos tenants tienen requisitos regulatorios que exigen que los datos residan en proveedores especificos (ej: un banco en Mexico podria requerir almacenamiento en una region especifica de AWS, mientras que un tenant europeo podria necesitar Azure por compliance con su infraestructura existente).

Decision

El almacenamiento de archivos se implementa como un adapter dentro del Provider Gateway. El Provider Gateway ya es el punto de integracion con servicios externos; storage es un proveedor mas.

Proveedores Soportados

ProveedorUso
AWS S3Default para produccion
Azure Blob StorageTenants con requisitos Azure
Google Cloud StorageTenants con requisitos GCP
MinIODesarrollo local y testing

Interfaz del Adapter

typescript
interface StorageAdapter {
  upload(params: UploadParams): Promise<StorageResult>;
  download(key: string): Promise<ReadableStream>;
  getSignedUrl(key: string, expiresIn: number): Promise<string>;
  delete(key: string): Promise<void>;
  list(prefix: string): Promise<StorageObject[]>;
}

interface UploadParams {
  key: string;
  body: Buffer | ReadableStream;
  contentType: string;
  metadata?: Record<string, string>;
  encryption?: EncryptionConfig;
}

interface StorageResult {
  key: string;
  bucket: string;
  url: string;
  size: number;
  checksum: string;
}

Configuracion por Tenant

json
{
  "tenant_id": "banco-xyz",
  "storage": {
    "provider": "s3",
    "config": {
      "bucket": "banco-xyz-documents",
      "region": "us-east-1",
      "encryption": "aws:kms",
      "kms_key_id": "arn:aws:kms:us-east-1:123456:key/abc-123"
    },
    "lifecycle": {
      "documents": { "retention_days": 3650 },
      "biometrics": { "retention_days": 90 },
      "temp": { "retention_days": 1 }
    }
  }
}

Flujo de Invocacion

Organizacion de Keys

{tenant_id}/{domain}/{entity_id}/{filename}

Ejemplos:
banco-xyz/lending/credit-123/comprobante-desembolso.pdf
banco-xyz/sign/contract-456/contrato-firmado.pdf
banco-xyz/flow/validation-789/selfie.jpg

Alternativas Consideradas

AlternativaProsContras
Servicio dedicado imagy-storageSeparacion clara, equipo dedicadoOtro servicio que mantener, latencia adicional, single point of failure
Cada servicio habla con S3 directamenteSimple, sin dependenciasDuplicacion de logica, no soporta multi-provider, cada servicio gestiona credenciales
Storage como adapter en Provider Gateway (elegida)Interfaz consistente, multi-provider, configuracion por tenantProvider Gateway se vuelve dependencia para operaciones de archivos

Consecuencias

Positivas

  • Interfaz unica para todos los servicios: no importa si el tenant usa S3, Azure o GCS
  • Configuracion por tenant permite cumplir requisitos regulatorios de residencia de datos
  • No se agrega un servicio adicional a la infraestructura
  • Encryption y lifecycle policies centralizados y consistentes
  • MinIO para desarrollo local elimina dependencia de cloud en dev

Negativas

  • Provider Gateway se convierte en dependencia critica para operaciones de archivos
  • Si Provider Gateway tiene un outage, ningun servicio puede leer/escribir archivos
  • Mayor complejidad en Provider Gateway (mas adapters que mantener)

Riesgos

  • Cuello de botella de performance si muchos servicios suben archivos grandes simultaneamente (mitigacion: signed URLs para uploads directos)
  • Vendor lock-in en la interfaz del adapter si no se abstrae correctamente
  • Provider Gateway como single point of failure (mitigacion: alta disponibilidad, circuit breaker)

Referencias

Reimagine Tech LLC — Documentacion Interna