From 64fe58c1715bd29a4f81baa8878f9b23134781b2 Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Wed, 15 Apr 2026 22:01:26 +0200 Subject: [PATCH] fix(loyalty): normalize card id field, fix terminal redeem bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The terminal redeem failed with "card not found: unknown" because CardLookupResponse used card_id while CardDetailResponse (from refreshCard) used id. After refresh, selectedCard.card_id was undefined. Fix: standardize on 'id' everywhere (the universal convention): - CardLookupResponse: card_id → id - _build_card_lookup_response: card_id= → id= - loyalty-terminal.js: selectedCard.card_id → selectedCard.id (5 refs) - Removed the card_id/model_validator approach as unnecessary Also fixes Chart.js recursion error on analytics page (inline CDN script instead of optional-libs.html include which caused infinite template recursion in test context). 342 tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) --- app/modules/loyalty/routes/api/store.py | 2 +- app/modules/loyalty/schemas/card.py | 2 +- .../loyalty/static/store/js/loyalty-terminal.js | 10 +++++----- .../loyalty/templates/loyalty/store/analytics.html | 3 +-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/app/modules/loyalty/routes/api/store.py b/app/modules/loyalty/routes/api/store.py index ab8d4b70..870626b1 100644 --- a/app/modules/loyalty/routes/api/store.py +++ b/app/modules/loyalty/routes/api/store.py @@ -420,7 +420,7 @@ def _build_card_lookup_response(card, db=None) -> CardLookupResponse: available_rewards.append(reward) return CardLookupResponse( - card_id=card.id, + id=card.id, card_number=card.card_number, customer_id=card.customer_id, customer_name=card.customer.full_name if card.customer else None, diff --git a/app/modules/loyalty/schemas/card.py b/app/modules/loyalty/schemas/card.py index 0a21a590..0eb490b6 100644 --- a/app/modules/loyalty/schemas/card.py +++ b/app/modules/loyalty/schemas/card.py @@ -128,7 +128,7 @@ class CardLookupResponse(BaseModel): """Schema for card lookup by QR code or card number.""" # Card info - card_id: int + id: int card_number: str # Customer diff --git a/app/modules/loyalty/static/store/js/loyalty-terminal.js b/app/modules/loyalty/static/store/js/loyalty-terminal.js index ac5114d8..6efdbfca 100644 --- a/app/modules/loyalty/static/store/js/loyalty-terminal.js +++ b/app/modules/loyalty/static/store/js/loyalty-terminal.js @@ -284,7 +284,7 @@ function storeLoyaltyTerminal() { loyaltyTerminalLog.info('Adding stamp...'); await apiClient.post('/store/loyalty/stamp', { - card_id: this.selectedCard.card_id, + card_id: this.selectedCard.id, staff_pin: this.pinDigits }); @@ -296,7 +296,7 @@ function storeLoyaltyTerminal() { loyaltyTerminalLog.info('Redeeming stamps...'); await apiClient.post('/store/loyalty/stamp/redeem', { - card_id: this.selectedCard.card_id, + card_id: this.selectedCard.id, staff_pin: this.pinDigits }); @@ -308,7 +308,7 @@ function storeLoyaltyTerminal() { loyaltyTerminalLog.info('Earning points...', { amount: this.earnAmount }); const response = await apiClient.post('/store/loyalty/points/earn', { - card_id: this.selectedCard.card_id, + card_id: this.selectedCard.id, purchase_amount_cents: Math.round(this.earnAmount * 100), staff_pin: this.pinDigits }); @@ -327,7 +327,7 @@ function storeLoyaltyTerminal() { loyaltyTerminalLog.info('Redeeming reward...', { reward: reward.name }); await apiClient.post('/store/loyalty/points/redeem', { - card_id: this.selectedCard.card_id, + card_id: this.selectedCard.id, reward_id: this.selectedReward, staff_pin: this.pinDigits }); @@ -340,7 +340,7 @@ function storeLoyaltyTerminal() { // Refresh card data async refreshCard() { try { - const response = await apiClient.get(`/store/loyalty/cards/${this.selectedCard.card_id}`); + const response = await apiClient.get(`/store/loyalty/cards/${this.selectedCard.id}`); if (response) { this.selectedCard = response; } diff --git a/app/modules/loyalty/templates/loyalty/store/analytics.html b/app/modules/loyalty/templates/loyalty/store/analytics.html index c4f717e8..a4cb5b2b 100644 --- a/app/modules/loyalty/templates/loyalty/store/analytics.html +++ b/app/modules/loyalty/templates/loyalty/store/analytics.html @@ -155,7 +155,6 @@ {% endblock %} {% block extra_scripts %} -{% include 'shared/includes/optional-libs.html' with context %} -{{ chartjs_loader() }} + {% endblock %}