Guest Profiles — House of Legends
Documented: 2026-05-11
Guest Journey
Reservation Made
│
▼
QR Code Received (via email/WhatsApp)
│
▼
Guest Arrives → Scan QR at Venue
│
▼
Profile Created/Linked
│
├──► Reaction (WAVE/CHEERS/HEART other guests)
├──► Photo Wall (submit photo, like others)
├──► Lucky Spin (win comp items)
└──► Google Review Challenge (earn rewards)QR Code & Onboarding
QR Code Content
Each reservation gets a unique QR code containing:
{
"reservationId": "abc123",
"token": "guest-token-xyz",
"showDate": "2026-05-15"
}Profile Creation Flow
- Guest scans QR with phone camera
- App opens
/profile?token=xxx - If not logged in → Clerk OAuth (Google/Facebook)
- Profile created/linked via token
- Guest sees: nickname input, mood tags, origin
Tables
guestProfiles: defineTable({
reservationId: v.optional(v.id("reservations")),
tableId: v.optional(v.id("tables")),
token: v.string(),
googleId: v.optional(v.string()),
facebookId: v.optional(v.string()),
email: v.optional(v.string()),
avatarUrl: v.optional(v.string()),
nickname: v.string(),
origin: v.string(),
moodTags: v.array(v.string()),
bio: v.optional(v.string()),
showDate: v.string(),
checkedIn: v.boolean(),
createdAt: v.number(),
updatedAt: v.number(),
})
.index("by_reservation", ["reservationId"])
.index("by_show_date", ["showDate"])
.index("by_token", ["token"]);Reactions (WAVE/CHEERS/HEART)
Guests can react to other guests (not themselves):
- WAVE 👋 — Hello/greeting
- CHEERS 🥂 — Toast/celebration
- HEART ❤️ — Love/appreciation
Reaction Flow
- Guest views other profiles on wall/table
- Taps reaction button
- Reaction saved to
guestReactions - Target guest sees reaction notification
Table
guestReactions: defineTable({
fromProfileId: v.id("guestProfiles"),
toProfileId: v.id("guestProfiles"),
reactionType: v.union(
v.literal("WAVE"),
v.literal("CHEERS"),
v.literal("HEART"),
),
showDate: v.string(),
createdAt: v.number(),
})
.index("by_to_profile", ["toProfileId"])
.index("by_from_profile", ["fromProfileId"])
.index("by_show_date", ["showDate"]);Mood Tags
Guests select mood tags during onboarding:
| Tag | Description |
|---|---|
LOOKING_FOR_DATE | Looking for a date |
GET_DRUNK | Here to enjoy drinks |
FIRST_TIME | First time visitor |
REGULAR | Returning guest |
CELEBRATING | Special occasion |
GOOD_FRIENDS | Out with friends |
SOLO | Flying solo |
WITH_FAMILY | Family outing |
Components
Profile Card
Displays:
- Avatar (or generated initial)
- Nickname
- Origin
- Mood tags
- Reaction count (received)
Reaction Button
Three-state button: WAVE / CHEERS / HEART
- Tapping cycles through reactions
- Shows count for each type
Onboarding Flow
Step 1: Scan QR → Token validated
Step 2: Login with Google/Facebook (or skip)
Step 3: Enter nickname
Step 4: Select mood tags (multi-select)
Step 5: Select origin (dropdown)
Step 6: Profile created → Redirect to experienceBackend Functions
| Function | Purpose |
|---|---|
profiles.createFromReservation | Create profile on check-in |
profiles.linkOAuth | Link Google/Facebook to profile |
profiles.addReaction | Add reaction to another guest |
profiles.getReactions | Get reactions for a profile |
profiles.updateMoodTags | Update mood tags |