Katkat

Design an extensible expense rule evaluator

RipplingSoftware Engineer · Technical Screen

Last updated

This problem tests your ability to design a flexible and extensible rule evaluation engine capable of processing expense reports against dynamic business policies.

Problem Statement

You are tasked with building the core of an expense management system that validates expense reports against a set of business rules (e.g., 'Expenses over $500 require manager approval', 'Meals cannot exceed $50 per day', or 'International travel requires VP approval').

Your design must be extensible: adding a new rule (e.g., 'Flag expenses from high-risk vendors') should not require modifying existing core engine code. Assume an expense report object has fields like amount, category, date, employee_level, and vendor_id.

Requirements

  1. Define a schema or class structure for a Rule and an ExpenseReport.
  2. Implement an Evaluator class that takes a list of rules and an expense report, returning a result indicating if the expense is 'APPROVED', 'REJECTED', or 'NEEDS_REVIEW'.
  3. Provide a clear mechanism for registering new rules dynamically.

Interface Example (Python-style)

class ExpenseReport:
    # Define fields: amount, category, date, etc.

class Rule:
    def evaluate(self, report: ExpenseReport) -> str: # e.g., 'PASS', 'FAIL', 'FLAG'
        pass

class Evaluator:
    def add_rule(self, rule: Rule):
        pass
    
    def evaluate_report(self, report: ExpenseReport) -> str:
        pass

Constraints

  • Rules may depend on multiple fields.
  • An expense might trigger multiple rules; define how to aggregate these results (e.g., if one rule rejects, is the whole report rejected?).
  • Consider how to handle rules that involve external data (e.g., checking a currency conversion rate).

Hints

Hint 1

Consider using the Strategy Pattern to encapsulate rule logic, allowing each rule to be an independent object implementing a common interface.

Hint 2

Think about the return type of the evaluate method; would a simple string suffice, or does the system need metadata (e.g., error messages, required approval levels) associated with a non-approval result?

Hint 3

Use a composite pattern or a list-based pipeline approach to determine the final status when multiple rules are triggered.

Follow-up questions

  • How would you store these rules in a database so that non-technical administrators could update them without redeploying code?
  • How would you optimize the evaluator if you had to process 10,000 expense reports per minute against 50 different rules?
  • How would you handle rules that need to access historical data, such as 'The total expense for this employee this month cannot exceed $2,000'?