Design an Extensible Expense Validation Engine
Company: Rippling
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: hard
Interview Round: Technical Screen
# Design an Extensible Expense Validation Engine
Design an object-oriented validation system for business-trip expenses. It must report all violations in one pass, including a cap on the trip total, a cap on any single expense, a type-specific meal cap of \$75, and rules that forbid selected pairs of expense types from appearing in the same trip. New rules should be addable without rewriting the engine.
### Constraints & Assumptions
- A trip contains an ID and a finite list of expenses with ID, type, amount, and currency.
- Currency conversion is outside scope; all amounts supplied to the validator use one currency.
- One expense may violate more than one rule.
- Rule results must identify the rule and the affected trip or expense IDs.
- Evaluation must continue after a violation is found.
### Clarifying Questions to Ask
- Are limits configuration data, code, or both?
- Must every rule inspect the whole trip, or may a rule declare a narrower dependency?
- Is violation order part of the API contract?
- How should malformed expenses be represented and reported?
### Part 1 - Domain and rule abstraction
Define the central domain objects and a rule interface that supports both single-expense checks and trip-wide checks without forcing the engine to know each rule type.
#### What This Part Should Cover
- Immutable validation input and structured violation output
- A uniform rule contract over a trip context
- Separation of configuration from evaluation
- Stable rule identity and deterministic results
### Part 2 - Engine behavior
Explain how the engine evaluates every configured rule, accumulates violations, orders them, and isolates a failed rule without silently accepting the trip.
#### What This Part Should Cover
- No short-circuit after the first failure
- Deterministic aggregation and deduplication
- Explicit policy for rule exceptions
- Observability without leaking sensitive expense details
### Part 3 - Extensibility and testing
Show how the incompatible-type rule can inspect the entire trip and how a later rule can be added with minimal engine changes. Describe focused and end-to-end tests.
#### What This Part Should Cover
- Whole-trip context for cross-expense constraints
- Open-ended rule registration
- Boundary, interaction, and multiple-violation cases
- Compatibility and configuration-version tests
```hint Unify the input boundary
If every rule receives an immutable trip context, a per-expense rule can iterate over expenses while a cross-expense rule can inspect the aggregate without changing the engine contract.
```
### What a Strong Answer Covers
- A rule interface that remains stable as requirements expand
- Complete violation collection with deterministic, structured output
- Correct support for aggregate, per-item, type-specific, and cross-item rules
- Failure isolation, configuration versioning, and a convincing test plan
### Follow-up Questions
1. How would rules be enabled for different customers without branching throughout the engine?
2. How would you explain why a trip failed while avoiding duplicate messages?
3. What changes if validation rules must be evaluated incrementally as expenses arrive?
Quick Answer: Design an extensible expense validation engine that handles per-item, trip-wide, and cross-type rules while reporting every violation.