POS
Read Conventions first.
pos_terminals
id,business_id,branch_idNOT NULLdefault_warehouse_idNOT NULLcode- UNIQUE (business_id, code);nameapi_key_hashNOT NULL - opaque token, SHA-256 hashedapp_versionDEFAULT ‘’ - self-reported on Pinglast_seen_atNULLis_active,created_by,created_at
pos_sales
Links a terminal sale to the A/R Invoice and payment it produced. Idempotent on the terminal’s own id.
id,business_id,terminal_idNOT NULLclient_sale_iduuid NOT NULL - UNIQUE (business_id, client_sale_id) - the offline outbox row’s id, making sync idempotentterminal_code,terminal_sale_noar_invoice_idNOT NULLincoming_payment_idNULLcashier_user_idNULLsource_ar_credit_memo_idNULL - an “exchange” is represented by a populated source id, not a flagfirst_scan_atNULLcreated_at; indexes(terminal_id, created_at),(ar_invoice_id)
pos_invoice_reservations
Real A/R invoice numbers reserved up front so a cashier sees the number from the first scanned item, even offline. An unconsumed reservation is marked ‘cancelled’, not deleted - the resulting gap in the sequence is expected, and this table is what the Cancelled Bills report reads to explain each gap.
id,business_id,branch_idNOT NULL,terminal_idNOT NULLdocument_no- UNIQUE (business_id, document_no)statusDEFAULT ‘reserved’ - CHECK IN (‘reserved’,‘used’,‘cancelled’)reserved_at,used_at,cancelled_atar_invoice_idNULL,cashier_user_idNULL,cancel_reason- Index
(terminal_id, status)
pos_void_events
One row per supervisor-authorized Void / Cancel / Discount action at a terminal.
id,business_id,terminal_idNOT NULLclient_event_idNOT NULL - UNIQUE (business_id, client_event_id) (idempotent sync)event_type- CHECK IN (‘line_void’,‘bill_cancel’,‘net_discount’,‘line_discount’)cashier_user_idNULL;authorized_by_user_idNOT NULLinvoice_reservation_idNULL - set for a bill_cancelcustomer_idNULLitem_name,quantityNULL,amountDEFAULT 0,reasonlines_jsonjsonb NULL - the cancelled/returned lines, used to build the cancelledar_invoicesrecord- Fraud signals:
tendered_amountNULL - non-null only when the cashier had typed a value into the Cash modal before backing out and voiding; a near-deterministic fraud signal;cart_total_before,cart_item_count_before- review context only created_at- Indexes
(business_id, event_type, created_at DESC); partial(business_id, cashier_user_id, created_at DESC) WHERE tendered_amount IS NOT NULL
pos_cash_movements
Cash In / Cash Out (“Paid Out”) ledger. Cash Out is the guarded direction.
id,business_id,terminal_idNOT NULLclient_movement_id- UNIQUE (business_id, client_movement_id)movement_type- CHECK IN (‘cash_in’,‘cash_out’)cashier_user_idNULL;authorized_by_user_idNULL - set for cash_out onlyamount- CHECK > 0reason;denominationsjsonb NULL - note breakdown, physically removed (cash_out only)created_at; index(terminal_id, created_at)
pos_register_sessions
One row per till session, upserted at open and at close. cash_sales/cash_in/cash_out/expected_cash/
cash_difference are computed server-side at close from real data - never trusted from the terminal’s own
totals.
id,business_id,terminal_idNOT NULLclient_session_id- UNIQUE (business_id, client_session_id)cashier_user_idNULLopening_cashDEFAULT 0;opened_atNOT NULLclosing_cashNULL;closed_atNULLstatusDEFAULT ‘open’ - CHECK IN (‘open’,‘closed’)denominationsjsonb NULLcash_sales,cash_in,cash_out,expected_cash,cash_differenceNULL (server-computed)actual_card_saleNULL - optional cashier-entered card-terminal total, for a Card Sale Differenceforce_closedDEFAULT false - closed by super admin master password, not a real Z Reading- X Reading (mid-shift check that does not close the till):
x_reading_at,x_reading_by,x_reading_declared_cash,x_reading_denominations,x_reading_actual_card_sale,x_reading_system_cash_in_hand,x_reading_system_card_sales - Index
(terminal_id, status)