supacommerce

Schema

All 14 Drizzle schema files copied into your project by the CLI.

Schema

supacommerce gives you 14 Drizzle ORM schema files covering the full ecommerce domain. Every file is plain TypeScript — read it, modify it, delete what you don't need.

All schemas live at src/ecommerce/schema/ after running npx @supacommerce/cli init.

currencies

File: currencies.ts

The foundation of your store. Everything else references a currency code. Set this up first.

ColumnTypeNotes
codevarchar(3)Primary key — ISO 4217 code, e.g. USD, ZAR, GBP
namevarchar(100)Human-readable name, e.g. US Dollar
symbolvarchar(10)Display symbol, e.g. $, £
includes_decimalbooleanfalse for zero-decimal currencies like JPY, KRW

Note: the primary key is code, not a UUID. This affects how you configure the react-admin dataProvider — see Examples.

regions

File: regions.ts

A region groups countries under a common currency. This is the primary way to support multi-currency storefronts.

regions

ColumnTypeNotes
iduuidPrimary key
namevarchar(255)e.g. North America, Europe
currency_codevarchar(3)FK → currencies.code
tax_ratevarchar(10)Display-only legacy field. Use tax_regions/tax_rates for actual tax calculation.
tax_includedbooleanWhether prices are tax-inclusive (e.g. VAT in EU)
is_activeboolean

countries

ColumnTypeNotes
iduuidPrimary key
region_iduuidFK → regions.id CASCADE
iso2varchar(2)ISO 3166-1 alpha-2, e.g. US, GB — unique
iso3varchar(3)ISO 3166-1 alpha-3, e.g. USA, GBR
namevarchar(100)
display_namevarchar(100)

customers

File: customers.ts

customers

Linked to a Supabase auth user via user_id.

ColumnTypeNotes
iduuidPrimary key
user_iduuidFK → auth.users.id — unique
emailvarchar(255)Unique
first_namevarchar(100)
last_namevarchar(100)
phonevarchar(30)
group_iduuidFK → customer_groups.id — optional
metadatajsonb

customer_groups

Used for price list targeting and promotion rules.

customer_addresses

Saved addresses for a customer. is_default marks the primary address.

catalog

File: catalog.ts

The largest schema. Products, variants, options, categories, collections, tags, and images.

products

ColumnTypeNotes
iduuidPrimary key
titlevarchar(255)
handlevarchar(255)URL slug — unique, indexed
statusproduct_statusdraft, published, archived
thumbnailtextURL — lives on the product, not on variants
discountablebooleanWhether promotions apply to this product
metadatajsonb

product_variants

A specific purchasable combination — e.g. Blue / Large.

ColumnTypeNotes
iduuidPrimary key
product_iduuidFK → products.id CASCADE
titlevarchar(255)
skuvarchar(100)Unique
weightintegerGrams
length / height / widthintegerCentimetres
allow_backorderboolean
manage_inventoryboolean
rankintegerDisplay order

Prices are not stored on variants — they live in the pricing schema and are resolved per-region via price_sets.

Thumbnails are not stored on variants — they live on the parent products record.

product_options / product_option_values

Option types (e.g. Size, Color) and their values (e.g. Small, Red).

product_variant_option_values

Junction table linking variants to their option values.

product_categories

Hierarchical categories via self-referencing parent_id. e.g. Clothing > Mens > Jackets.

product_collections

Flat curated groupings — Summer Drop, Best Sellers, etc.

product_tags

Free-form tags. Many-to-many with products via product_tag_products.

product_images

ColumnTypeNotes
iduuidPrimary key
product_iduuidFK → products.id CASCADE
urltextPublic URL from Supabase Storage
altvarchar(255)
rankintegerDisplay order

inventory

File: inventory.ts

stock_locations

Physical or virtual locations where inventory is held.

inventory_items

One inventory item per variant. Tracks whether inventory is managed for that variant.

inventory_levels

Stock quantities per location. quantity_available is decremented when reservations are created.

ColumnTypeNotes
inventory_item_iduuidFK → inventory_items.id
location_iduuidFK → stock_locations.id
stocked_quantityintegerTotal stock
reserved_quantityintegerHeld by pending reservations
quantity_availableintegerstocked - reserved

inventory_reservations

Soft holds created by cart-checkout before payment is captured. Released on payment failure, confirmed on payment success.

StatusDescription
pendingCreated at checkout, awaiting payment
confirmedPayment captured — stock permanently decremented
releasedPayment failed — stock restored

pricing

File: pricing.ts

price_sets

One price set per variant. A price set is a container for all the prices of a variant across currencies and regions.

prices

ColumnTypeNotes
price_set_iduuidFK → price_sets.id CASCADE
currency_codevarchar(3)FK → currencies.code
region_iduuidFK → regions.id — optional
amountintegerInteger in smallest currency unit
min_quantityintegerFor volume/tiered pricing
max_quantityintegerFor volume/tiered pricing

Price resolution priority: region + currencyregion onlycurrency only.

price_lists

Overriding prices for a specific context — a sale event, a VIP customer group, a B2B contract.

TypeBehaviour
saleApplied on top of regular prices
overrideCompletely replaces regular prices

price_list_prices

The actual override prices within a price list. Linked directly to variants.

price_list_customer_groups

Restricts a price list to specific customer groups. If no groups are linked, the price list applies to all customers.

promotions

File: promotions.ts

promotions

ColumnTypeNotes
codevarchar(100)Promotion code — null for automatic promotions
typepromotion_typepercentage, fixed_amount, free_shipping, buy_x_get_y
valueintegerPercent (e.g. 15) or amount in cents
is_automaticbooleanApplied automatically without a code
is_case_insensitivebooleanWhether code matching is case-insensitive
usage_limitintegerGlobal usage cap — null for unlimited
usage_countintegerIncremented atomically by increment_promotion_usage RPC
usage_limit_per_customerintegerPer-customer cap
starts_at / ends_attimestampValidity window

Note: buy_x_get_y is defined in the schema but not yet implemented in cart-checkout.

promotion_rules

Rules that must pass for the promotion to apply.

TypeValueBehaviour
cart_totalMinimum subtotal in centsPromotion only applies if cart subtotal >= value
customer_groupCustomer group IDPromotion only applies to customers in that group

promotion_usages

Audit log of which customer used which promotion on which order.

tax

File: tax.ts

tax_regions

A tax region maps a country (and optionally a province) to a set of tax rates.

ColumnTypeNotes
country_codevarchar(2)ISO 3166-1 alpha-2
province_codevarchar(10)Optional — province-specific rates take precedence

tax_rates

ColumnTypeNotes
ratenumericDecimal rate, e.g. 0.15 for 15%
is_defaultbooleanThe default rate for the tax region
namevarchar(100)e.g. VAT, GST

Tax calculation in cart-checkout matches by country_code first, then prefers a province_code match if available.

fulfillment

File: fulfillment.ts

shipping_profiles

Groups of products that share the same shipping rules.

fulfillment_providers

External fulfillment providers. is_installed controls visibility.

shipping_options

Available shipping methods shown to customers at checkout.

ColumnTypeNotes
price_typeshipping_price_typeflat_rate or calculated
amountintegerFlat rate amount in smallest currency unit
min_subtotalintegerOnly shown if cart subtotal >= this value
is_activeboolean

cart

File: cart.ts

carts

ColumnTypeNotes
customer_iduuidFK → customers.id CASCADE — anonymous customers supported
statuscart_statusactive, completed, abandoned
shipping_addressjsonbAddress snapshot
billing_addressjsonbAddress snapshot
promotion_codesjsonbArray of applied promotion code strings
subtotal / tax_total / shipping_total / discount_total / totalintegerWritten by checkout_cart RPC at completion. Do not read these for pre-checkout display — use commerce.cart.get() instead which computes totals live from line items.

cart_line_items

ColumnTypeNotes
variant_iduuidFK → product_variants.id SET NULL on delete
product_iduuidFK → products.id SET NULL on delete
title / subtitle / thumbnailSnapshotted at time of add — survives product deletion
unit_priceintegerSnapshotted at time of add — price changes don't affect open carts
subtotalintegerunit_price * quantity

cart_shipping_methods

The selected shipping method. price is snapshotted at time of selection.

orders

File: orders.ts

orders

Created by checkout_cart RPC. Immutable from the customer's perspective after creation.

ColumnTypeNotes
display_idintegerAuto-incrementing human-readable order number
statusorder_statuspending, processing, completed, cancelled, requires_action
payment_statusorder_payment_statuspending, captured, refunded, etc.
fulfillment_statusorder_fulfillment_statusnot_fulfilled, fulfilled, shipped, etc.
shipping_address / billing_addressjsonbAddress snapshots at time of checkout

order_line_items

Copied from cart_line_items at checkout. variant_id and product_id use SET NULL on delete — the historical record survives product deletion because title and price are snapshotted.

order_fulfillments

Records physical dispatch of items. One order can have multiple fulfillments.

order_returns / order_return_items

Return requests from customers.

order_refunds

Refund records. reason is one of discount, return, swap, claim, other.

payments

File: payments.ts

payment_collections

One payment collection per order. Tracks overall payment status and captured amount.

payment_sessions

One session per payment attempt. provider_session_id links to the external provider (e.g. Stripe PaymentIntent ID). data stores provider-specific data returned to the client (e.g. clientSecret).

sales_channels

File: sales_channels.ts

Sales channels allow you to control which products are available in which context — e.g. web, mobile, B2B.

admin_users

File: admin_users.ts

admin_users

ColumnTypeNotes
user_iduuidFK → auth.users.id — unique
roleadmin_roleadmin, manager, support
is_activebooleanDeactivated admins lose access immediately

admin_invitations

New admins are onboarded via invitation only — there is no direct create flow. The invitation stores a token and expires_at. The admin-send-invite edge function emails the invite link, and admin-accept-invite handles redemption.

On this page