# Product images are present and properly referenced

- **Pattern:** `ab-001117` (`ecommerce-catalog.product-data.image-presence`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001117
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001117)

## Why it matters

Products without images convert at dramatically lower rates — multiple e-commerce studies place the drop at 30–60% versus imaged listings. Beyond conversion, storing images as local filesystem paths (e.g., `/Users/dev/photos/`) means images resolve on the developer's machine and return 404s in every other environment: staging, production, and CI. ISO 25010:2011 functional-correctness requires the system to behave correctly across environments, not just locally. A schema that only supports a single image string also locks out gallery experiences and prevents future migration to multi-image CDN storage without a schema change.

## Severity rationale

High because products missing images or referencing local filesystem paths display broken UI in production, directly reducing catalog usability and purchase conversion.

## Remediation

Store images as an array of full CDN or absolute URLs in `prisma/schema.prisma`, and validate at least one URL is present on product creation in `src/app/api/products/route.ts`.

```prisma
model Product {
  id     String   @id @default(cuid())
  images String[]
}
```

```ts
if (!images || images.length === 0) {
  return Response.json({ error: 'At least one product image is required' }, { status: 400 })
}
```

On ingest, reject any URL that matches a local path pattern (`/Users/`, `/home/`, `C:\`) — these will break in every deployed environment.

## Detection

- **ID:** `image-presence`
- **Severity:** `high`
- **What to look for:** Count all products in seed data, fixture files, and sample responses. For each product, check whether at least 1 image URL is stored. Enumerate the image storage format used: absolute URLs, relative paths, S3/CDN references, or local filesystem paths. Count the total number of products with 0 images versus at least 1 image.
- **Pass criteria:** At least 90% of products have at least 1 image URL in the database or seed data, and the schema supports storing multiple images per product (array field or relation table). Report: "X of Y products have at least 1 image. Storage format: [format detected]."
- **Fail criteria:** More than 10% of products lack image references, or images are stored as local filesystem paths (e.g., `/Users/dev/photos/`) without CDN normalization, or the schema only supports a single image string (not an array or relation).
- **Skip (N/A) when:** The project is API-only with no visual product display, or the project is a wholesale/B2B platform where images are explicitly not part of the data model.
- **Cross-reference:** For image performance optimization, the Performance Core audit covers lazy loading, responsive images, and CDN configuration.
- **Cross-reference:** For image accessibility, the Accessibility Fundamentals audit covers alt text and image description patterns.
- **Cross-reference:** For image URL security, the Security Headers audit covers mixed content and CSP image-src policies.
- **Detail on fail:** `"4 of 10 products have no image URLs in prisma/seed.ts"` or `"Images stored as local filesystem paths (e.g., '/Users/dev/photos/shirt.jpg') in src/data/products.ts instead of CDN URLs"`
- **Remediation:** Store product images as full URLs or CDN paths in `prisma/schema.prisma`:

  ```prisma
  model Product {
    id String @id @default(cuid())
    images String[]
  }
  ```

  When creating or updating products in `src/app/api/products/route.ts`, ensure at least one image URL is provided and validate that it's a valid URL:

  ```ts
  if (!images || images.length === 0) {
    throw new Error('At least one product image is required')
  }
  ```

## External references

- iso-25010 functional-correctness

Taxons: data-integrity

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