Orders Flow¶
This page explains how orders work end-to-end: screens, columns/board, line items, inventory links, and Supabase tables.
Screens & views¶
Orders main screen (/orders)¶
File: src/pages/Orders.tsx
Responsibilities:
- Main entry point for order management.
- Provides two views:
- Kanban board (default) – orders grouped by custom columns.
- List view – table of all orders (including invoiced).
- Handles order creation, editing, deletion, file attachments, and column management.
Key UI pieces:
-
Tabs / view toggle
- Uses
viewquery param to switch between: kanban(default) – board view.list– tabular view viaOrdersListView.
- Uses
-
Kanban board
- Component:
src/components/orders/OrderBoard.tsx. - Columns:
- Backed by the
order_columnstable (per-tenant). - Drag-and-drop reordering of columns.
- Can be renamed, deleted, or collapsed.
- Cards:
- Each card represents an order in a given column.
- Cards can be dragged between columns to change status.
- Component:
-
List view
- Component:
src/components/orders/OrdersListView.tsx. - Shows all orders, including those linked to invoices.
- Displays key info: client, status (Paid/Invoiced/Column/Unassigned), amount, date.
- Component:
-
Order form
- Component:
src/components/orders/OrderForm.tsx. - Used for creating and editing orders.
- Supports:
- Client selection/creation.
- Line items (inventory + quantities + prices).
- Attachments.
- Component:
-
Order details drawer/modal
- Component:
src/components/orders/OrderDetailsModal.tsx. - Shows full order details, line items, attachments.
- Entry-point for editing or marking as paid.
- Component:
-
Order filters & column settings
OrderFiltersandColumnSettingsDialogcomponents manage advanced filtering and column configuration.
Hooks & operations¶
useOrders¶
File: src/hooks/useOrders.ts
Provides the core API for interacting with orders:
-
Queries
fetchOrders(silent?)– main board view:- Fetches orders for the current
tenant_id. - Excludes orders with
invoice_id(those are hidden from the board). - Includes joins:
clients,inventory_items,product_variations,order_columns.- Fetches
order_attachmentsandorder_line_itemsper order. fetchAllOrders(silent?)– list view:- Same as above, but includes orders with
invoice_id. - Also looks up invoice info (
invoicestable) wheninvoice_idis present. fetchOrdersByClient(clientId)– all orders for a given client.fetchOrderById(orderId)– single order + attachments + line items.
-
Board operations
moveOrderToColumn(orderId, columnId, position?)– moves card to a column with server-side position calculation.updateOrderPosition(orderId, columnId, position, silent?)– updates card position within a column.
-
CRUD
createOrder(input)updateOrder(input)deleteOrder(id)
-
Line items & totals
addOrderLineItem(orderId, lineItem)– insertsorder_line_itemsrow and recalculates order total.deleteOrderLineItem(lineItemId)– deletes line item, recalculates total, and restores inventory stock.
-
Attachments
uploadOrderAttachment(orderId, file)– uploads to Supabase Storage (order-attachmentsbucket) and createsorder_attachmentsrow.deleteOrderAttachment(attachmentId)– removes from storage and DB.
-
Status helpers
markOrderAsPaid(orderId, paidDate?)– setsis_paid = true,paid_atonorders.
Order creation & inventory interaction¶
Create flow¶
When createOrder(input) is called:
-
Stock validation
- For each
line_itemsentry withinventory_item_id: - If
track_variant_inventoryis true andproduct_variation_idis set: - Checks
product_variations.current_stock_qtyto ensure sufficient stock. - Otherwise:
- Checks
inventory_items.current_stock_qty. - Throws an error if requested quantity exceeds available stock (per item or variation).
- For each
-
Client auto-creation
- If no
client_idbutfirst_name,last_name, andphoneare provided: - Uses
useClients().createClient()to create a client. - Uses the order’s
email(if provided) for the client. - Sets
client_idon the order.
- If no
-
Column assignment
- If no
column_idand noinvoice_id: - Finds the first
order_columnsrow for the current tenant. - Assigns its
idascolumn_id. - If
invoice_idis present: - Leaves
column_idnull (order is hidden from board, considered part of invoicing flow).
- If no
-
Card position
- If no
card_positionis given and acolumn_idis set: - Looks at existing orders in that column.
- Sets
card_positionto the next available slot (max + 1).
- If no
-
Total price
- If
line_itemsare provided: - Computes
price = sum(quantity * unit_price). - Otherwise uses
input.priceas the order total.
- If
-
Insert order
- Inserts into
orderswith: tenant_id,client_id,first_name,last_name,phone,email.price,piece_description,inventory_item_id,product_variation_id(legacy fields).column_id,card_position,invoice_id.
- Inserts into
-
Insert line items & deduct stock
- For each entry in
line_items: - Inserts row into
order_line_itemswithline_total = quantity * unit_price. - Calls
deduct_inventory_stockRPC to adjust stock. - For legacy single-item orders (
inventory_item_idwithoutline_items): - Calls
deduct_inventory_stockonce.
- For each entry in
Update flow¶
When updateOrder(input) is called:
- Builds a partial update payload with only fields present.
- Updates
ordersrow. - If
line_itemsis provided:- Fetches existing
order_line_itemsfor the order. - Deletes items not present in the new list and restores their inventory via
restore_inventory_stockRPC. - Updates existing items and adjusts stock based on quantity differences.
- Inserts new items and deducts stock via
deduct_inventory_stock.
- Fetches existing
Status & columns¶
Board columns¶
- Table:
order_columns - Per-tenant list of columns used on the Kanban board.
- Fields (from code and usage):
id,tenant_id.name– column name (e.g. "New", "In Progress", "Completed").position– ordering on the board.color– hex color used in list view badges.
Columns can be:
- Created with
createColumn(name). - Updated with
updateColumn(id, updates). - Reordered with
reorderColumns(columnIds). - Deleted with
deleteColumn(id).
Order status¶
Orders don’t use a single status field; they derive status from:
-
Column:
- Column placement on the board indicates logical status.
- Example flow:
- New order appears in the first column.
- Orders move across columns as work progresses.
-
Invoicing:
- Orders with
invoice_idare considered invoiced and hidden from the board. - List view shows an "Invoiced" badge and invoice number if available.
- Orders with
-
Payment:
is_paidandpaid_aton theorderstable reflect payment status.- List view shows a "Paid" badge for such orders.
In OrdersListView, the priority is:
- Paid (
is_paid = true). - Invoiced (
invoice_idpresent or invoice object loaded). - Column name (if assigned).
- "Unassigned" (no column, not invoiced, not paid).
Tables & relationships¶
Key tables involved:
-
orders- Core order record per job.
- Important fields:
id,tenant_id,client_id.first_name,last_name,phone,email(for quick capture on forms).piece_description.price– total order amount.inventory_item_id,product_variation_id(legacy direct link).column_id,card_position– board placement.invoice_id– link toinvoicestable.is_paid,paid_at.- Timestamps (
created_at,updated_at).
-
order_line_items- One-to-many per order.
- Fields:
order_id(FK →orders.id).inventory_item_id(FK →inventory_items.id).product_variation_id(FK →product_variations.id).item_name,description.quantity,unit_price,line_total.position.
-
order_attachments- Files attached to orders.
- Fields:
order_id.file_url,storage_path,file_name,file_type,file_size.
-
order_columns- Kanban columns as described above.
-
invoices(linked to orders but documented in payments/checkout flow). -
inventory_items&product_variations- Referenced from line items.
- Stock mutations via
deduct_inventory_stockandrestore_inventory_stockRPCs.
Flow diagram¶
flowchart LR
U[User] --> ORD[/Orders screen/]
ORD --> HOOK[useOrders]
HOOK --> ORDERS[(orders)]
HOOK --> LINES[(order_line_items)]
HOOK --> COLS[(order_columns)]
LINES --> INV[(inventory_items & product_variations)]
click ORD "../architecture/frontend/" "Orders page & components"
click HOOK "../architecture/frontend/" "Frontend hooks (useOrders)"
click ORDERS "../architecture/supabase/" "Orders table (Supabase)"
click LINES "../architecture/supabase/" "Order line items & inventory links"
click INV "./inventory.md" "Inventory flow & stock rules"
Narrative:
- User opens
/ordersand sees either Kanban or list view. useOrdersfetches orders, line items, columns, attachments, and invoice links via Supabase.- Drag-and-drop and form actions call back into
useOrdersto updateorders,order_line_items, andorder_columns. - Inventory stock is enforced and updated via RPCs whenever line items change.
- Downstream flows (invoices, payments) use
ordersandorder_line_itemsas their starting point.
Related docs¶
- Inventory Flow – how stock is tracked and deducted.
- Payments Flow – how orders tie into invoices and payments (once documented).
- Supabase Architecture – table schemas and RLS.
- Frontend Architecture – route map and providers.