Variant options stored as free-form strings ('medium', 'Med', 'M') for the same logical value produce duplicate facets in filters, inconsistent add-to-cart payloads, and inventory mismatches when orders reference 'M' but the stock record uses 'Medium'. ISO 25010:2011 functional-correctness requires consistent behavior across the same logical input. Without an enum or lookup table, every new developer who touches the product creation form can introduce a new spelling, and there's no schema-level enforcement to catch it. Filter UIs built on free-form strings show three separate size options when there should be one.
High because uncontrolled variant option strings produce inventory mismatches, broken filters, and add-to-cart failures when the selected string doesn't exactly match a database record.
Define variant options as enum types or a reference table in prisma/schema.prisma so the database rejects any value not in the allowed set.
enum Size {
XS
S
M
L
XL
}
model ProductVariant {
id String @id @default(cuid())
productId String
product Product @relation(fields: [productId], references: [id])
size Size
color String
}
For more flexible option systems, use a separate OptionValue reference table and foreign key instead of a Prisma enum — this allows adding new values via migration rather than code change.
ID: ecommerce-catalog.variant-pricing.variant-options-defined
Severity: high
What to look for: Count all variant option types in the schema or codebase (size, color, material, etc.). For each option type, enumerate the allowed values: are they defined as enums, a reference table, or free-form strings? Check prisma/schema.prisma for enum definitions, src/types/ for TypeScript union types, or a separate options table in migrations.
Pass criteria: For products with variants, at least 1 option type has predefined allowed values (enum, lookup table, or union type), not free-form text input. Count all option types found and report: "X option types found, Y of X have predefined values."
Fail criteria: Variant options are stored as arbitrary strings with no enumeration or validation anywhere in the codebase — no enums, no lookup tables, no TypeScript unions.
Skip (N/A) when: The project has no products with variants (all SKUs are fixed) — confirmed by finding no variant model, no option fields, and no size/color references in the codebase.
Cross-reference: For data integrity of variant options, the Database Design & Operations audit covers enum and constraint patterns.
Cross-reference: For variant display and selection UX, the Accessibility Fundamentals audit covers form control patterns and label associations.
Cross-reference: For variant URL structure, the SEO Fundamentals audit covers parameterized URL patterns.
Detail on fail: "Variant sizes are stored as free-form text with no enumeration in prisma/schema.prisma. Examples: 'medium', 'Med', 'M' used for the same size in prisma/seed.ts" or "No variant option schema found — 0 option types defined"
Remediation: Define variant options with enums or a separate reference table in prisma/schema.prisma:
model ProductVariant {
id String @id @default(cuid())
productId String
product Product @relation(fields: [productId], references: [id])
size String @db.Enum("XS", "S", "M", "L", "XL")
color String @db.Enum("Red", "Blue", "Green", "Black")
}