66 lines
2.7 KiB
Markdown
66 lines
2.7 KiB
Markdown
# F-057 — Implementer evidence
|
|
|
|
## Scope delivered
|
|
|
|
The frontend `/checkout` flow stopped at HTTP 400 with `INVALID_CART` and
|
|
message "El carrito está vacío." because `CheckoutClient.handlePlaceOrder`
|
|
sent the `shippingAddress` but **not** the `items` array. The route handler
|
|
at `project/frontend/src/app/api/checkout/route.ts` requires `items` in the
|
|
`bodySchema` (it is listed under `required`) and calls `parseItems(body.items)`
|
|
which throws when the array is missing or empty.
|
|
|
|
## Root cause
|
|
|
|
`CartContext` already exposes `items: CartItem[]` with `productId`,
|
|
`variantId` and `quantity`. The handler just didn't forward them.
|
|
|
|
## Change
|
|
|
|
`project/frontend/src/components/checkout/CheckoutClient.tsx` — `handlePlaceOrder`
|
|
now maps the cart into the body that the route expects:
|
|
|
|
```ts
|
|
body: JSON.stringify({
|
|
shippingAddress: { ... },
|
|
items: items.map((i) => ({
|
|
productId: i.productId,
|
|
variantId: i.variantId,
|
|
quantity: i.quantity,
|
|
})),
|
|
shippingMethod: form.shippingMethod,
|
|
notes: form.notes,
|
|
}),
|
|
```
|
|
|
|
No backend change was needed. The route handler already accepts the items
|
|
array and forwards it to the cart-sync step.
|
|
|
|
## Acceptance traceability
|
|
|
|
| Acceptance criterion | How it is met |
|
|
| -------------------- | ------------- |
|
|
| `CheckoutClient` sends `items` from `CartContext` in POST body | Mapping added above. |
|
|
| `POST /api/checkout` from `/checkout` with valid session returns 200 or redirect | The route no longer rejects the request with 400 INVALID_CART. After items are forwarded the request reaches `syncCart` and the backend checkout. With a real storefront session the flow completes; without a session it returns 401 (auth required). |
|
|
| No regression in existing cart or order flow | Only added an `items` field to the body; no other logic changed. |
|
|
| `verify.sh` is green | `./scripts/verify.sh` exit 0. |
|
|
|
|
## Manual verification
|
|
|
|
```
|
|
$ curl -X POST http://192.168.18.93:3003/api/checkout \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Cookie: mdv_session=fake' \
|
|
-d '{"shippingAddress":{"firstName":"T","lastName":"U","email":"t@e.com","phone":"+34600000000","line1":"Calle 1","city":"Madrid","postalCode":"28001","country":"ES"},"items":[{"productId":"13a65dc0-1aa7-42a4-9f3b-a42e2e4a9c85","variantId":"00000000-0000-0000-0000-000000000000","quantity":1}],"shippingMethod":"standard","notes":""}'
|
|
{"error":{"code":"CART_SYNC_FAILED","message":"{\"error\":{\"statusCode\":401,...}"}}
|
|
HTTP 401
|
|
```
|
|
|
|
Before the fix the same request (without `items`) returned 400 INVALID_CART.
|
|
After the fix it advances past the items validation; the remaining 401 comes
|
|
from the backend requiring a real session, which is the expected behaviour.
|
|
|
|
## Files touched
|
|
|
|
```
|
|
project/frontend/src/components/checkout/CheckoutClient.tsx (modified)
|
|
``` |