Files
mercadodevida/work/artifacts/F-052/implementer.md
2026-08-19 10:47:17 +02:00

43 lines
2.1 KiB
Markdown

# Implementer — F-052 (iteración 2)
## Cambios (completos)
### Código
- `apps/admin/src/app/api/upload/route.ts`: tras `writeFile`, copia a `frontend/public/uploads/` y `storefront/public/uploads/` con `Promise.allSettled`. La copia no bloquea el upload principal.
- `project/scripts/monolith.sh`: nueva función `sync_uploads()` que se invoca al final de `build_prod()` y antes de `spawn_service` en `start_all()` para cubrir el caso "arranque en frío sin uploads aún".
- **`frontend/src/app/uploads/[filename]/route.ts`** y **`storefront/src/app/uploads/[filename]/route.ts`**: handlers dinámicos (idénticos al del admin) que leen cada petición de `public/uploads/<filename>` directamente del disco. Imprescindible: Next.js sirve los estáticos de `public/` cacheados al build time, por lo que cualquier archivo subido después devolvería 404 sin esta ruta.
### Assets
- `frontend/public/uploads/` y `storefront/public/uploads/` creados.
- Archivos sincronizados manualmente para evitar esperar al próximo restart.
### Servicios
- `next build` re-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.