# 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 |