Chain-Venue Booking Platform
203 features · 19 subsystems
Commercial booking platform for chain-type venue tenants — boule bars, pétanque clubs with court rentals, restaurant venues. Enables court bookings, table reservations, staff shifts, corporate events, and tournaments through a unified operational interface.
Umbrella & Design System (PL-T184)
F22.00- F22.00.01 Shipped
Booking color token system (8 types × 3 variants × 2 modes)
✅ - F22.00.02 Shipped
CSS custom properties for www and web
✅ - F22.00.03 Shipped
ChainVenueProfile Beanie model
✅ - F22.00.04 Shipped
GET /chain/venue-profile (admin-only)
✅ - F22.00.05 Shipped
PUT /chain/venue-profile (admin-only)
✅ - F22.00.06 Shipped
Audit logging on all profile mutations
✅ - F22.00.07 Shipped
Default seeding on CHAIN tenant onboarding
✅ - F22.00.08 Shipped
WCAG AA audit tool (audit-booking-colors.mjs)
✅ - F22.00.09 Shipped
Booking premium-criteria CI gate (audit-booking-premium-criteria.mjs)
✅
BookableResource Model (PL-T185)
F22.01Polymorphic resource abstraction covering courts, tables, packages, equipment and event spaces.
How it works- F22.01.01 Shipped
BookableResource Beanie document with tenant/location scoping
✅ - F22.01.02 Shipped
Resource types: court, table, package, equipment, event_space
✅ - F22.01.03 Shipped
Booking channels: online, phone, operator, drop_in
✅ - F22.01.04 Shipped
Color-type system with per-type defaults and operator override
✅ - F22.01.05 Shipped
Duration and lead-time configuration per resource
✅ - F22.01.06 Shipped
Floorplan position storage (x/y/rotation/width/height)
✅ - F22.01.07 Shipped
Compound index (tenant_id, location_id, code) — unique per location
✅ - F22.01.08 Shipped
Soft-delete (retired status + is_deleted flag)
✅ - F22.01.09 Shipped
CRUD API: GET list, POST create, PATCH update, DELETE retire
✅ - F22.01.10 Shipped
Admin UI: resource list with type + status filter
✅ - F22.01.11 Shipped
Admin UI: resource detail form with booking channel toggles
✅ - F22.01.12 Shipped
Migration script: backfill existing Court documents
✅
Maintenance Blocks (PL-T185)
F22.02Time-based blocks that prevent booking of a specific resource. One-off and recurring (RFC 5545 RRULE subset).
How it works- F22.02.01 Shipped
MaintenanceBlock Beanie document
✅ - F22.02.02 Shipped
One-off block with start/end/reason
✅ - F22.02.03 Shipped
Recurring block with FREQ=DAILY/WEEKLY/MONTHLY
✅ - F22.02.04 Shipped
BYDAY filter for weekly recurrence
✅ - F22.02.05 Shipped
UNTIL and COUNT limits; max 2-year recurring horizon
✅ - F22.02.06 Shipped
cancelled_from field to cancel recurring series from a date
✅ - F22.02.07 Shipped
Block expansion service: get_blocked_intervals()
✅ - F22.02.08 Shipped
API: GET expanded intervals, POST create, DELETE block
✅ - F22.02.09 Shipped
Admin UI: maintenance blocks management page
✅
Opening Hours Stack (PL-T185 + PL-T184)
F22.03Layered override system. A single date's effective hours are resolved from most-specific to least-specific override.
How it works- F22.03.01 Shipped
WeeklyHours + DayHours model (HH:MM time strings)
✅ - F22.03.02 Shipped
OpeningHoursOverride document for single-date overrides
✅ - F22.03.03 Shipped
Override modes: closed and modified
✅ - F22.03.04 Shipped
Time breaks within a day (e.g. lunch break)
✅ - F22.03.05 Shipped
get_effective_opening_hours() service method
✅ - F22.03.06 Shipped
API: GET effective hours per date range, POST create override
✅ - F22.03.07 Shipped
Unique constraint: one override per (tenant, location, date)
✅ - F22.03.08 Shipped
Seasonal override via ChainVenueProfile
✅
Booking Engine (PL-T186)
F22.04- F22.04.01 Shipped
Create / update / cancel booking with conflict detection
✅ - F22.04.02 Shipped
Booking validation (opening hours, buffer, capacity)
✅ - F22.04.03 Shipped
No-show logic with grace period
✅ - F22.04.04 Shipped
Audit trail per status change
✅ - F22.04.05 Shipped
Idempotency keys on create
✅ - F22.04.06 Shipped
WaitListEntry FIFO queue with promotion-on-free
✅ - F22.04.07 Shipped
SSE broadcast on status change (chain.bookings.<tenant>.<location>)
✅ - F22.04.08 Shipped
Multi-resource atomic booking (single document, list[resource_ids])
✅ - F22.04.09 Shipped
Per-(tenant,location) asyncio lock for race-free conflict check
✅ - F22.04.10 Shipped
Conflict response with suggested_slots (±2h scan) and can_join_waitlist
✅ - F22.04.20 Shipped
Restricted facility booking (military/school/civic/private_corporate/religious) with permission-gated flow (PL-T217)
✅ - F22.04.21 Shipped
Approval-chain (host_admin → security_officer → optional government_clearance) with role-allow-lists och self-approval-skydd (PL-T217)
✅ - F22.04.22 Shipped
Access-log audit (checkin/checkout/access_denied) med dispatch till security_officers vid access_denied (PL-T217)
✅ - F22.04.23 Shipped
Host-operations-konfliktcheck mot iCal-calendar + restricted_facility_request_expiry_tick (24h-cutoff) (PL-T217)
✅ - F22.04.30 Shipped
Shared-facility-overlay — Booking.shared_facility_owner_tenant_id exponerar bokningen som read-only-spegel hos delägar-tenant via list_for_tenant_including_shared (PL-T224)
✅
Pricing & Payments (PL-T187)
F22.05- F22.05.01 Shipped
Peak / off-peak pricing rules (rule-based stack with peak_multiplier, gated by dynamic_pricing_enabled)
✅ - F22.05.02 Shipped
Member-tier discount (ChainPassport BRONZE/SILVER/GOLD via tier_discount rule)
✅ - F22.05.03 Shipped
Group discount (group_discount rule with min_party_size threshold)
✅ - F22.05.04 Shipped
Duration-bracket discount (duration_bracket rule) and promo-code (promo_code rule)
✅ - F22.05.05 Shipped
Deterministic preview via POST /chain/pricing-rules/preview returning a Quote with line breakdown
✅ - F22.05.06 Shipped
Gift cards: 16-char CSPRNG codes, (tenant_id, code) unique, atomic redemption with audit trail
✅ - F22.05.07 Shipped
Anonymous balance lookup endpoint (rate-limited at gateway) — exposes balance + status only
✅ - F22.05.08 Shipped
Deposit flow — paired deposit + pay_at_venue rows, balance settled at check-in
✅ - F22.05.09 Shipped
Online payment via Stripe PaymentIntent with metadata round-trip
✅ - F22.05.10 Shipped
Stripe webhook /webhooks/stripe/booking-payments — signature verification + StripeWebhookEvent idempotency on event_id
✅ - F22.05.11 Shipped
Refund flow against succeeded rows with parent_payment_id linkage and recompute → PARTIAL_REFUND/REFUNDED
✅ - F22.05.12 Shipped
BookingPayment.audit_trail records every transition (actor, action, metadata)
✅
F&B Menu & Meal Orders (PL-T188)
F22.06- F22.06.01 Shipped
MenuItem with multi-language name/description, EU-14 allergens, dietary flags, kitchen station, course
✅ - F22.06.02 Shipped
MenuPackage with bundle pricing (price < original_total) and min_party_size enforcement
✅ - F22.06.03 Shipped
MealOrder attached to Booking; subtotal/total rolls into Booking.total_amount
✅ - F22.06.04 Shipped
Kitchen printout — ESC/POS thermal-printer payload over raw TCP, PDF-by-email fallback, manual mode
✅ - F22.06.05 Shipped
Time-window availability (available_from / available_until HH:MM)
✅ - F22.06.06 Shipped
Allergen acknowledgement gate when customer has declared allergens
✅ - F22.06.07 Shipped
Status lifecycle (draft/ordered/preparing/ready/delivered/cancelled) with audit trail
✅ - F22.06.08 Shipped
Reprint with idempotent first-print timestamp + audit trail
✅ - F22.06.09 Shipped
SSE broadcast on chain.kitchen.{tenant}.{location} and chain.bookings.{tenant}.{location}
✅ - F22.06.10 Shipped
GET /chain/kitchen/queue filtered by status with per-tenant + per-location isolation
✅ - F22.06.11 Shipped
Multi-language menu listing via Accept-Language header
✅
Customer Booking Flow on Tenant CMS (PL-T189)
F22.07- F22.07.01 Shipped
Multi-step booking wizard, mobile-first
✅ - F22.07.02 Shipped
Multi-language flow (sv/en/fr/de/es + cookie override)
✅ - F22.07.03 Shipped
Upsell prompts at checkout (consumes menu packages)
✅ - F22.07.04 Shipped
Tenant-branded ThemeProvider via ChainWhiteLabelConfig
✅ - F22.07.05 Shipped
Service-worker stale-while-revalidate for tenant-config / resources / menu
✅ - F22.07.06 Shipped
Real-time slot conflict via SSE on bookings.stream
✅ - F22.07.07 Shipped
Idempotent booking submit with crypto.randomUUID key
✅ - F22.07.08 Shipped
Confirmation page with ICS export and share button
✅
Operator Booking Console (PL-T190)
F22.08Hot-key-driven receptions-konsol i admin för chain-venues — single-screen-flow för telefon-bokningar, drop-ins, walk-ins och check-in. Tablet-först (iPad bakom disken), SSE-live, command-palette med actions.
How it works- F22.08.01 Shipped
Phone booking flow (/operator/quick-book med <QuickBookForm>, deterministisk idempotency-key, 409-konflikt-picker med ⌘1/⌘2/⌘3, success-toast med valfri SMS-bekräftelse)
✅ - F22.08.02 Shipped
Drop-in / walk-in queue (/operator/walk-ins 3-panel: walk-in-kö, ring-tillbaka, väntelista; HTML5-drag till floorplan; assign-via-bottom-sheet utan drag)
✅ - F22.08.03 Shipped
⌘K hot-key driven via <OperatorCommandPalette> (action-set: ny bokning/incheckning/walk-in/väntelista/ring tillbaka/avboka, fuzzy-filter, badge-tags för walk-in-count + check-in-due)
✅ - F22.08.04 Shipped
Quick customer search via <CustomerSearch> (debounced fuzzy-sök över ChainPassport + senaste 90 dagars guest-details, dedup på phone/email, 0-träffar autofokuserar "Skapa ny"-CTA)
✅ - F22.08.05 Shipped
Operator landing (/operator/today) med dagens schema, status-fördelning, check-in-due ±30 min, walk-in-räknare och next-slots per resurs-typ — allt i ett aggregerat API-anrop
✅ - F22.08.06 Shipped
Check-in-vy (/operator/check-in) med ±30 min-fönster, namn/telefon-filter och ett-klick "Checka in" mot POST /chain/bookings/{id}/check-in
✅ - F22.08.07 Shipped
Operator-aggregat-API (GET /chain/operator/{location}/today + /customer-search + /next-slots) — en round-trip för landing, dedupad sök, slot-prober per resurs
✅ - F22.08.08 Shipped
SSE-live på chain.bookings.{tenant}.{location} med 400 ms debounced refetch av today-data + walk-ins
✅
Booking Calendar UI (PL-T191)
F22.09- F22.09.01 Shipped
Day / week / month grid with multi-resource swim-lanes
✅ - F22.09.02 Shipped
Drag-and-drop reschedule + resize
✅ - F22.09.03 Shipped
Color-coded booking-type chips (booking-colors.mjs tokens)
✅ - F22.09.04 Shipped
Real-time updates via SSE (/chain/bookings/stream)
✅ - F22.09.05 Shipped
Month-view utilization heatmap (8% – 50% green alpha)
✅ - F22.09.06 Shipped
Optimistic update + 409 revert with toast
✅ - F22.09.07 Shipped
Keyboard nav (← → t Esc)
✅ - F22.09.08 Shipped
URL-driven view/date/location/resource_type
✅ - F22.09.09 Shipped
BookingDetailDrawer — confirm / check-in / cancel inline
✅
Booking List UI (PL-T192)
F22.10- F22.10.01 Shipped
DataTable with sticky resizable columns
✅ - F22.10.02 Shipped
Sort / filter / search
✅ - F22.10.03 Shipped
Saved-views per user (PL-T172)
✅ - F22.10.04 Shipped
Bulk-edit (confirm / cancel / notify)
✅ - F22.10.05 Shipped
Export CSV / Excel / PDF
✅ — POST /chain/bookings/export with {format, filter, columns}, CSV/XLSX/PDF (PL-T211) - F22.10.06 Shipped
Mobile card-variant
✅ — DataTable mobileCardRenderer prop + <MobileBookingCard> on phone widths (PL-T211)
Floorplan Live-View (PL-T193)
F22.11- F22.11.01 Shipped
SVG layout for lanes & tables (FloorplanView with optional svg_template + background_image_url)
✅ - F22.11.02 Shipped
Real-time status (available / reserved / confirmed / in_use / maintenance / retired) with 30 min lookahead
✅ - F22.11.03 Shipped
Counter-screen display mode (/floorplan/display, dark theme, oversized counters, SSE + 5 s polling fallback)
✅ - F22.11.04 Shipped
Drag-to-assign for walk-ins (HTML5 drag-drop → POST /chain/floorplan/{location}/assign-walk-in with 409-handling)
✅ - F22.11.05 Shipped
Floorplan editor for admins (/chain/floorplan/editor, drag tray-to-canvas, inspector for x/y/w/h/rotation)
✅ - F22.11.06 Shipped
Multi-view support (e.g. main floor + summer terrace) with per-view positions on each resource
✅ - F22.11.07 Shipped
SSE stream chain.floorplan.{tenant}.{location} with debounced refetch
✅ - F22.11.08 Shipped
Walk-in queue (enqueue / cancel / list / assign) with TTL → expired
✅
Staff & Event Linking (PL-T194)
F22.12- F22.12.01 Shipped
StaffMember model (roles, skills, certifications, hourly rate)
✅ - F22.12.02 Shipped
Roles: guide, server, kitchen, bartender, manager, host
✅ - F22.12.03 Shipped
Free-form skills tagging (petanque_intro, dj, etc.)
✅ - F22.12.04 Shipped
Certifications with expiry (alcohol_license, first_aid)
✅ - F22.12.05 Shipped
Per-staff location assignments
✅ - F22.12.06 Shipped
Hourly rate + currency tracking
✅ - F22.12.07 Shipped
Active/inactive status
✅ - F22.12.08 Shipped
Duplicate-guard: one StaffMember per user per tenant
✅ - F22.12.09 Shipped
Shift model with start/end datetimes
✅ - F22.12.10 Shipped
Shift conflict detection (409 on overlap)
✅ - F22.12.11 Shipped
Cross-midnight shift support
✅ - F22.12.12 Shipped
Certification expiry validation (bartender → alcohol_license)
✅ - F22.12.13 Shipped
Location-access validation per shift
✅ - F22.12.14 Shipped
Shift status flow (scheduled → confirmed → in_progress → completed)
✅ - F22.12.15 Shipped
Soft-delete with active-shift warning on staff delete
✅ - F22.12.16 Shipped
Staff schedule view (GET /chain/staff/{id}/shifts)
✅ - F22.12.17 Shipped
SSE stream for real-time shift events
✅ - F22.12.18 Shipped
ShiftTemplate with role quotas + time offsets
✅ - F22.12.19 Shipped
Template apply → expand into concrete shifts
✅ - F22.12.20 Shipped
Applicable event-type filter on templates
✅ - F22.12.21 Shipped
Template active/inactive management
✅ - F22.12.22 Shipped
Link shift to booking (POST /chain/bookings/{id}/staff)
✅ - F22.12.23 Shipped
Unlink shift from booking
✅ - F22.12.24 Shipped
List booking staff (GET /chain/bookings/{id}/staff)
✅ - F22.12.25 Shipped
Apply template to booking (auto-link all created shifts)
✅ - F22.12.26 Shipped
Booking cancellation → unlink shifts with audit trail
✅ — BookingService.cancel calls unlink_shifts_for_booking() and records unlinked_shifts_count in booking audit (PL-T211) - F22.12.27 Shipped
Drag-drop on staff calendar (admin UI)
✅
Staff App + Time-Clock (PL-T195)
F22.13- F22.13.01 Shipped
My-shifts view (mobile-first)
✅ - F22.13.02 Shipped
Swap-shift request (accept/decline/cancel)
✅ - F22.13.03 Shipped
Punch-in/out with geo-fence
✅ - F22.13.04 Shipped
Auto-close cron + manager override of open entries
✅ - F22.13.05 Shipped
Tip-distribution rules (even / weighted_by_hours / role_percentage / individual_assigned)
✅ - F22.13.06 Shipped
Tip pay-out with idempotency on (tenant, location, period)
✅ - F22.13.07 Shipped
Monthly payroll summary export (CSV / Fortnox / Visma)
✅
Notifications Hub (PL-T196)
F22.14- F22.14.01 Shipped
Booking confirmation (mail + SMS + push)
✅ - F22.14.02 Shipped
Reminder (24 h + 2 h before)
✅ - F22.14.03 Shipped
Cancellation confirmation
✅ - F22.14.04 Shipped
No-show notification
✅ - F22.14.05 Shipped
Multi-language templates
✅ - F22.14.06 Shipped
Per-channel opt-out in customer portal
✅
Wait-List & Dynamic Re-Allocation (PL-T197)
F22.15- F22.15.01 Shipped
FIFO queue per resource type + time range (WaitListEntry.position)
✅ - F22.15.02 Shipped
Auto-promote on cancellation (WaitListService.promote_for_freed_slot)
✅ - F22.15.03 Shipped
SMS-alert with configurable response deadline (waitlist_promoted event)
✅ - F22.15.04 Shipped
Cron job for expired deadlines (waitlist-expiration-tick, every minute)
✅ - F22.15.05 Shipped
WaitListPromotion-dokument med statusmaskin pending → accepted/declined/expired/superseded
✅ - F22.15.06 Shipped
POST /chain/waitlist/promotions/{id}/accept med token-baserad guest-access
✅ - F22.15.07 Shipped
POST /chain/waitlist/promotions/{id}/decline med valfritt skäl
✅ - F22.15.08 Shipped
Position-recompute vid create/cancel/promote (FIFO inom bucket)
✅ - F22.15.09 Shipped
Snapshot av promotion_response_window_minutes per entry
✅ - F22.15.10 Shipped
handle_resource_unavailable — supersede + retur till WAITING vid maintenance
✅ - F22.15.11 Shipped
Race-säkert accept (concurrent → slot_unavailable 409 + auto-promote nästa)
✅ - F22.15.12 Shipped
Hourly waitlist-position-metrics-rollup för materialiserad estimated_wait_minutes
✅ - F22.15.13 Shipped
SSE-broadcast på chain.waitlist.{tenant}.{location} + chain.waitlist.entry.{id}
✅ - F22.15.14 Shipped
Default-templates (sv/en × SMS/email) seedas vid första profile-create
✅ - F22.15.15 Shipped
Tenant-killswitch via WaitListPolicy.enabled=False
✅ - F22.15.16 Shipped
Customer cancel mid-promotion → SUPERSEDED + nästa kandidat erbjuds
✅
Customer Portal & Loyalty (PL-T198)
F22.16- F22.16.01 Shipped
"My bookings" view on tenant CMS (/account/bookings, three lazy-loaded buckets)
✅ - F22.16.02 Shipped
Booking history (history + cancelled tabs, paginated 50 per page)
✅ - F22.16.03 Shipped
Repeat-book ("same as last time") (POST /me/bookings/{id}/repeat + sessionStorage prefill → /book/{lane\
table|event}) | ✅ - F22.16.04 Shipped
ChainPassport tier-progress badge (<LoyaltyTierBadge> med animerad progress-arc, regular/gold/platinum)
✅ - F22.16.05 Shipped
NPS feedback after visit (<NpsPromptModal> 0-10 + comment, auto-open när outstanding prompt finns)
✅ - F22.16.06 Shipped
Self-service rebook / cancel (<CancelBookingDialog> med quote-preview + reason, party-size modify)
✅ - F22.16.07 Shipped
Gift-card balance overview (/account/gift-cards, balance + expiry + redemption count)
✅ - F22.16.08 Shipped
Notification preferences (/account/preferences, email/SMS/push toggles + audit-trail)
✅
Analytics & Utilization (PL-T199)
F22.17- F22.17.01 Shipped
Per-resource revenue dashboard (GET /chain/analytics/revenue med group_by=resource_type + RevenueChart)
✅ - F22.17.02 Shipped
Occupancy rate per resource (GET /chain/analytics/utilization + AnalyticsUtilization-vy)
✅ - F22.17.03 Shipped
No-show rate trend (KPI på AnalyticsDashboard, AnalyticsMetrics.no_show_rate)
✅ - F22.17.04 Shipped
Peak-time heatmap (GET /chain/analytics/heatmap + UtilizationHeatmap-komponent, 7×24 ISO-vecka)
✅ - F22.17.05 Shipped
Conversion funnel (visit → booking) (GET /chain/analytics/conversion + ConversionFunnel-komponent)
✅ - F22.17.06 Shipped
Customer cohorts (repeat vs first-time) (GET /chain/analytics/customers + CustomerCohortChart)
✅ - F22.17.07 Shipped
PDF monthly report export (POST /chain/analytics/export med format=pdf/csv/xlsx, sync ≤ 92 dagar)
✅ - F22.17.08 Shipped
Pre-computed AnalyticsRollup (day/week/month) + idempotent upsert
✅ - F22.17.09 Shipped
BookingFunnelEvent + unique session-de-dupe + _aggregate_funnel
✅ - F22.17.10 Shipped
analytics_rollup_hourly / _daily / _monthly_close cron-jobb
✅ - F22.17.11 Shipped
Live-delta för dagens bucket (in-memory compute_rollup ovanpå hourly-rollup)
✅ - F22.17.12 Shipped
Capability-gating (chain.analytics.read + chain.analytics.export)
✅
POS + Upsell + QR-Checkin + Marketing (PL-T200)
F22.18## Related documentation
How it works- F22.18.01 Shipped
POS integration Square (transaction push + signed webhook)
✅ - F22.18.02 Shipped
POS integration Zettle/iZettle (transaction push + signed webhook)
✅ - F22.18.03 Shipped
POS integration Stripe Terminal (PaymentIntent + Stripe-Signature skew)
✅ - F22.18.04 Shipped
POS device health-check job (15 min ping + ops-alert)
✅ - F22.18.05 Shipped
Rule-based smart upsell prompts (color_type · party · weekday · season)
✅ - F22.18.06 Shipped
Smart upsell preview API + sessions-dismiss UI
✅ - F22.18.07 Shipped
Signed-JWT QR check-in tokens (HS256, per-tenant HKDF, kid-rotation)
✅ - F22.18.08 Shipped
Instant QR check-in via operator scan (offline-capable via JWKS-cache)
✅ - F22.18.09 Shipped
Marketing-automation: birthday offer (days_before_birthday)
✅ - F22.18.10 Shipped
Marketing-automation: win-back (inactivity_days · historical_min)
✅ - F22.18.11 Shipped
Marketing-automation: gift-card-promo (årlig push)
✅ - F22.18.12 Shipped
Marketing-automation: post-detractor recovery (NPS-trigger)
✅
No features match your filters.