Files
orion/app/modules/loyalty/docs/index.md
Samir Boulahtit 6161d69ba2 feat(loyalty): cross-persona page alignment with shared components
Align loyalty pages across admin, merchant, and store personas so each
sees the same page set scoped to their access level. Admin acts as a
superset of merchant with "on behalf" capabilities.

New pages:
- Store: Staff PINs management (CRUD)
- Merchant: Cards, Card Detail, Transactions, Staff PINs (CRUD), Settings (read-only)
- Admin: Merchant Cards, Card Detail, Transactions, PINs (read-only)

Architecture:
- 4 shared Jinja2 partials (cards-list, card-detail, transactions, pins)
- 4 shared JS factory modules parameterized by apiPrefix/scope
- Persona templates are thin wrappers including shared partials
- PinDetailResponse schema for cross-store PIN listings

API: 17 new endpoints (11 merchant, 6 admin on-behalf)
Tests: 38 new integration tests, arch-check green
i18n: ~130 new keys across en/fr/de/lb
Docs: pages-and-navigation.md with full page matrix

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 19:28:07 +01:00

157 lines
6.6 KiB
Markdown

# Loyalty Programs
Stamp-based and points-based loyalty programs with Google Wallet and Apple Wallet integration. Includes anti-fraud features like staff PINs, cooldown periods, and daily limits.
## Overview
| Aspect | Detail |
|--------|--------|
| Code | `loyalty` |
| Classification | Optional |
| Dependencies | `customers` |
| Status | Active |
## Features
- `loyalty_stamps` — Stamp-based loyalty (collect N, get reward)
- `loyalty_points` — Points-based loyalty (earn per euro spent)
- `loyalty_hybrid` — Combined stamps and points programs
- `loyalty_cards` — Digital loyalty card management
- `loyalty_enrollment` — Customer enrollment flow
- `loyalty_staff_pins` — Staff PIN verification
- `loyalty_anti_fraud` — Cooldown periods, daily limits, lockout protection
- `loyalty_google_wallet` — Google Wallet pass integration
- `loyalty_apple_wallet` — Apple Wallet pass integration
- `loyalty_stats` — Program statistics
- `loyalty_reports` — Loyalty reporting
## Permissions
| Permission | Description |
|------------|-------------|
| `loyalty.view_programs` | View loyalty programs |
| `loyalty.manage_programs` | Create/edit loyalty programs |
| `loyalty.view_rewards` | View rewards |
| `loyalty.manage_rewards` | Manage rewards |
## Data Model
See [Data Model](data-model.md) for full entity relationships.
- **LoyaltyProgram** — Program configuration (type, targets, branding)
- **LoyaltyCard** — Customer cards with stamp/point balances
- **LoyaltyTransaction** — Immutable audit log of all operations
- **StaffPin** — Hashed PINs for fraud prevention
- **MerchantLoyaltySettings** — Admin-controlled merchant settings
- **AppleDeviceRegistration** — Apple Wallet push notification tokens
## Pages & Navigation
See [Pages & Navigation](pages-and-navigation.md) for the full cross-persona page matrix, URL patterns, sidebar navigation, and shared component architecture.
All personas share the same page set with scope-appropriate access:
| Page | Admin | Merchant | Store | Storefront |
|---|:---:|:---:|:---:|:---:|
| Program | Any merchant | Own | Own | Public |
| Analytics | Any merchant | Multi-store | Store-scoped | -- |
| Cards/Members | Any merchant | All stores | Store-scoped | Own card |
| Transactions | Any merchant | Store filter | Store-scoped | Own history |
| Staff PINs | Read-only | Full CRUD | Full CRUD | -- |
| Settings | Edit | Read-only | -- | -- |
| Terminal | -- | -- | POS | -- |
## API Endpoints
### Store Endpoints (`/api/v1/store/loyalty/`)
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/program` | Get store's loyalty program |
| `POST` | `/program` | Create loyalty program |
| `PUT` | `/program` | Update loyalty program |
| `DELETE` | `/program` | Delete loyalty program |
| `GET` | `/stats` | Get program statistics |
| `GET` | `/stats/merchant` | Get merchant-wide statistics |
| `GET` | `/cards` | List customer cards |
| `POST` | `/cards/enroll` | Enroll customer in program |
| `POST` | `/stamp` | Add stamp to card |
| `POST` | `/stamp/redeem` | Redeem stamps for reward |
| `POST` | `/stamp/void` | Void stamps |
| `POST` | `/points/earn` | Earn points from purchase |
| `POST` | `/points/redeem` | Redeem points for reward |
| `POST` | `/points/void` | Void points |
| `POST` | `/cards/{id}/points/adjust` | Manual point adjustment (owner) |
| `*` | `/pins/*` | Staff PIN management (list, create, update, delete, unlock) |
### Merchant Endpoints (`/api/v1/merchants/loyalty/`)
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET/POST/PATCH/DELETE` | `/program` | Program CRUD |
| `GET` | `/stats` | Merchant-wide statistics |
| `GET` | `/cards` | List cards across all stores |
| `GET` | `/cards/{id}` | Card detail |
| `GET` | `/cards/{id}/transactions` | Card transaction history |
| `GET` | `/transactions` | Merchant-wide transactions |
| `*` | `/pins/*` | Staff PIN management across stores |
| `GET` | `/settings` | Loyalty settings (read-only) |
| `GET` | `/locations` | Store list for filter dropdowns |
### Admin Endpoints (`/api/v1/admin/loyalty/`)
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/programs` | List all loyalty programs |
| `GET` | `/programs/{id}` | Get specific program |
| `GET` | `/stats` | Platform-wide statistics |
| `GET` | `/merchants/{mid}/cards` | Merchant's cards (on behalf) |
| `GET` | `/merchants/{mid}/cards/{cid}` | Card detail (on behalf) |
| `GET` | `/merchants/{mid}/transactions` | Merchant's transactions |
| `GET` | `/merchants/{mid}/pins` | Merchant's PINs (read-only) |
| `GET` | `/merchants/{mid}/locations` | Merchant's stores |
| `GET` | `/merchants/{mid}/stats` | Merchant statistics |
| `GET/PATCH` | `/merchants/{mid}/settings` | Merchant settings |
| `GET` | `/wallet-status` | Wallet integration status |
| `*` | `/debug/*` | Wallet debug endpoints (super admin) |
### Storefront Endpoints (`/api/v1/storefront/loyalty/`)
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/card` | Get customer's loyalty card |
| `GET` | `/transactions` | Transaction history |
| `POST` | `/enroll` | Self-enrollment |
| `GET` | `/program` | Public program info |
## Scheduled Tasks
| Task | Schedule | Description |
|------|----------|-------------|
| `loyalty.sync_wallet_passes` | Hourly | Sync cards that missed real-time updates |
| `loyalty.expire_points` | Daily 02:00 | Expire points for inactive cards |
## Configuration
Environment variables (prefix: `LOYALTY_`):
| Variable | Default | Description |
|----------|---------|-------------|
| `LOYALTY_DEFAULT_COOLDOWN_MINUTES` | 15 | Cooldown between stamps |
| `LOYALTY_MAX_DAILY_STAMPS` | 5 | Max stamps per card per day |
| `LOYALTY_PIN_MAX_FAILED_ATTEMPTS` | 5 | PIN lockout threshold |
| `LOYALTY_PIN_LOCKOUT_MINUTES` | 30 | PIN lockout duration |
| `LOYALTY_DEFAULT_POINTS_PER_EURO` | 10 | Points earned per euro |
| `LOYALTY_GOOGLE_ISSUER_ID` | — | Google Wallet issuer ID |
| `LOYALTY_GOOGLE_SERVICE_ACCOUNT_JSON` | — | Google service account path |
| `LOYALTY_APPLE_*` | — | Apple Wallet certificate paths |
## Additional Documentation
- [Data Model](data-model.md) — Entity relationships and database schema
- [Business Logic](business-logic.md) — Anti-fraud system, wallet integration, enrollment flow
- [Pages & Navigation](pages-and-navigation.md) — Cross-persona page matrix, URL patterns, shared components
- [User Journeys](user-journeys.md) — Detailed user journey flows with dev/prod URLs
- [Program Analysis](program-analysis.md) — Business analysis and platform vision
- [UI Design](ui-design.md) — Admin and store interface mockups and implementation roadmap