From 49c2777587df5601514f8a9b8d436e7d0e1b1f32 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Wed, 11 Feb 2026 23:15:20 +0200 Subject: [PATCH] fix: re-recognize transactions when bank rule is edited (closes #809) --- .../modules/BankingTranasctionsRegonize/_types.ts | 9 +++++++-- .../commands/RecognizeTranasctions.service.ts | 4 ++++ .../events/TriggerRecognizedTransactions.ts | 3 +++ .../jobs/RecognizeTransactionsJob.ts | 14 +++++++++++++- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/packages/server/src/modules/BankingTranasctionsRegonize/_types.ts b/packages/server/src/modules/BankingTranasctionsRegonize/_types.ts index 71a18e07e..5e5770bd3 100644 --- a/packages/server/src/modules/BankingTranasctionsRegonize/_types.ts +++ b/packages/server/src/modules/BankingTranasctionsRegonize/_types.ts @@ -15,8 +15,13 @@ export const RecognizeUncategorizedTransactionsJob = export const RecognizeUncategorizedTransactionsQueue = 'recognize-uncategorized-transactions-queue'; - export interface RecognizeUncategorizedTransactionsJobPayload extends TenantJobPayload { ruleId: number, - transactionsCriteria: any; + transactionsCriteria?: RecognizeTransactionsCriteria; + /** + * When true, first reverts recognized transactions before recognizing again. + * Used when a bank rule is edited to ensure transactions previously recognized + * by lower-priority rules are re-evaluated against the updated rule. + */ + shouldRevert?: boolean; } \ No newline at end of file diff --git a/packages/server/src/modules/BankingTranasctionsRegonize/commands/RecognizeTranasctions.service.ts b/packages/server/src/modules/BankingTranasctionsRegonize/commands/RecognizeTranasctions.service.ts index 9d79678c0..9fe353530 100644 --- a/packages/server/src/modules/BankingTranasctionsRegonize/commands/RecognizeTranasctions.service.ts +++ b/packages/server/src/modules/BankingTranasctionsRegonize/commands/RecognizeTranasctions.service.ts @@ -93,6 +93,10 @@ export class RecognizeTranasctionsService { q.whereIn('id', rulesIds); } q.withGraphFetched('conditions'); + + // Order by the 'order' field to ensure higher priority rules (lower order values) + // are matched first. + q.orderBy('order', 'asc'); }); const bankRulesByAccountId = transformToMapBy( diff --git a/packages/server/src/modules/BankingTranasctionsRegonize/events/TriggerRecognizedTransactions.ts b/packages/server/src/modules/BankingTranasctionsRegonize/events/TriggerRecognizedTransactions.ts index 791d7d8cd..7a3ce7286 100644 --- a/packages/server/src/modules/BankingTranasctionsRegonize/events/TriggerRecognizedTransactions.ts +++ b/packages/server/src/modules/BankingTranasctionsRegonize/events/TriggerRecognizedTransactions.ts @@ -69,10 +69,13 @@ export class TriggerRecognizedTransactionsSubscriber { const tenantPayload = await this.tenancyContect.getTenantJobPayload(); const payload = { ruleId: bankRule.id, + shouldRevert: true, ...tenantPayload, } as RecognizeUncategorizedTransactionsJobPayload; // Re-recognize the transactions based on the new rules. + // Setting shouldRevert to true ensures that transactions previously recognized + // by this or lower-priority rules are re-evaluated against the updated rule. await this.recognizeTransactionsQueue.add( RecognizeUncategorizedTransactionsJob, payload, diff --git a/packages/server/src/modules/BankingTranasctionsRegonize/jobs/RecognizeTransactionsJob.ts b/packages/server/src/modules/BankingTranasctionsRegonize/jobs/RecognizeTransactionsJob.ts index 3e4c81a85..eb72773f0 100644 --- a/packages/server/src/modules/BankingTranasctionsRegonize/jobs/RecognizeTransactionsJob.ts +++ b/packages/server/src/modules/BankingTranasctionsRegonize/jobs/RecognizeTransactionsJob.ts @@ -3,6 +3,7 @@ import { Processor, WorkerHost } from '@nestjs/bullmq'; import { Scope } from '@nestjs/common'; import { ClsService, UseCls } from 'nestjs-cls'; import { RecognizeTranasctionsService } from '../commands/RecognizeTranasctions.service'; +import { RevertRecognizedTransactionsService } from '../commands/RevertRecognizedTransactions.service'; import { RecognizeUncategorizedTransactionsJobPayload, RecognizeUncategorizedTransactionsQueue, @@ -15,10 +16,12 @@ import { export class RegonizeTransactionsPrcessor extends WorkerHost { /** * @param {RecognizeTranasctionsService} recognizeTranasctionsService - + * @param {RevertRecognizedTransactionsService} revertRecognizedTransactionsService - * @param {ClsService} clsService - */ constructor( private readonly recognizeTranasctionsService: RecognizeTranasctionsService, + private readonly revertRecognizedTransactionsService: RevertRecognizedTransactionsService, private readonly clsService: ClsService, ) { super(); @@ -29,12 +32,21 @@ export class RegonizeTransactionsPrcessor extends WorkerHost { */ @UseCls() async process(job: Job) { - const { ruleId, transactionsCriteria } = job.data; + const { ruleId, transactionsCriteria, shouldRevert } = job.data; this.clsService.set('organizationId', job.data.organizationId); this.clsService.set('userId', job.data.userId); try { + // If shouldRevert is true, first revert recognized transactions before re-recognizing. + // This is used when a bank rule is edited to ensure transactions previously recognized + // by lower-priority rules are re-evaluated against the updated rule. + if (shouldRevert) { + await this.revertRecognizedTransactionsService.revertRecognizedTransactions( + ruleId, + transactionsCriteria, + ); + } await this.recognizeTranasctionsService.recognizeTransactions( ruleId, transactionsCriteria,