Point of Sale (POS)

Overview

The POS is the heart of Bambu. It provides cashiers with a lightning-fast interface to click products, calculate cart totals, assign returning customers, and safely log transactions into the database.

Why it exists

Cashiers cannot be slowed down by complex software. The POS is heavily optimized for speed, supporting barcode scanners, keyboard navigation, and touch-screens on iPads. This ensures checkout lines move efficiently.

User flow

  1. Cashier opens the app/dashboard/pos route.
  2. Cashier clicks product tiles to load them into the Cart sidebar.
  3. Cashier taps 'Complete Sale', registers payment as Cash or Credit, and prints the theoretical receipt.

/docs-images/pos/main-view.png

Point of Sale Dashboard

Main interface showing quick product selection tiles and the current cart.

Replace with actual screenshot

/docs-images/pos/checkout.png

Checkout Sidebar

Reviewing the cart totals, applying discounts, and selecting payment methods.

Replace with actual screenshot

Backend logic

When a sale is requested:

  1. Next.js validates that all items requested currently exist with non-zero stock (unless strict mode overriden).
  2. It wraps the transaction:
    • Decrementing stock for Products.
    • Logging the transaction payload into the Sales table.
    • If Credit, appending the total to the Customer debt balance.
  3. Fast execution via the cached Prisma Tenant connection.

Database tables involved

Tenant Schema (e.g., business_abc):

  • Product: For adjusting stock levels.
  • Sale: The master record of the event.
  • SaleItem: Breakout rows for each product in that sale to allow analytic aggregations.

API endpoints

  • POST /api/pos/checkout - Submits the transaction payload.
  • GET /api/pos/products - Loads cached, quick-hit POS products.

Permissions / roles

  • Owner/Manager: Full access.
  • Cashier: Can transact, but cannot issue Refunds or view aggregate profit margins.

Edge cases

  • If the Wi-Fi drops while submitting the sale, Bambu handles client-side retries via React Query.

Validation rules

  • Total item cost must perfectly equal quantity * unitPrice.

Error handling

  • The API returns 400 Bad Request if a product in the cart was deleted mid-transaction by another user.
  • The UI triggers a Toast Notification so the cashier can drop the missing item from the cart.

Screenshots placeholders

/docs-images/pos/error-retry.png

Transaction Sync Failure

What the cashier sees if the Wi-Fi drops while checking out a customer.

Replace with actual screenshot

Troubleshooting

  • If scanners are not registering products, ensure the cursor is not focused inside a completely separate numeric input field.

Related features