Reception — booking operations
● Live (SSE · chain.bookings · 400 ms debounce)
Hot-key-driven reception console for Boulodrome Sjöstad — phone bookings, drop-ins, walk-ins, check-in, waitlist and protected facilities in a single screen. Tablet-first (iPad behind the desk). The floor plan lives in Floor plan (live), resources & opening hours in Venue profile.
31
Bookings today
3
Check-in due ±30 min
2
Walk-ins in queue
1
No-shows today (grace 15 min)
Everything on the tab comes from ONE aggregated call: GET /chain/operator/{location}/today (F22.08.07). Status distribution: 18 confirmed · 6 checked in · 4 reserved · 2 awaiting deposit · 1 no-show.
Today's schedule
| Time | Resource | Booker | Type | Party | Status |
|---|---|---|---|---|---|
| 17:00–18:00 | Court 1 · Center | Anna Lindqvist | member | 4 | Confirmed |
| 17:30–19:00 | Table 4 | Afterwork · Team Sjöstad | group | 8 | Confirmed |
| 18:00–19:00 | Court 3 | Jonas Bergström | standard | 2 | Checked in |
| 18:00–20:00 | Event space Terrace | Nordviks Redovisning AB | event | 22 | Awaiting deposit |
| 18:30–19:30 | Court 6 | Walk-in · Kjell | walk_in | 3 | Reserved |
⌘K
N New booking (phone)
I Check-in 3 due
W Register walk-in 2 in queue
V Add to waitlist
R Call back 1
A Cancel booking
Customer search — ChainPassport + guests (90 days)
Anna Lindqvist · GOLD · 070-123 45 67 14 visits · last 28 Jun · passport
Jonas Bergström · jonas.b@example.com 3 visits · guest · guest
Dedup on phone/email. On 0 hits, autofocus moves to the “Create new customer” CTA.
Next free · Court (court)
18:3019:0020:30
Next free · Table (table)
17:4518:0018:15
Next free · Event space (event_space)
Fri 10 Jul 17:00
Next free · Equipment (equipment)
Boule set A free now
Phone booking — QuickBookForm, deterministic idempotency key on create (F22.04.05)
Race-free conflict check via per-(tenant,location) lock (F22.04.09)
409 — the time is taken. Suggestions within ±2 h (suggested_slots, F22.04.10):
✅
Booked — Court 2, today 18:00–19:00 · Anna Lindqvist
SMS confirmation sent · validated against opening hours, buffer & capacity (F22.04.02) · audit record written per status change (F22.04.04)
⚠
Could not book — 422 outside_opening_hours
The time 07:00 is outside today's effective opening hours (08:00–22:00). See Venue profile → Opening hours.
DayWeekMonth
URL-driven: ?view=day&date=2026-07-02&location=sjostad&resource_type=court (F22.09.08) · Keyboard: ← → t Esc (F22.09.07)
standardmembergroupeventwalk_indrop_inmaintenancecompetition — tokens from booking-colors.mjs (8 types × solid/subtle/border × light/dark, WCAG AA ≥ 4.5:1)
16:0016:3017:0017:3018:0018:3019:0019:30
Court 1
Lindqvist 17–18Öberg 18:30–19:30
Court 2
Öström 18–19
Court 3
Bergström 18–19Maintenance 19:30–
Table 4
Team Sjöstad 17:30–19
Event space
Nordviks Redovisning 18–20
Month view — occupancy heatmap (F22.09.05)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Green alpha 8–50% by occupancy. Drag-and-drop rebooks, edges resize (F22.09.02); optimistic update with 409 revert + toast (F22.09.06).
Booking detail — BK-4714 · Event space Terrace 18–20 drawer
Staff on the booking — POST/GET/DELETE /chain/bookings/{id}/staff
| Frida Nyberg | host | 17:30–20:30 | — | |
| David Sjölund | bartender | 17:00–21:00 | alcohol_license ✓ (expires 2027-03) |
At cancellation the shifts are unlinked automatically and unlinked_shifts_count is written to the booking's audit (F22.12.26).
Walk-in queue (TTL → expired)
Kjell + 23 pers · waited 8 min
expires 18:52 · drag to the floor plan or ⤵ assign via the bottom sheet
Sjöstad family4 pers · waited 2 min
expires 19:04 · drag to the floor plan or ⤵ assign via the bottom sheet
Call back
Gunnar Wide · 070-555 12 34
Wants to move Sat booking to Sun
Empty when the list is cleared — good job.
Waitlist (FIFO per type + window)
#1Sara Vikström · Court~25 min
today 18:00–20:00 · promotion: pending · response within 10 min
#2Ali Nordgren · Court~40 min
today 18:00–21:00
#3Petra Almvik · Table~15 min
today 19:00–20:00
The waitlist machinery (F22.15): auto-promotion when a slot is freed (promote_for_freed_slot) → SMS with a response window (snapshot per entry, 10 min) → accept/decline via token link (guest access) → expired deadlines cleaned by a cron job every minute → status machine pending → accepted / declined / expired / superseded. Race-safe accept: simultaneous responses give 409 slot_unavailable and the next candidate is offered automatically. If the resource becomes unavailable (maintenance) the offer is superseded and the entry returns to WAITING. Positions are recomputed on create/cancel/promote; estimated wait is materialised hourly. Default templates (sv/en × SMS/email) are seeded at first profile creation. SSE: chain.waitlist.{tenant}.{location}.
Loading the waitlist …
Check-in window ±30 min
| Bokare | Resurs | Time | Phone | |
|---|---|---|---|---|
| Maja Öström | Court 2 | 18:00 | 070-123 45 67 | |
| Erik Sandvall | Table 7 | 18:15 | 073-987 65 43 | |
| Nordviks Redovisning AB | Event space Terrace | 18:00 | 08-55 01 02 |
One click → POST /chain/bookings/{id}/check-in. At check-in any deposit is settled against the pay_at_venue row (F22.05.08). No-show: 15-min grace period, then sweep + no-show notification (F22.04.03, F22.14.04).
QR check-in (operator scan)
▦
Point the camera at the guest's QR code
Signed JWT (HS256, per-tenant HKDF key, kid rotation). Verified offline via cached JWKS — works even when the network is down (F22.18.07–08).
✅ Verified: Maja Öström · Court 2 · 18:00 — checked in 17:58
⚠ Invalid token (wrong kid — rotated). Ask the guest to update the app or search by name.
Saved views (per user): Tonight unpaidEvents this weekNo-shows 30 daysMy phone bookings
2 selected Export: POST /chain/bookings/export {format, filter, columns}
| Booking id ⇕ | Resource ⇕ | Time ⇕ | Booker | Channel | Status | Payment | Amount ⇕ | |
|---|---|---|---|---|---|---|---|---|
| BK-4711 | Court 1 · Center | today 17:00 | Anna Lindqvist | online | Confirmed | Paid | 360 kr | |
| BK-4712 | Table 4 | today 17:30 | Team Sjöstad | phone | Confirmed | Invoice | 1 840 kr | |
| BK-4713 | Court 3 | today 18:00 | Jonas Bergström | operator | Checked in | Paid | 180 kr | |
| BK-4714 | Event space Terrace | today 18:00 | Nordviks Redovisning AB | online | Awaiting deposit | Deposit 2 000 kr | 9 500 kr | |
| BK-4715 | Court 6 | today 18:30 | Walk-in · Kjell | drop_in | Reserved | Not required | — |
Columns are sticky + resizable (drag the edge). On mobile the rows render as cards via mobileCardRenderer:
BK-4712 · Table 4Confirmed
today 17:30 · Team Sjöstad · phone · Invoice 1,840 kr
MobileBookingCard — same data, card layout at phone width (F22.10.06)
No bookings match the filter.
Protected facilities — permission-gated booking flow (military / school / civic / private_corporate / religious)
| Venue | Type | Applicant | Approval chain | Status |
|---|---|---|---|---|
| Garnisonshallen Almvik | military | Nordviks BK (club championship qualifier) | host_admin ✓ → security_officer ⏳ → gov_clearance — | Awaiting security officer |
| Sjöstadsskolan gym hall | school | Boulodrome Sjöstad (camp) | host_admin ✓ → security_officer ✓ | Approved |
| Nordvik chapel | religious | Private 60th-birthday party | host_admin ⏳ | Awaiting host admin · expires in 14 h |
The approval chain (F22.04.21): host_admin → security_officer → any government_clearance, with role allow-lists per step and self-approval protection (the applicant can never approve their own step). Unanswered requests expire after 24 h via restricted_facility_request_expiry_tick. Before approval a conflict check runs against the host's operations iCal (F22.04.23).
Access log (F22.04.22)
| 18:02 | Anna Lindqvist | checkin | Garnisonshallen · entrance B |
| 18:04 | Unknown card #8841 | access_denied → alarm to security_officers | Garnisonshallen · entrance B |
| 16:55 | Camp group 2 (12 people) | checkout | Sjöstadsskolan |
checkin / checkout / access_denied are audited; access_denied is dispatched directly to the facility's security_officers.
Shared facility — mirror bookings (F22.04.30)
| Sat 4 Jul 10–14 | Outdoor courts 1–4 | Nordviks BK (owner) | Club training (mirror, read-only) 🔒 |
| Sun 5 Jul 12–16 | Outdoor courts 1–4 | Nordviks BK (owner) | District championship qualifier (mirror, read-only) 🔒 |
Courts shared with the owner tenant (shared_facility_owner_tenant_id) are shown as a read-only mirror via list_for_tenant_including_shared — you see the time is taken but cannot change the owner's booking.