Skip to content

44 — Per-Product Collection Rule (Required) Implementation Plan

Cursor-ready plan for enforcing the blueprint rule: one testimonial request per delivered product line item and strict product binding from request to published content.

44 — Per-Product Collection Rule (Required) Implementation Plan

Section titled “44 — Per-Product Collection Rule (Required) Implementation Plan”

Source: 02-Implementation-Blueprint.md — required rule under architecture section:

  • one testimonial request per delivered product line item
  • one request token maps to exactly one Shopify product ID
  • approved testimonial remains linked to that same product and renders on that product detail page

This document is a build spec only. No code changes are implied until a task references this file.

Related: 07 (pipeline), 06 (public submission), 39 (request model), 37 (submission model), 05/11 (storefront publication), 41 (campaign-product targeting).


Guarantee strict product-level attribution from webhook request creation through submission, moderation, and storefront rendering so testimonials never drift away from the product they were requested for.


For every eligible delivered line item:

  1. Create exactly one TestimonialRequest row (or one per unit if quantity policy says so, but each request remains product-specific).
  2. Generate a token that maps to one and only one shopifyProductId.
  3. On submit, create TestimonialSubmission.shopifyProductId from the request, not client payload.
  4. On publish, PDP rendering uses that same shopifyProductId.

No workflow should break this chain without explicit admin override action.


TestimonialRequest must contain:

  • shopifyProductId (required)
  • submissionToken (unique)
  • token resolves to exactly one request row

TestimonialSubmission.shopifyProductId is required and initialized from request mapping.

TestimonialProductLink is additive only and does not replace primary linkage.


When processing order events:

  1. extract eligible delivered line items
  2. normalize line shopifyProductId
  3. create request row with that product id
  4. do not reuse same request token for multiple products

Choose one policy and document it clearly:

  • Per line item row (one request per distinct line), or
  • Per unit (quantity-aware multiple requests).

Either way, each request still maps to one product id.

Use a deterministic key including product identity:

(shopId, campaignId, shopifyOrderId, shopifyProductId, lineItemId?)

to prevent duplicate product requests on webhook retries.


token -> request -> shopifyProductId

  • ignore any client-provided product id in submit payload
  • always set submission product from resolved request
  • invalid/expired token: reject submit
  • request already submitted: conflict/idempotent response

Default behavior:

  • product binding is locked to request product.

If admin override is allowed:

  • must be explicit in Screen 6 merchandising controls
  • must log action in moderation log with reason
  • storefront should still use current primary product id deterministically

If override is not allowed in MVP, enforce read-only product binding in detail UI.


PDP widget query uses:

  • placement=pdp
  • product_id=currentProductId
  • returns only approved+published+ready submissions where shopifyProductId == currentProductId

Home widget may show store-wide entries, but each card should still carry original product attribution for link-back/label.


Because binding is strict:

  • product coverage metrics remain trustworthy
  • per-product testimonial counts are accurate
  • conversion comparisons (with vs without testimonials) are meaningful

If overrides are enabled, track override events separately to preserve data interpretability.


Strict mapping prevents:

  • customer tampering by submitting under another product
  • accidental cross-product misattribution
  • incorrect social proof on unrelated PDPs

This rule is central to merchant trust and should be covered by regression tests.


  • One eligible delivered product line item produces one product-bound request row.
  • Each request token resolves to exactly one shopifyProductId.
  • Submit endpoint always writes submission product from request, never client override.
  • PDP API returns only product-matching published submissions.
  • No cross-product leakage in storefront widgets.

  1. Order with 3 eligible products -> 3 product-bound request rows.
  2. Replay webhook -> no duplicate request rows.
  3. Submit payload with tampered shopifyProductId -> stored product remains request product.
  4. PDP query for product A never returns product B submissions.
  5. Optional override flow (if enabled) requires admin action and audit log.

11) Suggested implementation order (for Cursor)

Section titled “11) Suggested implementation order (for Cursor)”
  1. Lock request creation to per-product rows in webhook planner.
  2. Enforce token->product mapping in submit API.
  3. Add PDP query predicate and regression tests.
  4. Add UI guards in moderation detail (lock or audited override).
  5. Add analytics checks to verify product attribution consistency.

  • 02-Implementation-Blueprint.md — required per-product rule section
  • 07-email-sms-request-delivery-pipeline.md
  • 06-public-submission-page-screen-13.md
  • 39-testimonial-request-model-blueprint-section-5-5.md
  • 37-testimonial-submission-model-blueprint-section-5-7.md
  • 05-storefront-widgets-and-read-api.md

This folder already includes 05 through 43 plans. This file is 44-....