Skip to content

feat: add POST /api/cart/promo endpoint for promo-code discount#31

Open
samkerr4coding wants to merge 1 commit into
DevExpGbb:mainfrom
samkerr4coding:feature/promo-code-endpoint
Open

feat: add POST /api/cart/promo endpoint for promo-code discount#31
samkerr4coding wants to merge 1 commit into
DevExpGbb:mainfrom
samkerr4coding:feature/promo-code-endpoint

Conversation

@samkerr4coding

Copy link
Copy Markdown

Summary

Adds POST /api/cart/promo — a stateless endpoint that accepts a cart and a promo code and returns the full CartTotals breakdown (subtotal, discount, tax, total) plus a promoApplied boolean.

Re-uses the existing otalize() and �pplyDiscount() functions from lib/cart.ts; no new business logic or DB queries.

Changes

File Change
�pp/api/cart/promo/route.ts New POST handler; Zod input validation
ests/promo.test.ts 14 tests: �pplyDiscount branches + route handler
itest.config.ts Add @/ path alias so vitest can resolve Next.js imports

Request / Response

\
POST /api/cart/promo
Content-Type: application/json

{
"items": [{ "productId": "p1", "quantity": 2, "unitPriceCents": 1000 }],
"promoCode": "WELCOME10",
"region": "GB"
}

HTTP 200
{
"totals": { "subtotalCents": 2000, "discountCents": 200, "taxCents": 360, "totalCents": 2160 },
"promoCode": "WELCOME10",
"promoApplied": true
}
\\

Checks


  • pm run lint\ — no warnings or errors

  • pm test\ — 21/21 tests pass (14 new)

Out of scope — noted for team

The following were intentionally excluded from this work item; a human should decide on priority:

  1. Promo code persistence — codes are hardcoded in \�pplyDiscount(). A \promo_codes\ table + admin CRUD would be needed for dynamic codes.
  2. Redemption tracking — no per-user usage limits or expiry enforcement.
  3. Auth on this endpoint — consistent with the existing /api/products\ route (no auth), since this is a read-only calculation. Team should confirm whether a session cookie or Bearer token is required here before GA.

…lation

- Validates input with Zod (items, promoCode, region)
- Calls existing totalize() from lib/cart.ts; no new business logic
- Returns CartTotals + promoApplied boolean
- Tests cover applyDiscount branches and route handler (valid, invalid, missing fields)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant