feat(F-113): completed feature
This commit is contained in:
40
work/artifacts/F-113/architect.md
Normal file
40
work/artifacts/F-113/architect.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# F-113 — Arquitectura: email en procesando/enviado con tracking y courier editable
|
||||
|
||||
## Descubrimiento clave
|
||||
El mailer de estado ya existe (`order-status-mailer.ts`, F-106) y se dispara en
|
||||
`POST /orders/:id/transitions/admin`. PERO la UI admin (`apps/admin`) llama a la ruta de
|
||||
cliente `POST /orders/:id/transitions`, que **no** envía email, ignora `trackingNumber` y
|
||||
devuelve 404 si el backoffice no es el dueño del pedido. F-113 conecta la UI admin con la
|
||||
ruta admin correcta para que el email realmente salga en procesando/enviado.
|
||||
|
||||
## Decisiones
|
||||
1. **Courier persistido**: migración 039 añade `orders_orders.courier varchar(120) NULL`.
|
||||
Se propaga por dominio (`Order.courier`), repositorio, `updateState`/`transitionAdmin`
|
||||
(firma `courier?: string`), servicio y `serializeOrder`.
|
||||
2. **Lista editable de couriers**: se guarda como JSON array en
|
||||
`store_settings.shipping_couriers`. `GET/PATCH /admin/settings` exponen `couriers: string[]`
|
||||
(default si no existe: Correos, SEUR, MRW, GLS, DHL, UPS). Validación zod:
|
||||
array ≤30 items, cada string 1..60.
|
||||
3. **SHIPPED exige tracking y courier**: en la ruta admin, `state==='SHIPPED'` requiere
|
||||
`trackingNumber` (ya existía, 422 TRACKING_NUMBER_REQUIRED) y ahora también `courier`
|
||||
(422 COURIER_REQUIRED). Ambos se pasan al mailer.
|
||||
4. **Mailer**: `sendOrderStatusEmail` acepta `courier?: string | null`. En el cuerpo
|
||||
(texto y HTML) del email, si hay courier se añade línea "Transportista: X" junto a
|
||||
"Número de seguimiento: Y". Escape HTML ya presente.
|
||||
5. **Email en procesando y enviado**: como la UI admin ya usa `transition()` para todos los
|
||||
estados y la ruta admin envía email en cada transición, apuntar la UI a la ruta admin
|
||||
garantiza email en PROCESSING y SHIPPED (y el resto). No se añade lógica de envío nueva,
|
||||
solo se corrige el endpoint consumido.
|
||||
|
||||
## Admin UI (apps/admin)
|
||||
- `api-client.ts`: `ordersApi.transition(id, state, trackingNumber?, courier?)` →
|
||||
`POST /api/orders/{id}/transitions/admin` (envía courier si está presente).
|
||||
`StoreSettings.couriers?: string[]`.
|
||||
- `types/index.ts`: `Order.courier?: string | null`.
|
||||
- Página de pedido: al confirmar `SHIPPED`, mostrar selector de courier (desde ajustes)
|
||||
además del tracking; ambos obligatorios. Mostrar courier en el detalle.
|
||||
- Ajustes: nueva pestaña "Transportistas" con textarea (uno por línea) que edita la lista.
|
||||
|
||||
## Fuera de alcance
|
||||
- No rediseñar los demás emails de estado.
|
||||
- Sin integración con APIs externas de transportistas.
|
||||
Reference in New Issue
Block a user