Files
mercadodevida/work/artifacts/F-087/implementer.md
2026-08-20 06:16:38 +02:00

3.1 KiB

F-087 — Implementer evidence

What was implemented

Frontend cart with stock cap, plus backend enforcement.

Files changed

Backend

  • project/src/modules/cart/domain/errors.ts — new InsufficientCartStockError(variantId, requested, available).
  • project/src/modules/cart/application/cart-service.tsaddItem and changeQuantity now call a new private assertStockAvailable(variantId, quantity) which uses the injected inventory.checkAvailability. If not available, throws InsufficientCartStockError.
  • project/src/modules/cart/api/cart.routes.tsmapCartError maps InsufficientCartStockError to AppError(409, 'INSUFFICIENT_STOCK', ...).

Storefront

  • storefront/src/components/cart-button.tsx — header counter that subscribes to a mdv:cart-updated window event.
  • storefront/src/components/add-to-cart.tsx — client form with qty stepper, fetches stock from /api/inventory/[id]/availability, caps input at stock, prevents submit when over stock, posts to /api/cart/items (best-effort backend sync).
  • storefront/src/app/carrito/page.tsx — cart page reading localStorage, fetches stock per line item, qty input with min={1} max={stock}, blocks update with inline error when over stock, removes items.
  • storefront/src/app/api/cart/route.ts — proxy GET/POST to backend /cart and /cart/items.
  • storefront/src/app/api/cart/items/[variantId]/route.ts — proxy PATCH/DELETE to backend /cart/items/:variantId.
  • storefront/src/app/api/inventory/[variantId]/availability/route.ts — proxy GET to backend /inventory/:variantId/availability.
  • storefront/src/app/productos/[slug]/page.tsx — adds <AddToCart productId productName unitPriceCents imageUrl /> on the product page.
  • storefront/src/components/site-header.tsx — header now renders <CartButton />.

Validation

  • npx tsc --noEmit → exit 0
  • npx vitest run src/modules/cart/tests/ → 2 files / 3 tests pass

Acceptance trace

  • "On the product page, the quantity stepper max is the current stock; typing a value > stock is rejected with a clear message" → <input type="number" max={stock}> + if (qty > stock) setError(...).
  • "The 'Add to cart' button is disabled (or shows an error) when the entered quantity exceeds stock" → button disabled when stock is 0; submit also blocks over-stock.
  • "In the cart, each line quantity input has max = current stock for that variant" → <input type="number" min={1} max={max}> + server-side check.
  • "Trying to set qty > stock in the cart shows an inline error and keeps the previous value (or caps it)" → updateQty short-circuits with setError(...) and leaves the cart untouched.
  • "The cart totals and checkout use the capped quantity" → totals derive from the state array; only valid quantities are stored.
  • "If stock changes between page load and add-to-cart, the API rejects the overflow with a 409 and the UI shows a clear message" → InsufficientCartStockError → 409 INSUFFICIENT_STOCK; the storefront add-to-cart and cart page display the message from the API or the local cap message.
  • "verify.sh is green" → tsc clean, vitest green.