Debug and Harden a Ticketing Backend API
IBMSoftware Engineer · Online AssessmentLast updated
Implement and harden an in-memory ticket service backend to handle deterministic cursor pagination, idempotent reservations, cache invalidation, and oversell prevention.
Problem Statement
You are tasked with fixing and hardening the core logic of an event ticketing backend service. The existing implementation suffers from stale cached availability, race conditions that cause overselling, non-deterministic pagination, and lack of idempotency on booking retries.
Implement the TicketBookingService class with the following methods:
add_event(event_id: str, name: str, event_date: str, total_seats: int) -> None: Registers a new event.event_dateis an ISO-8601 string (YYYY-MM-DD).list_events(limit: int, cursor: str | None = None) -> dict: Returns a paginated list of events ordered chronologically byevent_date, breaking ties byevent_idin ascending order. The response format is{"events": list[dict], "next_cursor": str | None}. Each event dictionary containsevent_id,name,event_date, andavailable_seats. Use cursor-based pagination so concurrent event additions do not cause duplicate or skipped entries.book_tickets(idempotency_key: str, event_id: str, seat_count: int) -> tuple[int, dict]: Attempts to reserveseat_counttickets. Returns an HTTP-style status code and response payload(status_code, body):201: Successful booking. Body:{"booking_id": str, "event_id": str, "seat_count": int}.200: Replay of an identical previous request with the sameidempotency_key. Returns the exact body returned when the original booking was made.400: Invalid inputs (e.g.,seat_count <= 0, event does not exist, oridempotency_keyreused with mismatched parameters).409: Conflict due to insufficient available seats. Body:{"error": "Insufficient seats"}.
get_available_seats(event_id: str) -> int: Returns the current number of available seats. This must utilize an internal cache for read efficiency, but the cache must never return stale values after a successful booking.
Constraints
1 <= total_seats <= 100,0001 <= limit <= 100- Strings (
event_id,idempotency_key,name) consist of printable ASCII characters of length 1 to 64. - Up to
10,000total calls across all methods in a single test run.
Example
service = TicketBookingService()
service.add_event("ev_1", "Concert A", "2026-06-01", 10)
service.add_event("ev_2", "Concert B", "2026-05-01", 5)
# Availability read
assert service.get_available_seats("ev_1") == 10
# Booking tickets
code, res = service.book_tickets("key_1", "ev_1", 4)
# code: 201, res: {"booking_id": "...", "event_id": "ev_1", "seat_count": 4}
# Cached availability is refreshed
assert service.get_available_seats("ev_1") == 6
# Idempotent replay
code_retry, res_retry = service.book_tickets("key_1", "ev_1", 4)
assert code_retry == 200
assert res_retry == res
assert service.get_available_seats("ev_1") == 6
# Oversell attempt
code_err, res_err = service.book_tickets("key_2", "ev_1", 7)
assert code_err == 409
Edge Cases
- Reusing an
idempotency_keywith differentevent_idorseat_countshould return400. - Requesting pages with cursor values that point past the end of the collection should return an empty list and
Nonefornext_cursor. - Booking exactly the remaining number of seats leaves availability at
0without failing.
Hints
Hint 1
Encode your pagination cursor with the compound key `(event_date, event_id)` so pagination remains stable regardless of newly inserted events.
Hint 2
Store idempotency records mapping each `idempotency_key` to both the request parameters and the resulting response payload.
Hint 3
Ensure cache invalidation or synchronous cache updating happens within the same state transition as the seat reservation to prevent stale read windows.
Follow-up questions
- How would you handle distributed idempotency and distributed locking across multiple instances backed by Redis and a relational database?
- If clients need real-time seat selection rather than general admission counts, how does the reservation and lock acquisition pattern change?
- How would you implement cursor pagination if the user wanted to sort events by dynamic fields such as remaining seat availability?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.