43 lines
2.1 KiB
Markdown
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.
|