PracHub
QuestionsLearningGuidesInterview Prep
|Home/System Design/Rippling

Design expense rules engine and return type

Last updated: May 15, 2026

Quick Overview

This question evaluates a candidate's ability to design a scalable expense policy/rules engine for a corporate card system, testing skills in rule representation, API response modeling, conflict resolution, auditing/explanations, and performance and scalability considerations.

  • medium
  • Rippling
  • System Design
  • Software Engineer

Design expense rules engine and return type

Company: Rippling

Role: Software Engineer

Category: System Design

Difficulty: medium

Interview Round: Technical Screen

Design a rules engine for a corporate credit‑card expense system where managers define policies. Implement evaluateRules(rules: list<rule>, expenses: list<expense>) -> ?, given expenses as a list of dictionaries with string keys and values. Support at least these rules: ( 1) No restaurant expense over $75; ( 2) No airfare expenses; ( 3) No entertainment expenses; ( 4) No expense over $250. The system must flag violating expenses. What should the function return to serve as an API response? Explain rule representation, extensibility to hundreds of rules, conflict handling and precedence, auditing/explanations, performance/scalability, and how managers select and manage rules. Discuss assumptions and any product-oriented clarifications you would ask before coding.

Quick Answer: This question evaluates a candidate's ability to design a scalable expense policy/rules engine for a corporate card system, testing skills in rule representation, API response modeling, conflict resolution, auditing/explanations, and performance and scalability considerations.

Related Interview Questions

  • Design a News Aggregation System (Google News-style) - Rippling (medium)
  • Design a User Behavior Tracking (Clickstream Analytics) System - Rippling (medium)
  • Prevent Duplicate Payments Under High Load - Rippling (medium)
  • Design a personalized news aggregator - Rippling (medium)
  • Design a Scalable News Feed - Rippling (medium)
|Home/System Design/Rippling

Design expense rules engine and return type

Rippling logo
Rippling
Aug 7, 2025, 12:00 AM
mediumSoftware EngineerTechnical ScreenSystem Design
171
0

Design a Rules Engine for Corporate Card Expenses

Context

We offer a corporate credit card that employees use for business expenses. Managers set policies on the cards so employees do not misuse them or exceed allowances. You are building the rules engine that powers this product.

An expense is modeled as a dictionary/map with string keys and string values. Policies are rules that govern whether a submitted expense should be flagged for an expense manager to review. We will start with a few simple rules and then add requirements, so design for flexibility.

You are encouraged to ask product-oriented questions and to state your assumptions before writing code.

Sample Expense Data

Expenses are provided as a list of Map<String, String> (string keys and values). The dataset for this problem:

expense_idtrip_idamount_usdexpense_typevendor_typevendor_name
00100149.99suppliesrestaurantOutback Roadhouse
002001125.00suppliesretailerStaples
003002153.00mealsrestaurantOlive Yurt
0040021996.00airfaretransportationSoutheast Airlines
00500234.68mealsrestaurantThe Great Grill
00600222.40mealsrestaurantThe Great Grill
00700359.50entertainmenttheaterSilver Screen

Constraints & Assumptions

  • Amounts arrive as strings (e.g. "153.00" ); the field is amount_usd , so assume single-currency USD unless you choose to argue otherwise.
  • expense_type and vendor_type are distinct fields — a "restaurant" rule keys on vendor_type , an "airfare" rule keys on expense_type . Decide carefully which field each rule targets.
  • A company may maintain over a hundred rules; a manager selects the subset that applies to their team. evaluateRules receives the already-selected rules list.
  • In the future, rules will be created via an API, so adding a rule should not require new code or a deploy.
  • This is a review/approval flow (flag for a human), not a real-time card-authorization decline at swipe time.

Part 1 — Per-Expense Rules

Design a system that handles the following starter rules and flags individual expenses that violate them:

  1. No restaurant expense over $75.
  2. No airfare expenses.
  3. No entertainment expenses.
  4. No expense over $250.

Implement the function:

evaluateRules(rules: list<rule>, expenses: list<expense>) -> ?

You must pass a list of four rules to the rules argument for the policies above. The type of each rule and the return type of evaluateRules are up to you — but discuss and justify the return type before you start coding, because it is consumed as a response by our expenses API and rendered in a UI.

Expected behavior on the sample data: expense 003 is a restaurant meal over $75; expense 004 is both airfare and over $250; expense 007 is entertainment. All three should be flagged for review.

Address the following in your design:

  • Rule representation — flexible enough to grow from 4 hard-coded rules to hundreds of manager-selected rules, and later to rule creation via API.
  • Return type / API response — what the function returns so downstream services and a UI can answer which expenses need review and why (which rule(s) each broke).
  • Conflict handling and precedence — what happens when one expense matches multiple rules.
  • Auditing / explanations — how a manager later sees why an expense was flagged.
  • Performance and scalability — cost of evaluation and how it grows.
  • Manager rule management — how managers select and manage rules from a large library.
  • Assumptions and clarifications — product questions you would ask before coding.

What a Strong Answer Covers Guidance

  • A data-driven rule model (rules as configuration, not per-rule code) that visibly scales to hundreds of rules and to API-created rules.
  • A justified, structured return type that preserves which expense, which rule(s), and why — and serializes cleanly for an API/UI (not a bare boolean or ID list).
  • Correct handling of multiple violations per expense (e.g. 004 = airfare + over $250).
  • Care distinguishing expense_type vs vendor_type , and a defensible decision on boundary values (is exactly $75 "over $75"?).
  • A story for missing / malformed data (string amounts that don't parse, absent fields) and what the system does with them.
  • Sensible complexity reasoning and a path to scale.
  • Thoughtful clarifying questions and explicitly stated assumptions .

Clarifying Questions to Ask Guidance

  • Is the outcome per expense "approve vs decline at swipe time," or "flag for manager review"? (It changes the whole model.)
  • If an expense violates several rules, do we report all violated rules or just the first?
  • Which field does each rule target — expense_type , vendor_type , or vendor_name ?
  • Are amounts always single-currency USD, or must we handle multiple currencies?
  • What should happen when amount_usd is missing or unparseable — fail open or flag for review?
  • Who owns rule storage and selection — does evaluateRules get the full library or only the manager's chosen subset?

Part 2 — Aggregate (Per-Trip) Rules

Our return value is used as a response in the expenses API, consumed by a large number of companies, and we keep adding rules. In addition to reviewing individual expenses that violate rules, managers now need to review trips that violate rules.

Add support for rules that cannot be decided from a single expense, such as:

  • A trip cannot exceed $2,000 in total expenses.
  • Total meal expenses cannot exceed $200 per trip.

On the sample data, trip 002 violates both of these rules.

Implement a way to evaluate these more complex, aggregate rules in addition to the per-expense rules from Part 1. The output must surface trips that violate the new rules, alongside the individual flagged expenses from Part 1. As before, discuss the return type before coding — and keep the Part 1 response shape intact so existing API consumers do not break.

What a Strong Answer Covers Guidance

  • Recognizing that aggregate rules differ from per-expense rules only in evaluation scope (group-of-rows vs single row), and exploiting that to reuse the Part 1 machinery.
  • A clean rule shape for aggregates: grouping key + aggregation + optional filter + threshold , generalizable beyond trip_id (e.g. per-user-per-month).
  • A backward-compatible return type that adds trip-level results without breaking the Part 1 expense response.
  • Correct aggregation on the sample data (trip 002's total and meal total both exceed their caps).
  • How aggregate rules differ operationally — they are stateful / need full context , unlike independent per-expense checks.

Follow-up Questions Guidance

  • How does evaluation change at 100x scale (millions of expenses, thousands of rules) — what breaks first, and how do you keep per-expense vs per-trip evaluation fast?
  • How would you support rule creation via API without redeploying, and how do you validate a new rule before it goes live?
  • How do you make a past flag reproducible after the rule set changes (i.e. "which rules were in force when this was flagged")?
  • A future "auto-approve trusted vendor" exception must suppress a flag — how does your conflict/precedence model handle a rule whose effect is to clear a violation rather than add one?

Submit Your Answer to Earn 20XP

Sign in to leave a comment

Loading comments...

Browse More Questions

More System Design•More Rippling•More Software Engineer•Rippling Software Engineer•Rippling System Design•Software Engineer System Design

Your design canvas — auto-saved

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.