Doc Status: Current for the referral implementation in the Hono backend, landing booking flow, dashboard referral page, partner profile page, and Remotion sticker renderer as of 2026-06-11.
Why This Matters
House of Legends needs referrals that feel natural to guests while still giving operators accurate partner attribution. Hotels, bars, pubs, concierges, and influencers can share a clean public link or QR sticker without exposing the underlying referral code. The backend remains the source of truth for partner identity, discount rules, commission terms, earned commission rows, and payout state. One referral partner can own multiple managed codes and multiple public/go/{slug} or /{locale}/go/{slug} links. Landing only stores hidden attribution and passes it back during booking; dashboard manages partners, codes, links, commercial rules, and operational materials.
How It Works
The guest sees a friendly URL such as:referralCode and referralLinkId in first-party attribution storage, applies any guest discount in booking preview, shows the partner attribution in checkout, and sends the hidden referralLinkId when creating the reservation. Guests who have a visible promo or referral code can also enter it in the payment step before leaving for OnePay.
Partners can also open a dedicated noindex page:
GET /api/referral-partners/{slug}/profile, explains the current earning rules, and shows safe aggregate statistics, active codes, and active links. It is public for convenience but excluded from indexing and normal site navigation.
PostHog Attribution
PostHog receives referral context in three places:| Event source | Event | Referral fields |
|---|---|---|
| Hono resolver | referral link resolved | referral_code_id, referral_code, referral_partner_id, referral_partner_name, referral_partner_type, referral_link_id, referral_link_slug, referral_link_channel, attribution_event_id, has_referral |
| Hono booking and payment events | reservation created, checkout started, payment completed, payment failed, reservation cancelled, refund processed | Same partner/code/link identifiers plus referral_discount_amount_vnd |
| Landing browser analytics | referral_connected and later PostHog browser events | Registered referral super properties under the same partner/code/link names so checkout behavior can be filtered by partner |
/go/{slug} or /{locale}/go/{slug} link resolves successfully, even if the visitor never completes checkout.
Operator Workflow
Create or update a referral partner
In the dashboard referral page, create the partner once, set its type, status, contact fields, and public slug. The slug controls
/partner/{slug}.Attach one or more managed referral codes
Create referral codes under the partner. Each code owns optional guest discount rules and partner commission terms. Active referral codes require a positive commission value.
Generate a friendly link
Use the QR links panel to create a public slug, destination path, channel, placement label, and status. Channels include QR sticker, hotel menu, bar, pub, concierge, influencer, and other.
Create the sticker artwork
The dashboard previews the QR and provides a Remotion render command. The editor package renders printable PNG stickers from the same
/go/{slug} URL.Track paid attribution
When a referred reservation is paid, Hono creates an earned commission row based on the final paid amount and the code’s commission rules.
Commercial Rules
| Rule | Owner | Notes |
|---|---|---|
| Partner identity | Hono | Stored once in hol_referral_partners; multiple codes can point to the same partner. |
| Guest discount | Hono | Optional. Can be percentage or fixed VND amount. |
| Partner commission | Hono | Required for active codes. Can be percentage or fixed VND amount. |
| Commission basis | Hono | Currently final paid amount. |
| Commission cap | Hono | Optional maximum commission amount in VND. |
| Partner profile page | Hono and Landing | /partner/{slug} is public/noindex and shows safe rules, stats, active codes, and active links. |
| Hidden attribution storage | Landing | Cookie and local storage under first-party House of Legends origin. |
| QR and sticker artwork | Dashboard and editor | Dashboard creates links and previews QR; Remotion renders print assets. |
| Payout state | Hono | Dashboard updates commission status and creates payout batches. |
Referral discounts and referral commissions are separate values. A partner can receive a commission even when the guest receives no discount.
Data Model
The referral implementation adds these major records:| Table | Purpose |
|---|---|
hol_referral_partners | Partner identity, status, type, contact fields, notes, and public slug. |
hol_referral_codes | Managed code rules, guest discount configuration, partner commission configuration, and partner relation. |
hol_referral_links | Public slug, destination path, placement channel, and managed code link. |
hol_referral_attribution_events | Resolve-time attribution events for audit and conversion analysis. |
hol_referral_commissions | Earned commission rows created after successful paid reservations. |
hol_referral_payouts | Payout batches that group approved or payout-pending commissions. |
hol_reservation_records.referral_link_id | The hidden link attached to a paid reservation. |
API Surfaces
- Public resolve
- Dashboard links
- Dashboard partners
- Public partner page
- Commission ledger
/go/{slug} and /{locale}/go/{slug} routes. It resolves a friendly public slug, records attribution metadata, and returns hidden booking attribution for the landing app.Remotion Sticker Templates
The editor package includes three still templates:| Template | Composition ID | Use case |
|---|---|---|
| Classic Gold | ReferralSticker-ClassicGold | General square sticker or menu placement. |
| Menu Tent | ReferralSticker-MenuTent | Vertical table card or menu insert. |
| Influencer Card | ReferralSticker-InfluencerCard | Social profile or creator media card. |
Release Audit Notes
Focused verification for this implementation should include:| Check | Command or action |
|---|---|
| Hono typecheck | pnpm --filter @hol/hono typecheck |
| Hono OpenAPI | pnpm --filter @hol/hono generate |
| Fern client | pnpm --filter @hol/client generate |
| Landing typecheck | pnpm --filter @hol/landing typecheck |
| Dashboard typecheck | pnpm --filter @hol/dashboard typecheck |
| Sticker render | pnpm --filter @hol/editor render:referral-sticker -- --url "https://houseoflegends.vn/go/test" |
Implementation owners
Implementation owners
| Area | Owner files |
|---|---|
| Backend schema and services | apps/hono/src/db/schema/referrals.sql.ts, apps/hono/src/services/booking-config/referral-link.service.ts, apps/hono/src/services/booking-config/referral-commission.service.ts |
| Landing hidden attribution | apps/landing/app/go/[slug]/route.ts, apps/landing/app/[locale]/go/[slug]/route.ts, apps/landing/lib/referrals/referral-go-route.ts, apps/landing/lib/referrals/referral-attribution.ts, apps/landing/contexts/booking/booking-context.tsx |
| Dashboard operations | apps/dashboard/app/dashboard/referrals/referrals-client.tsx, apps/dashboard/components/admin/referrals/referral-link-sticker-panel.tsx, apps/dashboard/components/admin/referrals/referral-commission-ledger.tsx |
| Sticker renderer | apps/editor/src/compositions/referral/referral-sticker.tsx, apps/editor/scripts/render-referral-sticker.ts |
