Subidas a almacenamiento privado
Configura subidas privadas S3 con políticas, entitlement, cuota, checksum y borrado duradero.
Sincronizado con el commit
2a1a04adel starter.
Usa esta función cuando tu producto necesite guardar avatares, documentos, importaciones o archivos generados sin hacerlos públicos ni enviar cada byte a través del servidor de Next.js. Al terminar, una persona autenticada debería poder subir, descargar y eliminar un archivo desde Cuenta → Archivos, sin que otra organización pueda acceder a él.
Elige la política de almacenamiento adecuada
- Docker Compose usa Garage como opción local open source mantenida y crea el bucket privado. Cloudflare R2 y AWS S3 son opciones habituales de producción.
miniosigue soportado para quien lo opera, pero ya no es el valor local incluido. Todos comparten adaptador. - Usa
generalpara archivos mixtos,imagespara imágenes con un límite de política de 10 MB,documentspara archivos ofimáticos y de texto, overifiedcuando el navegador deba aportar un SHA-256. - El límite efectivo es el menor entre el plan,
STORAGE_MAX_UPLOAD_MBy la política. Mantén el bucket privado; el modelo incluido entrega URLs firmadas de corta duración.
Está listo para producción cuando: el flujo de la UI funciona completo, CORS solo admite tus orígenes, una URL pública directa falla, se rechaza el acceso entre organizaciones y cron termina eliminando el objeto de un archivo borrado.
Define STORAGE_PROVIDER como garage, s3, r2 o minio y configura bucket, región, endpoint y credenciales. Los objetos son privados y el navegador solo recibe URLs firmadas breves. El ejemplo de imagen usa el mismo ciclo de archivos privados.
Contrato
POST /api/storage/uploadsvalida organización,storage.upload, política (general,images,documents,verified), tipo y el menor límite entre plan, entorno y política; reserva cuota atómicamente.- El navegador hace PUT directo; XHR solo expone progreso.
POST /api/storage/uploads/completeverifica metadatos y SHA-256 opcional y activa la fila.GET /api/storage/files/[uuid]?download=1entrega URL de descarga limitada a la organización.DELETE /api/storage/files/[uuid]hace soft-delete y programastorage_object_deleteduradero.
Las subidas abandonadas liberan reserva tras una hora. El borrado reintenta por la cola, así que cron debe funcionar. El servicio genera las keys; el cliente no elige keys del bucket.
Prueba flujo completo, MIME/checksum incorrecto, carreras de cuota, URL caducada, acceso cruzado, reintento y limpieza. Consulta docs/storage-providers.md del starter para CORS.
Siguiente paso: haz fiables el borrado y la limpieza con Trabajos duraderos y readiness.