Skip to content

[Due for payment 2026-10-13] [Tracking] Rules Revamp Project #92735

Closed
7 of 8 issues completed
Closed

Description

@JmillsExpensify

This is an internal tracking issue for the rulesog revamp project. We'll add sub-issues below so that everything is linked via one central issue.

Issue Owner

Current Issue Owner: @situchan

Activity

  1. added
    InternalRequires API changes or must be handled by Expensify staff
    on Jun 4, 2026
  2. melvin-bot commented on Jun 4, 2026

    @melvin-bot

    Triggered auto assignment to Design team member for new feature review - @dannymcclain (NewFeature)

  3. 41 remaining items

  4. JmillsExpensify commented on Oct 15, 2026

    @JmillsExpensify
    ContributorAuthor

    Great work on this one!

  5. situchan commented on Oct 15, 2026

    @situchan
    Contributor

    @JmillsExpensify @JS00001 any recommended suggestions for regression tests on this entire feature?

  6. JmillsExpensify commented on Oct 15, 2026

    @JmillsExpensify
    ContributorAuthor

    I think we'll need to get them from all the PRs right?

  7. laurenreidexpensify commented on Oct 15, 2026

    @laurenreidexpensify
    Contributor

    Approved @situchan $8,500 New Expensify

  8. laurenreidexpensify commented on Oct 21, 2026

    @laurenreidexpensify
    Contributor

    Approved @Krishna2323 $8,500 New Expensify

  9. melvin-bot commented on Oct 22, 2026

    @melvin-bot

    @cead22, @JmillsExpensify, @luacmartins, @mallenexpensify, @JS00001, @Krishna2323, @situchan, @dubielzyk-expensify Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

  10. situchan commented on Oct 22, 2026

    @situchan
    Contributor

    Regression Test Proposal

    Setup

    • Control workspace (A): Rules, Categories (3+), Tags, Taxes (default plus 5% and 10% rates), Expensify Card with a bank account, Company cards, Invoices, Per diem, Workflows enabled. A second member invited.
    • Collect workspace (B): fresh, Rules not yet enabled. A virtual Expensify Card issued.
    • Submit workspace (C): created on OldDot.
    • Workspace (D): connected to Sage Intacct, with tag import off and Categories disabled.
    • Accounts: admin, plus a member and an auditor of A. The custom agent beta is needed for Agents checks.
    • Run each section on wide web, narrow web and native unless it says otherwise.

    1. Rules page shell

    1.1 Tabs

    1. A > Workspace settings > Rules.
    2. Expected: tabs General, Card restrictions, Expense defaults, Field requirements, Flag for review, Agents. Each opens with no crash, blank or Not Here page.

    1.2 Header buttons on every tab

    1. Switch through all tabs.
    2. Expected: New rule and More stay visible on each.
    3. Select a row on any table tab. Expected: the bulk actions header replaces both buttons. Deselect and they return.
    4. Narrow and native: enter selection mode (long press on native) and exit. Expected: same swap.

    1.3 New rule options

    1. Tap New rule.
    2. Expected: Restrict card spend, Flag for review, Field requirements (subtitle "Require specific expense fields or waive requiring them."), Apply expense defaults, Describe agent rule. Each opens its editor and Back works.
    3. Native: go offline on this page. Expected: offline indicator sits at the bottom of the page, not under the content.

    1.4 Selection behavior

    1. Switch tabs with rows selected. Expected: selection clears.
    2. Expense defaults tab opens with no crash.
    3. Card restrictions with only the default row: hover the select-all checkbox. Expected: not-allowed cursor, not clickable.
    4. Expense defaults: check a custom rule, open it, delete it. Expected: the "1 selected" button is gone back on the table.

    1.5 Search

    1. On a table tab with several rows, use the find search. Expected: filters by category and rule text.

    1.6 Inline delete in every editor

    1. Open a saved rule of each type: merchant, category tax, Field requirements, Flag for review, Card restrictions, Agents.
    2. Expected: trashcan at top right with "Delete" on hover. Confirm deletes it from the table. No "Delete rule" button at the bottom.
    3. New unsaved rule of each type. Expected: no trashcan.
    4. Category tax rule on a workspace with no default tax rate. Expected: no trashcan.

    1.7 Read-only access

    1. As the A member and the A auditor, open a saved rule of each type.
    2. Expected: readable, no chevrons, Save, or trashcan, no Not Here page.
    3. As admin on an archived workspace, open a rule. Expected: same read-only state.
    4. As a read-only member, Rules > More > Import spreadsheet. Expected: the read-only modal, import page doesn't open.

    1.8 Import spreadsheet

    1. A > Rules > Field requirements > More > Import spreadsheet.
    2. Upload a CSV, map columns, import, dismiss the confirmation.
    3. Expected: lands on Rules > Expense defaults with the imported rules.

    2. General tab

    2.1 Row titles

    1. Expected rows include Flag expenses older than, Flag expenses above amount, Flag receipt line items, Require receipts, Require fields for all expenses, Billable expenses, Require company cards for all purchases (directly above eReceipts), Public receipt visibility.
    2. Open each row. Expected: RHP title matches, saving updates the row description.

    2.2 Flag receipt line items

    1. Toggle without saving, go back. Expected: not saved.
    2. Toggle and Save. Expected: saved.
    3. Offline save. Expected: only changed toggles grey out, the General row greys out, both clear after sync.

    2.3 Require receipts validation

    1. Enable, leave amount empty, save. Expected: field error, form alert, "fix the errors" focuses the first invalid field.
    2. Both toggles on with receipt amount above itemized amount. Expected: errors on both fields.
    3. Offline, change one toggle and save. Expected: only that row greys out.

    2.4 Require fields for all expenses

    1. Single tag list (Department). Expected: one Department toggle plus Category, General row matches.
    2. Dependent tag lists. Expected: one Tag toggle.
    3. Two independent tag lists (State, Region). Expected: one toggle per list. Turn State on, Region off, Save rule once. Expected: saves and returns to Rules on the first tap. Reopen shows State on, Region off.
    4. Disable every tag in Region. Expected: Region toggle disabled, State still interactive. If Region was already required, its toggle stays interactive so it can be turned off.
    5. Hard refresh, go straight to this page without visiting Tags. Expected: per-level rows load.
    6. Offline save. Expected: changed row and the General row grey out.

    2.5 Billable expenses

    1. Open Billable expenses. Expected: subtitle first, then Track billable expenses, then Billable and Non-billable options.
    2. Turn tracking off. Expected: options disappear, the General row shows no description.

    2.6 Require company cards for all purchases

    1. Expected: credit card icon, subtitle "Flag all cash spend, including mileage and per-diem expenses.", off and unlocked.
    2. Turn on, refresh. Expected: still on. Workspace chat shows "enabled the company card purchases requirement".
    3. Turn off. Expected: chat shows "disabled the company card purchases requirement".
    4. Turn on, submit a manual cash expense. Expected: Company card purchases required violation. Turn off. Expected: violation gone.
    5. Turn off Company cards and Expensify Card in More features. Expected: lock icon, tooltip "Enable Company cards (under More features) to unlock.", tapping does not open the upgrade page. Turn Company cards back on and it unlocks.

    2.7 Public receipt visibility

    1. Expected: default off, subtitle says receipts are only viewable by members with report access.
    2. Toggle on. Expected: subtitle switches to the public URL copy. Toggle off and the private copy returns.

    2.8 eReceipts and attendee tracking

    1. Toggle each. Expected: saves, offline shows pending grey-out.

    3. Card restrictions

    3.1 Default rule

    1. Expected: the Block / All cards / adult services, ATMs, gambling and money transfers rule under Default, lock in place of a checkbox, not selectable (also on native long press).
    2. Hover the lock. Expected: tooltip "Default rules cannot be deleted", no console errors.
    3. Card not enabled on a workspace. Expected: upsell shown instead of the table.

    3.2 Custom rules

    1. New rule > Restrict card spend, create, edit, delete. Expected: card and category pickers work, rule sits under Custom rules with a normal checkbox.
    2. Assign virtual cards to yourself and the member, add one rule per card, sort by Card. Expected: "Custom rules" header appears once.

    4. Expense defaults

    4.1 Type chooser

    1. New rule > Apply expense defaults. Expected: "What should this rule match on?" with Merchant and Category.
    2. Deep link workspaces/<id>/rules/merchant-rules/new. Expected: redirects to the chooser.
    3. Taxes off. Expected: Category locked, modal "Turn on taxes first".
    4. Delete every rate except the workspace default. Expected: Category locked, modal "Add a tax rate first", dismiss stays on the chooser, Merchant still opens.
    5. Add a 5% rate. Expected: Category unlocks and its picker offers 5%.
    6. Disable the 5% rate so only it and the default remain. Expected: Category locked again. Re-enable and it unlocks.

    4.2 Merchant types (locked defaults)

    1. With no custom merchant rules. Expected: 12 locked Merchant type rows (Gas, Hotel, Taxi, ...), lock instead of a checkbox, tooltip "Default rules cannot be deleted".
    2. Open Gas. Expected: Merchant type condition locked, Category editable, save updates the row.
    3. Add a custom merchant rule. Expected: table splits into Merchants and Merchant types.

    4.3 Merchant rule

    1. Chooser > Merchant. Expected: required Merchant, all defaults, Preview matches and apply-to-existing usable.
    2. Save with nothing. Expected: "Enter a merchant, and apply at least one default". Default without merchant: "Please enter a merchant".
    3. Save with a category default. Expected: row under Merchants.
    4. Tax picker on a merchant rule. Expected: the workspace default rate is offered.
    5. Delete the category a merchant rule matches on. Expected: the merchant rule stays listed and opens.

    4.4 Category tax rule: create

    1. Chooser > Category. Expected: required Category, only Tax under defaults, no Preview matches. Apply-to-existing locked with "Category rules apply going forward".
    2. Tax picker. Expected: no None, no workspace default, no disabled rates.
    3. Pick 3 categories and one rate, save. Expected: 3 rows.
    4. Category search. Expected: filters, selected stay pinned, select-all only selects filtered results.
    5. Save without category: "Please select a category". Without tax: "Please select a tax rate".
    6. Taxes off inside the Tax picker. Expected: "Taxes are not enabled" with Enable taxes, which returns to a working picker.

    4.5 Category tax rule: edit

    1. Open a Categories row. Expected: only category and tax, pre-filled.
    2. Change category (radios, not checkboxes), save. Expected: old row removed, new row keeps the rate, no not-found flash.
    3. Change only tax. Expected: row updates.
    4. Deep link workspaces/<id>/rules/category-tax-rules/edit/<category>. Expected: correct values load.
    5. Reset on an unsaved rule. Expected: clears condition and defaults, stays on the same type. Absent on saved or empty rules.

    4.6 Category tax rule: rate edge cases

    1. Save a 5% rule, disable 5% in Taxes, open the rule. Expected: Tax reads 5% and the picker lists it as selected, no other disabled rate.
    2. Save a 10% rule, set Workspace default and Foreign default to 10%. Expected: row and Tax field still read 10% and the picker lists it.
    3. Save a 5% rule, disable Taxes, Troubleshoot > Clear cache and restart > Reset and refresh. Expected: row shows no rate and never a raw ID like id_TAX_RATE_1, Tax field empty. Re-enable Taxes and the name returns.
    4. Search by the rate name. Expected: row found. Search a raw tax ID. Expected: no match.

    4.7 Delete

    1. Bulk delete 2 merchant and 1 category rule. Expected: all gone, Merchant types rows not selectable.
    2. Delete a category rule, then create an expense in that category. Expected: tax falls back to the workspace default.
    3. Delete the category or rate a category rule uses. Expected: the rule disappears with it.

    5. Field requirements

    5.1 Empty state and create

    1. Workspace with no rules. Expected: empty state with a create CTA that opens the editor.
    2. Pick a category, leave Require, check Itemized receipt, save. Expected: Require pill, "Require itemized receipt".
    3. Second category, Do not require, check Receipt. Expected: Do not require pill, "Do not require receipt". One row per category.
    4. Open each row. Expected: direction and checkboxes pre-filled.

    5.2 Direction defaults

    1. New rule on a category. Expected: Description and Attendees default to Don't require.
    2. Set Don't require on Receipt and Itemized receipt, save, reopen. Expected: Don't require still selected for all four.

    5.3 Receipt tooltip

    1. Require Description, Receipt and Itemized receipt, close the tooltip with X, save.
    2. Create another rule the same way. Expected: tooltip does not return.

    5.4 Category picker

    1. Categories with rules are still listed. Picking one pre-fills it and saving updates the same row.
    2. Pick a category with a rule, then one without, then another with a rule. Expected: form fills, resets, then fills again each time.
    3. Expected: None is never listed or selectable, before or after picking.

    5.5 Edit and offline

    1. Rule with Description, edit to Attendees only, save. Expected: row updates in place and does not flicker away.
    2. Offline, same edit. Expected: greyed-out row, still editable, not crossed out. Reopen shows Attendees only and the row reads only that field.

    5.6 Bulk delete

    1. Delete one row. Expected: only that category's settings cleared.

    6. Flag for review

    6.1 Empty state and create

    1. Empty state with a create CTA.
    2. Category, amount, Individual expense, save. Expected: condition Category is "..." and amount above $X.
    3. Category total limit. Expected: "daily category total above $X".
    4. Categories with a rule are still listed in the picker. Edit amount or type, then bulk delete.

    6.2 Editor layout

    1. New rule > Flag for review. Expected: bold dark "If any expense matches:", Category and Amount rows, a divider, bold "Then do the following:", a row with Flag type / Warning / "Submitter will be warned, but can still submit expense".
    2. Expected: other rule editors use the same bold section headers.

    7. Agents (custom agent beta)

    7.1 Agent rules

    1. No rules. Expected: centered empty state with Add agent rule.
    2. CTA or New rule > Describe agent rule, enter a prompt, Next. Expected: back on Agents with the rule listed.
    3. Expected: card layout with title, Beta badge, subtitle, RuleBot line, bordered rows, width matching other sections.
    4. Tap a row. Expected: Edit rule with the right prompt.

    8. Category and Tags pages

    8.1 Category RHP: Category rules section

    1. Open a category with Flag for review and Field requirements rules. Expected: tappable rows with a bolt icon and chevron below Delete.
    2. Tap one, save. Expected: summary updates here and on the Rules page.
    3. Category with no rules. Expected: only Create new rule. Pick Flag for review or Field requirements. Expected: category preselected.
    4. Create a Field requirements rule with Require on all fields, then Create new rule > Field requirements again. Expected: category and existing settings pre-filled, saves with no "Please select at least one field" error.
    5. Category with a tax rule. Expected: Update tax to "VAT (20%)" listed. A category with none shows no tax row.
    6. Tap the tax rule. Expected: Expense defaults editor over the category, Category row locked. Refresh keeps it open.
    7. Pick another rate, save. Expected: back on the category RHP showing the new rate. Delete from the header. Expected: back on the RHP with the row gone.
    8. Category with no tax rule > Create new rule > Apply expense defaults. Expected: editor opens directly with the category locked and no chooser or Reset. Save lands back on the RHP. Repeat opens the saved rate with delete.
    9. Only the workspace default rate left. Expected: the "add a tax rate" explainer.

    8.2 Category RHP: legacy rows gone

    1. Expected: Approver and Description hint remain. No Flag amounts over, Require receipts over, Require itemized receipts over, Required fields or Default tax rate row.

    8.3 Category RHP: offline deletes

    1. Create Flag for review and Field requirements rules from a category, go offline, delete both from the Rules tabs, reopen the category.
    2. Expected: both rows crossed out, the deleted Flag for review rule can't be opened.

    8.4 Categories More menu

    1. Categories > More. Expected: no Settings page with legacy rule settings. Import and Download still there.
    2. On a workspace with GL codes. Expected: the Show GL codes when categorizing expenses toggle is reachable from this menu.

    8.5 Tags

    1. Single-level Tags > More > Settings. Expected: Custom tag name stays, no Require tags or Track billable expenses.
    2. Independent multi-level tags. Expected: no Required column, row switches, Require or Make optional bulk actions, or detail-page toggle. No checkboxes when no bulk action applies. Delete selection still works where available.

    9. Collect and Submit plans

    9.1 Enable Rules

    1. B > More features > Rules on. Expected: enables without an upgrade.
    2. C (Submit) > More features > Rules. Expected: upgrade page.

    9.2 What Collect gets

    1. B > Rules > General. Expected: Billable expenses and Require fields for all expenses open and work. Public receipt visibility is shown.
    2. B > Categories > a category. Expected: Description hint, Approver and Category rules visible. Tags > Tag rules > Approver visible.
    3. Disable Rules in More features. Expected: Category rules hidden.

    9.3 Upgrade paths return where you started

    1. On B, trigger each locked item: another General row (Flag expenses older than), Require company cards, each locked tab, New rule, More > Import spreadsheet, a category's Description hint, Approver, Create new rule, an existing category rule.
    2. Expected: the Control upgrade page, never Not Here.
    3. Back without upgrading. Expected: returns to where you were (General tab for tabs, the category page for category rows, Rules for import).
    4. Upgrade > Got it, thanks. Expected: lands on the item you tapped (the RHP, the selected tab, the import page). Back leaves Rules with no extra Rules page. Switching tabs afterwards doesn't reset.
    5. General > agent banner > Try it out on Collect. Expected: upgrade page, then Agents after upgrading.
    6. Upgrade via More features. Expected: returns to More features.
    7. On A, every one of these opens directly.

    9.4 Accounting connected

    1. D > Rules > General > Require fields for all expenses. Expected: Tags row locked, tapping shows "Not so fast".
    2. D > Field requirements or Flag for review > create > Category > Enable categories. Expected: "Not so fast". Confirm goes to Accounting, Cancel leaves Categories off. After disconnecting, Categories can be enabled.
    3. NetSuite-imported tag levels. Expected: their Required toggle is not locked by the connection.

    9.5 Category empty state

    1. Categories off > Field requirements or Flag for review > create > Category. Expected: folder illustration and Enable categories.
    2. Native landscape. Expected: centered, button fully visible. Portrait still correct.

    10. Expensify Card entry points

    10.1 Edit spend rules

    1. B with Rules off > Wallet > Card > Edit spend rules. Expected: More features.
    2. B with Rules on. Expected: upgrade page, then Spend rules after upgrading.
    3. A with Rules on. Expected: opens and saves. A with Rules off. Expected: More features.

    10.2 Smart limit link

    1. Disable Approvals > Expensify Card > Issue card > Limit type > Enable approvals link. Expected: Workflows on the Approvals tab. Repeat from an existing card's Limit type.

    11. Workflows tabs

    11.1 Tabs and content

    1. A > Workflows. Expected: Submissions (default), Approvals, Payments, Advanced, only the active tab rendered.
    2. Submissions: toggle, description, Frequency. Approvals: toggle, description, default workflow note, cards with Expenses from, Members, Edit, and Add approval workflow. Payments: toggle and either Add bank account or bank account and Payer rows. Advanced: Prevent self-approvals, Auto-approve compliant reports, Auto-pay approved reports, Auto-pay locked when Payments isn't set up.

    11.2 Settings still work

    1. Toggle Submissions and reload. Change Frequency. Add and edit an approval workflow. Disable Approvals and see the warning. Toggle Payments and change the payer. Toggle each Advanced setting and open Auto-approve reports under, Random report audit, Auto-pay reports under.

    11.3 Persistence and deep links

    1. Select Payments, leave and return, reload. Expected: Payments stays.
    2. /workspaces/<policyID>/workflows?tab=payments. Expected: Payments regardless of the saved tab. Switching tabs removes ?tab=.
    3. Collect: Advanced > upgrade > Back. Expected: Advanced stays.
    4. Members > member > owner details > payer link. Expected: Payments.
    5. More > Import workflows, finish. Expected: Approvals.

    11.4 Permissions and HR

    1. Member without Payments access. Expected: Payments disabled with "Your workspace role doesn't have access to these settings. Ask an admin if you need it.", falls back to the first visible tab. Read-only member sees the read-only state.
    2. HR-connected workspace. Expected: Configure via provider link, cards not editable, header More hidden.

    12. "Create a rule" prompt on expense edits

    12.1 Appearance

    1. A admin, expense with a merchant, edit Category. Expected: "Create a rule to apply your changes to all expenses that match your criteria." with "Create a rule" bold and blue in light and dark. One prompt only, pinned while scrolling, no layout shift, clean wrapping. Above the composer on wide and wide RHP, below the header on narrow and native.

    12.2 Triggers

    1. Expected: appears after Category, Tag, Tax, Description, Billable, Reimbursable. Not after Merchant, Amount, Date.

    12.3 Prefill and navigation

    1. Tap Create a rule. Expected: merchant rule editor with Merchant and every edited field filled, the rest Don't change. Multi-level tags fill every level. Renamed taxes keep rate and name. Description keeps markdown. Billable and Reimbursable use the real values.
    2. Save. Expected: back on the expense, rule under Expense defaults. Back without saving. Expected: back on the expense, no rule. Either way the prompt goes and returns on the next edit.

    12.4 Dismissal

    1. X hides it for that expense this session. Navigating away also consumes it. Another expense still shows its own. Reload resets. Only the most recently edited expense can show it.

    12.5 Must not appear

    1. Non-admins, workspaces with Rules off, personal and self DM expenses, expenses without a merchant, the multi-expense report list.
    2. Self DM expense with a category edit, then Submit to the workspace and open it.
    3. Inline edit of Category, Tag or Description from a report list or Search, then open the expense. A single-expense report edited from the expense itself still shows it.
    4. Failed scan with no merchant: add a category, then a merchant.
    5. Invoice category edit.
    6. Distance and per diem category edits.
  11. mallenexpensify commented on Oct 22, 2026

    @mallenexpensify
    Contributor

    That's an awful lot of tests! Thx @situchan. Are we good to close?!?!

  12. situchan commented on Oct 22, 2026

    @situchan
    Contributor

    yes good to close

  13. JmillsExpensify commented on Oct 26, 2026

    @JmillsExpensify
    ContributorAuthor

    Thanks for putting all those together, much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Awaiting PaymentAuto-added when associated PR is deployed to productionDailyKSv2InternalRequires API changes or must be handled by Expensify staffNewFeatureSomething to build that is a new item.Skip PaymentSkips all the payment process steps for an issue. Use it for fixed-price projects.

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions