Skip to content

feat(rules): apply a new rule to existing transactions on creation#310

Merged
tassionoronha merged 1 commit into
mainfrom
feat/issue-306-apply-rule-on-create
Jun 10, 2026
Merged

feat(rules): apply a new rule to existing transactions on creation#310
tassionoronha merged 1 commit into
mainfrom
feat/issue-306-apply-rule-on-create

Conversation

@tassionoronha

Copy link
Copy Markdown
Contributor

Summary

Follow-up to the rule-form UX work on #306. Previously, creating a rule only saved it — existing transactions stayed untouched until the user manually clicked Reapply all. This was an invisible gap, especially when creating rules in bulk.

Now, creating a rule immediately applies it to existing transactions and the success toast reports the result with a single combined message:

Rule created and applied to 4 transactions

(falling back to plain "Rule created" when nothing matched).

Behavior

The auto-apply is non-destructive by design:

  • A transaction that already has a category keeps it — same semantics used when new transactions arrive via sync/import, so creating a rule never silently overwrites your manual categorizations.
  • Payee / notes / ignore actions still apply on a match.
  • Only transactions whose fields actually change are counted, so the toast number is honest.

For a full reset that re-runs every rule and overwrites, Reapply all is still there and unchanged.

Changes

  • backend: new rule_service.apply_single_rule(); POST /api/rules now returns RuleCreateResponse (= RuleRead + applied_count).
  • frontend: combined toast in createMutation.onSuccess, plus invalidateFinancialQueries when count > 0 so transactions/reports refresh.
  • i18n: rules.createdAndApplied added to en, pt-BR, es, it, pl.
  • tests: 3 new backend tests — applies & counts, no-match → 0, and non-destructive on an already-categorized transaction.

Testing

  • Backend rule suites pass (test_new_rules_api, test_rule_service, test_rule_engine) — 38 tests including the 3 new ones. Frontend tsc -b + eslint clean.
  • Verified live in the running app (Docker + Chrome): created a rule matching 4 uncategorized transactions → toast showed "Rule created and applied to 4 transactions"; the transactions were categorized without an explicit Reapply. An already-categorized transaction was confirmed untouched. Test rule and transaction changes were reverted afterward.

Creating a rule previously only persisted it; existing transactions were
left untouched until the user manually hit "Reapply all". Now the create
endpoint applies the new rule to existing transactions right away and
returns how many were affected, and the success toast reports it ("Rule
created and applied to N transactions") for transparency.

The auto-apply is non-destructive: a transaction that already has a
category keeps it (same semantics used when new transactions arrive), so
creating a rule never silently overwrites manual categorizations. Payee,
notes and ignore actions still apply on a match. Only transactions whose
fields actually change are counted.

- backend: add rule_service.apply_single_rule; POST /api/rules returns
  RuleCreateResponse with applied_count
- frontend: combined toast + financial query invalidation when count > 0
- i18n: rules.createdAndApplied across all locales
- tests: cover match/apply, no-match, and non-destructive behavior
@tassionoronha
tassionoronha merged commit 5eca42e into main Jun 10, 2026
2 checks passed
ADolkun pushed a commit to ADolkun/lovenest that referenced this pull request Jul 21, 2026
…ecuro-finance#310)

Creating a rule previously only persisted it; existing transactions were
left untouched until the user manually hit "Reapply all". Now the create
endpoint applies the new rule to existing transactions right away and
returns how many were affected, and the success toast reports it ("Rule
created and applied to N transactions") for transparency.

The auto-apply is non-destructive: a transaction that already has a
category keeps it (same semantics used when new transactions arrive), so
creating a rule never silently overwrites manual categorizations. Payee,
notes and ignore actions still apply on a match. Only transactions whose
fields actually change are counted.

- backend: add rule_service.apply_single_rule; POST /api/rules returns
  RuleCreateResponse with applied_count
- frontend: combined toast + financial query invalidation when count > 0
- i18n: rules.createdAndApplied across all locales
- tests: cover match/apply, no-match, and non-destructive behavior
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant