# NOTIF-INVENTORY-ALERTS — Documenter notes > Documenter: document · Estado: ready for close ## Cambio de contrato ### Nuevo endpoint **`GET /api/inventory/admin/notifications`** - **Auth:** requiere rol `admin` (HTTP 403 si no). - **Response:** ```jsonc { "items": [ { "id": "low_stock", "count": 7, "href": "/inventory?filter=low_stock", "label": "Stock bajo", "tone": "amber" }, { "id": "out_of_stock", "count": 3, "href": "/inventory?filter=out_of_stock", "label": "Sin stock", "tone": "red" }, { "id": "expired", "count": 2, "href": "/inventory?filter=expired", "label": "Caducados", "tone": "red" }, { "id": "expiring_soon", "count": 5, "href": "/inventory?filter=expiring", "label": "Por caducar (≤30d)", "tone": "amber" }, { "id": "low_margin", "count": 4, "href": "/inventory?filter=low_margin", "label": "Margen <30%", "tone": "red" } ], "total": 21 } ``` - **Reglas:** - Solo se incluyen items con `count > 0`. - `total` es la suma de los counts de items incluidos. - Items NO incluidos en respuesta cuando su count es 0 (no aparecen como `{count: 0}`). ### Cambio en filtro existente `GET /api/inventory/admin/overview?filter=...` ahora acepta `expired` además de los filtros anteriores (`all`, `in_stock`, `low_stock`, `out_of_stock`, `expiring`, `low_margin`). - **`expired`:** productos activos cuya `expiration_date < current_date`. Ordenados por `expiration_date DESC NULLS LAST` (caducados más recientes primero). ### Cambio en UI `OrderNotifications` (campanita del header admin) ahora tiene 3 tabs en lugar de 2: | Tab | Icono | Color del badge | Datos | |---|---|---|---| | Pendientes | 📦 | amber | stale orders (PENDING/SHIPPED >24h) | | Esperando pago | 💳 | purple | orders AWAITING_PAYMENT | | **Inventario** | 🏷️ | emerald | alertas operativas de inventario (este feature) | - Solo visible para `user.role === 'admin'`. - Polling cada 5 min vía `Promise.all([staleNotifications, awaitingPaymentNotifications, inventoryApi.notificationCounts])`. - Badge total suma los 3 totales. ## Quién se ve afectado - **Operador admin del backoffice:** ahora ve alertas de inventario en la campanita sin entrar a `/inventory`. - **No-admin (customer, cashier):** sin cambios (no ven la campanita). - **API consumers externos:** nuevo endpoint disponible (auth admin). Sin breaking change en endpoints existentes. ## Comportamiento observable | Escenario | Antes | Después | |---|---|---| | Admin abre campanita | 2 tabs (Pendientes, Esperando pago) | 3 tabs (Pendientes, Esperando pago, **Inventario**) | | Producto caduca | Sin notificación visible | Aparece en tab Inventario como "Caducados" (rojo), badge se incrementa | | Producto entra en stock bajo (<5) | Sin notificación visible | Aparece en tab Inventario como "Stock bajo" (amber), badge se incrementa | | Producto baja de margen 30% | Sin notificación visible | Aparece en tab Inventario como "Margen <30%" (rojo), badge se incrementa | | Click en cualquier alerta de inventario | n/a | Navega a `/inventory?filter=...` con la lista filtrada | ## Notas operacionales - **Umbrales hardcoded:** 5 unidades (low_stock), 30 días (expiring), 30% (low_margin). Consistente con los filtros existentes. Si en el futuro el operador pide flexibilidad, se mueven a `store_settings` en otro ticket. - **Polling:** 5 minutos. Si la campanita está abierta, el polling refresca los 3 endpoints. Latencia añadida: <50ms (3er endpoint). - **No hay emails:** las alertas son solo in-app. Si en el futuro se piden emails, sería un nuevo ticket en el módulo `notifications`. ## Notas de release (sugeridas) ``` feat(notif-inventory-alerts): admin bell shows inventory alerts (low stock, out of stock, expired, expiring, low margin) Adds GET /api/inventory/admin/notifications (admin role) with 5 count types. Extends OrderNotifications header bell with third tab "Inventario". Extends inventory filter enum with 'expired' (expiration_date < current_date). 5/5 unit tests for the new endpoint; tsc + next build green. ``` ## Cross-references - architect.md §2 — diseño de las 3 piezas (backend, helper, frontend). - implementer.md §3 — detalle de los cambios y evidencia. - reviewer.json — 10/12 checks PASS + 2 PASS_WITH_NOTE. - security.json — 10/10 checks PASS. - qa.json — 8/9 AC + 4/4 integration + 3/3 regression. ## Próximo stage → **close (leader)**: ejecutar `scripts/close_feature.py NOTIF-INVENTORY-ALERTS`.