Detect Fraud by Propagating Suspicious PII
Company: Affirm
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
# Detect Fraud by Propagating Suspicious PII
Process a stream of `underwriting` and `fraud_flag` events in order. Maintain a set of suspicious PII values drawn from `address`, `phone`, `email`, and `ssn`.
- A `fraud_flag` event adds all of its nonempty PII values and produces `""`.
- An `underwriting` event is suspicious when at least one of its PII values is already suspicious. It produces `"1"` when suspicious and `"0"` otherwise.
- When an underwriting event is suspicious, add *all* of its nonempty PII values to the suspicious set so suspicion can propagate to later events.
Return one result string per input event.
### Function Signature
```python
def classify_fraud_events(events: list[dict]) -> list[str]:
...
```
### Example
```text
Input: [
{"event_type": "underwriting",
"customer_details": {"address": "A", "phone": "P1", "email": "E1", "ssn": "S1"}},
{"event_type": "fraud_flag",
"customer_details": {"address": "A", "phone": "P1", "email": "E1", "ssn": "S1"}},
{"event_type": "underwriting",
"customer_details": {"address": "A", "phone": "P2", "email": "E2", "ssn": "S1"}},
{"event_type": "underwriting",
"customer_details": {"address": "B", "phone": "P2", "email": "E3", "ssn": "S3"}}
]
Output: ["0", "", "1", "1"]
```
### Constraints
- `0 <= len(events) <= 200_000`
- Each event's `event_type` is exactly `"underwriting"` or `"fraud_flag"`.
- `customer_details` may be absent or `null`.
- Recognized PII values, when present, are strings.
### Clarifications
- Ignore missing, `null`, and empty-string PII values.
- Suspicion is global across recognized fields: a value seen as a phone can match the same string in another recognized field.
- A clean underwriting event does not add its PII values.
- A suspicious underwriting event adds its values only after deciding its own result; this produces the same result but makes the ordering explicit.
- Results preserve input-event order, including one empty string for each `fraud_flag` event.
- Do not mutate the input.
### Hints
- Extract the recognized nonempty values once per event.
- Test intersection before updating the set for an underwriting event.
Quick Answer: Process underwriting and fraud-flag events in order while maintaining a global set of suspicious PII values. Fraud flags seed the set, and a matching underwriting event returns suspicious before adding all its own values so suspicion can propagate to later records.
Process underwriting and fraud-flag events in order using one global set of suspicious nonempty address, phone, email, and SSN values. Fraud flags seed the set; a matching underwriting emits 1 and propagates all its values, while a clean underwriting emits 0.
Constraints
- customer_details may be absent or None.
- Recognized present PII values must be strings; empty strings are ignored.
- Suspicion matches globally across field names.
- One output string is returned for every event.
- Inputs are not mutated.
Examples
Input: ([{'event_type':'underwriting','customer_details':{'address':'A','phone':'P1','email':'E1','ssn':'S1'}},{'event_type':'fraud_flag','customer_details':{'address':'A','phone':'P1','email':'E1','ssn':'S1'}},{'event_type':'underwriting','customer_details':{'address':'A','phone':'P2','email':'E2','ssn':'S1'}},{'event_type':'underwriting','customer_details':{'address':'B','phone':'P2','email':'E3','ssn':'S3'}}],)
Expected Output: ['0', '', '1', '1']
Explanation: The supplied example demonstrates two propagation steps.
Input: ([],)
Expected Output: []
Explanation: No events produce no results.
Hints
- Extract recognized nonempty values once per event.
- For underwriting, test intersection before adding values.
- Only suspicious underwriting events propagate.