fix(loyalty): cross-store enrollment, card scoping, i18n flicker
Some checks failed
Some checks failed
Fix duplicate card creation when the same email enrolls at different stores under the same merchant, and implement cross-location-aware enrollment behavior. - Cross-location enabled (default): one card per customer per merchant. Re-enrolling at another store returns the existing card with a "works at all our locations" message + store list. - Cross-location disabled: one card per customer per store. Enrolling at a different store creates a separate card for that store. Changes: - Migration loyalty_004: replace (merchant_id, customer_id) unique index with (enrolled_at_store_id, customer_id). Per-merchant uniqueness enforced at application layer when cross-location enabled. - card_service.resolve_customer_id: cross-store email lookup via merchant_id param to find existing cardholders at other stores. - card_service.enroll_customer: branch duplicate check on allow_cross_location_redemption setting. - card_service.search_card_for_store: cross-store email search when cross-location enabled so staff at store2 can find cards from store1. - card_service.get_card_by_customer_and_store: new service method. - storefront enrollment: catch LoyaltyCardAlreadyExistsException, return existing card with already_enrolled flag, locations, and cross-location context. Server-rendered i18n via Jinja2 tojson. - enroll-success.html: conditional cross-store/single-store messaging, server-rendered translations and context, i18n_modules block added. - dashboard.html, history.html: replace $t() with server-side _() to fix i18n flicker across all storefront templates. - Fix device-mobile icon → phone icon. - 4 new i18n keys in 4 locales (en, fr, de, lb). - Docs: updated data-model, business-logic, production-launch-plan, user-journeys with cross-location behavior and E2E test checklist. - 12 new unit tests + 3 new integration tests (334 total pass). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -135,6 +135,10 @@
|
||||
"view_dashboard": "Mein Treue-Dashboard anzeigen",
|
||||
"continue_shopping": "Weiter einkaufen"
|
||||
},
|
||||
"already_enrolled_title": "Sie sind bereits Mitglied!",
|
||||
"cross_location_message": "Ihre Karte gilt an allen unseren Standorten:",
|
||||
"single_location_message": "Ihre Karte ist bei {store_name} registriert",
|
||||
"available_locations": "Nutzen Sie Ihre Karte an allen unseren Standorten:",
|
||||
"errors": {
|
||||
"load_failed": "Programminformationen konnten nicht geladen werden",
|
||||
"email_exists": "Diese E-Mail ist bereits in unserem Treueprogramm registriert.",
|
||||
|
||||
@@ -135,6 +135,10 @@
|
||||
"view_dashboard": "View My Loyalty Dashboard",
|
||||
"continue_shopping": "Continue Shopping"
|
||||
},
|
||||
"already_enrolled_title": "You're already a member!",
|
||||
"cross_location_message": "Your card works at all our locations:",
|
||||
"single_location_message": "Your card is registered at {store_name}",
|
||||
"available_locations": "Use your card at all our locations:",
|
||||
"errors": {
|
||||
"load_failed": "Failed to load program information",
|
||||
"email_exists": "This email is already registered in our loyalty program.",
|
||||
|
||||
@@ -135,6 +135,10 @@
|
||||
"view_dashboard": "Voir mon tableau de bord fidélité",
|
||||
"continue_shopping": "Continuer mes achats"
|
||||
},
|
||||
"already_enrolled_title": "Vous êtes déjà membre !",
|
||||
"cross_location_message": "Votre carte est valable dans tous nos points de vente :",
|
||||
"single_location_message": "Votre carte est enregistrée chez {store_name}",
|
||||
"available_locations": "Utilisez votre carte dans tous nos points de vente :",
|
||||
"errors": {
|
||||
"load_failed": "Impossible de charger les informations du programme",
|
||||
"email_exists": "Cet e-mail est déjà inscrit dans notre programme de fidélité.",
|
||||
|
||||
@@ -135,6 +135,10 @@
|
||||
"view_dashboard": "Mäin Treie-Dashboard kucken",
|
||||
"continue_shopping": "Weider akafen"
|
||||
},
|
||||
"already_enrolled_title": "Dir sidd schonn Member!",
|
||||
"cross_location_message": "Är Kaart gëllt an all eise Standuerter:",
|
||||
"single_location_message": "Är Kaart ass bei {store_name} registréiert",
|
||||
"available_locations": "Benotzt Är Kaart an all eise Standuerter:",
|
||||
"errors": {
|
||||
"load_failed": "Programminformatiounen konnten net gelueden ginn",
|
||||
"email_exists": "Dës E-Mail ass schonn an eisem Treieprogramm registréiert.",
|
||||
|
||||
Reference in New Issue
Block a user