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
This commit is contained in:
committed by
Linus Flood
parent
022fb729f7
commit
5848f486f3
113
apps/scandic-web/docs/rewards.md
Normal file
113
apps/scandic-web/docs/rewards.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# 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 |
|
||||
Reference in New Issue
Block a user