Weak ticket
Add coupon codes to checkout. Make sure invalid codes do not break payment.
This is the homepage example expanded into a full case: one vague request becomes a bounded spec, implementation slices, acceptance criteria, and evidence reviewers can check before merge.
Add coupon codes to checkout. Make sure invalid codes do not break payment.
Feature: Checkout coupon code Owner: Web Checkout Status: Ready for review Context: - Checkout UI lives in apps/web/routes/checkout. - Totals are computed in packages/billing/totals.ts. - Coupon table exists but is not wired into checkout. Goal: - Let signed-in users apply one valid coupon before payment. - Show invalid, expired, and already-used codes inline. Non-goals: - No coupon admin UI. - No coupon stacking. - No rewrite of billing totals.
- [ ] Add coupon lookup by code and user. - [ ] Validate expired, disabled, and reused codes. - [ ] Recompute checkout total with one discount. - [ ] Show inline errors without clearing payment form. - [ ] Add feature flag for rollback.
- Given a valid coupon When the user applies it before payment Then the discounted total is shown and used for payment. - Given an expired code When the user applies it Then an inline error appears and the original total remains.
Automated: - coupon validation unit test - checkout total integration test - reused coupon regression test Manual: - screenshot for valid code - screenshot for invalid code - rollback flag documented
Implement only coupon application at checkout. Do not add admin UI, stacking, price rules, or totals refactors. Every changed file must map to one task and one acceptance criterion.
The spec names the totals module and blocks unrelated refactors before an AI coding tool broadens the task.
Expired, reused, and invalid coupons become concrete acceptance paths rather than late QA discoveries.
The rollback flag and evidence list tell reviewers how to pause the change if checkout metrics move.
Start with the generator, then paste the packet into the issue or PR before asking an AI coding assistant to implement it.
This case is intentionally small and concrete: the goal is to show the spec boundary that prevents AI-generated implementation drift.