diff --git a/docs/api-reference.md b/docs/api-reference.md index 442a9b3..ec7ed36 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -15,6 +15,7 @@ the catalog. | Method | Path | Notes | |---|---|---| | `GET` | `/restaurants/{id}` | Restaurant profile | +| `GET` | `/restaurants/by-slug/{slug}` | Restaurant profile by URL slug — used by webapps that route on `/r/:slug` and need to resolve to an `id` before any other lookup. 404 when no match | | `GET` | `/restaurants/{id}/menu` | `{restaurant, tree, items}` — the canonical [[menu-tree|menu tree]] (hydrated children + items per node) plus a flat enriched items list with modifier groups + availability windows pre-joined | | `GET` | `/menu_items/{id}` | Single item | | `GET` | `/menu_nodes/{id}` | Single node row | diff --git a/docs/cms.md b/docs/cms.md index 119be3f..59bef8c 100644 --- a/docs/cms.md +++ b/docs/cms.md @@ -73,6 +73,26 @@ orange, `>15min` red) and offers one-tap state transitions. Today the monitor + KDS poll every 5–8 s. SSE / Nostr push is on the roadmap. +### Dark-mode color discipline + +Quasar's pale `bg-{color}-1` utility classes (e.g. `bg-orange-1`, +`bg-red-1`, `bg-amber-1`) pair fine with the default light theme +but render **white-on-cream** under LNbits' dark theme — the +q-card otherwise inherits the body's light text color. The KDS +cards pin a dark text class alongside every pale background so +the card stays legible regardless of theme: + +```js +if (order.status === 'ready') return 'bg-amber-1 text-grey-9' +if (ageSec > 900) return 'bg-red-1 text-grey-9' +if (ageSec > 300) return 'bg-orange-1 text-grey-9' +return '' // theme-default branch keeps q-card's own text color +``` + +Any future surface that ages / escalates with `bg-{color}-1` must +do the same. Never assume a pale background "just works" on dark +theme. + ## Settings `settings.html` saves restaurant fields via diff --git a/docs/order-flow.md b/docs/order-flow.md index ffa2888..fd29bc7 100644 --- a/docs/order-flow.md +++ b/docs/order-flow.md @@ -37,14 +37,22 @@ States and their meaning: 2. Re-prices every line item against the live menu (modifier ids are matched server-side; the customer's claimed `price_delta` values are ignored). -3. Sums `subtotal_msat`, applies `tax_rate`, adds `tip_msat` → +3. Converts each item's `price` from its declared `currency` to + msat. For sat-denominated items (`currency` ∈ `{sat, sats, + satoshi}`) this is a flat `× 1000`. For fiat (`USD`, `GTQ`, …) + it calls `lnbits.utils.exchange_rates.fiat_amount_as_satoshis` + to look up the live rate, then `× 1000`. The conversion lives + in `services._price_to_msat` so the rate lookup is the same path + the quote endpoint uses — a customer's preview and the recorded + `order.total_msat` cannot drift apart between request and place. +4. Sums `subtotal_msat`, applies `tax_rate`, adds `tip_msat` → `total_msat`. -4. For Lightning / internal: calls +5. For Lightning / internal: calls `lnbits.core.services.create_invoice` with `extra={"tag": "restaurant", "restaurant_id": ...}`. -5. Persists the order with `id = payment_hash` so the listener can +6. Persists the order with `id = payment_hash` so the listener can look it up cheaply, plus one `order_items` row per line. -6. For cash: `payment_method = "cash"` skips invoice creation and +7. For cash: `payment_method = "cash"` skips invoice creation and marks the order `accepted` directly. Returns `(Order, OrderInvoice | None)`. The webapp pays the bolt11. diff --git a/docs/webapp-integration.md b/docs/webapp-integration.md index 4c0a925..e37c0c8 100644 --- a/docs/webapp-integration.md +++ b/docs/webapp-integration.md @@ -9,7 +9,17 @@ of restaurants, especially the multi-restaurant cart pattern. A webapp can either talk to one restaurant directly or aggregate many. There's no central directory inside this extension — grouping ("festival", "collective space", "food court") is **emergent** via -NIP-51 list events curated by whoever runs the venue: +NIP-51 list events curated by whoever runs the venue. + +For the **single-venue** case, a webapp that routes on a URL slug +(`/r/big-jays-bustaurant`) resolves the slug → restaurant via the +public `GET /restaurants/by-slug/{slug}` endpoint +([[api-reference]]) and proceeds with that one `id` for menu reads +and order placement. Slug is just a URL nicety — internally +everything continues to key on the restaurant `id`. + +For the **aggregator** case (multiple restaurants in one cart), the +webapp consumes a curated NIP-51 list event: ``` {