Skip to main content

Módulo File

src/app/modules/file/

Gestiona la subida y almacenamiento de archivos adjuntos (imágenes, audio, video y documentos) en un almacenamiento privado compatible con S3/MinIO. Los mensajes referencian estos archivos por su _id.

Modelo — File​

Colección files, con timestamps.

CampoTipoDescripción
_idObjectIdID de MongoDB
tenantIdObjectId → TenantTenant propietario
filenamestringNombre del archivo (la extensión puede cambiar tras la conversión)
urlstringURL guardada al subir; no es accesible directamente (ver Gotchas)
storageKeystringClave del objeto en el almacenamiento: tenantId/año/mes/carpeta/uuid.ext
mimetypestringTipo MIME final
sizenumberTamaño en bytes del contenido guardado
typeenumimage, audio, video o document
durationSecondsnumberSolo audio
waveformnumber[]Solo audio: 64 niveles de 0 a 100
thumbnailstringSolo video: primer fotograma en JPEG base64
createdAt / updatedAtDateTimestamps

Endpoints​

Base: /api/v1/files. Controlador con @Auth() y PermissionsGuard; todo se limita al tenant del usuario.

MétodoRutaPermisoDescripción
POST/files/uploadFILE_CREATESube un archivo (multipart/form-data, campo file)
GET/files/get-allFILE_READLista los archivos del tenant (data.results), con URL firmada
GET/files/get-one/:idFILE_READMetadatos de un archivo, con URL firmada
DELETE/files/remove/:idFILE_DELETEElimina el objeto del almacenamiento y el registro

DTOs y parámetros​

El módulo no define DTOs de class-validator; la validación ocurre en FileService.

ParámetroUbicaciónTipoObligatorioValidaciónUsado en
filebody multipartarchivoSíCampo file; tipo MIME permitido y tamaño máximo por tipo; en audio, duración de 1 s a 2 min. Si no se cumple, 400POST /files/upload
idrutastringSíNinguna en el controlador; se busca por _id y tenant, y si no existe responde 404get-one/:id, remove/:id

Tipos permitidos y límites​

TipoMIME permitidosTamaño máximo
imageimage/jpeg, image/png, image/gif, image/webp5 MB
audioaudio/webm, audio/ogg, audio/mp4, audio/mpeg, audio/wav, audio/x-m4a15 MB
videovideo/mp4, video/webm, video/quicktime, video/x-msvideo, video/x-matroska, video/mpeg, video/3gpp, video/x-flv20 MB
documentPDF, Word (doc, docx) y Excel (xls, xlsx)10 MB

El parámetro del MIME se normaliza (se descarta lo que sigue a ;).

Flujo de subida​

Las imágenes se reprocesan, los videos se procesan y generan una miniatura, y los audios se convierten y generan duración y forma de onda. La duración de un audio se valida antes de convertirlo.

Gotchas​

  • El bucket es privado: la url guardada nunca es accesible. Cada lectura (upload, get-all, get-one) la sustituye por una URL firmada de corta duración generada desde storageKey.
  • Los archivos que entran por canales externos (WhatsApp, Meta) se guardan con storeIncoming, que no valida el tipo MIME ni reprocesa el contenido.
  • El endpoint público del widget sube archivos con el token de la conexión y reutiliza FileService.upload (ver Widget).
  • Quien sube el archivo no se registra: el modelo no tiene uploadedBy.