Skip to content

GraphQL Barcode Schema Requirements

Date: 2026-01-30
Status: ⚠️ Schema Verification Needed
Related: Scan Bottle to Add Implementation

This document outlines the GraphQL schema requirements for the ProductBarcode structure used in the barcode scanning implementation. The frontend implementation expects a specific structure that must be supported by the backend GraphQL API.

type ProductBarcode {
code: String! # Barcode number (e.g., "012345678901")
type: BarcodeType! # Type of barcode (UPC, EAN, QR, CODE128)
scannedDate: String # ISO date string when barcode was scanned (optional)
}
enum BarcodeType {
UPC
EAN
QR
CODE128
}

The CreateProductInput input type should accept a barcode field with the following structure:

input ProductBarcodeInput {
code: String!
type: BarcodeType!
scannedDate: String
}
input CreateProductInput {
name: String!
brand: String
productType: ProductType!
category: String
volume: Float
unit: MeasurementUnit
storageLocation: String
currentLevel: Float!
barcode: ProductBarcodeInput # Optional
alcoholContent: Float
minimumLevel: Float
costPrice: Float
expirationDate: String
imageUrl: String
description: String
tags: [String!]
# ... other fields
}

The mutation should accept and return the barcode structure:

mutation CreateProduct($input: CreateProductInput!) {
createProduct(input: $input) {
id
name
brand
type
# ... other fields
barcode {
code
type
scannedDate
}
createdAt
updatedAt
}
}

The frontend sends barcode data in the following format:

{
barcode: {
code: "012345678901",
type: "UPC",
scannedDate: "2026-01-30T23:43:24.000Z" // ISO string, optional
}
}

Location: shaker/lib/inventory/add-product/formValidation.ts - prepareMutationData() function

The frontend expects barcode data in the following format:

{
barcode: {
code: string;
type: "UPC" | "EAN" | "QR" | "CODE128";
scannedDate?: string; // ISO date string, optional
}
}

Location: shaker/graphql/fragments/_Product.graphql - ProductFields fragment

  • prepareMutationData formats barcode as ProductBarcode object
  • CreateProduct.graphql mutation includes barcode in response
  • ProductFields fragment includes barcode with code, type, scannedDate
  • TypeScript types match GraphQL structure
  • GraphQL schema includes ProductBarcode type
  • GraphQL schema includes BarcodeType enum
  • CreateProductInput accepts ProductBarcodeInput
  • createProduct mutation returns barcode field
  • Backend validates barcode type enum values
  • Backend stores scannedDate when provided
  • Backend handles optional barcode field correctly
  • ✅ Frontend: prepareMutationData formats barcode correctly
  • ✅ Frontend: Barcode type mapping utility tested
  • ⏳ Backend: GraphQL schema validation
  • ⏳ Backend: Mutation resolver handles ProductBarcode
  • ⏳ End-to-end: Scan barcode → Create product → Verify barcode stored
  • ⏳ End-to-end: Create product with manual barcode entry
  • ⏳ End-to-end: Query product → Verify barcode returned correctly

If the backend currently stores barcode as a string:

  1. Backward Compatibility: Backend should accept both formats during migration:

    • Old: barcode: String (deprecated)
    • New: barcode: ProductBarcodeInput (preferred)
  2. Data Migration: Existing products with string barcodes should be migrated:

    // Migration logic
    if (typeof product.barcode === 'string') {
    product.barcode = {
    code: product.barcode,
    type: 'UPC', // Default for legacy data
    scannedDate: undefined
    };
    }
  3. Frontend Compatibility: Frontend already handles both:

    • Products with barcode: ProductBarcode object
    • Products with barcode: undefined (no barcode)

If backend receives invalid barcode type, it should:

  • Return GraphQL validation error
  • Error message: "Invalid barcode type. Must be one of: UPC, EAN, QR, CODE128"

If backend receives invalid barcode code format:

  • For numeric types (UPC, EAN, CODE128): Validate digits only
  • For QR: Accept any non-empty string
  • Return GraphQL validation error with specific message
mutation {
createProduct(input: {
name: "Tito's Vodka"
productType: SPIRIT
volume: 750
unit: ML
currentLevel: 750
barcode: {
code: "012345678901"
type: UPC
scannedDate: "2026-01-30T23:43:24.000Z"
}
}) {
id
name
barcode {
code
type
scannedDate
}
}
}
query {
product(id: "product-123") {
id
name
barcode {
code
type
scannedDate
}
}
}
  • Frontend Mutation: shaker/graphql/mutations/CreateProduct.graphql
  • Frontend Fragment: shaker/graphql/fragments/_Product.graphql
  • Frontend Data Prep: shaker/lib/inventory/add-product/formValidation.ts
  • TypeScript Types: shaker/types/product.ts
  • Implementation Docs: scan-bottle-to-add-missing-implementation.md

Last Updated: 2026-01-30
Status: Frontend implementation complete, backend verification pending