# Social proof elements (purchase count, trending badge) are factually accurate

- **Pattern:** `ab-001214` (`ecommerce-reviews.moderation-trust.proof-accuracy`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001214
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001214)

## Why it matters

Hardcoded social proof numbers — "Purchased 500+ times", "Best Seller", "4.8 stars" — violate the FTC Endorsement Guides on social proof and, when displayed in schema.org markup, cause Google to flag rich results as inaccurate. A product page that shows "Purchased 500+ times" backed by a literal JSX string rather than a database count misrepresents sales volume, which is deceptive advertising under FTC guidelines. The failure compounds as your catalog grows: the hardcoded number never updates, so the gap between claimed and actual performance widens automatically.

## Severity rationale

Medium because hardcoded social proof numbers violate FTC truthful-advertising requirements and diverge silently from actual product performance as time passes.

## Remediation

Move all social proof calculations to database aggregation queries in `components/SocialProof.tsx` — no numeric literals in JSX.

```ts
// components/SocialProof.tsx
export async function SocialProof({ productId }: { productId: string }) {
  const [purchaseCount, helpfulCount] = await Promise.all([
    db.orders.count({ where: { product_id: productId, status: 'completed' } }),
    db.reviewVotes.count({ where: { product_id: productId, vote: 'helpful' } })
  ])

  // Only render elements when count > 0 to avoid showing "0 people purchased this"
  return (
    <div className="social-proof">
      {purchaseCount > 0 && <p>{purchaseCount.toLocaleString()} verified purchases</p>}
      {helpfulCount > 0 && <p>{helpfulCount} people found these reviews helpful</p>}
    </div>
  )
}
```

Search for numeric literals adjacent to words like "purchased", "sold", "reviews", or "trending" in JSX/HTML files and replace each with a live query.

## Detection

- **ID:** `proof-accuracy`
- **Severity:** `medium`
- **What to look for:** List all social proof elements displayed on product pages (purchase counts, trending badges, "Best Seller" labels, helpful-vote counts). For each, classify whether the displayed value is dynamically calculated from a database query or hardcoded in markup. Count how many are dynamic vs hardcoded. Report the ratio.
- **Pass criteria:** At least 100% of social proof numbers (purchase counts, helpful votes, trending indicators) are dynamically calculated from actual database queries — no hardcoded numeric values in JSX/HTML for social proof elements. Report even on pass: list the social proof elements found and confirm each is dynamic.
- **Fail criteria:** At least 1 social proof element displays a hardcoded number or string, or a count that does not correspond to a database aggregation query.
- **Skip (N/A) when:** The project has no social proof elements (no purchase counts, trending badges, or similar indicators on product pages).
- **Detail on fail:** `"2 social proof elements found. 1 of 2 is hardcoded: 'Purchased 500+ times' in JSX markup. The review count is dynamic (from query)."` or `"'Best Seller' badge applied to all products regardless of actual sales volume."`
- **Remediation:** Calculate social proof dynamically in `components/SocialProof.tsx` using database aggregation queries:

  ```ts
  // components/SocialProof.tsx
  export async function SocialProof({ productId }) {
    const [purchaseCount, reviewCount] = await Promise.all([
      db.orders.count({ where: { product_id: productId, status: 'completed' } }),
      db.reviews.count({ where: { product_id: productId, status: 'approved' } })
    ])

    return (
      <div className="proof">
        <p>{purchaseCount} people purchased this</p>
        <p>{reviewCount} reviews</p>
      </div>
    )
  }
  ```

## External references

- external ftc-endorsement-guides-social-proof — https://www.ecfr.gov/current/title-16/chapter-I/subchapter-B/part-255

Taxons: content-integrity

HTML version: https://auditbuffet.com/patterns/ab-001214
