Files
orion/app/modules/loyalty/docs/production-readiness.md
Samir Boulahtit 4a1f71a312
Some checks failed
CI / ruff (push) Successful in 11s
CI / validate (push) Successful in 26s
CI / dependency-scanning (push) Successful in 32s
CI / pytest (push) Failing after 3h8m55s
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
fix(loyalty): resolve critical production readiness issues
- Add pessimistic locking (SELECT FOR UPDATE) on card write operations
  to prevent race conditions in stamp_service and points_service
- Replace 16 console.log/error/warn calls with LogConfig.createLogger()
  in 3 storefront JS files (dashboard, history, enroll)
- Delete all stale lu.json locale files across 8 modules (lb is the
  correct ISO 639-1 code for Luxembourgish)
- Update architecture rules and docs to reference lb.json not lu.json
- Add production-readiness.md report for loyalty module

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:18:18 +01:00

5.7 KiB

Loyalty Module — Production Readiness Report

Date: 2026-03-13 Tests: 213 passing | Languages: en, fr, de, lb (complete)


Overall Assessment: READY WITH RESERVATIONS

The module has strong fundamentals — clean architecture, comprehensive tests, proper exception handling, full i18n (4 languages), wallet integration, and anti-fraud controls. All critical issues have been resolved.


CRITICAL — Must Fix Before Launch

1. Race Conditions on Card Operations — RESOLVED

Added get_card_for_update() method to card_service.py using SELECT ... FOR UPDATE. All 7 write methods in stamp_service.py (3) and points_service.py (4) now re-fetch the card with a row-level lock before modifying fields.

2. Stale Locale File lu.json — RESOLVED

All lu.json files deleted across the codebase. lb is the canonical Luxembourgish code (ISO 639-1). Architecture rules and docs updated.

3. Console.log Statements in Storefront JS — RESOLVED

All 16 console.log/error/warn calls replaced with LogConfig.createLogger() in 3 storefront JS files (dashboard, history, enroll).


HIGH — Should Fix Before Launch

4. Rate Limiting on Public Endpoints

Status: Rate limiter middleware exists (middleware/rate_limiter.py) but is NOT applied to loyalty endpoints.

Vulnerable endpoints:

  • POST /loyalty/enroll — public, no auth required
  • POST /pins/{pin_id}/verify — PIN lockout helps but doesn't prevent request flooding

Fix: Apply @rate_limit() decorator to public loyalty routes.

Effort: 1 hour

5. T&C Strategy Unresolved

Location: storefront/enroll.html line 140 — TODO comment noting current approach (small text field on program model) won't scale for full legal T&C.

Options:

  • (A) Leverage CMS module to host T&C pages
  • (B) Create dedicated T&C page within loyalty module
  • (C) Accept current approach for MVP, plan post-launch

Effort: Depends on option chosen

6. Accessibility (ARIA Labels)

Status: Zero aria-label attributes across all loyalty templates. Icon-only buttons, modals, and form inputs lack screen reader support.

Priority areas:

  • PIN entry modal (terminal) — security-critical, needs aria-modal
  • Icon-only action buttons (view, edit, delete in tables)
  • Modal dialogs (delete confirmation, terms, barcode)

Effort: 2-3 hours


MEDIUM — Address Post-Launch

7. Point Expiration Task Performance

point_expiration.py processes cards one-by-one. With large card volumes, this could cause long-running DB locks.

Fix: Batch processing with LIMIT and chunked commits.

8. Wallet Sync Retry Logic

Wallet sync task doesn't retry failed individual cards. A transient API error skips the card until next hourly run.

Fix: Add retry with exponential backoff per card.

9. Audit Logging Enhancement

Current: LoyaltyTransaction captures operations but not all operations create transaction records (e.g., program config changes, PIN management).

Fix: Add structured audit logging for admin/management operations.

10. Test Coverage Metrics

Tests pass (213) but no coverage measurement. Unknown blind spots.

Fix: Add pytest-cov and target >80% line coverage.


LOW / Nice-to-Have

11. Field-Level Validation Errors

Current: Generic toast notifications for form errors. No field-specific error highlighting.

12. Session Storage in Enroll-Success

enroll-success.html stores wallet URLs in sessionStorage. Fragile if user navigates away before page loads.

13. Tier System (Future)

Model has tier_config field (Bronze/Silver/Gold) but no business logic implementation. Properly marked as future.


What's Already Solid

Area Status Details
Architecture Excellent Clean service layer, proper separation of concerns
Exception Handling Excellent 30+ custom exceptions, no bare except clauses
Authentication Strong All routes protected, role-based access
PIN Security Strong bcrypt hashing, lockout mechanism, timing-safe comparison
Wallet Security Strong JWT/PKCS#7 signing, env-based secrets, token validation
SQL Injection Safe SQLAlchemy ORM throughout, no raw SQL
Input Validation Good Pydantic schemas on all endpoints
Database Design Excellent Proper indexes, FKs, cascades, composite indexes
Tests Good 213 tests, unit + integration coverage
i18n Complete 4 languages (en/fr/de/lb), ~300 keys each
Dark Mode Excellent Consistent dark: variants on all elements
Responsive Design Excellent Mobile-first with proper breakpoints
Empty States Excellent All list views have proper empty states
Loading States Excellent Spinners and loading indicators everywhere
Confirmation Dialogs Good All destructive actions have modals
Pagination Excellent Full pagination on all list views
Documentation Good 5 docs (business logic, data model, user journeys, UI design, analysis)

Pre-Launch Checklist

  • Fix race conditions with with_for_update() on card operations — DONE
  • Resolve lu.json vs lb.json locale situation — DONE
  • Replace console.log with LogConfig in 3 storefront JS files — DONE
  • Apply rate limiting to public enrollment endpoint
  • Decide on T&C strategy (or accept current for MVP)
  • Add basic ARIA labels to modals and icon-only buttons
  • Manual QA: Walk through all 8 user journeys in docs/user-journeys.md
  • Verify Google Wallet configuration in production environment
  • Configure Apple Wallet (if needed for launch) or gracefully disable
  • Review LOYALTY_* environment variables in production config