docs(pos): record created PB collections, live test results, catalog paging

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Dave 2026-08-31 02:25:28 +02:00
parent a956b70137
commit bef2a08299

View file

@ -2075,14 +2075,50 @@ Smaller adjustments made along the way:
`/pos/*`, all four endpoints 401 without a valid key, and `/catalog` +
`/customers` return real PocketBase data with one.
### Blocked before Task 20 can run
### PocketBase collections — created 2026-08-31
Created directly against the live instance via the superuser API (the user
asked for this explicitly; `AGENTS.md`'s "user does it in PB admin" convention
was waived for this one-off). Script kept at `/tmp/pb-create-pos.mjs`, not
committed — the repo still runs no migrations against the live instance.
- **`pos_sales`** (`pbc_4138824761`) — all API rules null (superuser-only).
Fields: `created`/`updated` autodate, `sale_number`, `payment_method`
(select: cash/card/eft/account), `cash_given`, `change_given`, `subtotal`,
`vat`, `total`, `customer` (relation → customers), `client_ref`.
Indexes: `idx_pos_sales_created`, and a **partial** unique index
`idx_pos_sales_client_ref ... WHERE client_ref != ''` — a plain UNIQUE would
have rejected every sale after the first that carried an empty `client_ref`.
- **`pos_sale_items`** (`pbc_1600525088`) — all API rules null. Fields:
`created`/`updated` autodate, `sale` (relation → pos_sales, required,
cascadeDelete), `stock_item` (relation → stock_items, required), `sku`,
`description`, `qty`, `unit_cost`, `unit_price`. Index on `sale`.
### Live end-to-end results (dev server, real PocketBase)
- Cash sale of 3 units: sale written, VAT split correct (R300 → R260.87 +
R39.13), change R50, `current_qty` 7 → 4, one ledger row.
- Replay of the same `client_ref`: returned the original sale with
`duplicate: true`, wrote nothing, `current_qty` stayed 4. Idempotency holds.
- `account` and `eft` sales: recorded under their own method with
`cash_given` 0, customer relation populated, stock still decremented.
- Over-selling (999 of 7): HTTP 409 with per-line shortage detail.
- All test rows deleted and `current_qty` restored to 7 afterwards.
### Still blocked before the till can take real money
- `pos_sales` / `pos_sale_items` collections do not exist yet (`/sales` returns
500). Per the prerequisite at the top of this plan, plus two additions:
`payment_method` must include `eft` and `account`, and `pos_sales` needs a
`client_ref` text field with a unique index.
- **No sellable stock.** Of 373 active `stock_items`, zero have a
`selling_price` and zero have a `markup`; only 98 have a `cost_price`. The POS
prices from `selling_price`, so today every line would ring up at R0.00. This
needs a pricing decision before the till can take real money — see the handover
notes for the options.
prices from `selling_price`, so every line currently rings up at R0.00. The
user opted to populate `selling_price` in the main app rather than add a
code-side fallback.
- Bluetooth thermal printing is still unverified — needs the physical printer.
### Catalog paging (added 2026-08-31, beyond the original plan)
The till was rendering all 373 items at once. `listActiveStockCatalog` now
sorts `-created` and `PosCatalogItem` carries `created`; the frontend renders
50 at a time behind a Show-more button that also auto-loads on scroll. Header
shows "Recently added" while browsing, "Results" once filtered; changing the
search or category resets to the first chunk. Scroll position survives
re-renders so adding to the cart no longer jumps to the top.