# Stock levels are initialized and tracked accurately

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

## Why it matters

A product schema without a `stock` field, or with a nullable `stock` that defaults to `null`, means the application has no authoritative source for inventory state. Every in-stock/out-of-stock display becomes a guess, overselling becomes possible on the first order, and inventory reports return `NULL` aggregates that silently break dashboards. ISO 25010:2011 functional-correctness requires correct outputs; a stock value of `null` produces neither "in stock" nor "out of stock" — it produces an error or a wrong assumption depending on how `null` is coerced in the display layer. Tracking stock is not optional for e-commerce.

## Severity rationale

High because an absent or nullable stock field makes overselling possible on every order and renders all inventory reporting unreliable from the first data row.

## Remediation

Add a `stock` field with a default of `0` in `prisma/schema.prisma` so newly created products start tracked rather than untracked.

```prisma
model Product {
  id    String @id @default(cuid())
  name  String
  stock Int    @default(0)
}
```

In `src/app/api/products/route.ts`, always pass `stock` explicitly on creation rather than relying on the default — this prevents silent omissions in bulk import paths:

```ts
const product = await prisma.product.create({
  data: { name, price, stock: initialStock ?? 0 },
})
```

## Detection

- **ID:** `stock-initialized`
- **Severity:** `high`
- **What to look for:** Count all product and variant schema definitions. For each, check for a `stock`, `quantity`, or `inventory` field. Enumerate all product creation paths and verify that stock is explicitly set during creation (not left null or undefined). Count the number of products in seed data with null, undefined, or missing stock values.
- **Pass criteria:** All products/variants have a stock field initialized to a numeric value (0 or higher) in the schema, stock is never null in seed data, and at least 1 product creation path sets stock explicitly. Report: "X of Y products in seed data have initialized stock values."
- **Fail criteria:** Stock field is missing from the schema, stock is nullable in the schema definition, or more than 0 products in seed data have stock = null.
- **Skip (N/A) when:** Never — stock tracking is essential for e-commerce.
- **Cross-reference:** For database default values and schema design, the Database Design & Operations audit covers default value patterns.
- **Cross-reference:** For inventory display accuracy, the Pre-Launch audit covers data consistency between backend and frontend.
- **Cross-reference:** For stock field in variant model, the check `ecommerce-catalog.variant-pricing.unique-sku` in this audit covers variant data completeness.
- **Detail on fail:** `"Product schema in prisma/schema.prisma has no stock field"` or `"8 of 15 products have stock = null in prisma/seed.ts"`
- **Remediation:** Add and initialize a stock field in `prisma/schema.prisma`:

  ```prisma
  model Product {
    id String @id @default(cuid())
    name String
    stock Int @default(0)
  }
  ```

  When creating products in `src/app/api/products/route.ts`, set stock explicitly:

  ```ts
  const product = await prisma.product.create({
    data: {
      name,
      price,
      stock: initialStock ?? 0,
    },
  })
  ```

## External references

- iso-25010 functional-correctness

Taxons: data-integrity

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