Process auth requests with fraud rules
Company: Stripe
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Technical Screen
Quick Answer: This question evaluates a candidate's ability to implement stateful stream processing and event handling, including applying time-scoped fraud rules to authorization requests, maintaining chronological ordering, and producing verified outputs via unit tests.
Constraints
- 0 <= len(requests) <= 200000
- 0 <= len(rules) <= 200000
- 0 <= time <= 10^9
- 0 <= amount <= 10^9 (integer)
- field ∈ {"unique_id", "amount", "card_number", "merchant"}
- A rule with time t applies to any request with timestamp >= t
- Report must be sorted by time ascending; if times are equal, preserve request input order
- Rule matching uses string equality: rule.value == str(request[field])
Solution
def process_authorizations(requests, rules):
# Build earliest activation time for each (field, value)
allowed_fields = {"unique_id", "amount", "card_number", "merchant"}
earliest = {}
for r in rules:
f = r.get("field")
if f not in allowed_fields:
continue
t = r["time"]
v = str(r["value"]) # compare using string equality
key = (f, v)
if key in earliest:
if t < earliest[key]:
earliest[key] = t
else:
earliest[key] = t
# Sort requests by time; stable for equal times (preserve input order)
indexed = list(enumerate(requests))
indexed.sort(key=lambda it: (it[1]["time"], it[0]))
result_lines = []
for _, req in indexed:
t = req["time"]
decision = "APPROVE"
for f in ("unique_id", "amount", "card_number", "merchant"):
v = str(req[f])
start = earliest.get((f, v))
if start is not None and start <= t:
decision = "REJECT"
break
result_lines.append(f"{t} {req['unique_id']} {req['amount']} {decision}")
return result_lines
Explanation
Time complexity: O(n log n + r), where n = number of requests and r = number of rules. Space complexity: O(r) additional space for the rule index (excluding output).
Hints
- Precompute the earliest activation time for each (field, value) pair using a dictionary.
- Sort requests by time; for equal times, rely on stable sort to preserve input order.
- For each request, check if any matching (field, str(value)) has activation_time <= request.time.