Files
web/apps/scandic-web/docs/rewards.md
Chuma Mcphoy (We Ahead) 5848f486f3 Merged in chore/LOY-511-Rewards-Documentation (pull request #3367)
Chore/LOY-511): Add documentation for rewards & redeem flow

* chore(LOY-511): Add documentation for the rewards system

* chore(LOY-511): move doc

* chore(LOY-511): remove old doc

* Removed AI documentation

* Remove ToC


Approved-by: Matilda Landström
2026-01-07 11:01:43 +00:00

3.6 KiB

Rewards System

This doc provides a comprehensive guide to the rewards system for developers maintaining the codebase.

Overview

The rewards system manages loyalty benefits for Scandic Hotels members. It combines data from two sources:

  1. Scandic Profile API - Provides reward availability, states, and coupon codes
  2. Contentstack CMS - Provides reward content (labels, descriptions, redeem instructions)

Rewards are tied to membership levels (L1-L7, called "Friends") and come in different types (Tier, Surprise, Campaign, Member-voucher).


### Data Merging Process

Rewards are matched between API and CMS using the `reward_id` field:

```typescript
// From query.ts - merging API and CMS data
const rewards: BaseReward[] = cmsRewards.map((cmsReward) => {
  const apiReward = redeemableRewards.find(
    ({ rewardId }) => rewardId === cmsReward.reward_id
  )!
  return {
    ...apiReward,  // API data: status, coupon codes, redeem location
    ...cmsReward,  // CMS data: label, description, redeem_description
  }
})

Reward Types

1. Tier Rewards (rewardType: "Tier")

Permanent benefits tied to membership level. These are always available once a member reaches the required tier.

Characteristics:

  • Linked to rewardTierLevel (e.g., "L1", "L2")
  • No coupon codes required for most
  • Examples: 10% food discount, early check-in, late checkout

Redeem behavior:

  • On-site: Show membership number at hotel
  • Non-redeemable: Display-only benefits (e.g., earn rate bonuses)

2. Surprise Rewards (rewardType: "Surprise")

Special rewards that appear as wrapped gifts and need to be "unwrapped" before use.

Characteristics:

  • Part of coupons array in API response
  • Have unwrapped: boolean flag on each coupon
  • Must call unwrap mutation before becoming redeemable
  • After unwrapping, appear in regular rewards list

Flow:

  1. User sees surprise modal with wrapped gift
  2. User clicks to reveal/unwrap
  3. Frontend calls rewards.unwrap mutation
  4. Surprise moves to current rewards

3. Campaign Rewards (rewardType: "Campaign")

Promotional rewards with promo codes for online use.

Characteristics:

  • Part of coupons array
  • Have couponCode for redemption
  • Typically redeemed online
  • May have expiration dates

Redeem behavior:

  • Display promo code with copy-to-clipboard functionality

4. Member Voucher (rewardType: "Member-voucher")

Voucher-based rewards similar to campaigns.

Characteristics:

  • Part of coupons array
  • Have coupon codes
  • Similar flow to Campaign rewards

Coupon States & Redemption

Coupon States

State Description Redeemable
claimed Coupon has been claimed by user Yes
viewed Coupon has been viewed (schema only, not used) Yes
redeemed Coupon has been used No

Note: Only redeemed state is actively filtered out in business logic. Both claimed and viewed are treated as redeemable.

Redeem Locations

Location Description UI Behavior
On-site Redeem at hotel (show to staff) Shows membership number badge
Online Redeem digitally with promo code Shows copy-to-clipboard
Non-redeemable Display-only (automatic benefits) No redeem button, info only