Vape architecture and workflows
Keystone schema by domain, the go-live release gate, product publication, checkout evidence, fulfillment, safety stop, reporting, GraphQL operations, and access control.
Application surfaces
| Surface | Location | Notes |
|---|---|---|
| Storefront | app/(storefront)/[countryCode]/**, features/storefront | Age gate, catalog, bag, checkout with compliance panel, account |
| Operator dashboard | app/dashboard/(admin)/platform/**, features/platform | Vape and retail workspaces inside the shared shell |
| Generic model pages | app/dashboard/(admin)/[listKey]/**, features/dashboard | Keystone list and item screens for lists without a dedicated page |
| GraphQL | /api/graphql | Keystone CRUD (where access allows) plus custom queries and mutations |
| Other HTTP | /api/payment-webhooks/[providerId], /api/oauth/*, /api/mcp-transport/[transport], /api/completion | Payment webhooks, OAuth apps, MCP tools, dashboard AI chat |
Schema by domain
Catalog. Product (status draft / proposed / published / rejected, regulatedCommerceRequired defaulting to true, exemption fields), ProductVariant (SKU, barcodes, inventory, one-to-one regulatedClassification), ProductImage, ProductOption, ProductOptionValue, ProductCategory, ProductCollection, ProductTag, ProductType, Measurement, StockMovement, Location.
Pricing and markets. MoneyAmount, PriceList, PriceSet, PriceRule, RuleType, CustomerGroup, Region, Country, Currency, TaxRate, TaxProvider, Discount, DiscountRule, DiscountCondition, GiftCard, GiftCardTransaction.
Carts, orders, and fulfillment. Cart, LineItem, LineItemAdjustment, ShippingMethod, Order (GraphQL create/update/delete disabled; changed only through custom mutations), OrderLineItem, OrderEvent, DraftOrder, Fulfillment, FulfillmentItem, ShippingLabel, Return, ReturnItem, Refund, ClaimOrder, ClaimItem, Swap, IdempotencyKey.
Payments and shipping. PaymentProvider, PaymentCollection, PaymentSession, Payment, Capture, ShippingProvider, ShippingOption, ShippingProfile, FulfillmentProvider.
Customers and accounts. User, Address, Role, Team, Invite, BusinessAccountRequest, Account, AccountLineItem, Invoice, InvoiceLineItem, UserField, Notification.
Regulated authority. Jurisdiction (draft → active → retired), RegulatedRuleSet (draft → approved → active → retired / emergency_disabled; signed policy hash, citations, validated rules JSON), RegulatedMerchantProfile (draft → review → active → suspended / revoked; PACT registration fields, launch jurisdictions, killSwitch defaulting to true), MerchantLicense, ProviderApproval (purpose identity, payment, tax, registry, or carrier; payment and carrier approvals bind to a PaymentProvider or ShippingProvider).
Product evidence. RegulatedProductClassification (one per variant: category, nicotine source and concentration, flavor, volume, marketing review) and ProductAuthorization (federal_marketing_order, preexisting_status, state_directory, local_directory).
Transaction evidence and ledger. AgeVerificationAttempt, RegulatedTaxQuote, CarrierEligibilityDecision, ComplianceDecision (immutable per-cart verdict with snapshot, expiring within five minutes), ComplianceEvent (append-only), ComplianceReportRun.
Platform. ApiKey, OAuthApp, OAuthToken, WebhookEndpoint, WebhookEvent, BatchJob, Note.
Evidence counts as current only between effectiveAt and expiresAt. Nothing expires records on a schedule; lapsed evidence stops counting when it is read. Once a regulated record reaches a usable state, its evidence fields are immutable (validateAuthorityRevision); it can only move to a terminal or suspended state, and a change needs a new revision.
Workflow: go live
regulatedCommerceReadiness reports blockers; releaseBlockers in features/regulated-commerce/core/release-gate.ts is the hard gate on every cart, payment, and checkout step.
- Store business details and all five policies saved in store settings, or the gate returns
STORE_POLICIES_REQUIRED. - One active
RegulatedMerchantProfilewith PACT registration reference and SHA-256 digest, origin jurisdiction, and bounded dates. - The profile's kill switch turned off, or the gate returns
KILL_SWITCH_ENABLED. - At least one active launch
Jurisdictionwith authority sources. - Verified
MerchantLicenserecords where a rule set has alicense_requiredrule. - Exactly one active, approved, signed
RegulatedRuleSetper destination. - Active
ProviderApprovalrecords for identity, payment, tax, carrier, and registry. - At least one approved classification with a current federal authorization.
Only when the gate returns no blockers is transactionMode enabled; otherwise checkout throws "Checkout isn't available for this store yet."
Workflow: product to publish
- Create the product as a draft (a regulated product cannot be created as published).
- Add options, variants, prices, images, and measurements.
- Classify each variant and approve the classification with a reviewer, digest, dates, and approved marketing review.
- Add an authorized federal
ProductAuthorization(authorizedneedslastVerifiedAtand a digest). - Publish.
assertProductPublicationEvidencerequires evidence for every variant, or a current reviewed exemption.
After publishing, customer-facing copy and variant identity edits are refused. Swapping an image, or moving a classification or authorization out of a usable state, moves the product back to draft.
Workflow: checkout
createActiveCart, thenupdateActiveCartLineItem/updateActiveCart; each variant must pass publication evidence, and every cart change revokes prior evidence and open decisions.- Address resolves a destination jurisdiction such as
US-CA. addActiveCartShippingMethodevaluates the cart and requires an allowedCarrierEligibilityDecisionfor that option.- Age verification, committed tax quote, and carrier eligibility must be recorded for the same cart fingerprint (internal functions only; see limitations).
- Payment sessions (
createActiveCartPaymentSessions,setActiveCartPaymentSession,initiatePaymentSession) need an active payment approval covering the destination and categories. evaluateActiveCartCompliancepreviews the decision; the storefront compliance panel shows readable reasons and keeps Place order disabled unless allowed.completeActiveCartpersists acheckoutComplianceDecision, uses anIdempotencyKey, creates theOrder, line items, and payment, and binds the evidence to the order.
Workflow: fulfillment, returns, and orders
getRatesForOrderreturns only the exact approved carrier rate for regulated orders;createProviderShippingLabelneeds an allowing fulfillment decision and order-bound adult-signature carrier evidence. ManualcreateOrderFulfillmentis refused for regulated orders.cancelShippingLabelmust precedecancelOrderFulfillment;trackShipmentreads label status.- Orders move from
pendingtocompletedwhen every line is fulfilled.transitionOrderStatuscancels only fully refunded, unfulfilled orders. processReturnRefundrecords the refund and aregulated.return_refundedevent with reasonTAX_AND_REPORTING_REVERSAL_REVIEW_REQUIRED, shown on the order page.
Workflow: safety stop and reporting
stopRegulatedCommerce(profileId, reason)(needscanOperateComplianceKillSwitch, reason 10 to 500 characters) turns the kill switch on, suspends the active profile, revokes open decisions and unbound carrier allows, and writesmerchant.emergency_stop, in one transaction. Resuming is done on the merchant profile page.exportComplianceInventoryandgenerateComplianceReport(onlyevidence_inventory, period of 93 days at most) createComplianceReportRunrecords;recordComplianceReportSubmissionrecords a filing receipt assubmitted,accepted, orrejected. A generated report is not a jurisdiction filing.
Custom GraphQL operations
Queries: activeCart, activeCartShippingOptions, activeCartPaymentProviders, activeCartRegion, getCustomerOrder, getCustomerOrders, getCustomerAccount, getCustomerAccounts, getUnpaidLineItemsByRegion, getInvoicePaymentSessions, activeInvoice, getCustomerPaidInvoices, getAnalytics, getFinanceClose, getMyPrivacyData, regulatedCommerceReadiness, evaluateActiveCartCompliance, getProductsSortedByPrice, redirectToInit.
Mutations: active-user and address mutations, active-cart mutations (create, update, line items, discounts, shipping method, payment sessions, completeActiveCart), initiatePaymentSession, handlePaymentProviderWebhook, adjustInventory, getRatesForOrder, validateShippingAddress, trackShipment, createProviderShippingLabel, cancelShippingLabel, createOrderFulfillment, cancelOrderFulfillment, transitionOrderStatus, invoice mutations, processReturnRefund, stopRegulatedCommerce, exportComplianceInventory, generateComplianceReport, recordComplianceReportSubmission, retryWebhookDeliveries, registerWebhookEndpoint, updatePrivacyPreferences, requestPrivacyAction.
Access control
Dashboard visibility is not the control. Every list and custom operation checks role permissions on the server.
- Role checkbox permissions (
features/keystone/models/fields.ts,features/keystone/access.ts) decide human sessions. API keys and OAuth tokens need both the credential scope and the owner's role permission. managedComplianceAccess(authority and evidence lists): read with read or manage compliance, create and update withcanManageCompliance, delete denied.immutableComplianceAccess(ledger lists): read with compliance read; create, update, and delete denied and omitted from GraphQL. Only system code writes them.- Evidence digests are never readable; identity fields on
AgeVerificationAttemptneedcanAccessIdentityEvidence. UpdatingkillSwitchneedscanOperateComplianceKillSwitch.