AI Briefing
KO

Where Can I Use This Coupon? — Building an Event-Driven Applicable Product Lookup System

·2025.04.21 07:02

Key point

The team indexed applicable products for coupons into Elasticsearch, reflecting coupon and product changes in real time.

Details

The Sale Pricing team at 29CM Commerce Core Engineering launched the coupon-applicable product list lookup feature in February 2025 to answer the question users asked most often: "What products can I use this coupon on?"

While it looked like a simple list lookup, it was actually far more complex. Even when a coupon was mapped to a product, whether it could actually be applied depended on individual settings such as the product's selling price or whether coupons were allowed on it, and the relationship between coupons and products kept changing according to operational policies and discount schedules. In particular, "exclusion mapping" required evaluating against 29CM's entire set of hundreds of thousands of active products minus specific excluded items, which meant the system had to automatically reflect newly registered or reactivated products as well.

The feature also had to match the existing PLP/SRP user experience. Since it needed to provide the same category, price range, and brand filters along with sorting by popularity, latest, and price, the team designed it around indexing per-product coupon-applicability information into Elasticsearch.

There were three core requirements:

  • Real-time data synchronization: Immediately reflect coupon and product changes
  • Support for various mapping methods: Handle both inclusion mapping and exclusion mapping with the same structure
  • Search optimization: Provide fast filtering and sorting via ES indexing

The implementation was built as an event-driven architecture. When a product or coupon was created or modified, a message was published to the A.Coupon Applicable Product Update Kafka topic, and the Coupon-Event-Worker consumed it to determine the applicability of each coupon-product pair. If applicable, it was stored in the Coupon Applicable Product Denormalized Table; if not, it was deleted.

Changes to this denormalized table were captured via Debezium and published to the B.Coupon Applicable Product CDC topic. The Coupon-Event-Worker then consumed this again, looked up the full list of applicable coupons based on the changed product, and sent it to the C.Coupon Applicable Product Sync topic. Finally, the ES-Indexer received this message and indexed the list of applicable coupons per product into Elasticsearch.

With this structure, the latest state was kept near real-time whenever coupon settings or products changed, and complex policies such as inclusion and exclusion mapping could be expressed with the same data structure. More importantly, thanks to the denormalized table, determining "whether a specific coupon is applicable to a specific product" could now be done quickly with a single table lookup, improving both performance and maintainability across the entire coupon domain.

The design changed several times during development. Initially, a structure running multiple parallel batches was considered, but based on team feedback, the design converged on the event-driven structure. When excessive messages were published early on and caused a consumption bottleneck, throughput was improved through Batch Consuming, Kafka tuning, and logic improvements that limited publishing to only the targets that actually needed updating.

Over about two and a half months, the work was carried out from design to launch together with fellow developer Yang Yu-rim on the same team, and it was deeply rewarding to actually deliver a feature that so many users had been waiting for. In the end, this project went beyond a simple "coupon usage lookup" to build a foundation that makes the entire coupon domain simpler and faster.

This summary was generated automatically by AI. Check the original for the author's claims and context. Copyright belongs to the original author.

Our guide explains how the AI works. Report summary errors, attribution issues, or removal requests via Contact.