# 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.
