Commit Graph

8 Commits

Author SHA1 Message Date
Víctor Falcón a5697d886c test(automation-rules): cover apply job execution and failure branches
ApplySingleAutomationRuleJob was only ever asserted to be *pushed* under
Queue::fake() — its handle() body (chunked apply, progress accumulation)
and failed() branch had no coverage. ReEvaluateTransactionRulesJob's
failed() branch was likewise untested.

Add direct handle() and failed() tests for the apply job, and a failed()
test for the re-evaluate job, pinning the progress-cache payloads so the
'failed' status and preserved counts can't silently drift.
2026-07-03 13:27:56 +02:00
Víctor Falcón 1ed4a1a833 fix(automation-rules): re-check only_uncategorized at apply time
The apply flow resolves matching transaction IDs into a snapshot cached
for up to 15 minutes and keyed only by rule.updated_at. Both the sync
path and ApplySingleAutomationRuleJob then applied the rule's category to
every id in that snapshot without re-checking eligibility.

A transaction categorized after the snapshot was taken (by the user, a
sibling rule, or a concurrent AI backfill) was therefore silently
re-categorized to the rule's target and stamped category_source=Rule,
reverting a choice the user never asked the rule to touch.

Re-filter the set through shouldSkipForOnlyUncategorized() inside
applyRuleActionsToTransactions() when only_uncategorized was requested,
threading the flag through the job constructor. Skipped transactions are
no longer counted as changed.
2026-07-03 13:22:36 +02:00
Víctor Falcón 93e2d6823c fix(security): scope job-status cache keys to the owning user
The categorization, bulk rule re-evaluation, and automation-rule apply
status endpoints looked jobs up by a bare job UUID. Any authenticated
user who obtained another user's job id could poll its progress payload.

Include the owning user's id in the cache key so a status request keyed
by the polling user's id can only resolve that user's own jobs; a
mismatched owner now falls through to the existing 404. No ownership
store or extra lookup needed. Added cross-user isolation tests for all
three endpoints.
2026-07-03 13:09:18 +02:00
Víctor Falcón 10da06ed84
feat(transactions): add counterparty fields (#440)
## Summary
- add creditor/debtor fields to transactions with raw_data backfill
- store counterparties on bank sync and CSV/XLS imports
- add creditor/debtor filters plus hidden table columns

## Tests
- php artisan test --compact tests/Feature/LocalizationTest.php
tests/Feature/OpenBanking/TransactionSyncServiceTest.php
tests/Feature/TransactionFilterTest.php
- npm test -- resources/js/lib/file-parser.test.ts --run
- vendor/bin/pint --dirty --format agent

Note: `npm run types` still has pre-existing unrelated errors; no
creditor/debtor/import-related errors remained in filtered output.

## Screenshot
<img width="1241" height="676" alt="8odYWtFcvUM"
src="https://github.com/user-attachments/assets/55653485-d588-4beb-9e6a-5c7c81ba7cf8"
/>
2026-05-27 16:20:55 +02:00
Víctor Falcón 606093d311
fix: batch automation rule application (#435)
## Sentry
- Issue: PHP-LARAVEL-2C
- URL: https://whisper-money.sentry.io/issues/122336983/

## Root cause
Applying an automation rule to multiple transactions used
per-transaction `saveQuietly()` and `syncWithoutDetaching()`. Sentry
detected repeated transaction updates and pivot lookups/inserts on
`/settings/automation-rules/{automationRule}/apply`.

## Fix
- Added batched automation rule application for transaction collections.
- Bulk updates category changes in one query.
- Bulk inserts missing label pivots with `insertOrIgnore`.
- Reused batching from sync controller path and queued job chunks.

## Verification
- `vendor/bin/pint --dirty --format agent`
- `php artisan test --compact
tests/Feature/AutomationRuleApplicationTest.php`
2026-05-26 10:45:37 +02:00
Víctor Falcón 9772cfc37c
fix(automation): avoid skipping rule matches (#433)
## Summary
- replace ordered automation match scanning from chunkById to chunk so
sorted rows are not skipped
- make regression fixture deterministic across chunk boundaries

## Tests
- vendor/bin/pint --dirty --format agent
- php artisan test --compact
tests/Feature/AutomationRuleApplicationTest.php --filter='matches
endpoint avoids repeated relationship queries'
- php artisan test --compact
tests/Feature/AutomationRuleApplicationTest.php
2026-05-26 08:26:20 +02:00
Víctor Falcón fd67cf7c72
fix(automation): avoid rule preview n+1 (#431)
## Sentry issue
- PHP-LARAVEL-2F: https://whisper-money.sentry.io/issues/122581787/

## Root cause
- Automation rule match preview eagerly loaded account, bank, category,
and labels for every 500-transaction chunk, even for rules that only
inspect description fields.
- Sentry flagged repeated account/bank eager-load queries across chunks
as an N+1 pattern on
`/settings/automation-rules/{automationRule}/matches`.

## Fix
- Detect variables used by an automation rule and eager load only
relationships required for evaluation.
- Keep label eager loading only when label-only skip logic needs it.
- Avoid lazy loading unused relationships while preserving full data
shape for rule evaluation.
- Update the Sentry prompt to use the `sentry` CLI workflow.

## Verification
- `vendor/bin/pint --dirty --format agent`
- `php artisan test --compact
tests/Feature/AutomationRuleApplicationTest.php`
- `php artisan test --compact
tests/Feature/AutomationRuleEvaluationTest.php
tests/Feature/AutomationRuleApplicationTest.php`
2026-05-26 08:02:46 +02:00
Víctor Falcón 9d7a91dcd0
Apply automation rules to existing transactions (#413)
## Summary
- add apply-to-existing-transactions flow for automation rules
- preview matching transactions with uncategorized filter and infinite
scroll
- apply rule actions sync or via queued job with progress polling
- fix duplicate preview rows and repeat apply prompt when labels change

## Tests
- vendor/bin/pint --dirty --format agent
- npm test -- --run
resources/js/components/automation-rules/post-save-apply-rule-prompt.test.ts
resources/js/components/automation-rules/apply-automation-rule-flow.test.ts
- php artisan test --compact
tests/Feature/AutomationRuleApplicationTest.php

## Video

https://github.com/user-attachments/assets/e74f5e58-e582-4fb6-b6d4-2702398804b7
2026-05-22 08:36:18 +02:00