Prompt Details
Model
Chat - (gpt-5)
Token size
1,442 ($0.04506 / call)
Example input
[MODE]: draft_prd
[PRODUCT_CONTEXT]: Checkout “Buy Again” carousel for grocery; web + app; high repeat buyers
[OBJECTIVES]: Lift AOV +8%; reduce time-to-cart −20%
[INPUTS]: Figma link text dump; past AB results
[STYLE_AND_COLLAB]: Opinionated, implementation-aware
Example output
# PRD — Checkout “Buy Again” Carousel (Grocery) — Web & App (High-Repeat Buyers)
> Assumption: We’re targeting signed-in grocery shoppers with ≥3 orders in the last 90 days (or ≥2 repeat purchases for ≥3 SKUs). Inputs mentioned (“Figma link text dump; past A/B results”) are not attached, so this PRD proceeds with sensible defaults and flags evidence gaps where needed.
---
## tl;dr
Add a “Buy Again” carousel on Cart/Checkout that surfaces each shopper’s most-reordered staples with one-tap add. Optimize for speed and certainty (inventory-aware, price-fresh, substitution-ready). Success = AOV +8% and time-to-cart −20% without harming checkout conversion or latency.
---
## Problem Statement
Grocery repeat buyers often remember one or two forgotten staples at the moment of checkout, but today must search/navigate to find them, adding time and causing drop-offs or smaller baskets. We lack a fast, trustworthy recall surface in checkout that’s tailored to each shopper’s actual re-order cadence and real-time availability.
Evidence gaps to confirm
Top repeat SKUs by shopper segment and their reorder intervals.
Past A/B learnings (attach rate, latency, placement) for any “recently bought” experiences upstream.
---
## Goals
### Business
Primary: Increase Average Order Value (AOV) +8% for eligible sessions.
Secondary: Lift incremental units/order +0.25–0.40 (eligible sessions).
Guardrails: No negative impact to Checkout CVR (≤−0.5pp) and p95 checkout latency (≤+50ms) attributable to the carousel.
### User
Primary: Time-to-cart −20% (from checkout entry to “Place Order” click) for eligible sessions.
Delight: Add common staples with ≤1 tap per item; provide clear price, size, availability; allow quick undo.
### Non-Goals
Building a net-new recommendations platform.
Cross-selling non-grocery categories.
Changing store/fulfillment selection logic.
---
## User Stories & Acceptance Criteria
1. As a weekly grocery buyer, I see a “Buy Again” row on Cart and the first Checkout step showing up to 12 of my frequently repurchased items.
AC1.1: Visible only for eligible signed-in users; hidden for guests/new users.
AC1.2: Items ranked by personal recency × reorder cadence fit × net margin × in-stock.
AC1.3: Each tile shows name, pack/size, price (promo if any), availability, and an “Add” button.
2. As that buyer, I can add an item instantly without losing my place.
AC2.1: Tap “Add” → item added to cart in <300ms p95 (cached price; server confirms).
AC2.2: “Added” state appears with quantity stepper and Undo (5s toast or inline).
3. If an item is OOS or limited, I’m clearly guided.
AC3.1: OOS items are suppressed; if stock turns OOS post-render, tapping “Add” surfaces substitution (if enabled) or OOS message.
AC3.2: Substitution preference respected if set; otherwise offer top substitute (same brand/size or nearest unit price).
4. If pricing changes, I’m never surprised at pay.
AC4.1: Price in tile must match server price at add time; if changed, tile shows a “Price updated” micro-badge before add.
5. I can manage quantities quickly.
AC5.1: Quantity stepper on the tile post-add; AC5.2: Removing restores “Add” state.
6. Accessibility & performance
AC6.1: Fully keyboard navigable; proper ARIA roles/labels.
AC6.2: Adds ≤10KB gz critical CSS/JS per platform; no CLS from late image loads.
---
## User Experience
### Placement
Cart page: Row sits below cart items and above order summary; sticky within cart content on mobile (not global sticky).
Checkout step 1 (Delivery/Payment review): Collapsible section default expanded for eligible users with ≥1 candidate.
### Interaction Flow (Web/App)
1. Enter Cart/Checkout → Feature flag & eligibility check → Async request for candidate list (batched with cart totals).
2. Render tiles (skeleton 6–8 placeholders) → Populate with server response.
3. Tap Add → Optimistic add with server confirmation; on success, show Added + stepper; on failure, show inline error (OOS, price change).
4. Optional See more opens a bottom sheet (app) / modal (web) with up to 24 candidates (virtualized list).
5. Telemetry fires on impression, exposure list, add, quantity change, remove, errors.
### Key Capabilities
Personalized ranking (rules-first MVP; ML later).
Inventory-aware suppression (no dead ends).
Price freshness (server truth at add).
Substitution pathway if enabled.
Undo safety net (fast removal).
### Edge Cases
Mixed fulfillment (store vs delivery windows): only show items available to the chosen fulfillment.
Age-restricted items: honor age-check flow if applicable; otherwise suppress.
Weight-priced produce: show est. unit price; stepper adjusts weight/qty per store rules.
Coupons/loyalty: badges appear if promo will auto-apply.
Store switch mid-flow: invalidate list; refetch.
Connectivity blips (app): display cached last-known list with stale badge; block add until reconnected.
---
## Narrative (Exec-Ready)
When Maria, a weekly shopper, reaches checkout, she sees her staples—milk, eggs, rice—right where she’s deciding whether she’s done. Instead of hunting, she taps Add twice and finishes. We pick up incremental units without adding friction; Maria feels confident because every tile is in-stock and price-accurate. At scale, that becomes +8% AOV with no CVR loss, helping grocery margins while making checkout feel smarter and faster.
---
## Success Metrics & Instrumentation
### Primary
AOV uplift (eligible sessions): +8% target vs. holdout.
Time-to-cart (eligible sessions): −20% from checkout entry to “Place Order”.
### Secondary
Attach rate: % of eligible sessions adding ≥1 Buy Again item.
Incremental units/order: +0.25–0.40 target.
Tile CTR: add taps ÷ exposures.
Removal after add: ≤10% (quality signal).
Substitution rate (if enabled) and OOS after tap (should be ~0 with suppression).
### Guardrails
Checkout CVR: Δ ≥ −0.5pp vs. holdout.
p95 Add latency: <300ms client-perceived; <150ms service.
p95 page TTI delta: ≤+50ms.
Customer Care contacts about “wrong price at checkout”: no increase.
### Experiment Design
Unit: user-level 50/50 split of eligible shoppers; 4-week run or until power achieved.
Holdout: removes carousel entirely.
Attribution: incremental basket size using CUPED with pre-period AOV as covariate for variance reduction (internal only; verify with Data Science).
### Event Taxonomy (examples)
`ba_impression` {slot: cart|checkout, count_exposed}
`ba_exposure` [{sku, rank, price_cents, in_stock, promo_flag}]
`ba_add` {sku, qty, price_cents, source: tile|sheet}
`ba_remove` {sku, qty}
`ba_error` {type: oos|price_change|network}
`ba_substitute_select` {sku_from, sku_to}
All events include `{user_id, session_id, experiment_id, store_id, fulfillment_type, device}`
---
## Technical Considerations
### Architecture (MVP)
Eligibility: edge guard via auth profile (order count, recency).
Candidate service (`buy-again-svc`):
Inputs: user purchase history (SKU, last bought ts, count), current store/fulfillment, inventory feed, price/promo service, exclusion rules.
Ranking (rules): Score = `recency_weight f(days_since_last) + cadence_fit g(habit) + margin_weight margin + promo_boost - oos_penalty`.
Response SLA: p95 <120ms. Cache results for 5 minutes per user-store key with inventory-invalidation hooks.
API: `GET /v1/buy-again?store_id=…&fulfillment=…` → candidates; `POST /v1/cart/items` for add (reuse cart API).
Client: Server-render shell with hydrated tiles to avoid CLS; lazy-request candidates post-TTI; app uses background prefetch on cart open.
### Dependencies
Identity/auth (signed-in), purchase history store, inventory & pricing APIs, cart API, experimentation platform, analytics pipeline, feature flag service, translation/i18n.
### Performance & Resilience
Fallback: If service fails or >300ms, collapse section silently (no jank).
Image handling: fixed aspect thumbnails with width/height hints; preconnect to image CDN.
Batching: coalesce candidate fetch with cart totals call when feasible.
### Privacy & Compliance
Data use: 1P purchase history for on-site personalization only; no external sharing.
Retention: align with existing order data retention; do not create new PII stores.
Consent: honor personalization opt-outs (feature auto-disables).
### Risks & Mitigations
Price/stock drift → Always validate on add; show “updated” badge before add when detected.
Latency regressions → Strict budgets + kill-switch; shadow canary.
Wrong-time placement → Use impression → add rate by slot to tune default expansion.
Segment bias (new users) → Eligibility gating prevents noise; show nothing if <threshold.
---
## Milestones & Sequencing (no dates)
0–2 weeks — Align & Foundations
Confirm eligibility rules & ranking factors; finalize Figma spec (tile anatomy, row behavior, sheet).
Define API contract; stubs in `buy-again-svc`.
Event schema implemented; feature flag created; kill-switch path verified.
3–6 weeks — Web MVP
Implement web row on Cart + Checkout (collapsible on Checkout).
Rules-based ranking; inventory-aware suppression; price validation on add.
Launch 10% canary → 50% eligible A/B. Monitor latency, attach rate, CVR guardrails.
7–10 weeks — App Parity & Quality
iOS/Android components with bottom sheet.
Substitution pathway (if enabled); “Price updated” badge; undo.
Performance hardening (caching, images); accessibility pass.
11–14 weeks — Optimization
Add promo/loyalty badges; boost logic tuning.
Expand to 24-item sheet; virtualized list.
Post-test decision: roll, iterate, or kill per metrics; ML ranking exploration gate.
---
## Implementation Notes (Opinionated)
Show 8–12 tiles max in the row; anything more goes in See more.
Prefer one-tap add; details page only on long-press/secondary action.
Keep copy minimal: product name, size, price, promo, and a tiny “Often bought” hint; avoid persuasive upsell text in checkout.
On mobile, ensure the row doesn’t push primary actions below the fold.
Use server truth for price at add; do not trust cached price when committing.
If inventory feed misses SLAs, fail silent (hide the section) rather than show stale suggestions.
---
## Open Questions (answer inline if easy)
1. Confirm eligibility threshold (orders/90d? SKU repeat count?) and any exclusions (alcohol, Rx, EBT-restricted).
2. Preferred primary slot: Cart only, Checkout only, or both (default both in MVP)?
3. Do we enable substitution flow in MVP or defer?
4. Are there must-show SKUs (e.g., private label) that warrant a rank boost cap?
5. What were the past A/B results and latency budgets from similar modules we can inherit?
---
### Clarifying Questions (Socratic, short)
Which exact pages get the row at launch (Cart, Checkout Step 1, both)?
What’s the inventory API p95 and cart add API p95 today?
Any legal/compliance constraints on showing price badges in checkout in your markets?
Should promo/loyalty badges appear in MVP or Phase 2?
Do we need store-specific suppression rules (e.g., fragile/heavy items)?
---
Focused next step: Can you share (or paste highlights from) the past A/B results and the Figma tile anatomy so I can lock the ranking factors, tile data fields, and exact placement?
By purchasing this prompt, you agree to our terms of service
GPT-5
Draft and improve crystal-clear PRDs, critique requirements, and coach PMs with precise, actionable guidance, rigorous thinking, markdown outputs.
...more
Added over 1 month ago
