Skip to content

Customer Dashboard — Commerce ​

The Commerce section is the connected storefront/catalog layer: Stores, Inventory, Orders, and Transactions. It lets a customer manage a product catalog, track orders, and record payments — often fed by a Shopify connection. Labels are customer-configurable (a school sees "Branches/Courses/Enrollments" instead of "Stores/Inventory/Orders").

Commerce is a single module gate (FEATURES.COMMERCE). What a team member may do inside is governed by the commerce RBAC resource (view/create/edit/delete).

Screenshots ​

Commerce — storesCommerce — inventoryCommerce — ordersCommerce — transactions

Architecture Overview ​

Every commerce route runs the same four layers (from the crmInventory.routes.ts header): verifyJwt → requireFeatureAccess(commerce) → resolveCommerceScope → requirePermission("commerce", view|create|edit|delete).

How It Works (Step-by-Step) ​

  1. Stores (/stores). List + overview + detail, CRUD, and per-store stock (/stores/:id/stock, transferStock). Stores can be assigned orders/transactions (assignOrderToStore). Shared catalog data scoped by customerUID — no per-record assignment filter. Managing shared store custom fields is manager-only (requireCommerceManager). Backed by CrmStore + CrmStoreStock.
  2. Inventory (/inventory). The product catalog: list with facets, CRUD items, and custom-field definitions. Shared catalog (no per-record assignment). Backed by CrmInventory.
  3. Orders (/orders). Order list + stats + CRUD. Orders carry a per-record visibility scope — a team member sees only orders assigned to them (enforced via forcedAssignedToUID in the service). Managing order custom fields is manager-only. Backed by CrmOrder.
  4. Transactions (/transactions). Payment records. A transaction's visibility follows its order. List + stats + /by-order/:orderId + CRUD. Backed by CrmTransaction.
  5. Shopify feed (optional). When the Shopify connector is on, orders/inventory sync in from a connected store (see CRM Commerce and Shopify Order Calls). Settings in CrmCommerceSettings / ShopifyConnectionConfig.

File Reference ​

FileRoleKey Functions
routes/crmStore.routes.tsStores + stock + assignment + custom fieldslistStores, transferStock, assignOrderToStore
routes/crmInventory.routes.tsCatalog items + facets + custom fieldslistInventory, getInventoryFacets
routes/crmOrder.routes.tsOrders + stats + custom fieldslistOrders, getOrderStats
routes/crmTransaction.routes.tsPayments + by-order lookuplistTransactions, listTransactionsByOrder
middleware/commerceScope.middleware.tsTenant scope + manager checkresolveCommerceScope, requireCommerceManager
controllers/crmCommerceSettings.controller.tsCommerce settings + terminologycommerce settings

Data Model ​

CollectionWhy it existsKey fields
CrmStoreA store/branchcustomerUID, name, config
CrmStoreStockPer-store stock of an inventory itemstoreId, inventoryId, qty
CrmInventoryCatalog itemsku, price, stock, custom fields
CrmOrderAn ordertotal, status, assignedToUID
CrmTransactionA payment against an orderorderId, amount, status
CrmCommerceSettingsTerminology + behaviorentity names, order-call rules

API Endpoints ​

List inventory (+ facets) ​

  • GET /api/inventory / GET /api/inventory/facets · Auth: commerce gate + view.

Create / edit / delete item ​

  • POST /api/inventory (create), PATCH /api/inventory/:id (edit), DELETE /api/inventory/:id (delete).

Orders ​

  • GET /api/orders, GET /api/orders/stats, POST/PATCH/DELETE /api/orders[/:id] (view/create/edit/delete). Custom-field routes are manager-gated.

Transactions ​

  • GET /api/transactions, GET /api/transactions/stats, GET /api/transactions/by-order/:orderId, POST/PATCH/DELETE.

Stores + stock ​

  • GET /api/stores, GET /api/stores/overview, POST /api/stores/:id/stock, POST /api/stores/transfer (transfer stock). Custom-field routes manager-gated.

External Integrations ​

  • Shopify — two-way sync of orders/products; order-confirmation calls can fire on orders/create. See Shopify Order Calls.
  • Payments — transactions may reconcile against the payment system / Razorpay (see Payment System).

How to Test (End-to-End) ​

  1. Grant commerce (+ commerce view/create). Open /inventory; add an item.
  2. Create a Store, then set stock for the item in that store; transfer stock to another store.
  3. Create an Order referencing the item → it appears in /orders and increments GET /api/orders/stats; the Dashboard Commerce card updates.
  4. Record a Transaction against the order → confirm /api/transactions/by-order/:orderId returns it.
  5. As a team member, confirm you only see orders assigned to you (per-record scope).

Troubleshooting ​

SymptomCauseFix
Commerce hiddencommerce module offGrant Commerce
Labels say Stores/Inventory not my termsTerminology not setConfigure terms in Commerce settings (CrmCommerceSettings)
Team member sees no ordersOrders are per-record scopedAssign orders to that member, or give manager scope
Custom-field edit returns 403Managing shared fields is manager-onlyUse a commerce manager account
Shopify orders not syncingConnector disconnectedReconnect in Connecter and Sync now

Last updated: