docs(README): rewrite intro as positive framing

Drop the 'What this extension is not' negation list and absorb
its content into 'What this extension is' as positive descriptions
under five headings: a CMS for operators, a REST API, a Nostr
publisher, an order pipeline, and a single-tenant view of the
world (the last folds in customer-UI-lives-elsewhere, festivals-
are-external-NIP-51-lists, and per-restaurant-invoices-no-
splitter).
This commit is contained in:
Padreug 2026-05-02 08:26:15 +02:00
commit c2ea0297f9

View file

@ -1,35 +1,51 @@
# Restaurant — LNbits extension # Restaurant — LNbits extension
A Nostr-native restaurant CMS for LNbits. Restaurant owners enable this A Nostr-native restaurant CMS for LNbits. The operator (the person who
extension on their LNbits account to build menus, manage modifiers and enables this extension on their LNbits account) builds menus, manages
inventory, and watch orders in real time. Customer-facing UIs (kiosks, modifiers and inventory, watches orders in real time, and routes paid
mobile, the AIO webapp) live elsewhere and connect via REST + Nostr. tickets to a thermal printer. Each restaurant's data is owned by that
restaurant's wallet; menus are published to Nostr so any client — from
a single venue's customer kiosk to a webapp aggregating dozens of
restaurants for a festival — can subscribe and stay live.
## What this extension is ## What this extension is
- **A CMS** for one operator (one or many restaurants per LNbits wallet). **A CMS for restaurant operators.** One LNbits account can host one or
- **A REST API** for menu read + order placement. many restaurants under the same login. Each restaurant carries its own
- **A Nostr publisher** for menus (NIP-99 classified listings) and a profile, menu tree (categories → subcategories → items), modifier
Nostr inbound sync skeleton for orders (NIP-17 DMs). groups (required choices and optional addons, single- or multi-select),
- **An order state machine** with print-job queueing and a Kitchen per-item availability windows, inventory, and Nostr identity.
Display screen.
## What this extension is not **A REST API.** Public read endpoints serve menu trees and item
details; gated write endpoints (admin key) handle CRUD; an unauthenticated
order placement endpoint accepts carts and returns a Lightning invoice.
- **Not a customer kiosk.** Customer-facing UI is the AIO webapp at **A Nostr publisher.** Menu items are published as NIP-99 classified
`~/dev/webapp`. listings (kind 30402, parameterized replaceable) every time they're
- **Not a festival platform.** "Festival" / "collective space" / created or edited; restaurant profiles are kind 0 metadata; deletions
"food court" are emergent — a curator publishes a NIP-51 list of are NIP-09. Tags carry structured price, dietary flags, allergens, and
restaurant pubkeys, the webapp aggregates from that list. The ingredients so subscribers can filter without parsing markdown.
extension itself only ever knows about its own restaurant.
- **Not a payment splitter.** Per the design discussion: each menu **An order pipeline.** Every cart placed against this restaurant
item belongs to one restaurant, each restaurant issues its own becomes one order with snapshotted line-item prices and selected
invoice, and the customer pays N invoices to complete a multi- modifiers. The invoice listener settles `pending → paid` on payment;
restaurant cart. The webapp pre-flights the total via the operator (or auto-accept) walks it through `accepted → ready →
`POST /api/v1/orders/quote` to confirm sufficient balance before completed`. Stock decrements on settlement, a print job lands in the
opening any per-restaurant invoice. If a payment ever fails after queue, and the Kitchen Display picks it up.
another succeeded (rare on internal LNbits transfers), the
customer settles the remainder in person. **A single-tenant view of the world.** Customer-facing UIs (kiosks,
mobile apps, the AIO webapp at `~/dev/webapp`) live outside this
extension and connect via REST and Nostr. When a customer wants to
order across multiple restaurants — at a festival, in a collective
space, across a food court — that grouping is curated externally
(typically as a NIP-51 list of restaurant pubkeys), the webapp fetches
each menu independently, builds a unified cart, and sends one order
per restaurant. Each restaurant issues its own bolt11 invoice; the
customer pays N invoices to complete the cart. No central wallet
holds the float, no splitter divides the payment, and each operator
sees their own sats land directly. The webapp pre-flights the total
via `POST /api/v1/orders/quote` so a customer with insufficient
balance gets one clean error rather than a partially-paid cart.
## Architecture ## Architecture