Skip to main content

Overview

Openfront’s data layer is powered by 88 KeystoneJS models organized into logical domains. Each model is defined declaratively and automatically generates GraphQL queries, mutations, and database tables.
All models are located in features/keystone/models/ and exported from features/keystone/models/index.ts.

Model Categories

Core E-Commerce Models

Product Models

The main product model representing items in your catalog.Key Fields:
  • title (text, required) - Product name
  • handle (text, unique) - URL-friendly slug
  • description (document) - Rich text description
  • status (enum) - draft | proposed | published | rejected
  • isGiftcard (boolean) - Whether this is a gift card product
  • discountable (boolean) - Whether discounts can be applied
Relationships:
  • productVariants → ProductVariant (one-to-many)
  • productImages → ProductImage (many-to-many)
  • productCollections → ProductCollection (many-to-many)
  • productCategories → ProductCategory (many-to-many)
  • productTags → ProductTag (many-to-many)
  • productType → ProductType
  • shippingProfile → ShippingProfile
Virtual Fields:
  • thumbnail - First product image URL
  • dimensionsRange - Min/max dimensions from variants
  • defaultDimensions - Default variant dimensions
Example:
query {
  products(where: { status: { equals: "published" } }) {
    id
    title
    handle
    thumbnail
    productVariants {
      id
      title
      sku
    }
  }
}
Product variations (size, color, etc.) with separate SKUs and pricing.Key Fields:
  • title (text) - Variant name (e.g., “Large / Blue”)
  • sku (text, unique) - Stock keeping unit
  • barcode (text) - UPC/EAN barcode
  • inventoryQuantity (integer) - Stock on hand
  • allowBackorder (boolean) - Allow orders when out of stock
  • manageInventory (boolean) - Track inventory for this variant
Relationships:
  • product → Product (required)
  • productOptionValues → ProductOptionValue (many-to-many)
  • moneyAmounts → MoneyAmount (one-to-many)
  • measurements → Measurement (one-to-many)
Virtual Fields:
  • formattedPrice - Formatted price string
  • inStock - Whether variant has inventory
Product images with S3 storage integration.Key Fields:
  • image (image) - S3-stored image
  • altText (text) - Accessibility description
  • imagePath (text) - External image URL
Relationships:
  • products → Product (many-to-many)
Product groupings for merchandising and organization.Key Fields:
  • title (text, required)
  • handle (text, unique)
  • metadata (json)
Relationships:
  • products → Product (many-to-many)
Hierarchical product categorization.Key Fields:
  • name (text, required)
  • handle (text, unique)
  • isActive (boolean)
  • isInternal (boolean)
Relationships:
  • products → Product (many-to-many)
  • parent → ProductCategory (self-referencing)
Multi-currency pricing for product variants.Key Fields:
  • amount (integer) - Price in smallest currency unit (cents)
  • minQuantity (integer) - Minimum order quantity
  • maxQuantity (integer) - Maximum order quantity
Relationships:
  • productVariant → ProductVariant
  • region → Region
  • currency → Currency
  • priceList → PriceList
Virtual Fields:
  • calculatedPrice - Final price after rules and lists

Order Models

Customer orders with complete lifecycle management.Key Fields:
  • displayId (integer, required) - Human-readable order number
  • email (text, required) - Customer email
  • status (enum) - pending | completed | archived | canceled | requires_action
  • taxRate (float) - Applied tax rate
  • canceledAt (timestamp) - Cancellation date
  • secretKey (text, auto-generated) - Order verification key
Relationships:
  • user → User - Customer who placed the order
  • cart → Cart - Original shopping cart
  • lineItems → OrderLineItem (one-to-many)
  • shippingAddress → Address
  • billingAddress → Address
  • region → Region
  • currency → Currency
  • payments → Payment (one-to-many)
  • fulfillments → Fulfillment (one-to-many)
  • returns → Return (one-to-many)
  • discounts → Discount (many-to-many)
  • events → OrderEvent (one-to-many)
Virtual Fields:
  • subtotal - Formatted subtotal
  • shipping - Formatted shipping cost
  • discount - Formatted discount amount
  • tax - Formatted tax amount
  • total - Formatted total price
  • rawTotal - Numeric total (in cents)
  • fulfillmentStatus - Fulfillment progress
  • paymentDetails - Payment information
  • unfulfilled - Items not yet fulfilled
Hooks:
  • afterOperation - Sends order confirmation email on creation
  • beforeOperation - Creates order events for status changes
Example:
query {
  orders(
    where: { status: { equals: "pending" } }
    orderBy: { createdAt: desc }
  ) {
    id
    displayId
    email
    total
    subtotal
    fulfillmentStatus
    lineItems {
      id
      title
      quantity
      formattedTotal
    }
  }
}
Shopping cart with automatic calculations.Key Fields:
  • email (text) - Guest checkout email
  • type (enum) - default | swap | draft_order | payment_link | claim
  • metadata (json) - Custom data
  • context (json) - Session context
  • abandonedEmailSent (boolean) - Abandoned cart tracking
Relationships:
  • user → User (optional for guest carts)
  • region → Region (required)
  • lineItems → LineItem (one-to-many)
  • shippingAddress → Address
  • billingAddress → Address
  • shippingMethods → ShippingMethod (one-to-many)
  • discounts → Discount (many-to-many)
  • paymentCollection → PaymentCollection
  • order → Order (when completed)
Virtual Fields:
  • subtotal - Formatted subtotal
  • total - Formatted total with tax and shipping
  • rawTotal - Numeric total (in cents)
  • discount - Applied discount amount
  • tax - Calculated tax
  • shipping - Shipping cost
  • checkoutStep - Current checkout step (cart | address | delivery | payment | review)
  • status - ACTIVE | COMPLETED
Hooks:
  • beforeOperation - Auto-assigns user, handles region changes
Example:
mutation AddToCart {
  addToCart(
    cartId: "..."
    variantId: "..."
    quantity: 2
  ) {
    id
    subtotal
    total
    lineItems {
      id
      title
      quantity
    }
  }
}
Cart line items with quantity and pricing.Key Fields:
  • title (text, required) - Product title (snapshot)
  • quantity (integer, required) - Item quantity
  • sku (text) - SKU at time of add to cart
  • thumbnail (text) - Product image URL
  • variantTitle (text) - Variant name
  • fulfillQuantity (integer) - Quantity fulfilled
  • returnedQuantity (integer) - Quantity returned
Relationships:
  • cart → Cart
  • productVariant → ProductVariant
  • order → Order (when cart is completed)
Virtual Fields:
  • formattedUnitPrice - Formatted price per unit
  • formattedTotal - Formatted line total
Order-specific line items (created from cart line items).Key Fields:
  • title (text, required)
  • quantity (integer, required)
  • sku (text)
  • variantTitle (text)
  • productData (json) - Product snapshot
  • variantData (json) - Variant snapshot
Relationships:
  • order → Order
  • moneyAmount → OrderMoneyAmount
  • fulfillmentItems → FulfillmentItem (one-to-many)

Customer Models

Customer and admin user accounts.Key Fields:
  • name (text, required) - Full name
  • email (text, unique, required) - Email address
  • password (password, required) - Hashed password
  • phone (text) - Phone number
  • hasAccount (boolean) - Whether user has account access
  • customerToken (text, unique) - API token for customer
  • onboardingStatus (enum) - not_started | in_progress | completed | dismissed
Relationships:
  • role → Role - Permission role
  • addresses → Address (one-to-many)
  • orders → Order (one-to-many)
  • carts → Cart (one-to-many)
  • customerGroups → CustomerGroup (many-to-many)
  • accounts → Account (one-to-many) - Business accounts
  • apiKeys → ApiKey (one-to-many)
Virtual Fields:
  • firstName - Extracted first name
  • lastName - Extracted last name
  • activeCartId - Most recent active cart ID
  • billingAddress - Primary billing address
Example:
query {
  user(where: { id: "..." }) {
    id
    name
    email
    firstName
    lastName
    activeCartId
    addresses {
      id
      address1
      city
      country { displayName }
    }
  }
}
Shipping and billing addresses.Key Fields:
  • firstName (text)
  • lastName (text)
  • company (text)
  • address1 (text, required)
  • address2 (text)
  • city (text, required)
  • province (text) - State/province
  • postalCode (text, required)
  • phone (text)
  • isBilling (boolean)
  • isShipping (boolean)
Relationships:
  • user → User
  • country → Country (required)
  • ordersUsingAsShippingAddress → Order (one-to-many)
  • ordersUsingAsBillingAddress → Order (one-to-many)
Virtual Fields:
  • formattedAddress - Full formatted address string
Customer segmentation for targeted pricing and discounts.Key Fields:
  • name (text, required)
  • metadata (json)
Relationships:
  • users → User (many-to-many)
  • priceLists → PriceList (many-to-many)

Payment & Billing Models

Payment records for orders.Key Fields:
  • status (enum) - pending | authorized | captured | failed | canceled
  • amount (integer, required) - Amount in cents
  • currencyCode (text, required)
  • amountRefunded (integer) - Total refunded
  • data (json) - Provider-specific data
  • capturedAt (timestamp)
  • canceledAt (timestamp)
Relationships:
  • order → Order
  • cart → Cart
  • currency → Currency
  • user → User
  • captures → Capture (one-to-many)
  • refunds → Refund (one-to-many)
  • paymentCollection → PaymentCollection
Virtual Fields:
  • paymentLink - Link to payment provider dashboard (Stripe/PayPal)
Hooks:
  • beforeOperation - Creates order events and capture records
Payment integration configuration (Stripe, PayPal, etc.).Key Fields:
  • name (text, required) - Provider name
  • code (text, unique, required) - Must start with “pp_”
  • isInstalled (boolean) - Whether provider is active
  • credentials (json) - API keys and secrets
  • createPaymentFunction (text) - Adapter function name
  • capturePaymentFunction (text) - Adapter function name
  • refundPaymentFunction (text) - Adapter function name
  • handleWebhookFunction (text) - Webhook handler name
Relationships:
  • regions → Region (many-to-many)
  • sessions → PaymentSession (one-to-many)
Example:
// Payment provider adapter implementation
const paymentResult = await paymentProviderAdapter.createPaymentFunction({
  cart,
  amount: cart.total,
  currency: cart.currency.code,
  customer: cart.customer
});
Temporary payment sessions during checkout.Key Fields:
  • amount (integer) - Session amount
  • status (enum) - pending | authorized | requires_more
  • isSelected (boolean) - Currently selected payment method
  • data (json) - Session data from provider
Relationships:
  • paymentProvider → PaymentProvider
  • paymentCollection → PaymentCollection
Collection of payment sessions for a checkout.Key Fields:
  • amount (integer, required)
  • currencyCode (text, required)
  • status (enum) - not_paid | awaiting | authorized | partially_authorized | canceled
Relationships:
  • cart → Cart
  • region → Region
  • paymentSessions → PaymentSession (one-to-many)
  • payments → Payment (one-to-many)

Fulfillment & Shipping Models

Order fulfillment records.Key Fields:
  • canceledAt (timestamp)
  • shippedAt (timestamp)
  • metadata (json)
Relationships:
  • order → Order
  • fulfillmentItems → FulfillmentItem (one-to-many)
  • shippingLabels → ShippingLabel (one-to-many)
  • location → Location - Fulfillment warehouse
Selected shipping method for cart/order.Key Fields:
  • price (integer) - Shipping cost in cents
  • data (json) - Method details
Relationships:
  • shippingOption → ShippingOption
  • cart → Cart
  • order → Order
Shipping labels from providers (Shippo, ShipEngine).Key Fields:
  • trackingNumber (text)
  • trackingUrl (text)
  • labelUrl (text) - PDF label URL
  • carrier (text) - USPS, FedEx, UPS, etc.
  • service (text) - Service level
  • rate (integer) - Actual shipping cost
Relationships:
  • fulfillment → Fulfillment
  • order → Order
Shipping integration configuration.Key Fields:
  • name (text, required)
  • code (text, unique) - Must start with “sp_”
  • isInstalled (boolean)
  • credentials (json)
  • getRatesFunction (text) - Adapter function
  • createLabelFunction (text) - Adapter function
  • validateAddressFunction (text) - Adapter function
Relationships:
  • shippingOptions → ShippingOption (one-to-many)

Discount & Promotion Models

Discount codes and automatic promotions.Key Fields:
  • code (text, unique) - Discount code (e.g., “SUMMER20”)
  • isDynamic (boolean) - Auto-generated codes
  • isDisabled (boolean)
  • startsAt (timestamp)
  • endsAt (timestamp)
  • usageLimit (integer)
  • usageCount (integer)
Relationships:
  • discountRule → DiscountRule - Discount logic
  • regions → Region (many-to-many)
  • carts → Cart (many-to-many)
  • orders → Order (many-to-many)
Discount calculation logic.Key Fields:
  • type (enum) - percentage | fixed | free_shipping
  • value (float) - Discount value (percentage or amount)
  • allocation (enum) - total | item
Relationships:
  • discount → Discount
  • discountConditions → DiscountCondition (one-to-many)
  • products → Product (many-to-many) - Direct product targeting
Conditions for discount application.Key Fields:
  • type (enum) - products | product_types | product_collections | product_tags | customer_groups
  • operator (enum) - in | not_in
Relationships:
  • discountRule → DiscountRule
  • products → Product (many-to-many)
  • productTypes → ProductType (many-to-many)
  • productCollections → ProductCollection (many-to-many)
  • productTags → ProductTag (many-to-many)
  • customerGroups → CustomerGroup (many-to-many)
Gift cards with balance tracking.Key Fields:
  • code (text, unique) - Gift card code
  • value (integer) - Original value in cents
  • `balance” (integer) - Remaining balance
  • isDisabled (boolean)
  • endsAt (timestamp)
Relationships:
  • region → Region
  • `order” → Order - Purchase order
  • carts → Cart (many-to-many)
  • transactions → GiftCardTransaction (one-to-many)

Returns & Claims Models

Customer return requests.Key Fields:
  • status (enum) - requested | received | requires_action | canceled
  • `refundAmount” (integer)
  • `receivedAt” (timestamp)
Relationships:
  • order → Order
  • returnItems → ReturnItem (one-to-many)
  • `shippingMethod” → ShippingMethod
Order claims for damaged/missing items.Key Fields:
  • type (enum) - refund | replace
  • status (enum) - pending | accepted | rejected
  • `refundAmount” (integer)
Relationships:
  • order → Order
  • claimItems → ClaimItem (one-to-many)
  • `additionalItems” → LineItem (one-to-many) - Replacement items

Regional & Localization Models

Multi-regional commerce support.Key Fields:
  • name (text, required) - Region name (e.g., “North America”)
  • `currencyCode” (text, required)
  • `taxRate” (float) - Default tax rate
  • `taxCode” (text) - Tax jurisdiction code
  • `giftCardsTaxable” (boolean)
  • `automaticTaxes” (boolean)
Relationships:
  • currency → Currency
  • countries → Country (many-to-many)
  • `paymentProviders” → PaymentProvider (many-to-many)
  • `fulfillmentProviders” → FulfillmentProvider (many-to-many)
  • `taxRates” → TaxRate (one-to-many)
Supported countries.Key Fields:
  • iso2 (text, unique) - ISO 3166-1 alpha-2 code
  • iso3 (text, unique) - ISO 3166-1 alpha-3 code
  • `numCode” (integer) - ISO numeric code
  • `name” (text, required) - Country name
  • `displayName” (text, required) - Localized display name
Relationships:
  • regions → Region (many-to-many)
Multi-currency support.Key Fields:
  • code (text, unique) - ISO 4217 code (USD, EUR, etc.)
  • `symbol” (text) - Currency symbol ($, €, etc.)
  • `symbolNative” (text) - Native symbol
  • `name” (text) - Currency name
  • `noDivisionCurrency” (boolean) - No decimal places (JPY, KRW)
Relationships:
  • regions → Region (one-to-many)
  • `moneyAmounts” → MoneyAmount (one-to-many)

Authentication & Authorization Models

Role-based access control.Key Fields: All permission fields (boolean):
  • canAccessDashboard
  • canManageProducts
  • canManageOrders
  • canManageUsers
  • canManagePayments
  • … and 20+ more permissions
Relationships:
  • assignedTo → User (one-to-many)
API keys for programmatic access.Key Fields:
  • name (text, required) - Descriptive name
  • `tokenSecret” (password, required) - Hashed token
  • `tokenPreview” (text) - First/last chars for display
  • `scopes” (json) - Array of permission scopes
  • `status” (enum) - active | inactive | revoked
  • `expiresAt” (timestamp)
  • `lastUsedAt” (timestamp)
  • `usageCount” (json) - Total and daily usage stats
  • `restrictedToIPs” (json) - IP whitelist
Relationships:
  • user → User
Available Scopes:
  • read_products, write_products
  • read_orders, write_orders
  • read_customers, write_customers
  • read_fulfillments, write_fulfillments
  • … and more (see features/keystone/models/ApiKey.ts:15)
Third-party app integrations.Key Fields:
  • name (text, required)
  • `clientId” (text, unique) - OAuth client ID
  • `clientSecret” (password) - OAuth secret
  • `redirectUris” (json) - Allowed redirect URIs
  • `scopes” (json) - Allowed scopes
  • `status” (enum) - active | inactive | suspended
Relationships:
  • tokens → OAuthToken (one-to-many)
OAuth access and refresh tokens.Key Fields:
  • tokenType (enum) - authorization_code | access_token | refresh_token
  • `token” (text, unique)
  • `clientId” (text)
  • `scopes” (json)
  • `expiresAt” (timestamp)
  • `isRevoked” (enum) - false | true
Relationships:
  • user → User

Business Account Models

Business accounts for B2B commerce.Key Fields:
  • `accountType” (enum) - business | personal
  • `status” (enum) - active | inactive | suspended
  • `creditLimit” (integer) - Maximum credit allowed
  • `availableCredit” (integer) - Remaining credit
  • `paymentTerms” (text) - Net 30, Net 60, etc.
Relationships:
  • user → User
  • `orders” → Order (one-to-many)
  • `invoices” → Invoice (one-to-many)
Invoices for business accounts.Key Fields:
  • `invoiceNumber” (text, unique)
  • `status” (enum) - draft | sent | paid | overdue | canceled
  • `subtotal” (integer)
  • `total” (integer)
  • `amountPaid” (integer)
  • `dueDate” (timestamp)
Relationships:
  • account → Account
  • `user” → User
  • `lineItems” → InvoiceLineItem (one-to-many)

Webhook & Event Models

Webhook endpoint configuration.Key Fields:
  • url (text, required) - Webhook URL
  • `events” (json) - Array of subscribed events
  • `isActive” (boolean)
  • `secret” (text) - Signature secret
Relationships:
  • webhookEvents → WebhookEvent (one-to-many)
Webhook delivery log.Key Fields:
  • event (text) - Event type
  • `payload” (json) - Event data
  • `status” (enum) - pending | sent | failed
  • `attempts” (integer)
  • `response” (json) - Response from endpoint
Relationships:
  • webhookEndpoint → WebhookEndpoint
Order activity timeline.Key Fields:
  • type (text) - Event type (STATUS_CHANGE, PAYMENT_CAPTURED, etc.)
  • `data” (json) - Event details
Relationships:
  • order → Order
  • `user” → User - Who triggered the event
Common Event Types:
  • STATUS_CHANGE - Order status updated
  • PAYMENT_CAPTURED - Payment processed
  • TRACKING_NUMBER_ADDED - Shipping label created
  • RETURN_REQUESTED - Return initiated
  • REFUND_PROCESSED - Refund completed

Complete Model List

All 88 models exported from features/keystone/models/index.ts:
Product Domain (11 models)
  • Product
  • ProductVariant
  • ProductImage
  • ProductCollection
  • ProductCategory
  • ProductOption
  • ProductOptionValue
  • ProductTag
  • ProductType
  • MoneyAmount
  • PriceList
Order Domain (12 models)
  • Order
  • OrderLineItem
  • OrderMoneyAmount
  • OrderEvent
  • Cart
  • LineItem
  • LineItemAdjustment
  • LineItemTaxLine
  • DraftOrder
  • Swap
  • IdempotencyKey
  • Note
Customer Domain (6 models)
  • User
  • UserField
  • Address
  • CustomerGroup
  • Team
  • Invite
Payment Domain (9 models)
  • Payment
  • PaymentProvider
  • PaymentSession
  • PaymentCollection
  • Capture
  • Refund
  • Account
  • AccountLineItem
  • Invoice
  • InvoiceLineItem
  • BusinessAccountRequest
Fulfillment Domain (11 models)
  • Fulfillment
  • FulfillmentItem
  • FulfillmentProvider
  • ShippingMethod
  • ShippingMethodTaxLine
  • ShippingOption
  • ShippingOptionRequirement
  • ShippingProfile
  • ShippingProvider
  • ShippingLabel
  • Location
  • StockMovement
  • Measurement
Discount Domain (9 models)
  • Discount
  • DiscountRule
  • DiscountCondition
  • GiftCard
  • GiftCardTransaction
  • ClaimOrder
  • ClaimItem
  • ClaimImage
  • ClaimTag
  • Return
  • ReturnItem
  • ReturnReason
Regional Domain (6 models)
  • Region
  • Country
  • Currency
  • TaxRate
  • TaxProvider
  • SalesChannel
Integration Domain (11 models)
  • ApiKey
  • OAuthApp
  • OAuthToken
  • WebhookEndpoint
  • WebhookEvent
  • NotificationProvider
  • Notification
  • BatchJob
  • PriceRule
  • PriceSet
  • RuleType
Configuration (2 models)
  • Store
  • Role
  • CustomShippingOption

Model Relationships Diagram

Working with Models

Querying Models

# Get product with relationships
query GetProduct($id: ID!) {
  product(where: { id: $id }) {
    id
    title
    handle
    status
    productVariants {
      id
      title
      sku
      inventoryQuantity
      moneyAmounts(where: { 
        region: { id: { equals: "region_id" } } 
      }) {
        amount
        currency { code }
      }
    }
    productImages {
      image { url }
      altText
    }
  }
}

Creating Records

mutation CreateProduct {
  createProduct(
    data: {
      title: "New Product"
      handle: "new-product"
      status: "draft"
      productVariants: {
        create: [
          {
            title: "Default"
            sku: "NEW-001"
            inventoryQuantity: 100
          }
        ]
      }
    }
  ) {
    id
    title
  }
}

Using Virtual Fields

query GetCart($id: ID!) {
  cart(where: { id: $id }) {
    id
    subtotal        # Virtual field
    discount        # Virtual field
    shipping        # Virtual field
    tax             # Virtual field
    total           # Virtual field
    checkoutStep    # Virtual field
    lineItems {
      id
      title
      quantity
    }
  }
}

Next Steps

Architecture

Learn about the overall system architecture

Authentication

Understand auth models and security

GraphQL API

Explore the complete API reference

Custom Mutations

Build custom business logic

Build docs developers (and LLMs) love