Entertainment & Experiences
The Entertainment vertical powers arcades, escape rooms, event venues, and entertainment centers with four integrated systems: session booking, event ticketing, digital credits, and gamified loyalty. Malet Owners configure these features via the Storefront Window layout system.
NOTE
These features live in the experiences subgraph โ a cross-vertical Feature Plane designed for progressive extraction. Future verticals (Culture, Wellness, Tech) will share these modules. The architecture is documented in docs/architecture/18-progressive-vertical-extraction.md.
Architecture: Two-Plane Design
The Entertainment vertical uses a Control + Feature plane separation:
- Control Plane (
maletssubgraph): VerticalConfig feature flags decide which Entertainment modules are enabled per Malet โeventTicketing,digitalCredits,gamifiedLoyalty,sessionBooking. - Feature Plane (
experiencessubgraph): Self-contained modules for Events, Credit Wallets, and Loyalty. Each module can be extracted to its own subgraph when dedicated vertical Teams form. - Extensions (
servicessubgraph): Session booking fields on the existing Service and Booking entities.
Three new Storefront Window layout slot types are available: EVENT_CALENDAR, CREDIT_STORE, and LEADERBOARD.
Event Ticketing
Create events with tiered pricing, automatic capacity tracking, and QR-code check-in at venues.
Event Lifecycle
DRAFT โ ON_SALE โ SOLD_OUT โ CANCELLED
โ COMPLETED
Events start as DRAFT (invisible to Visitors). The Malet Owner calls publishEvent to begin ticket sales. When all tier capacity is consumed, the event auto-transitions to SOLD_OUT.
Mutations
# Create an event (Malet Owner only)
mutation {
createEvent(
input: {
maletId: "m_luminara"
title: "Friday Game Night"
description: "Weekly competitive gaming tournament"
startDate: "2026-05-01T19:00:00Z"
endDate: "2026-05-01T23:00:00Z"
tiers: [
{ name: "General", price: 1500, capacity: 50 }
{ name: "VIP", price: 3500, capacity: 10 }
]
venue: { name: "Arena Floor", address: "123 Mall Ave" }
}
) {
id
slug
status
}
}
# Publish โ starts ticket sales
mutation {
publishEvent(id: "evt_1") {
id
status
}
}
# Visitor purchases a ticket โ atomic capacity check
mutation {
purchaseEventTicket(input: { eventId: "evt_1", tierId: "vip", userId: "v_meekdenzo" }) {
id
ticketCode # "TK-A7K3M9X2B1" โ for QR scanning
status
}
}
# Scan QR at venue entry
mutation {
checkInEventTicket(ticketCode: "TK-A7K3M9X2B1") {
id
status
}
}
Queries
# Upcoming events for a Malet
query {
upcomingEvents(maletId: "m_luminara") {
id
title
startDate
tiers {
name
price
capacity
soldCount
}
}
}
# Single event by slug (for Malet storefront URLs)
query {
eventBySlug(maletId: "m_luminara", slug: "friday-game-night") {
id
title
description
tiers {
name
price
capacity
soldCount
}
venue {
name
address
}
}
}
Ticket Codes
Each ticket receives a unique TK-{code} identifier for QR scanning โ consistent with the BK-{code} pattern used for booking confirmation codes in the services subgraph.
Digital Credit Wallets
Per-Visitor, per-Malet prepaid credit wallets for in-venue spending (arcade tokens, game credits, etc.).
How Credits Work
- Purchase โ Visitor buys a credit pack via uCart (e.g., 100 tokens for $20)
- Spend โ Credits are deducted per game or activity
- Balance โ Real-time balance query via
myCreditBalance
TIP
Credit packs will be purchasable as a CREDIT_PACK product type through uCart in a future release. For now, Malet Owners can award credits manually via addCredits.
Transaction Types
| Type | Description |
|---|---|
PURCHASE |
Bought credit pack via uCart |
SPEND |
Deducted for game or activity |
REFUND |
Credits returned for cancelled booking |
BONUS |
Welcome bonus or promotional credits |
ADJUSTMENT |
Manual Malet Owner adjustment |
Mutations
# Malet Owner adds credits to Visitor's wallet
mutation {
addCredits(
maletId: "m_luminara"
userId: "v_meekdenzo"
amount: 100
type: PURCHASE
description: "100 Token Pack"
) {
balance
}
}
# Malet Owner deducts credits (with balance guard)
mutation {
deductCredits(
maletId: "m_luminara"
userId: "v_meekdenzo"
amount: 30
description: "Bowling Game"
) {
balance
}
}
# Visitor tops up own credits
mutation {
topUpCredits(maletId: "m_luminara", amount: 50) {
balance
}
}
Queries
# Visitor checks their wallet
query {
myCreditWallet(maletId: "m_luminara") {
balance
transactions {
type
amount
description
createdAt
}
}
}
# Quick balance check
query {
myCreditBalance(maletId: "m_luminara") # Returns: 70
}
Gamified Loyalty
Reward repeat Visitors with points, tier promotions, and achievement badges.
Tier System
Malet Owners configure custom tiers with automatic promotion. When a Visitor earns enough points, their tier is upgraded automatically:
| Tier | Points Required | Example Perks |
|---|---|---|
| Bronze | 100 | 5% credit bonus |
| Silver | 500 | 10% credit bonus, priority booking |
| Gold | 1,000 | 20% credit bonus, VIP access, free birthday game |
Achievements
Award badges for milestones โ idempotent ($addToSet ensures duplicate awards are safely ignored):
played-10-gamesfirst-visitbirthday-booking
Mutations
# Configure loyalty program (Malet Owner)
mutation {
configureLoyalty(
maletId: "m_luminara"
input: {
pointsPerPurchase: 10
pointsPerVisit: 5
tiers: [
{ name: "Bronze", minPoints: 100 }
{ name: "Silver", minPoints: 500 }
{ name: "Gold", minPoints: 1000 }
]
}
) {
id
}
}
# Award points (auto-promotes tier)
mutation {
awardLoyaltyPoints(
maletId: "m_luminara"
userId: "v_meekdenzo"
points: 50
reason: "Murchase completed"
) {
totalPoints
tier
}
}
# Record a visit
mutation {
recordVisit(maletId: "m_luminara") {
visitCount
totalPoints
}
}
# Award achievement badge
mutation {
awardAchievement(maletId: "m_luminara", userId: "v_meekdenzo", slug: "first-visit") {
achievements {
slug
awardedAt
}
}
}
Queries
# Visitor's loyalty state
query {
myLoyalty(maletId: "m_luminara") {
totalPoints
currentPoints
tier
visitCount
achievements {
slug
awardedAt
}
}
}
# Top Visitors leaderboard
query {
loyaltyLeaderboard(maletId: "m_luminara", limit: 10) {
userId
totalPoints
tier
}
}
Session Booking
Extended booking fields for entertainment venues on the existing services subgraph:
| Field | Description |
|---|---|
sessionType |
INDIVIDUAL, GROUP, or OPEN_PLAY |
maxParticipants |
Capacity per session (e.g., 6 for escape room) |
groupBookingEnabled |
Allow multi-Visitor reservations |
checkInStatus |
NOT_CHECKED_IN โ CHECKED_IN / NO_SHOW |
checkInCode |
Unique code for QR scan at venue |
These fields extend the existing Service and Booking entities โ no new subgraph needed.
Related
- Storefront Sections โ Configure
EVENT_CALENDAR,CREDIT_STORE, andLEADERBOARDlayout slots - Search Engine Administration โ Events are indexable in Universal Search
- Alerts & Notifications โ Event reminders and loyalty milestone notifications
- Tag Registry โ Categorize entertainment Malets with section tags
- Teams & Sub-Groups โ Organize venue staff with Custom RBAC roles
- Professional Services & Client Portals โ Sibling vertical in the shared
experiencessubgraph Feature Plane - Wellness & Beauty โ Sibling vertical sharing the
experiencessubgraph; reuses gamified loyalty - Culture & Arts โ Sibling vertical reusing Event Ticketing and Gamified Loyalty for cultural venues
- Tech & Electronics โ Sibling vertical reusing Credit Wallets for trade-in and Gamified Loyalty for purchases
- Arcade & Gaming โ Sibling vertical reusing Credit Wallets for store credit and Gamified Loyalty for purchases
- Fashion Vertical โ Sibling vertical with variant grids, size charts, lookbooks, and product collections
- Vertical Seeding Infrastructure โ Multi-tenant test data seeding for all 11 verticals including entertainment events and loyalty