Loyalty Program
Staccato’s loyalty program uses a 3-tier star system inspired by major coffee chains.
Earning Stars
Stars are earned on every purchase:
- Rate: 2 stars per $1 spent
- Calculation: Based on item price including modifiers
- Example: A $4.95 Caffe Latte with Oat Milk (+$0.80) = $5.75 → 11 stars
Stars are awarded automatically when an order is placed.
Tier System
| Tier | Lifetime Stars | Color | Benefits |
|---|---|---|---|
| Green | 0+ | #22C55E | Base rewards (25, 50, 100 star items) |
| Gold | 300+ | #EAB308 | All Green rewards + Gold-exclusive rewards (150 stars) |
| Platinum | 600+ | #94A3B8 | All rewards + Platinum-exclusive rewards (400 stars) |
Tier Progress
The TierProgress struct calculates:
struct TierProgress {
let currentTier: LoyaltyTier
let lifetimeStars: Int
let nextTier: LoyaltyTier? // nil for Platinum
let starsToNextTier: Int
let progress: Double // 0.0 to 1.0
}Progress is shown as a visual bar on the Rewards tab.
Star Balance vs Lifetime Stars
| Field | Purpose |
|---|---|
starsBalance | Current redeemable stars (decreases when redeemed) |
lifetimeStars | Total stars ever earned (determines tier, never decreases) |
Star Transactions
Every star change is recorded in star_transactions:
| Type | Description |
|---|---|
earned | Stars from a purchase |
redeemed | Stars spent on a reward (negative amount) |
expired | Stars that expired |
bonus | Promotional bonus stars |
adjustment | Manual adjustment by admin |
Transaction history is visible on the Rewards tab (last 50 transactions).
Account Auto-Creation
If a user places their first order without a loyalty account, one is automatically created with the green tier. The LoyaltyService and OrderService both handle this case.