Design a flexible event recommendation framework that powers various marketing campaigns through the composition of reusable components. Avoid hardcoding individual campaigns with scattered conditional logic. Instead, build extensible abstractions such as filters, rankers, scorers, and a pipeline or strategy that orchestrates them.
Event {id, name, city, date}Customer {id, name, city}Inventory {eventId, price, quantity}EventsService.getEvents() — fetches all candidate eventsInventoryService.getInventory() — fetches inventory and pricing dataUsersService.getCustomer() — fetches the target userLocationService.getLocationCoordsByCity(city) — returns geographic coordinates for a cityLocationService.calculateDistanceInMiles(coord1, coord2) — computes the distance between two coordinate pairsThe system must support pluggable capabilities that can be mixed and matched:
Inventory.price is below a given threshold (e.g., $50).Implement an entry point method such as:
List<Event> recommend(Customer user, Campaign campaign, int limit)
A Campaign definition should be built via composition and include:
AND / OR logicEvent and Inventory on eventId where necessary.limit events, ordered by the campaign’s ranking strategy.limit up to 100within 100 miles OR price < $50. Rank using a combined score of proximity and price. Return the top 5.this weekend AND price < $50. If the result set is empty, fallback to within the next 30 days. Return the top 5.within the next 30 days. Rank by nearest upcoming date. Return the top 5.The design goal: adding a novel filter or ranker should primarily mean introducing a new component, not rewriting existing orchestration logic.
limit = 5, user city = San Francisco (use sample Events/Inventory provided in your environment)