feat: enhance transaction notification logging and error handling

- Added console logging for emitted transaction creation events in TransactionService.
- Improved error handling in TransactionNotificationListener for i18n translation failures, providing fallback messages.
- Updated amount parsing in MoneyRequestNotificationListener to ensure consistent handling of string and numeric values.
This commit is contained in:
Abdalhamid Alhamad
2026-01-12 16:47:28 +03:00
parent d3ff755439
commit 45acf73a4a
3 changed files with 85 additions and 45 deletions

View File

@ -117,7 +117,10 @@ export class TransactionService {
isChildSpending: true,
timestamp: new Date(),
};
console.log(`[TransactionService] Emitting TRANSACTION_CREATED event for transaction ${transaction.id}`);
this.eventEmitter.emit(NOTIFICATION_EVENTS.TRANSACTION_CREATED, event);
console.log(`[TransactionService] Event emitted successfully`);
return transaction;
}

View File

@ -128,7 +128,7 @@ export class MoneyRequestNotificationListener {
const child = moneyRequest?.junior;
const childUser = child?.customer?.user;
const childName = childUser?.firstName || 'Your child';
const amount = moneyRequest.amount;
const amount = typeof moneyRequest.amount === 'string' ? parseFloat(moneyRequest.amount) : moneyRequest.amount;
const reason = moneyRequest.reason || 'No reason provided';
this.logger.debug(
@ -175,7 +175,7 @@ export class MoneyRequestNotificationListener {
return;
}
const amount = moneyRequest.amount;
const amount = typeof moneyRequest.amount === 'string' ? parseFloat(moneyRequest.amount) : moneyRequest.amount;
this.logger.debug(
`Notifying child (user ${childUser.id}): Money request of $${amount} was approved`
@ -218,7 +218,7 @@ export class MoneyRequestNotificationListener {
return;
}
const amount = moneyRequest.amount;
const amount = typeof moneyRequest.amount === 'string' ? parseFloat(moneyRequest.amount) : moneyRequest.amount;
const reason = rejectionReason || 'No reason provided';
this.logger.debug(

View File

@ -41,12 +41,15 @@ export class TransactionNotificationListener {
@OnEvent(NOTIFICATION_EVENTS.TRANSACTION_CREATED)
async handleTransactionCreated(event: ITransactionCreatedEvent): Promise<void> {
try {
console.log(`[TransactionNotificationListener] Event received: ${NOTIFICATION_EVENTS.TRANSACTION_CREATED}`);
const { transaction, card, isTopUp, isChildSpending } = event;
this.logger.log(
`Processing transaction notification for transaction ${transaction.id} - ` +
`isTopUp: ${isTopUp}, isChildSpending: ${isChildSpending}`
);
console.log(`[TransactionNotificationListener] Transaction: ${transaction.id}, Card: ${card?.id}, isTopUp: ${isTopUp}, isChildSpending: ${isChildSpending}`);
await this.notifyTransactionOwner(transaction, card, isTopUp, isChildSpending);
@ -62,6 +65,7 @@ export class TransactionNotificationListener {
`Transaction notification processed successfully for transaction ${transaction.id}`
);
} catch (error: any) {
console.error(`[TransactionNotificationListener] ERROR:`, error);
this.logger.error(
`Failed to process transaction notification: ${error?.message || 'Unknown error'}`,
error?.stack
@ -96,28 +100,41 @@ export class TransactionNotificationListener {
const balance = card.account?.balance || 0;
const currency = card.account?.currency || transaction.transactionCurrency || 'SAR';
const title = isTopUp
? this.i18n.t('app.NOTIFICATION.CHILD_TOP_UP_TITLE', { lang: locale })
: this.i18n.t('app.NOTIFICATION.CHILD_SPENDING_TITLE', { lang: locale });
let title: string;
let message: string;
try {
title = isTopUp
? this.i18n.t('app.NOTIFICATION.CHILD_TOP_UP_TITLE', { lang: locale })
: this.i18n.t('app.NOTIFICATION.CHILD_SPENDING_TITLE', { lang: locale });
const message = isTopUp
? this.i18n.t('app.NOTIFICATION.CHILD_TOP_UP_MESSAGE', {
lang: locale,
args: {
amount: amount.toString(),
currency: currency,
balance: balance.toString(),
},
})
: this.i18n.t('app.NOTIFICATION.CHILD_SPENDING_MESSAGE', {
lang: locale,
args: {
amount: amount.toString(),
currency: currency,
merchant: merchant,
balance: balance.toString(),
},
});
message = isTopUp
? this.i18n.t('app.NOTIFICATION.CHILD_TOP_UP_MESSAGE', {
lang: locale,
args: {
amount: amount.toString(),
currency: currency,
balance: balance.toString(),
},
})
: this.i18n.t('app.NOTIFICATION.CHILD_SPENDING_MESSAGE', {
lang: locale,
args: {
amount: amount.toString(),
currency: currency,
merchant: merchant,
balance: balance.toString(),
},
});
} catch (i18nError: any) {
console.error(`[TransactionNotificationListener] i18n error:`, i18nError);
this.logger.error(`i18n translation failed: ${i18nError?.message}`, i18nError?.stack);
// Fallback to English without i18n
title = isTopUp ? 'Card Topped Up' : 'Purchase Successful';
message = isTopUp
? `You received ${amount} ${currency}. Total balance: ${balance} ${currency}`
: `You spent ${amount} ${currency} at ${merchant}. Balance: ${balance} ${currency}`;
}
this.logger.debug(
`Notifying transaction owner (user ${user.id}) - Amount: ${amount} ${currency}, Merchant: ${merchant}`
@ -180,17 +197,27 @@ export class TransactionNotificationListener {
`Notifying parent (user ${parentUser.id}): ${childName} spent ${amount} ${currency} at ${merchant}`
);
const title = this.i18n.t('app.NOTIFICATION.PARENT_SPENDING_TITLE', { lang: locale });
const message = this.i18n.t('app.NOTIFICATION.PARENT_SPENDING_MESSAGE', {
lang: locale,
args: {
childName: childName,
amount: amount.toString(),
currency: currency,
merchant: merchant,
balance: balance.toString(),
},
});
let title: string;
let message: string;
try {
title = this.i18n.t('app.NOTIFICATION.PARENT_SPENDING_TITLE', { lang: locale });
message = this.i18n.t('app.NOTIFICATION.PARENT_SPENDING_MESSAGE', {
lang: locale,
args: {
childName: childName,
amount: amount.toString(),
currency: currency,
merchant: merchant,
balance: balance.toString(),
},
});
} catch (i18nError: any) {
console.error(`[TransactionNotificationListener] i18n error in parent spending:`, i18nError);
this.logger.error(`i18n translation failed: ${i18nError?.message}`, i18nError?.stack);
title = 'Child Spending Alert';
message = `${childName} spent ${amount} ${currency} at ${merchant}. Balance: ${balance} ${currency}`;
}
await this.notificationFactory.send({
userId: parentUser.id,
@ -250,16 +277,26 @@ export class TransactionNotificationListener {
`Notifying parent (user ${parentUser.id}): Transferred ${amount} ${currency} to ${childName}`
);
const title = this.i18n.t('app.NOTIFICATION.PARENT_TOP_UP_TITLE', { lang: locale });
const message = this.i18n.t('app.NOTIFICATION.PARENT_TOP_UP_MESSAGE', {
lang: locale,
args: {
amount: amount.toString(),
currency: currency,
childName: childName,
balance: balance.toString(),
},
});
let title: string;
let message: string;
try {
title = this.i18n.t('app.NOTIFICATION.PARENT_TOP_UP_TITLE', { lang: locale });
message = this.i18n.t('app.NOTIFICATION.PARENT_TOP_UP_MESSAGE', {
lang: locale,
args: {
amount: amount.toString(),
currency: currency,
childName: childName,
balance: balance.toString(),
},
});
} catch (i18nError: any) {
console.error(`[TransactionNotificationListener] i18n error in parent top-up:`, i18nError);
this.logger.error(`i18n translation failed: ${i18nError?.message}`, i18nError?.stack);
title = 'Top-Up Confirmation';
message = `You transferred ${amount} ${currency} to ${childName}. Balance: ${balance} ${currency}`;
}
await this.notificationFactory.send({
userId: parentUser.id,