Skip to main content
Petanque Life
← Back to all features
22

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
How it works
  • 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.01

Polymorphic 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.02

Time-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.03

Layered 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
How it works
  • 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
How it works
  • 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
How it works
  • 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
How it works
  • 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.08

Hot-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
How it works
  • 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
How it works
  • 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
How it works
  • 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
How it works
  • 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
How it works
  • 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
How it works
  • 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
How it works
  • 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
How it works
  • 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
How it works
  • 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)