Design a Rewards/Loyalty Points System
Requirements: Design a rewards/loyalty system for Zomato: users earn points on orders (based on order value or a defined ruleset), can view their points balance, redeem points for discounts, and the system should support promotional multipliers (e.g., 2x points weekends) without double-counting or losing points on failures.
Design: Model PointsLedger as an append-only event log (earn/redeem events) rather than a mutable balance column, so balance is always derivable and auditable (mirrors real ledger systems, avoids race conditions on concurrent updates). A RewardsService computes eligible points at order-completion time (consuming an order-completed event from a queue for reliability/idempotency, keyed by order ID to prevent double-crediting on retries), while a RedemptionService validates sufficient balance before applying a discount transactionally. Discuss how you'd handle order cancellations/refunds after points were already earned/redeemed (compensating ledger entries), and how promotional multiplier rules would be looked up at earn-time (a rules engine or config service).