# F-130 — Caducidad editable inline en /inventory ## Cambios ### `apps/admin/src/app/(dashboard)/inventory/page.tsx` - `ProductRow` ahora tiene 3 campos nuevos para edición inline de caducidad: ```ts editingExp: boolean; editExpValue: string; savingExp: boolean; ``` - Inicialización de fila incluye `editExpValue: product.expirationDate?.slice(0, 10) ?? ''` (formato YYYY-MM-DD para ``). - Nueva función `handleSaveExp(variantId, productId, value)`: - Llama `productsApi.update(productId, { expirationDate: value || null })` — string vacía se mapea a `null` (caducidad sin valor). - Actualiza la fila con el resultado y sale del modo edición. - Celda de caducidad modificada: clic en la celda → entra en modo edición con `` + autofocus + blur/Enter para guardar + Escape para cancelar. ## Patrón seguido Sigue el mismo patrón que la edición inline de Stock y EAN (F-075): estado por fila, handler dedicado, save con optimistic UI updates. ## Verificación - `cd apps/admin && npx tsc --noEmit` → exit 0. - `cd apps/admin && NEXT_PUBLIC_API_URL=http://192.168.18.93:3000 npm run build` → exit 0. ## Notas - Backend ya soportaba `PATCH /products/:id { expirationDate }` (catalog.routes.ts:96 — `z.iso.date().optional().nullable()`). - Sin cambios en backend ni migración. - Operador reinicia admin (`./scripts/monolith.sh prod restart`) para desplegar.