Promotion Feed
Problem
Design PromotionFeed to collect offers and advertisements from named sources in one ordered feed for internal consumers.
Requirements
- Empty feed. A new feed returns an empty array from
listPromotions. - Offer normalization.
ingestOfferappends exactly{source, sourceId: offerId, kind: "offer", text: description}. - Advertisement normalization.
ingestAdvertisementappends exactly{source, sourceId: advertisementId, kind: "advertisement", text: message}. - Complete listing.
listPromotionsreturns every record appended through either ingestion method. - Receipt order. Returned records preserve the exact global ingestion order across sources and promotion kinds.
API
| Signature | Returns | Behavior |
|---|---|---|
PromotionFeed() | A new PromotionFeed | Creates an empty feed. |
ingestOffer(source, offerId, description) | Nothing | Adds one offer supplied by source. |
ingestAdvertisement(source, advertisementId, message) | Nothing | Adds one advertisement supplied by source. |
listPromotions() | An array of objects | Reads the canonical records collected so far. |
Each returned object has exactly four string fields: source, sourceId, kind, and text.
Examples
| Step | Operation | Result |
|---|---|---|
| 1 | ingestOffer("restaurant-app", "offer-7", "20% off") | Nothing |
| 2 | ingestAdvertisement("partner-network", "ad-3", "Free delivery") | Nothing |
| 3 | listPromotions() | [{source: "restaurant-app", sourceId: "offer-7", kind: "offer", text: "20% off"}, {source: "partner-network", sourceId: "ad-3", kind: "advertisement", text: "Free delivery"}] |
Constraints
- Every supplied string is non-empty and has at most 200 characters.
- At most 1,000 promotions are ingested into one feed.
- Calls are sequential.
Notes
Inputs are valid. Duplicate identifiers, validation failures, and concurrent calls are outside the contract.