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