Flujo: Descarga de Imágenes
¿Quién lo usa?
| Rol | Permiso requerido |
|---|---|
BRAND_ADMIN | DOWNLOADER |
COMPANY_ADMIN | DOWNLOADER |
ADMIN (equipo Rial) | Sin restricción |
¿Por qué importa?
Las imágenes viven en Google Cloud Storage (GCS) y no son públicamente accesibles. Para descargarlas, el sistema necesita generar signed URLs temporales para cada archivo. Como esto puede involucrar cientos o miles de imágenes, el proceso se delega a un worker asíncrono (images-download) a través de Cloud Tasks. El frontend hace polling hasta recibir los resultados.
Entrada en la plataforma
URL: /library (tab “Aprobadas”) o desde la vista de cualquier proyecto
El cliente puede descargar:
- Un reporte Excel (con metadatos de todas las imágenes) — botón “Descargar reporte”
- Las imágenes en ZIP — botón “Descargar” con selección individual o masiva
Pasos del flujo
Paso 1 — Iniciar descarga
El cliente selecciona las imágenes o el caso completo y hace clic en “Descargar”. El backend crea un Job de tipo IMAGE_DOWNLOAD y encola una tarea en Cloud Tasks.
Endpoint:
POST /downloads/project-images
Query params: filtros (projectFolderId, projectId, statuses, etc.)
Response: { jobId: "uuid-del-job" }El jobId se persiste en localStorage para que si el usuario recarga la página pueda retomar el estado de la descarga en curso.
Paso 2 — Polling del job
Mientras Cloud Tasks procesa la tarea, el frontend hace polling cada pocos segundos para actualizar la barra de progreso.
Endpoint:
GET /jobs/{jobId}
Response: {
status: "RUNNING",
progress: 45,
totalBatches: 10,
currentBatch: 4
}Paso 3 — Worker genera signed URLs
El worker images-download (Cloud Function) recibe la tarea, consulta GCS por lotes y va actualizando el Job con las URLs firmadas a medida que avanza.
Paso 4 — Descarga de archivos
Cuando el job llega a COMPLETED, el frontend recibe el array de signedUrls y comienza a descargar los archivos directamente desde GCS.
Endpoint final:
POST /downloads/project-images/complete
Body: { jobId }
— Marca el job y los SKUs como DOWNLOADED
— Si todos los SKUs de un proyecto están descargados:
ProjectFolder.clientStatus → COMPLETEDSecuencia técnica completa
Persistencia con localStorage
El hook useDownloadImages guarda el jobId activo en localStorage:
// Al iniciar
localStorage.setItem(`download-job-${projectFolderId}`, jobId);
// Al recargar la página
const savedJobId = localStorage.getItem(`download-job-${projectFolderId}`);
if (savedJobId) {
// Retoma el polling sin necesidad de volver a iniciar la descarga
startPolling(savedJobId);
}Estado resultante
Job.status COMPLETED
ProjectImage.clientStatus PENDING_DOWNLOAD → DOWNLOADED
ProjectFolder.clientStatus PENDING_DOWNLOAD → COMPLETED (si todos descargados)Notas importantes
- Las signed URLs tienen una expiración de 1 hora. Si el usuario tarda más en descargar, necesitará iniciar una nueva descarga.
- El
Jobqueda persistido en la BD. Si se cancela el proceso a mitad, el frontend puede retomarlo con eljobIdguardado enlocalStorage. - Para grandes volúmenes (>500 imágenes), el worker procesa en lotes para evitar timeouts en Cloud Functions.