Design a Rule Evaluation Engine for Spending Policy Violations
RipplingSoftware Engineer · Technical ScreenLast updated
This problem tests your ability to design a scalable, extensible rule engine that evaluates financial transactions against dynamic spending policies.
Problem Statement
Design a software component that evaluates incoming transaction requests against a set of spending policies to determine if the transaction should be 'APPROVED' or 'DENIED'.
Requirements
- Policy Structure: Policies consist of conditions (e.g.,
amount > 500,category == 'Travel',merchant == 'Amazon'). - Dynamic Evaluation: Policies should be configurable without requiring a full system deployment.
- Transaction Context: A transaction includes
transaction_id,user_id,amount,currency,category, andmerchant_name. - Performance: Evaluation must be performed in near real-time (latency < 100ms).
Task
Define an interface or class structure that allows for defining, storing, and evaluating these rules. You must implement an evaluation function that processes a transaction against a list of active rules. Consider how to handle conflicting rules (e.g., a whitelist and a blacklist policy).
Interface
class Rule:
# Define structure for a rule
pass
def evaluate_transaction(transaction: dict, rules: list[Rule]) -> str:
# Returns 'APPROVED' or 'DENIED'
pass
Example
- Input: Transaction
{'amount': 600, 'category': 'Travel'}. Rules:[Rule('amount < 500'), Rule('category == Travel', action='DENY')] - Output:
'DENIED'(due to the category-based policy).
Constraints
- Assume rules are stored in a database or cache.
- Consider how to handle rule dependencies or sequential order.
Hints
Hint 1
Represent each rule as a collection of predicates that can be serialized (e.g., JSON) to support dynamic loading from a database.
Hint 2
Use the Strategy Pattern or an expression evaluation tree to decouple the transaction evaluation logic from specific rule definitions.
Hint 3
Think about the order of operations: should you evaluate 'Deny' rules before 'Allow' rules, or stop at the first matching violation?
Follow-up questions
- How would you optimize the engine if you have 10,000+ rules to evaluate per transaction?
- How would you implement an 'Audit Log' for the engine so that users can understand why a specific transaction was denied?
- How would you handle rules that depend on historical data, such as 'limit spending to $1000 per rolling 30 days'?
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.