# F-106 — Admin order editing, status notifications, tracking ## Implementación ### Backend (orders module) - `PUT /orders/:id/items` (admin): reemplaza artículos del pedido. Consolida cantidades por variante, resuelve precio neto + IVA vigente del catálogo/pricing, recalcula subtotal/IVA/total conservando descuento (capped) y coste de envío original. Transacción BEGIN/COMMIT con rollback. - `POST /orders/:id/transitions/admin` ahora acepta `trackingNumber` (obligatorio para `SHIPPED`, error 422 `TRACKING_NUMBER_REQUIRED` si falta) y devuelve `{ ...order, notified, notificationError? }`. - Nuevo `order-status-mailer.ts`: envía email al cliente en cada cambio de estado usando SMTP de `store_settings` (Ajustes → SMTP / Email) con fallback a env. HTML escapado, sin raw HTML de usuario. Fallos de envío no bloquean la transición. - Migración `036_order_tracking_number.js`: `orders_orders.tracking_number text NULL`. - `serializeOrder` expone `trackingNumber`. ### Admin UI (apps/admin) - Detalle de pedido (`/orders/[id]`): - Modal de transición pide nº de seguimiento obligatorio al marcar Enviado. - Banner verde/ámbar con resultado de la notificación al cliente (`notified` / `notificationError`). - Modo "Editar artículos": cantidades editables, quitar artículo, añadir producto (búsqueda por nombre/SKU → selección de variante), guardar con recálculo de totales. - Bloque "Seguimiento" en Resumen mostrando `trackingNumber`. - `api-client.ts`: `ordersApi.transition(id, state, trackingNumber?)` y `ordersApi.editItems`. ## Evidencia - `npm run typecheck` (backend) OK; `tsc --noEmit` (apps/admin) OK. - `npm run build` backend OK; `next build` admin OK. - Migración 036 aplicada (`Migrations complete!`). - `monolith.sh prod restart` → backend/frontend/admin/storefront 200. - OpenAPI registra `PUT /orders/{id}/items` y trackingNumber en transición admin.