# Exercise 1: Choose the Broker for Five Real Requirements

For each scenario below, choose **RabbitMQ**, **Kafka**, or **both**, and justify the choice using the comparison table and sections 3–5 of `broker_rabbitmq_vs_kafka_theory.md`. Cite the specific property that decides it (e.g. "acked messages are deleted," "parallelism capped by partitions," "per-message TTL/priority," "consumer groups read independently").

## Scenario 1: Thumbnail generation

Users upload ~5,000 images/hour. Each image must be resized into 4 thumbnails exactly once by a pool of 20 workers. Some images are corrupt and always fail; they must be set aside for manual inspection after 3 attempts. Premium users' images should be processed before free users' images when there's a backlog.

## Scenario 2: Clickstream analytics

The web app emits ~80,000 click events/second. Three teams consume them: a real-time dashboard (needs the last few seconds), a fraud model (needs per-user ordering), and a data-lake loader (writes hourly Parquet files). Next quarter a fourth team wants to train a model on the last 14 days of events.

## Scenario 3: Order lifecycle events

`orders-service` publishes `OrderCreated`, `OrderPaid`, `OrderShipped`, `OrderCancelled`. Consumers: inventory, email, loyalty points, search index. Events for the same order must be processed in order. When the search team rebuilds their index from scratch, they need every order event since launch.

## Scenario 4: Regional routing of support tickets

Support tickets must be routed to queues by `region.product.severity` (e.g. `eu.payments.critical`). The on-call team subscribes to `*.*.critical`; the EU payments team to `eu.payments.*`; an audit service to everything. Volume is low (a few hundred per hour), and a new routing rule should not require changing the producer.

## Scenario 5: Database change data capture (CDC)

Every committed row change in the `customers` table must be streamed to a cache invalidator, an Elasticsearch indexer and a data warehouse. The warehouse loader is down for maintenance for 6 hours every Sunday and must catch up afterwards without data loss. Only the **latest** state of each customer matters for a new consumer bootstrapping from the stream.

## Deliverables

1. Broker choice + the decisive property for each scenario (two or three sentences each).
2. For every Kafka choice: the topic's **partition key** and a sensible **partition count**, with one sentence on why.
3. For every RabbitMQ choice: the **exchange type** and the queues/bindings you'd declare.
4. For Scenario 3, explain what would go wrong if you used RabbitMQ with four competing consumers on one queue *and* tried to preserve per-order ordering.
5. Name one scenario where running **both** brokers is reasonable, and describe the bridge between them.

## Requirements Checklist

- [ ] Scenario 1 → RabbitMQ: competing consumers, per-message ack, max-retries → DLX, priority queue (or separate premium queue).
- [ ] Scenario 2 → Kafka: many consumer groups on one log, key = `userId` for per-user ordering, retention ≥ 14 days for the new team's replay.
- [ ] Scenario 3 → Kafka: key = `orderId` (per-order ordering), and replay from offset 0 (or retention/compaction) for the index rebuild.
- [ ] Scenario 4 → RabbitMQ: topic exchange with binding keys `*.*.critical`, `eu.payments.*`, `#`.
- [ ] Scenario 5 → Kafka: offsets let the warehouse catch up after downtime; **log compaction** keyed by customer ID gives new consumers the latest state per key.
- [ ] Q4 explains that competing consumers process messages of the same order concurrently (and requeues reorder them), so per-order ordering breaks.
