feat: handle card status changed webhook

This commit is contained in:
Abdalhamid Alhamad
2025-07-21 15:30:55 +03:00
parent 5a780eeb17
commit bf43e62b17
21 changed files with 350 additions and 18 deletions

View File

@ -10,7 +10,7 @@ import {
UpdateDateColumn, UpdateDateColumn,
} from 'typeorm'; } from 'typeorm';
import { Customer } from '~/customer/entities'; import { Customer } from '~/customer/entities';
import { CardColors, CardIssuers, CardScheme, CardStatus, CustomerType } from '../enums'; import { CardColors, CardIssuers, CardScheme, CardStatus, CardStatusDescription, CustomerType } from '../enums';
import { Account } from './account.entity'; import { Account } from './account.entity';
import { Transaction } from './transaction.entity'; import { Transaction } from './transaction.entity';
@ -41,6 +41,12 @@ export class Card {
@Column({ type: 'varchar', nullable: false, default: CardStatus.PENDING }) @Column({ type: 'varchar', nullable: false, default: CardStatus.PENDING })
status!: CardStatus; status!: CardStatus;
@Column({ type: 'varchar', nullable: false, default: CardStatusDescription.PENDING_ACTIVATION })
statusDescription!: CardStatusDescription;
@Column({ type: 'decimal', precision: 10, scale: 2, default: 0.0, name: 'limit' })
limit!: number;
@Column({ type: 'varchar', nullable: false, default: CardScheme.VISA }) @Column({ type: 'varchar', nullable: false, default: CardScheme.VISA })
scheme!: CardScheme; scheme!: CardScheme;

View File

@ -0,0 +1,68 @@
/**
* import { CardStatus, CardStatusDescription } from '../enums';
export const CardStatusMapper: Record<string, { description: CardStatusDescription; status: CardStatus }> = {
//ACTIVE
'00': { description: 'NORMAL', status: CardStatus.ACTIVE },
//PENDING
'02': { description: 'NOT_YET_ISSUED', status: CardStatus.PENDING },
'20': { description: 'PENDING_ISSUANCE', status: CardStatus.PENDING },
'21': { description: 'CARD_EXTRACTED', status: CardStatus.PENDING },
'22': { description: 'EXTRACTION_FAILED', status: CardStatus.PENDING },
'23': { description: 'FAILED_PRINTING_BULK', status: CardStatus.PENDING },
'24': { description: 'FAILED_PRINTING_INST', status: CardStatus.PENDING },
'30': { description: 'PENDING_ACTIVATION', status: CardStatus.PENDING },
'27': { description: 'PENDING_PIN', status: CardStatus.PENDING },
'16': { description: 'PREPARE_TO_CLOSE', status: CardStatus.PENDING },
//BLOCKED
'01': { description: 'PIN_TRIES_EXCEEDED', status: CardStatus.BLOCKED },
'03': { description: 'CARD_EXPIRED', status: CardStatus.BLOCKED },
'04': { description: 'LOST', status: CardStatus.BLOCKED },
'05': { description: 'STOLEN', status: CardStatus.BLOCKED },
'06': { description: 'CUSTOMER_CLOSE', status: CardStatus.BLOCKED },
'07': { description: 'BANK_CANCELLED', status: CardStatus.BLOCKED },
'08': { description: 'FRAUD', status: CardStatus.BLOCKED },
'09': { description: 'DAMAGED', status: CardStatus.BLOCKED },
'50': { description: 'SAFE_BLOCK', status: CardStatus.BLOCKED },
'51': { description: 'TEMPORARY_BLOCK', status: CardStatus.BLOCKED },
'52': { description: 'RISK_BLOCK', status: CardStatus.BLOCKED },
'53': { description: 'OVERDRAFT', status: CardStatus.BLOCKED },
'54': { description: 'BLOCKED_FOR_FEES', status: CardStatus.BLOCKED },
'67': { description: 'CLOSED_CUSTOMER_DEAD', status: CardStatus.BLOCKED },
'75': { description: 'RETURN_CARD', status: CardStatus.BLOCKED },
//Fallback
'99': { description: 'UNKNOWN', status: CardStatus.PENDING },
};
*/
export enum CardStatusDescription {
NORMAL = 'NORMAL',
NOT_YET_ISSUED = 'NOT_YET_ISSUED',
PENDING_ISSUANCE = 'PENDING_ISSUANCE',
CARD_EXTRACTED = 'CARD_EXTRACTED',
EXTRACTION_FAILED = 'EXTRACTION_FAILED',
FAILED_PRINTING_BULK = 'FAILED_PRINTING_BULK',
FAILED_PRINTING_INST = 'FAILED_PRINTING_INST',
PENDING_ACTIVATION = 'PENDING_ACTIVATION',
PENDING_PIN = 'PENDING_PIN',
PREPARE_TO_CLOSE = 'PREPARE_TO_CLOSE',
PIN_TRIES_EXCEEDED = 'PIN_TRIES_EXCEEDED',
CARD_EXPIRED = 'CARD_EXPIRED',
LOST = 'LOST',
STOLEN = 'STOLEN',
CUSTOMER_CLOSE = 'CUSTOMER_CLOSE',
BANK_CANCELLED = 'BANK_CANCELLED',
FRAUD = 'FRAUD',
DAMAGED = 'DAMAGED',
SAFE_BLOCK = 'SAFE_BLOCK',
TEMPORARY_BLOCK = 'TEMPORARY_BLOCK',
RISK_BLOCK = 'RISK_BLOCK',
OVERDRAFT = 'OVERDRAFT',
BLOCKED_FOR_FEES = 'BLOCKED_FOR_FEES',
CLOSED_CUSTOMER_DEAD = 'CLOSED_CUSTOMER_DEAD',
RETURN_CARD = 'RETURN_CARD',
UNKNOWN = 'UNKNOWN',
}

View File

@ -1,6 +1,7 @@
export * from './card-colors.enum'; export * from './card-colors.enum';
export * from './card-issuers.enum'; export * from './card-issuers.enum';
export * from './card-scheme.enum'; export * from './card-scheme.enum';
export * from './card-status-description.enum';
export * from './card-status.enum'; export * from './card-status.enum';
export * from './customer-type.enum'; export * from './customer-type.enum';
export * from './transaction-scope.enum'; export * from './transaction-scope.enum';

View File

@ -0,0 +1,109 @@
import { UserLocale } from '~/core/enums';
import { CardStatusDescription } from '../enums';
export const CardStatusMapper: Record<CardStatusDescription, { [key in UserLocale]: { description: string } }> = {
[CardStatusDescription.NORMAL]: {
[UserLocale.ENGLISH]: { description: 'The card is active' },
[UserLocale.ARABIC]: { description: 'البطاقة نشطة' },
},
[CardStatusDescription.NOT_YET_ISSUED]: {
[UserLocale.ENGLISH]: { description: 'The card is not yet issued' },
[UserLocale.ARABIC]: { description: 'البطاقة لم تصدر بعد' },
},
[CardStatusDescription.PENDING_ISSUANCE]: {
[UserLocale.ENGLISH]: { description: 'The card is pending issuance' },
[UserLocale.ARABIC]: { description: 'البطاقة قيد الإصدار' },
},
[CardStatusDescription.CARD_EXTRACTED]: {
[UserLocale.ENGLISH]: { description: 'The card has been extracted' },
[UserLocale.ARABIC]: { description: 'تم استخراج البطاقة' },
},
[CardStatusDescription.EXTRACTION_FAILED]: {
[UserLocale.ENGLISH]: { description: 'The card extraction has failed' },
[UserLocale.ARABIC]: { description: 'فشل استخراج البطاقة' },
},
[CardStatusDescription.FAILED_PRINTING_BULK]: {
[UserLocale.ENGLISH]: { description: 'The card printing in bulk has failed' },
[UserLocale.ARABIC]: { description: 'فشل الطباعة بالجملة للبطاقة' },
},
[CardStatusDescription.FAILED_PRINTING_INST]: {
[UserLocale.ENGLISH]: { description: 'The card printing in institution has failed' },
[UserLocale.ARABIC]: { description: 'فشل الطباعة في المؤسسة للبطاقة' },
},
[CardStatusDescription.PENDING_ACTIVATION]: {
[UserLocale.ENGLISH]: { description: 'The card is pending activation' },
[UserLocale.ARABIC]: { description: 'البطاقة قيد التفعيل' },
},
[CardStatusDescription.PENDING_PIN]: {
[UserLocale.ENGLISH]: { description: 'The card is pending PIN' },
[UserLocale.ARABIC]: { description: 'البطاقة قيد الانتظار لرقم التعريف الشخصي' },
},
[CardStatusDescription.PREPARE_TO_CLOSE]: {
[UserLocale.ENGLISH]: { description: 'The card is being prepared for closure' },
[UserLocale.ARABIC]: { description: 'البطاقة قيد التحضير للإغلاق' },
},
[CardStatusDescription.PIN_TRIES_EXCEEDED]: {
[UserLocale.ENGLISH]: { description: 'The card PIN tries have been exceeded' },
[UserLocale.ARABIC]: { description: 'تم تجاوز محاولات رقم التعريف الشخصي للبطاقة' },
},
[CardStatusDescription.CARD_EXPIRED]: {
[UserLocale.ENGLISH]: { description: 'The card has expired' },
[UserLocale.ARABIC]: { description: 'انتهت صلاحية البطاقة' },
},
[CardStatusDescription.LOST]: {
[UserLocale.ENGLISH]: { description: 'The card is lost' },
[UserLocale.ARABIC]: { description: 'البطاقة ضائعة' },
},
[CardStatusDescription.STOLEN]: {
[UserLocale.ENGLISH]: { description: 'The card is stolen' },
[UserLocale.ARABIC]: { description: 'البطاقة مسروقة' },
},
[CardStatusDescription.CUSTOMER_CLOSE]: {
[UserLocale.ENGLISH]: { description: 'The card is being closed by the customer' },
[UserLocale.ARABIC]: { description: 'البطاقة قيد الإغلاق من قبل العميل' },
},
[CardStatusDescription.BANK_CANCELLED]: {
[UserLocale.ENGLISH]: { description: 'The card has been cancelled by the bank' },
[UserLocale.ARABIC]: { description: 'البطاقة ألغيت من قبل البنك' },
},
[CardStatusDescription.FRAUD]: {
[UserLocale.ENGLISH]: { description: 'Fraud' },
[UserLocale.ARABIC]: { description: 'احتيال' },
},
[CardStatusDescription.DAMAGED]: {
[UserLocale.ENGLISH]: { description: 'The card is damaged' },
[UserLocale.ARABIC]: { description: 'البطاقة تالفة' },
},
[CardStatusDescription.SAFE_BLOCK]: {
[UserLocale.ENGLISH]: { description: 'The card is in a safe block' },
[UserLocale.ARABIC]: { description: 'البطاقة في حظر آمن' },
},
[CardStatusDescription.TEMPORARY_BLOCK]: {
[UserLocale.ENGLISH]: { description: 'The card is in a temporary block' },
[UserLocale.ARABIC]: { description: 'البطاقة في حظر مؤقت' },
},
[CardStatusDescription.RISK_BLOCK]: {
[UserLocale.ENGLISH]: { description: 'The card is in a risk block' },
[UserLocale.ARABIC]: { description: 'البطاقة في حظر المخاطر' },
},
[CardStatusDescription.OVERDRAFT]: {
[UserLocale.ENGLISH]: { description: 'The card is in overdraft' },
[UserLocale.ARABIC]: { description: 'البطاقة في السحب على المكشوف' },
},
[CardStatusDescription.BLOCKED_FOR_FEES]: {
[UserLocale.ENGLISH]: { description: 'The card is blocked for fees' },
[UserLocale.ARABIC]: { description: 'البطاقة محظورة للرسوم' },
},
[CardStatusDescription.CLOSED_CUSTOMER_DEAD]: {
[UserLocale.ENGLISH]: { description: 'The card is closed because the customer is dead' },
[UserLocale.ARABIC]: { description: 'البطاقة مغلقة لأن العميل متوفى' },
},
[CardStatusDescription.RETURN_CARD]: {
[UserLocale.ENGLISH]: { description: 'The card is being returned' },
[UserLocale.ARABIC]: { description: 'البطاقة قيد الإرجاع' },
},
[CardStatusDescription.UNKNOWN]: {
[UserLocale.ENGLISH]: { description: 'The card status is unknown' },
[UserLocale.ARABIC]: { description: 'حالة البطاقة غير معروفة' },
},
};

View File

@ -0,0 +1,37 @@
import { CardStatus, CardStatusDescription } from '../enums';
export const CardStatusMapper: Record<string, { description: CardStatusDescription; status: CardStatus }> = {
//ACTIVE
'00': { description: CardStatusDescription.NORMAL, status: CardStatus.ACTIVE },
//PENDING
'02': { description: CardStatusDescription.NOT_YET_ISSUED, status: CardStatus.PENDING },
'20': { description: CardStatusDescription.PENDING_ISSUANCE, status: CardStatus.PENDING },
'21': { description: CardStatusDescription.CARD_EXTRACTED, status: CardStatus.PENDING },
'22': { description: CardStatusDescription.EXTRACTION_FAILED, status: CardStatus.PENDING },
'23': { description: CardStatusDescription.FAILED_PRINTING_BULK, status: CardStatus.PENDING },
'24': { description: CardStatusDescription.FAILED_PRINTING_INST, status: CardStatus.PENDING },
'30': { description: CardStatusDescription.PENDING_ACTIVATION, status: CardStatus.PENDING },
'27': { description: CardStatusDescription.PENDING_PIN, status: CardStatus.PENDING },
'16': { description: CardStatusDescription.PREPARE_TO_CLOSE, status: CardStatus.PENDING },
//BLOCKED
'01': { description: CardStatusDescription.PIN_TRIES_EXCEEDED, status: CardStatus.BLOCKED },
'03': { description: CardStatusDescription.CARD_EXPIRED, status: CardStatus.BLOCKED },
'04': { description: CardStatusDescription.LOST, status: CardStatus.BLOCKED },
'05': { description: CardStatusDescription.STOLEN, status: CardStatus.BLOCKED },
'06': { description: CardStatusDescription.CUSTOMER_CLOSE, status: CardStatus.BLOCKED },
'07': { description: CardStatusDescription.BANK_CANCELLED, status: CardStatus.BLOCKED },
'08': { description: CardStatusDescription.FRAUD, status: CardStatus.BLOCKED },
'09': { description: CardStatusDescription.DAMAGED, status: CardStatus.BLOCKED },
'50': { description: CardStatusDescription.SAFE_BLOCK, status: CardStatus.BLOCKED },
'51': { description: CardStatusDescription.TEMPORARY_BLOCK, status: CardStatus.BLOCKED },
'52': { description: CardStatusDescription.RISK_BLOCK, status: CardStatus.BLOCKED },
'53': { description: CardStatusDescription.OVERDRAFT, status: CardStatus.BLOCKED },
'54': { description: CardStatusDescription.BLOCKED_FOR_FEES, status: CardStatus.BLOCKED },
'67': { description: CardStatusDescription.CLOSED_CUSTOMER_DEAD, status: CardStatus.BLOCKED },
'75': { description: CardStatusDescription.RETURN_CARD, status: CardStatus.BLOCKED },
//Fallback
'99': { description: CardStatusDescription.UNKNOWN, status: CardStatus.PENDING },
};

View File

@ -3,7 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
import { CreateApplicationResponse } from '~/common/modules/neoleap/dtos/response'; import { CreateApplicationResponse } from '~/common/modules/neoleap/dtos/response';
import { Card } from '../entities'; import { Card } from '../entities';
import { CardColors, CardIssuers, CardScheme, CardStatus, CustomerType } from '../enums'; import { CardColors, CardIssuers, CardScheme, CardStatus, CardStatusDescription, CustomerType } from '../enums';
@Injectable() @Injectable()
export class CardRepository { export class CardRepository {
@ -19,7 +19,6 @@ export class CardRepository {
firstSixDigits: card.firstSixDigits, firstSixDigits: card.firstSixDigits,
lastFourDigits: card.lastFourDigits, lastFourDigits: card.lastFourDigits,
color: CardColors.BLUE, color: CardColors.BLUE,
status: CardStatus.ACTIVE,
scheme: CardScheme.VISA, scheme: CardScheme.VISA,
issuer: CardIssuers.NEOLEAP, issuer: CardIssuers.NEOLEAP,
accountId: accountId, accountId: accountId,
@ -40,4 +39,11 @@ export class CardRepository {
where: { customerId, status: CardStatus.ACTIVE }, where: { customerId, status: CardStatus.ACTIVE },
}); });
} }
updateCardStatus(id: string, status: CardStatus, statusDescription: CardStatusDescription) {
return this.cardRepository.update(id, {
status: status,
statusDescription: statusDescription,
});
}
} }

View File

@ -1,7 +1,9 @@
import { BadRequestException, Injectable } from '@nestjs/common'; import { BadRequestException, Injectable } from '@nestjs/common';
import { Transactional } from 'typeorm-transactional'; import { Transactional } from 'typeorm-transactional';
import { AccountCardStatusChangedWebhookRequest } from '~/common/modules/neoleap/dtos/requests';
import { CreateApplicationResponse } from '~/common/modules/neoleap/dtos/response'; import { CreateApplicationResponse } from '~/common/modules/neoleap/dtos/response';
import { Card } from '../entities'; import { Card } from '../entities';
import { CardStatusMapper } from '../mappers/card-status.mapper';
import { CardRepository } from '../repositories'; import { CardRepository } from '../repositories';
import { AccountService } from './account.service'; import { AccountService } from './account.service';
@ -42,4 +44,11 @@ export class CardService {
} }
return card; return card;
} }
async updateCardStatus(body: AccountCardStatusChangedWebhookRequest) {
const card = await this.getCardByReferenceNumber(body.cardId);
const { description, status } = CardStatusMapper[body.newStatus] || CardStatusMapper['99'];
return this.cardRepository.updateCardStatus(card.id, status, description);
}
} }

View File

@ -1,20 +1,29 @@
import { Body, Controller, Post } from '@nestjs/common'; import { Body, Controller, Post } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger'; import { ApiTags } from '@nestjs/swagger';
import { TransactionService } from '~/card/services/transaction.service'; import {
import { AccountTransactionWebhookRequest, CardTransactionWebhookRequest } from '../dtos/requests'; AccountCardStatusChangedWebhookRequest,
AccountTransactionWebhookRequest,
CardTransactionWebhookRequest,
} from '../dtos/requests';
import { NeoLeapWebhookService } from '../services';
@Controller('neoleap-webhooks') @Controller('neoleap-webhooks')
@ApiTags('Neoleap Webhooks') @ApiTags('Neoleap Webhooks')
export class NeoLeapWebhooksController { export class NeoLeapWebhooksController {
constructor(private readonly transactionService: TransactionService) {} constructor(private readonly neoleapWebhookService: NeoLeapWebhookService) {}
@Post('card-transaction') @Post('card-transaction')
async handleCardTransactionWebhook(@Body() body: CardTransactionWebhookRequest) { async handleCardTransactionWebhook(@Body() body: CardTransactionWebhookRequest) {
return this.transactionService.createCardTransaction(body); return this.neoleapWebhookService.handleCardTransactionWebhook(body);
} }
@Post('account-transaction') @Post('account-transaction')
async handleAccountTransactionWebhook(@Body() body: AccountTransactionWebhookRequest) { async handleAccountTransactionWebhook(@Body() body: AccountTransactionWebhookRequest) {
return this.transactionService.createAccountTransaction(body); return this.neoleapWebhookService.handleAccountTransactionWebhook(body);
}
@Post('account-card-status-changed')
async handleAccountCardStatusChangedWebhook(@Body() body: AccountCardStatusChangedWebhookRequest) {
return this.neoleapWebhookService.handleAccountCardStatusChangedWebhook(body);
} }
} }

View File

@ -37,7 +37,7 @@ export class NeoTestController {
@ApiDataResponse(InquireApplicationResponse) @ApiDataResponse(InquireApplicationResponse)
async inquireApplication(@AuthenticatedUser() user: IJwtPayload) { async inquireApplication(@AuthenticatedUser() user: IJwtPayload) {
const customer = await this.customerService.findCustomerById(user.sub); const customer = await this.customerService.findCustomerById(user.sub);
const data = await this.neoleapService.inquireApplication(customer.waitingNumber.toString()); const data = await this.neoleapService.inquireApplication(customer.applicationNumber.toString());
return ResponseFactory.data(data); return ResponseFactory.data(data);
} }

View File

@ -0,0 +1,20 @@
import { ApiProperty } from '@nestjs/swagger';
import { Expose } from 'class-transformer';
import { IsString } from 'class-validator';
export class AccountCardStatusChangedWebhookRequest {
@ApiProperty()
@Expose({ name: 'InstId' })
@IsString()
instId!: string;
@ApiProperty()
@Expose({ name: 'cardId' })
@IsString()
cardId!: string;
@ApiProperty()
@Expose({ name: 'newStatus' })
@IsString()
newStatus!: string;
}

View File

@ -1,3 +1,4 @@
export * from './account-card-status-changed-webhook.request.dto';
export * from './account-transaction-webhook.request.dto'; export * from './account-transaction-webhook.request.dto';
export * from './card-transaction-webhook.request.dto'; export * from './card-transaction-webhook.request.dto';
export * from './update-card-controls.request.dto'; export * from './update-card-controls.request.dto';

View File

@ -4,11 +4,12 @@ import { CardModule } from '~/card/card.module';
import { CustomerModule } from '~/customer/customer.module'; import { CustomerModule } from '~/customer/customer.module';
import { NeoLeapWebhooksController } from './controllers/neoleap-webhooks.controller'; import { NeoLeapWebhooksController } from './controllers/neoleap-webhooks.controller';
import { NeoTestController } from './controllers/neotest.controller'; import { NeoTestController } from './controllers/neotest.controller';
import { NeoLeapWebhookService } from './services';
import { NeoLeapService } from './services/neoleap.service'; import { NeoLeapService } from './services/neoleap.service';
@Module({ @Module({
imports: [HttpModule, CustomerModule, CardModule], imports: [HttpModule, CustomerModule, CardModule],
controllers: [NeoTestController, NeoLeapWebhooksController], controllers: [NeoTestController, NeoLeapWebhooksController],
providers: [NeoLeapService], providers: [NeoLeapService, NeoLeapWebhookService],
}) })
export class NeoLeapModule {} export class NeoLeapModule {}

View File

@ -0,0 +1,2 @@
export * from './neoleap-webook.service';
export * from './neoleap.service';

View File

@ -0,0 +1,25 @@
import { Injectable } from '@nestjs/common';
import { CardService } from '~/card/services';
import { TransactionService } from '~/card/services/transaction.service';
import {
AccountCardStatusChangedWebhookRequest,
AccountTransactionWebhookRequest,
CardTransactionWebhookRequest,
} from '../dtos/requests';
@Injectable()
export class NeoLeapWebhookService {
constructor(private readonly transactionService: TransactionService, private readonly cardService: CardService) {}
handleCardTransactionWebhook(body: CardTransactionWebhookRequest) {
return this.transactionService.createCardTransaction(body);
}
handleAccountTransactionWebhook(body: AccountTransactionWebhookRequest) {
return this.transactionService.createAccountTransaction(body);
}
handleAccountCardStatusChangedWebhook(body: AccountCardStatusChangedWebhookRequest) {
return this.cardService.updateCardStatus(body);
}
}

View File

@ -50,7 +50,7 @@ export class NeoLeapService {
CreateNewApplicationRequestDetails: { CreateNewApplicationRequestDetails: {
ApplicationRequestDetails: { ApplicationRequestDetails: {
InstitutionCode: this.institutionCode, InstitutionCode: this.institutionCode,
ExternalApplicationNumber: customer.waitingNumber.toString(), ExternalApplicationNumber: customer.applicationNumber.toString(),
ApplicationType: '01', ApplicationType: '01',
Product: '1101', Product: '1101',
ApplicationDate: moment().format('YYYY-MM-DD'), ApplicationDate: moment().format('YYYY-MM-DD'),

View File

@ -1,4 +1,8 @@
export enum UserLocale { import { ObjectValues } from '../types';
ARABIC = 'ar',
ENGLISH = 'en', export const UserLocale = {
} ARABIC: 'ar',
ENGLISH: 'en',
} as const;
export type UserLocale = ObjectValues<typeof UserLocale>;

View File

@ -97,7 +97,7 @@ export class CustomerResponseDto {
this.gender = customer.gender; this.gender = customer.gender;
this.isJunior = customer.isJunior; this.isJunior = customer.isJunior;
this.isGuardian = customer.isGuardian; this.isGuardian = customer.isGuardian;
this.waitingNumber = customer.waitingNumber; this.waitingNumber = customer.applicationNumber;
this.country = customer.country; this.country = customer.country;
this.region = customer.region; this.region = customer.region;
this.city = customer.city; this.city = customer.city;

View File

@ -71,9 +71,9 @@ export class Customer extends BaseEntity {
@Column('boolean', { default: false, name: 'is_guardian' }) @Column('boolean', { default: false, name: 'is_guardian' })
isGuardian!: boolean; isGuardian!: boolean;
@Column('int', { name: 'waiting_number' }) @Column('int', { name: 'application_number' })
@Generated('increment') @Generated('increment')
waitingNumber!: number; applicationNumber!: number;
@Column('varchar', { name: 'user_id' }) @Column('varchar', { name: 'user_id' })
userId!: string; userId!: string;

View File

@ -0,0 +1,16 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class UpdateCardTable1753098116701 implements MigrationInterface {
name = 'UpdateCardTable1753098116701'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "cards" ADD "statusDescription" character varying NOT NULL DEFAULT 'PENDING_ACTIVATION'`);
await queryRunner.query(`ALTER TABLE "cards" ADD "limit" numeric(10,2) NOT NULL DEFAULT '0'`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "cards" DROP COLUMN "limit"`);
await queryRunner.query(`ALTER TABLE "cards" DROP COLUMN "statusDescription"`);
}
}

View File

@ -0,0 +1,16 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class EditCustomerTable1753098326876 implements MigrationInterface {
name = 'EditCustomerTable1753098326876'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "customers" RENAME COLUMN "waiting_number" TO "application_number"`);
await queryRunner.query(`ALTER SEQUENCE "customers_waiting_number_seq" RENAME TO "customers_application_number_seq"`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER SEQUENCE "customers_application_number_seq" RENAME TO "customers_waiting_number_seq"`);
await queryRunner.query(`ALTER TABLE "customers" RENAME COLUMN "application_number" TO "waiting_number"`);
}
}

View File

@ -29,3 +29,5 @@ export * from './1749633935436-create-card-entity';
export * from './1751456987627-create-account-entity'; export * from './1751456987627-create-account-entity';
export * from './1751466314709-create-transaction-table'; export * from './1751466314709-create-transaction-table';
export * from './1752056898465-edit-transaction-table'; export * from './1752056898465-edit-transaction-table';
export * from './1753098116701-update-card-table';
export * from './1753098326876-edit-customer-table';