Production-Ready Event Ingestion Handler: Validation, Idempotent Writes, DLQ, Metrics
Company: Scribd
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Onsite
Write a function that receives a single event, validates its fields and their types, and writes it to a database. An event is a JSON-like record that includes an `event_id` and an `object_id` plus other fields.
No real database is available in the interview environment, and the code does not need to run. Use a small database interface of your own, such as `db.execute(sql, params)`, and explain your reasoning as you write. The interviewer evaluates production readiness as well as correctness: what happens to bad input, how failures surface, and whether the handler can be operated.
### Constraints and Clarifications
- The source names only `event_id` and `object_id`. For the other fields, state your assumptions. A reasonable working set is an event type, an occurrence timestamp, and a free-form payload.
- Events arrive from an upstream system over the network. That system may deliver the same event more than once.
- You may define the target table.
### Clarifying Questions
- Which fields are required, and what are their types? Are `event_id` values globally unique, and are they strings or integers?
- Should unknown extra fields be rejected, dropped, or stored as they are?
- Is a dead-letter queue (DLQ) or similar side channel available for events that cannot be processed?
- If the same `event_id` arrives again with different contents, which version is correct?
### Part 1 — Implement Validation and the Write
Write the handler. It should check that required fields are present and have the expected types, then insert the event.
```hint Separate the outcomes
Before writing code, list every outcome of one call, including valid input, each kind of invalid input, and each kind of failed write, and decide what the caller and the operators should see for each.
```
#### What This Part Should Cover
- Presence and type checks with clear, specific error reasons.
- A parameterized write with a table definition that supports it.
- Explicit behavior when validation fails, rather than a silent return.
### Part 2 — Justify Your Type Enforcement
The interviewer asks why you strictly enforce types only on `event_id` and `object_id`, and why you do not handle the other fields the same way. Defend or revise your choice.
```hint What the identifiers are used for
Think about which fields the storage layer and downstream consumers depend on for identity and lookups, and what goes wrong if one of them arrives with the wrong type.
```
#### What This Part Should Cover
- Why identifier fields need stricter guarantees than descriptive fields.
- The trade-off between strict validation and tolerance of schema evolution.
- What happens to fields you do not validate.
### Part 3 — Duplicate Events
"The upstream network has a fault, and we start receiving duplicate events. How does your current code handle it?" Change the code so that duplicates are handled correctly.
```hint Let the database decide
Consider where a uniqueness guarantee must live so that it still holds when two copies of the same event are processed at the same moment.
```
#### What This Part Should Cover
- An idempotent write that holds under concurrency.
- How a duplicate is reported to the caller and counted.
- What to do when a duplicate ID carries different contents.
### Part 4 — Failure Handling and Operability
Where do events that fail validation go? What happens when the database write fails? What do you log, and which metrics does this handler emit?
```hint Assume someone must debug this later
Picture an operator trying to answer "how many events did we lose yesterday, and why" using only what your handler produced.
```
#### What This Part Should Cover
- Logging and a DLQ for events that cannot be processed.
- Retry behavior that distinguishes transient from permanent failures.
- Metrics and alerts that make rejected, duplicated, and failed events visible.
### What a Strong Answer Covers
- Correct validation and a safe, parameterized insert.
- Idempotency enforced by a database constraint, not by a check-then-insert in application code.
- No silent data loss: every rejected or failed event is logged, routed to a DLQ, and counted.
- Metrics, retries, and a DLQ raised proactively while writing the handler, not only after the interviewer asks.
### Follow-up Questions
1. The database is down for ten minutes. What happens to incoming events, and how are they recovered?
2. A new version of the upstream producer sends `object_id` as a string instead of an integer. How does your handler behave, and how would you roll out a schema change safely?
3. How would you batch writes for higher throughput without losing per-event error reporting?
Overview: A coding question that asks you to write a handler that validates an incoming event's fields and types and writes it to a database. It tests production readiness: why identifier fields need strict type checks, idempotent writes when upstream network faults cause duplicate events, and logging, dead-letter queues, retries, and metrics for failures.
Read the full Scribd Software Engineer interview experience this question came from