feat: make products server managed
CI / build-and-test (push) Canceled after 0s

This commit is contained in:
2026-10-20 23:55:40 +02:00
parent 0ca9f4d16a
commit e7f59f7583
14 changed files with 697 additions and 181 deletions
+12 -5
View File
@@ -62,9 +62,10 @@ and `docs/server-stock-source-of-truth.md`.
first, at most 500; the response's `settlementsCursor` is sent back next time.
- `openTabs` is only used once per venue, on the first sync after the server started holding the tabs: the terminal's
own tabs (and catalog stock) are taken over and the events of that request are stored without applying them again.
- `products` (optional, at most 2000) upserts names, categories and prices. Its `stock` is ignored (counts arrive as
`stock_set`), a new product starts untracked, and products are never removed because one terminal doesn't report
them. An invalid product is skipped and logged.
- The dashboard manages the products. `products` in the request (at most 2000) is only used on that same first sync,
to take over the terminal's catalog with its stock; after that it is ignored. The response's `catalog` lists every
product of the venue: `[{ id, name, category, priceInCents, lowStockThreshold, archived }]`. The terminal adds and
updates its products from it and hides archived products and products the catalog doesn't list.
- Planned customers are opened as tabs by the server, once; `plannedTabNames` is always empty.
- Dashboard stock adjustments are applied by the server right away; `stockAdjustments` is always empty.
`stockAdjustmentResults` from older app versions are still recorded and acknowledged.
@@ -91,12 +92,18 @@ Names match case-insensitively and keep their existing spelling; `replace` also
`POST /venues/:venueId/reminders/test/:plannedTabId` - Send a test email (admin)
### Stock
`GET /venues/:venueId/stock` - The terminal's products with stock, low stock level and pending adjustments
`GET /venues/:venueId/stock` - The venue's products (archived ones too, with `archivedAt`) with stock, low stock
level and pending adjustments
`GET /venues/:venueId/stock/adjustments?productId=&limit=&offset=` - Stock adjustment history, newest first
`POST /venues/:venueId/stock/adjustments` - Request stock changes (admins and viewers): `{ adjustments: [{ productId, type: 'add' | 'set', quantity, note? }] }`.
`add` takes a non-zero quantity (negative for breakage) and needs a tracked product; `set` takes 0 or more.
`POST /venues/:venueId/stock/adjustments/:id/cancel` - Cancel an adjustment the terminal hasn't received yet (admins and viewers)
`PUT /venues/:venueId/stock/products/:productId` - Set `{ lowStockThreshold: number | null }` (admin, dashboard only)
`POST /venues/:venueId/stock/products` - Add a product (admin): `{ name, category?, priceInCents, stock?, lowStockThreshold? }`.
`stock` is the starting count (recorded as an applied `set` adjustment); null or left out: not tracked.
`product_name_exists` when an active product has the same name (ignoring case).
`PATCH /venues/:venueId/stock/products/:productId` - Change a product (admin): any of `{ name, category, priceInCents,
lowStockThreshold, archived }`. `archived: true` deletes it for the terminals (kept for tabs and history),
`archived: false` brings it back. The stock itself changes through adjustments.
### Commands
`POST /venues/:venueId/commands` - Settle a tab: `{ tabId, type: "close_tab", expectedVersion, paymentMethod }`. The