diff --git a/app/modules/loyalty/docs/production-launch-plan.md b/app/modules/loyalty/docs/production-launch-plan.md index ab98b07b..ccee779b 100644 --- a/app/modules/loyalty/docs/production-launch-plan.md +++ b/app/modules/loyalty/docs/production-launch-plan.md @@ -294,40 +294,106 @@ Tracked separately, not blocking launch. --- -## Critical Path +## Development Status (as of 2026-04-16) -``` -Phase 0 (done) ──┬─► Phase 1 ──┬─► Phase 3 ──┐ - ├─► Phase 2 ──┤ ├─► Phase 8 ──► LAUNCH - └─► Phase 5 ──┘ │ - │ - Phase 4, 6, 7 (parallelizable) ───────────┘ +**All development phases (0-8) are COMPLETE.** 342 automated tests pass. - Phase 9 — post-launch -``` +| Phase | Status | Completed | +|---|---|---| +| Phase 0 — Decisions | ✅ Done | 2026-04-09 | +| Phase 1 — Config & Security | ✅ Done | 2026-04-09 | +| Phase 1.x — Cross-store enrollment fix | ✅ Done | 2026-04-10 | +| Phase 2A — Transactional notifications (5 templates) | ✅ Done | 2026-04-11 | +| Phase 3 — Task reliability (batched expiration + wallet backoff) | ✅ Done | 2026-04-11 | +| Phase 4.1 — T&C via CMS | ✅ Done | 2026-04-11 | +| Phase 4.2 — Accessibility audit | ✅ Done | 2026-04-11 | +| Phase 5 — Wallet UI flags | ✅ Done (already handled) | 2026-04-11 | +| Phase 6 — GDPR, bulk ops, point restore, cascade restore | ✅ Done | 2026-04-11 | +| Phase 7 — Analytics (cohort, churn, revenue + Chart.js) | ✅ Done | 2026-04-11 | +| Phase 8 — Runbooks, monitoring docs, OpenAPI tags | ✅ Done | 2026-04-11 | -Phases 4, 6, 7 can run in parallel with 2/3/5 if multiple developers are available. +**Additional bugfixes during manual testing (2026-04-15):** -## Effort Summary - -| Phase | Days | -|---|---| -| 0 — Decisions | done | -| 1 — Config & security | 2 | -| 2 — Notifications | 4 | -| 3 — Task reliability | 1.5 | -| 4 — A11y + CMS T&C | 2 | -| 5 — Google Wallet hardening | 1 | -| 6 — Admin / GDPR / bulk | 3 | -| 7 — Analytics | 2.5 | -| 8 — Tests / docs / observability | 2 | -| **Launch total** | **~18 days sequential, ~10 with 2 parallel tracks** | -| 9 — Apple Wallet (post-launch) | 3 | +- Terminal redeem: `card_id` → `id` normalization across schemas/JS +- Card detail: enrolled store name resolution, copy buttons, paginated transactions +- i18n flicker: server-rendered translations on success page +- Icon fix: `device-mobile` → `phone` --- -## Open Items Needing Sign-off +## Pre-Launch Checklist -1. ~~**Rate limit caps**~~ — confirmed. -2. **Email copywriting** for the 7 templates × 4 locales (Phase 2.3) — flow: I draft EN, Samir reviews, then translate. -3. ~~**`birth_date` column**~~ — confirmed missing; addressed in Phase 1.4. No backfill needed (not yet live). +Everything below must be completed before going live. Items are ordered by dependency. + +### Step 1: Seed email templates on prod DB +- [ ] SSH into prod server +- [ ] Run: `python scripts/seed/seed_email_templates_loyalty.py` +- [ ] Verify: 20 rows created (5 templates × 4 locales) +- [ ] Review EN email copy — adjust subject lines/body if needed via admin UI at `/admin/email-templates` + +### Step 2: Deploy Google Wallet service account +- [ ] Place service account JSON at `~/apps/orion/google-wallet-sa.json` (app user, mode 600) +- [ ] Set `LOYALTY_GOOGLE_SERVICE_ACCOUNT_JSON=~/apps/orion/google-wallet-sa.json` in prod `.env` +- [ ] Set `LOYALTY_GOOGLE_ISSUER_ID=` in prod `.env` +- [ ] Restart app — verify no startup error (validator checks file exists) +- [ ] Verify: `GET /api/v1/admin/loyalty/wallet-status` returns `google_configured: true` + +### Step 3: Apply database migrations +- [ ] Run: `alembic upgrade heads` +- [ ] Verify migrations applied: `loyalty_003` through `loyalty_006`, `customers_003` + +### Step 4: FR/DE/LB translations for new analytics i18n keys +- [ ] Add translations for 7 keys in `app/modules/loyalty/locales/{fr,de,lb}.json`: + - `store.analytics.revenue_title` + - `store.analytics.at_risk_title` + - `store.analytics.cards_at_risk` + - `store.analytics.no_at_risk` + - `store.analytics.cohort_title` + - `store.analytics.cohort_month` + - `store.analytics.cohort_enrolled` + - `store.analytics.no_data_yet` + +### Step 5: Investigate email template menu visibility +- [ ] Check if `messaging.manage_templates` permission is assigned to `merchant_owner` role +- [ ] If not, add it to permission discovery or default role assignments +- [ ] Verify menu appears at `/store/{store_code}/email-templates` +- [ ] Verify admin menu at `/admin/email-templates` shows loyalty templates + +### Step 6: Manual E2E testing (user journeys) +Follow the **Pre-Launch E2E Test Checklist** at the bottom of `user-journeys.md`: + +- [ ] **Test 1:** Customer self-enrollment (with birthday) +- [ ] **Test 2:** Cross-store re-enrollment (cross-location enabled) +- [ ] **Test 3:** Staff operations — stamps/points via terminal +- [ ] **Test 4:** Cross-store redemption (earn at store1, redeem at store2) +- [ ] **Test 5:** Customer views dashboard + transaction history +- [ ] **Test 6:** Void/return flow +- [ ] **Test 7:** Admin oversight (programs, merchants, analytics) +- [ ] **Test 8:** Cross-location disabled behavior (separate cards per store) + +### Step 7: Google Wallet real-device test +- [ ] Enroll a test customer on prod +- [ ] Tap "Add to Google Wallet" on success page +- [ ] Open Google Wallet on Android device — verify pass renders +- [ ] Trigger a stamp/points transaction — verify pass auto-updates within 60s + +### Step 8: Go live +- [ ] Remove any test data from prod DB (test customers, test cards) +- [ ] Verify Celery workers are running (`loyalty.expire_points`, `loyalty.sync_wallet_passes`) +- [ ] Verify SMTP is configured and test email sends work +- [ ] Enable the loyalty platform for production stores +- [ ] Monitor first 24h: check email logs, wallet sync, expiration task + +--- + +## Post-Launch Roadmap + +| Item | Priority | Effort | Notes | +|---|---|---|---| +| **Phase 9 — Apple Wallet** | P1 | 3d | Requires Apple Developer certs. See `runbook-wallet-certs.md`. | +| **Phase 2B — Marketing module** | P2 | 4d | Birthday + re-engagement emails. Cross-platform (OMS, loyalty, hosting). | +| **Coverage to 80%** | P2 | 2d | Needs Celery task mocking infrastructure for task-level tests. | +| **Admin trash UI** | P3 | 2d | Trash tab on programs/cards pages using existing `?only_deleted=true` API. The cascade restore API exists but has no UI. | +| **Bulk PIN assignment** | P3 | 1d | Batch create staff PINs. API exists for single PIN; needs bulk endpoint + UI. | +| **Cross-location enforcement** | P3 | 2d | `allow_cross_location_redemption` controls enrollment behavior but stamp/point operations don't enforce it yet. | +| **Email template menu** | P2 | 0.5d | Investigate and fix `messaging.manage_templates` permission for store owners. |