Visual seating/floor design, kitchen tickets, and venue display playlists —
plus the product goal: relay a customer’s seat on prep-area screens
(one or many), driven by the same layout the POS used.
Floor → POS → KDS seat chips: worksFloor map on venue displays: not built yetProduct name: GPE Signage (not third-party brand names)
Naming
Digital displays in this platform are GPE Signage (or “venue displays / digital signage”).
Do not use third-party product names (e.g. nSign) in product, marketing, or docs.
Product vision (your intent)
Draw the room — theater, restaurant, patio — in the visual floor mapper (stable seat/table IDs).
Sell at POS — staff (or kiosk) attach that seat/table to the order.
Prep sees where it goes — KDS already shows text chips; the fuller goal is a
visual mini floor map on one or more prep/expo screens (and optionally lobby screens),
highlighting the seat and order state.
GPE Signage carries the screen — same player/display registry that already runs ads,
with a new live board / map mode fed by KDS (not only static ad playlists).
That last hop (live map/board on Signage displays) is the missing product slice.
Floor design + POS + kitchen tickets already share IDs for it.
Who is at which seat? (this is where it gets deep)
A prep screen cannot highlight a seat unless the order carries a seat.
A seat only means something for CRM/rewards if the order also carries a customer.
Those are two independent attachments that can arrive in different ways.
flowchart TB
subgraph WHERE["WHERE — seat on the order"]
W1[Staff taps seat on floor map Modern POS · seating visualizer]
W2[Staff types table/seat label]
W3[Guest picks seat at kiosk / storefront future]
W4[Admission / show ticket already has seat future link]
end
subgraph WHO["WHO — customer on the order"]
H1[Staff attaches customer at POS search CRM]
H2[Member scans / looks up loyalty ID]
H3[Logged-in storefront / app account]
H4[Guest checkout — no member]
end
WHERE --> CART[POS cart metadata + customerId]
WHO --> CART
CART --> SALE[Finalize → Invoice + kitchen_tickets]
SALE --> KDS[Prep sees seat]
SALE --> LOY[Loyalty earn / rewards if customer linked]
SALE --> MAP[Future live map on GPE Signage]
Paths that already work in code
Path
What staff/customer does
Today
Server-attached seat
On Modern POS with seating visualizer, pick seat on map → cart metadata
Built (not on Mobile POS yet)
Server-attached customer
Search/attach customer on cart · posApi.attachCustomer
Built Modern + Mobile
Loyalty tender / points
Redeem against cart when customer/loyalty account exists
Built (Modern UI; loyalty program admin)
Anonymous walk-up
No customer, seat optional
Works — seat alone still helps kitchen; no rewards trail
Paths that are product design / future glue
Path
Idea
What must exist
Member-required seat map
Only members can reserve/show seat on board
Policy flag + enforce customer on cart before seat (or before finalize)
Admission ticket → seat
They bought Row F Seat 12 under their account earlier; concessions auto-tag that seat
Event/admission inventory linked to same seat IDs + customer; not the same as service-desk “tickets” module today
Scan membership → last seat
Scan rewards barcode; system recalls “currently seated in …” for this visit
Visit/session object: customer + layout + seat + time window
Important split
Platform service tickets (salon/repair queue) and admission/show tickets
(movie seat sold in advance) are different product concepts. Today’s tickets module is service-desk oriented.
Theater admission → seat is a vertical that reuses floor IDs + customers + invoicing, not necessarily the existing ticket-workflow engine as-is.
How deep the graph actually goes
Floor mapper — geometry + stable seat IDs
POS / Mobile POS — attach seat + customer at order time
Customers CRM — who they are
Loyalty / rewards / tiers — earn/redeem when customer is on the sale
Invoicing — money spine; sale is source of truth
KDS — prep execution + seat chips (and later mini-map)
GPE Signage — multi prep/lobby screens (playlist today; live map later)
Optional: visits / admissions — pre-known seat before concessions order
None of that requires every guest to be a member. Membership deepens personalization and rewards;
seat-on-order is enough for kitchen routing; customer-on-order is enough for rewards.
Combining both is how theater “knows” it’s the same person in F12 ordering nachos.
Tap a seat on the same grid → writes cart metadata
Device flag
Device settings · seatingVisualizerEnabled
Turns on visualizer for that POS device
What gets stored on the cart / ticket
Stable identities from the designer — this is the join key for every downstream screen.
Field
Meaning
seatId
Stable cell/seat id from layout grid
tableId
Table identity when used
seatNumber / tableNumber
Human labels for chips (“Seat 12”, “Table 5”)
Already on kitchen tickets
Finalize / send-to-kitchen copies these onto kitchen_tickets.
KDS renders them as text chips. The layout JSON itself is not yet re-rendered on KDS or Signage.
Three systems (as-built vs intended)
Floor mapper
KDS
GPE Signage
Job
Define room + stable seat IDs
Cook/expo work tickets
Drive TVs (ads today; live boards later)
Primary UI
/admin/seating-layouts
/pos/kitchen
/admin/signage + public player
Data
seating layouts + layoutData
kitchen_tickets
SignageFolders / Ads / Displays
Sees seats today?
Designs them
Text chips only
No
Intended for prep screens
Source of map geometry
Source of order state
Player that can show map + state on one or many displays
Detail tables for routes/schema remain valid from the prior KDS write-up; focus here is floor + multi-screen vision.
GPE Signage today (summary)
Product name: GPE Signage / venue digital displays
Admin: folders, ads (image/video/URL/HTML), displays with slugs
Player: /:tenantSlug/signage/:displaySlug
Public playlist API + bridge signageUpdate + optional ?reloadSec=
Media = hosted URLs (not the platform barcode upload store)
Today’s Signage is playlist-only
There is no display “mode” for live kitchen tickets or a floor map overlay.
Prep-area TVs can only show whatever ads you put in the playlist unless we build live modes.
As-built data path
flowchart TD
FL[Floor mapper layoutData + seat IDs]
POS[Modern POS PosSeatingPicker]
META[Cart metadata seatId tableId numbers]
KT[(kitchen_tickets)]
KDS[KDS text chips]
SIG[GPE Signage ad playlist only]
FL --> POS
POS --> META
META -->|finalize / send-to-kitchen| KT
KT --> KDS
KT -.->|no feed| SIG
ADS[Admin ads] --> SIG
Goal: any prep/expo/lobby display can show a live map (or ticket board) for seats that have open food,
without re-drawing the floor in three products.
flowchart TB
subgraph SOURCE["Single sources of truth"]
FL[Floor layout JSON geometry + seat IDs]
KT[kitchen_tickets order state + seatId]
end
subgraph FEED["New: status feed"]
API["GET /api/kds/board or /api/signage/live/… layoutId + open tickets + lane"]
end
subgraph SCREENS["One or many displays"]
KDSUI[KDS web · optional mini-map]
PREP1[GPE Signage display A mode=live-map · grill]
PREP2[GPE Signage display B mode=live-map · expo]
LOBBY[Optional lobby mode=order-ready]
end
FL --> API
KT --> API
API --> KDSUI
API --> PREP1
API --> PREP2
API --> LOBBY
Recommended design choices
Choice
Rationale
Reuse seating layout IDs
Already on tickets; never invent a second seat key space
Reuse GPE Signage Displays
Already multi-screen (many slugs), bridge refresh, player URL pattern — add a display_mode or ad type: live_map / order_board vs playlist
Filter by station / lane
Grill TV only shows grill tickets; expo shows all FIRE/DONE as needed — mirrors KDS ?station=
Read-only on prep TVs
Bump/recall stay on staff KDS (or PIN-gated); map screens only highlight
Poll first, WS later
Match current KDS ~3s poll for v1; push via bridge when ready
Build list (to match the vision)
#
Work
Depends on
1
Board/status API — layout snapshot + open tickets with seatId/lane/station
Existing tickets + seating layouts
2
Shared FloorMapView component — render layoutData.grid + highlight seats by ticket state
layoutData schema (exists)
3
Optional mini-map on KDS — same component, staff screen
#1–2
4
GPE Signage display mode — live_map / order_board on a display slug; player branch
#1–2 · SignageDisplays schema extension
5
Multi-display config — per-display station filter, layout pick, orientation
#4
6
Mobile POS seating — parity with Modern so concessions phones can attach seats
PosSeatingPicker reuse
7
Bridge push for live board refresh (optional polish)