mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-08-24 21:32:28 +00:00
feat: add vpan to card entity
This commit is contained in:
@ -23,6 +23,10 @@ export class Card {
|
||||
@Column({ name: 'card_reference', nullable: false, type: 'varchar' })
|
||||
cardReference!: string;
|
||||
|
||||
@Index({ unique: true })
|
||||
@Column({ name: 'vpan', nullable: false, type: 'varchar' })
|
||||
vpan!: string;
|
||||
|
||||
@Column({ length: 6, name: 'first_six_digits', nullable: false, type: 'varchar' })
|
||||
firstSixDigits!: string;
|
||||
|
||||
|
@ -22,6 +22,7 @@ export class CardRepository {
|
||||
scheme: CardScheme.VISA,
|
||||
issuer: CardIssuers.NEOLEAP,
|
||||
accountId: accountId,
|
||||
vpan: card.vpan,
|
||||
}),
|
||||
);
|
||||
}
|
||||
@ -34,9 +35,9 @@ export class CardRepository {
|
||||
return this.cardRepository.findOne({ where: { cardReference: referenceNumber }, relations: ['account'] });
|
||||
}
|
||||
|
||||
getCardByAccountNumber(accountNumber: string): Promise<Card | null> {
|
||||
getCardByVpan(vpan: string): Promise<Card | null> {
|
||||
return this.cardRepository.findOne({
|
||||
where: { account: { accountNumber } },
|
||||
where: { vpan },
|
||||
relations: ['account'],
|
||||
});
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ export class CardService {
|
||||
return card;
|
||||
}
|
||||
|
||||
async getCardByAccountNumber(accountNumber: string): Promise<Card> {
|
||||
const card = await this.cardRepository.getCardByAccountNumber(accountNumber);
|
||||
async getCardByVpan(vpan: string): Promise<Card> {
|
||||
const card = await this.cardRepository.getCardByVpan(vpan);
|
||||
|
||||
if (!card) {
|
||||
throw new BadRequestException('CARD.NOT_FOUND');
|
||||
@ -55,7 +55,7 @@ export class CardService {
|
||||
}
|
||||
|
||||
async updateCardStatus(body: AccountCardStatusChangedWebhookRequest) {
|
||||
const card = await this.getCardByAccountNumber(body.cardId);
|
||||
const card = await this.getCardByVpan(body.cardId);
|
||||
const { description, status } = CardStatusMapper[body.newStatus] || CardStatusMapper['99'];
|
||||
|
||||
return this.cardRepository.updateCardStatus(card.id, status, description);
|
||||
|
@ -20,7 +20,7 @@ export class TransactionService {
|
||||
|
||||
@Transactional()
|
||||
async createCardTransaction(body: CardTransactionWebhookRequest) {
|
||||
const card = await this.cardService.getCardByAccountNumber(body.cardId);
|
||||
const card = await this.cardService.getCardByVpan(body.cardId);
|
||||
const existingTransaction = await this.findExistingTransaction(body.transactionId, card.account.accountReference);
|
||||
|
||||
if (existingTransaction) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Body, Controller, Post } from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { ResponseFactory } from '~/core/utils';
|
||||
import {
|
||||
AccountCardStatusChangedWebhookRequest,
|
||||
AccountTransactionWebhookRequest,
|
||||
@ -14,16 +15,19 @@ export class NeoLeapWebhooksController {
|
||||
|
||||
@Post('card-transaction')
|
||||
async handleCardTransactionWebhook(@Body() body: CardTransactionWebhookRequest) {
|
||||
return this.neoleapWebhookService.handleCardTransactionWebhook(body);
|
||||
await this.neoleapWebhookService.handleCardTransactionWebhook(body);
|
||||
return ResponseFactory.data({ message: 'Card transaction processed successfully', status: 'success' });
|
||||
}
|
||||
|
||||
@Post('account-transaction')
|
||||
async handleAccountTransactionWebhook(@Body() body: AccountTransactionWebhookRequest) {
|
||||
return this.neoleapWebhookService.handleAccountTransactionWebhook(body);
|
||||
await this.neoleapWebhookService.handleAccountTransactionWebhook(body);
|
||||
return ResponseFactory.data({ message: 'Account transaction processed successfully', status: 'success' });
|
||||
}
|
||||
|
||||
@Post('account-card-status-changed')
|
||||
async handleAccountCardStatusChangedWebhook(@Body() body: AccountCardStatusChangedWebhookRequest) {
|
||||
return this.neoleapWebhookService.handleAccountCardStatusChangedWebhook(body);
|
||||
await this.neoleapWebhookService.handleAccountCardStatusChangedWebhook(body);
|
||||
return ResponseFactory.data({ message: 'Card status updated successfully', status: 'success' });
|
||||
}
|
||||
}
|
||||
|
22
src/db/migrations/1754210729273-add-vpan-to-card.ts
Normal file
22
src/db/migrations/1754210729273-add-vpan-to-card.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddVpanToCard1754210729273 implements MigrationInterface {
|
||||
name = 'AddVpanToCard1754210729273';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "cards" ADD "vpan" character varying`);
|
||||
await queryRunner.query(`
|
||||
UPDATE "cards"
|
||||
SET "vpan" = 'TEMP_VPAN_' || id
|
||||
`);
|
||||
|
||||
await queryRunner.query(`ALTER TABLE "cards" ALTER COLUMN "vpan" SET NOT NULL`);
|
||||
|
||||
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_1ec2ef68b0370f26639261e87b" ON "cards" ("vpan") `);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP INDEX "public"."IDX_1ec2ef68b0370f26639261e87b"`);
|
||||
await queryRunner.query(`ALTER TABLE "cards" DROP COLUMN "vpan"`);
|
||||
}
|
||||
}
|
@ -4,3 +4,4 @@ export * from './1734247702310-seeds-goals-categories';
|
||||
export * from './1753869637732-seed-default-avatar';
|
||||
export * from './1753874205042-add-neoleap-related-entities';
|
||||
export * from './1753948642040-add-account-number-and-iban-to-account-entity';
|
||||
export * from './1754210729273-add-vpan-to-card';
|
||||
|
Reference in New Issue
Block a user