2.1 KiB
2.1 KiB
Implementer — F-052 (iteración 2)
Cambios (completos)
Código
apps/admin/src/app/api/upload/route.ts: traswriteFile, copia afrontend/public/uploads/ystorefront/public/uploads/conPromise.allSettled. La copia no bloquea el upload principal.project/scripts/monolith.sh: nueva funciónsync_uploads()que se invoca al final debuild_prod()y antes despawn_serviceenstart_all()para cubrir el caso "arranque en frío sin uploads aún".frontend/src/app/uploads/[filename]/route.tsystorefront/src/app/uploads/[filename]/route.ts: handlers dinámicos (idénticos al del admin) que leen cada petición depublic/uploads/<filename>directamente del disco. Imprescindible: Next.js sirve los estáticos depublic/cacheados al build time, por lo que cualquier archivo subido después devolvería 404 sin esta ruta.
Assets
frontend/public/uploads/ystorefront/public/uploads/creados.- Archivos sincronizados manualmente para evitar esperar al próximo restart.
Servicios
next buildre-ejecutado para admin, frontend y storefront.- Servicios reiniciados.
Verificación end-to-end
Imágenes existentes (en build)
GET 3004 /uploads/fa7a31db-...jpg → 200 image/jpeg 129711
GET 3003 /uploads/fa7a31db-...jpg → 200 image/jpeg 129711
GET 3005 /uploads/fa7a31db-...jpg → 200 image/jpeg 129711
Imagen subida en caliente (sin rebuild)
POST 3004 /api/upload (admin) → 201 {url: /uploads/a7e3aa30-...jpg}
GET 3004 /uploads/a7e3aa30-...jpg → 200 image/jpeg
GET 3003 /uploads/a7e3aa30-...jpg → 200 image/jpeg
GET 3005 /uploads/a7e3aa30-...jpg → 200 image/jpeg
Favicons siguen 200
GET 3004 /favicon.ico → 200
GET 3005 /favicon.ico → 200
Por qué fue necesaria la 2ª iteración
El mirrorToPeers del admin copia el archivo al disco de frontend/storefront, pero los servicios en producción cachean el listado de public/ al build. Sin una ruta dinámica /uploads/[filename]/, los archivos nuevos solo se sirven si existían al hacer next build. La ruta dinámica los lee frescos del disco en cada request, igual que hace el admin desde F-050.