From ac63d4cdc7463a3c8521ec9d84952be680b3ab00 Mon Sep 17 00:00:00 2001 From: Abdalhamid Alhamad Date: Mon, 11 Aug 2025 15:33:32 +0300 Subject: [PATCH] refactor: refactor the code --- src/auth/auth.module.ts | 4 +- src/auth/controllers/auth.controller.ts | 21 ---- .../apple-additional-data.request.dto.ts | 14 --- .../dtos/request/apple-login.request.dto.ts | 21 ---- .../request/disable-biometric.request.dto.ts | 4 - .../request/enable-biometric.request.dto.ts | 14 --- .../dtos/request/google-login.request.dto.ts | 10 -- .../dtos/request/set-email.request.dto.ts | 8 -- .../interfaces/apple-payload.interface.ts | 11 --- src/auth/services/auth.service.ts | 75 --------------- src/auth/services/index.ts | 1 - src/auth/services/oauth2.service.ts | 83 ---------------- ...5164809-create-neoleap-related-entities.ts | 95 +++++++++++++++++++ src/db/migrations/index.ts | 1 + 14 files changed, 98 insertions(+), 264 deletions(-) delete mode 100644 src/auth/dtos/request/apple-additional-data.request.dto.ts delete mode 100644 src/auth/dtos/request/apple-login.request.dto.ts delete mode 100644 src/auth/dtos/request/disable-biometric.request.dto.ts delete mode 100644 src/auth/dtos/request/enable-biometric.request.dto.ts delete mode 100644 src/auth/dtos/request/google-login.request.dto.ts delete mode 100644 src/auth/dtos/request/set-email.request.dto.ts delete mode 100644 src/auth/interfaces/apple-payload.interface.ts delete mode 100644 src/auth/services/oauth2.service.ts create mode 100644 src/db/migrations/1754915164809-create-neoleap-related-entities.ts diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts index 138e689..74360e2 100644 --- a/src/auth/auth.module.ts +++ b/src/auth/auth.module.ts @@ -4,12 +4,12 @@ import { JwtModule } from '@nestjs/jwt'; import { JuniorModule } from '~/junior/junior.module'; import { UserModule } from '~/user/user.module'; import { AuthController } from './controllers'; -import { AuthService, Oauth2Service } from './services'; +import { AuthService } from './services'; import { AccessTokenStrategy } from './strategies'; @Module({ imports: [JwtModule.register({}), UserModule, JuniorModule, HttpModule], - providers: [AuthService, AccessTokenStrategy, Oauth2Service], + providers: [AuthService, AccessTokenStrategy], controllers: [AuthController], exports: [], }) diff --git a/src/auth/controllers/auth.controller.ts b/src/auth/controllers/auth.controller.ts index 122d34f..3094142 100644 --- a/src/auth/controllers/auth.controller.ts +++ b/src/auth/controllers/auth.controller.ts @@ -86,25 +86,4 @@ export class AuthController { async logout(@Req() request: Request) { await this.authService.logout(request); } - - // @Post('biometric/enable') - // @HttpCode(HttpStatus.NO_CONTENT) - // @UseGuards(AccessTokenGuard) - // enableBiometric(@AuthenticatedUser() { sub }: IJwtPayload, @Body() enableBiometricDto: EnableBiometricRequestDto) { - // return this.authService.enableBiometric(sub, enableBiometricDto); - // } - - // @Post('biometric/disable') - // @HttpCode(HttpStatus.NO_CONTENT) - // @UseGuards(AccessTokenGuard) - // disableBiometric(@AuthenticatedUser() { sub }: IJwtPayload, @Body() disableBiometricDto: DisableBiometricRequestDto) { - // return this.authService.disableBiometric(sub, disableBiometricDto); - // } - - // @Post('junior/set-passcode') - // @HttpCode(HttpStatus.NO_CONTENT) - // @Public() - // setJuniorPasscode(@Body() setPasscodeDto: setJuniorPasswordRequestDto) { - // return this.authService.setJuniorPasscode(setPasscodeDto); - // } } diff --git a/src/auth/dtos/request/apple-additional-data.request.dto.ts b/src/auth/dtos/request/apple-additional-data.request.dto.ts deleted file mode 100644 index fae4a53..0000000 --- a/src/auth/dtos/request/apple-additional-data.request.dto.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsNotEmpty, IsString } from 'class-validator'; -import { i18nValidationMessage as i18n } from 'nestjs-i18n'; -export class AppleAdditionalData { - @ApiProperty({ example: 'Ahmad' }) - @IsString({ message: i18n('validation.IsString', { path: 'general', property: 'customer.firstName' }) }) - @IsNotEmpty({ message: i18n('validation.IsNotEmpty', { path: 'general', property: 'customer.firstName' }) }) - firstName!: string; - - @ApiProperty({ example: 'Khan' }) - @IsString({ message: i18n('validation.IsString', { path: 'general', property: 'customer.lastName' }) }) - @IsNotEmpty({ message: i18n('validation.IsNotEmpty', { path: 'general', property: 'customer.lastName' }) }) - lastName!: string; -} diff --git a/src/auth/dtos/request/apple-login.request.dto.ts b/src/auth/dtos/request/apple-login.request.dto.ts deleted file mode 100644 index 34e89da..0000000 --- a/src/auth/dtos/request/apple-login.request.dto.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { Type } from 'class-transformer'; -import { IsNotEmpty, IsOptional, IsString, ValidateNested } from 'class-validator'; -import { i18nValidationMessage as i18n } from 'nestjs-i18n'; -import { AppleAdditionalData } from './apple-additional-data.request.dto'; - -export class AppleLoginRequestDto { - @ApiProperty({ example: 'apple_token' }) - @IsString({ message: i18n('validation.IsString', { path: 'general', property: 'auth.appleToken' }) }) - @IsNotEmpty({ message: i18n('validation.IsNotEmpty', { path: 'general', property: 'auth.appleToken' }) }) - appleToken!: string; - - @ApiProperty({ type: AppleAdditionalData }) - @ValidateNested({ - each: true, - message: i18n('validation.ValidateNested', { path: 'general', property: 'auth.apple.additionalData' }), - }) - @IsOptional() - @Type(() => AppleAdditionalData) - additionalData?: AppleAdditionalData; -} diff --git a/src/auth/dtos/request/disable-biometric.request.dto.ts b/src/auth/dtos/request/disable-biometric.request.dto.ts deleted file mode 100644 index f30df1e..0000000 --- a/src/auth/dtos/request/disable-biometric.request.dto.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { PickType } from '@nestjs/swagger'; -import { EnableBiometricRequestDto } from './enable-biometric.request.dto'; - -export class DisableBiometricRequestDto extends PickType(EnableBiometricRequestDto, ['deviceId']) {} diff --git a/src/auth/dtos/request/enable-biometric.request.dto.ts b/src/auth/dtos/request/enable-biometric.request.dto.ts deleted file mode 100644 index b582391..0000000 --- a/src/auth/dtos/request/enable-biometric.request.dto.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsNotEmpty, IsString } from 'class-validator'; -import { i18nValidationMessage as i18n } from 'nestjs-i18n'; -export class EnableBiometricRequestDto { - @ApiProperty({ example: 'device-id' }) - @IsString({ message: i18n('validation.IsString', { path: 'general', property: 'auth.deviceId' }) }) - @IsNotEmpty({ message: i18n('validation.IsNotEmpty', { path: 'general', property: 'auth.deviceId' }) }) - deviceId!: string; - - @ApiProperty({ example: 'publicKey' }) - @IsString({ message: i18n('validation.IsString', { path: 'general', property: 'auth.publicKey' }) }) - @IsNotEmpty({ message: i18n('validation.IsNotEmpty', { path: 'general', property: 'auth.publicKey' }) }) - publicKey!: string; -} diff --git a/src/auth/dtos/request/google-login.request.dto.ts b/src/auth/dtos/request/google-login.request.dto.ts deleted file mode 100644 index 0ca1ca4..0000000 --- a/src/auth/dtos/request/google-login.request.dto.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsNotEmpty, IsString } from 'class-validator'; -import { i18nValidationMessage as i18n } from 'nestjs-i18n'; - -export class GoogleLoginRequestDto { - @ApiProperty({ example: 'google_token' }) - @IsString({ message: i18n('validation.IsString', { path: 'general', property: 'auth.googleToken' }) }) - @IsNotEmpty({ message: i18n('validation.IsNotEmpty', { path: 'general', property: 'auth.googleToken' }) }) - googleToken!: string; -} diff --git a/src/auth/dtos/request/set-email.request.dto.ts b/src/auth/dtos/request/set-email.request.dto.ts deleted file mode 100644 index 489c08f..0000000 --- a/src/auth/dtos/request/set-email.request.dto.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger'; -import { IsEmail } from 'class-validator'; -import { i18nValidationMessage as i18n } from 'nestjs-i18n'; -export class SetEmailRequestDto { - @ApiProperty({ example: 'test@test.com' }) - @IsEmail({}, { message: i18n('validation.IsEmail', { path: 'general', property: 'auth.email' }) }) - email!: string; -} diff --git a/src/auth/interfaces/apple-payload.interface.ts b/src/auth/interfaces/apple-payload.interface.ts deleted file mode 100644 index 06a5d63..0000000 --- a/src/auth/interfaces/apple-payload.interface.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface ApplePayload { - iss: string; - aud: string; - exp: number; - iat: number; - sub: string; - c_hash: string; - auth_time: number; - nonce_supported: boolean; - email?: string; -} diff --git a/src/auth/services/auth.service.ts b/src/auth/services/auth.service.ts index acfd6bc..3ce8b63 100644 --- a/src/auth/services/auth.service.ts +++ b/src/auth/services/auth.service.ts @@ -13,8 +13,6 @@ import { User } from '../../user/entities'; import { ChangePasswordRequestDto, CreateUnverifiedUserRequestDto, - DisableBiometricRequestDto, - EnableBiometricRequestDto, ForgetPasswordRequestDto, LoginRequestDto, SendForgetPasswordOtpRequestDto, @@ -24,7 +22,6 @@ import { } from '../dtos/request'; import { Roles } from '../enums'; import { IJwtPayload, ILoginResponse } from '../interfaces'; -import { Oauth2Service } from './oauth2.service'; const ONE_THOUSAND = 1000; const SALT_ROUNDS = 10; @@ -40,7 +37,6 @@ export class AuthService { private readonly deviceService: DeviceService, private readonly userTokenService: UserTokenService, private readonly cacheService: CacheService, - private readonly oauth2Service: Oauth2Service, ) {} async sendRegisterOtp(body: CreateUnverifiedUserRequestDto) { @@ -100,43 +96,6 @@ export class AuthService { return [tokens, user]; } - async enableBiometric(userId: string, { deviceId, publicKey }: EnableBiometricRequestDto) { - this.logger.log(`Enabling biometric for user with id ${userId}`); - const device = await this.deviceService.findUserDeviceById(deviceId, userId); - - if (!device) { - this.logger.log(`Device not found, creating new device for user with id ${userId}`); - return this.deviceService.createDevice({ - deviceId, - userId, - publicKey, - }); - } - - if (device.publicKey) { - this.logger.error(`Biometric already enabled for user with id ${userId}`); - throw new BadRequestException('AUTH.BIOMETRIC_ALREADY_ENABLED'); - } - - return this.deviceService.updateDevice(deviceId, { publicKey }); - } - - async disableBiometric(userId: string, { deviceId }: DisableBiometricRequestDto) { - const device = await this.deviceService.findUserDeviceById(deviceId, userId); - - if (!device) { - this.logger.error(`Device not found for user with id ${userId} and device id ${deviceId}`); - throw new BadRequestException('AUTH.DEVICE_NOT_FOUND'); - } - - if (!device.publicKey) { - this.logger.error(`Biometric already disabled for user with id ${userId}`); - throw new BadRequestException('AUTH.BIOMETRIC_ALREADY_DISABLED'); - } - - return this.deviceService.updateDevice(deviceId, { publicKey: null }); - } - async sendForgetPasswordOtp({ countryCode, phoneNumber }: SendForgetPasswordOtpRequestDto) { this.logger.log(`Sending forget password OTP to ${countryCode + phoneNumber}`); const user = await this.userService.findUserOrThrow({ countryCode, phoneNumber }); @@ -319,40 +278,6 @@ export class AuthService { return [tokens, user]; } - // private async loginWithBiometric(loginDto: LoginRequestDto, deviceId: string): Promise<[ILoginResponse, User]> { - // const user = await this.userService.findUserOrThrow({ email: loginDto.email }); - - // this.logger.log(`validating biometric for user with email ${loginDto.email}`); - // const device = await this.deviceService.findUserDeviceById(deviceId, user.id); - - // if (!device) { - // this.logger.error(`Device not found for user with email ${loginDto.email} and device id ${deviceId}`); - // throw new UnauthorizedException('AUTH.DEVICE_NOT_FOUND'); - // } - - // if (!device.publicKey) { - // this.logger.error(`Biometric not enabled for user with email ${loginDto.email}`); - // throw new UnauthorizedException('AUTH.BIOMETRIC_NOT_ENABLED'); - // } - - // const cleanToken = removePadding(loginDto.signature); - // const isValidToken = await verifySignature( - // device.publicKey, - // cleanToken, - // `${user.email} - ${device.deviceId}`, - // 'SHA1', - // ); - - // if (!isValidToken) { - // this.logger.error(`Invalid biometric for user with email ${loginDto.email}`); - // throw new UnauthorizedException('AUTH.INVALID_BIOMETRIC'); - // } - - // const tokens = await this.generateAuthToken(user); - // this.logger.log(`Biometric validated successfully for user with email ${loginDto.email}`); - // return [tokens, user]; - // } - private async generateAuthToken(user: User) { this.logger.log(`Generating auth token for user with id ${user.id}`); const [accessToken, refreshToken] = await Promise.all([ diff --git a/src/auth/services/index.ts b/src/auth/services/index.ts index 69c39b4..2a719d1 100644 --- a/src/auth/services/index.ts +++ b/src/auth/services/index.ts @@ -1,2 +1 @@ export * from './auth.service'; -export * from './oauth2.service'; diff --git a/src/auth/services/oauth2.service.ts b/src/auth/services/oauth2.service.ts deleted file mode 100644 index a3577bb..0000000 --- a/src/auth/services/oauth2.service.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { HttpService } from '@nestjs/axios'; -import { Injectable, Logger, UnauthorizedException } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { JwtService } from '@nestjs/jwt'; -import { OAuth2Client } from 'google-auth-library'; -import jwkToPem from 'jwk-to-pem'; -import { lastValueFrom } from 'rxjs'; -import { ApplePayload } from '../interfaces'; - -@Injectable() -export class Oauth2Service { - private readonly logger = new Logger(Oauth2Service.name); - private appleKeysEndpoint = 'https://appleid.apple.com/auth/keys'; - private appleIssuer = 'https://appleid.apple.com'; - private readonly googleWebClientId = this.configService.getOrThrow('GOOGLE_WEB_CLIENT_ID'); - private readonly googleAndroidClientId = this.configService.getOrThrow('GOOGLE_ANDROID_CLIENT_ID'); - private readonly googleIosClientId = this.configService.getOrThrow('GOOGLE_IOS_CLIENT_ID'); - private readonly client = new OAuth2Client(); - constructor( - private readonly httpService: HttpService, - private readonly jwtService: JwtService, - private readonly configService: ConfigService, - ) {} - - async verifyAppleToken(appleToken: string): Promise { - try { - const response = await lastValueFrom(this.httpService.get(this.appleKeysEndpoint)); - - const keys = response.data.keys; - - const decodedHeader = this.jwtService.decode(appleToken, { complete: true })?.header; - - if (!decodedHeader) { - this.logger.error(`Invalid apple token`); - throw new UnauthorizedException(); - } - - const keyId = decodedHeader.kid; - - const appleKey = keys.find((key: any) => key.kid === keyId); - - if (!appleKey) { - this.logger.error(`Invalid apple token`); - throw new UnauthorizedException(); - } - - const publicKey = jwkToPem(appleKey); - - const payload = this.jwtService.verify(appleToken, { - publicKey, - algorithms: ['RS256'], - audience: this.configService.getOrThrow('APPLE_CLIENT_ID').split(','), - issuer: this.appleIssuer, - }); - - return payload; - } catch (error) { - this.logger.error(`Error verifying apple token: ${error} `); - throw new UnauthorizedException(error); - } - } - - async verifyGoogleToken(googleToken: string): Promise { - try { - const ticket = await this.client.verifyIdToken({ - idToken: googleToken, - audience: [this.googleWebClientId, this.googleAndroidClientId, this.googleIosClientId], - }); - - const payload = ticket.getPayload(); - - if (!payload) { - this.logger.error(`payload not found in google token`); - throw new UnauthorizedException(); - } - - return payload; - } catch (error) { - this.logger.error(`Invalid google token`, error); - throw new UnauthorizedException(); - } - } -} diff --git a/src/db/migrations/1754915164809-create-neoleap-related-entities.ts b/src/db/migrations/1754915164809-create-neoleap-related-entities.ts new file mode 100644 index 0000000..105415d --- /dev/null +++ b/src/db/migrations/1754915164809-create-neoleap-related-entities.ts @@ -0,0 +1,95 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class CreateNeoleapRelatedEntities1754915164809 implements MigrationInterface { + name = 'CreateNeoleapRelatedEntities1754915164809'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "customers" DROP CONSTRAINT "FK_e7574892da11dd01de5cfc46499"`); + await queryRunner.query( + `CREATE TABLE "transactions" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "transaction_scope" character varying NOT NULL, "transaction_type" character varying NOT NULL DEFAULT 'EXTERNAL', "card_reference" character varying, "account_reference" character varying, "transaction_id" character varying, "card_masked_number" character varying, "transaction_date" TIMESTAMP WITH TIME ZONE, "rrn" character varying, "transaction_amount" numeric(12,2) NOT NULL, "transaction_currency" character varying NOT NULL, "billing_amount" numeric(12,2) NOT NULL, "settlement_amount" numeric(12,2) NOT NULL, "fees" numeric(12,2) NOT NULL, "vat_on_fees" numeric(12,2) NOT NULL DEFAULT '0', "card_id" uuid, "account_id" uuid, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), CONSTRAINT "UQ_9162bf9ab4e31961a8f7932974c" UNIQUE ("transaction_id"), CONSTRAINT "PK_a219afd8dd77ed80f5a862f1db9" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "accounts" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "account_reference" character varying(255) NOT NULL, "account_number" character varying(255) NOT NULL, "iban" character varying(255) NOT NULL, "currency" character varying(255) NOT NULL, "balance" numeric(10,2) NOT NULL DEFAULT '0', "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), CONSTRAINT "UQ_829183fe026a0ce5fc8026b2417" UNIQUE ("account_reference"), CONSTRAINT "PK_5a7a02c20412299d198e097a8fe" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE UNIQUE INDEX "IDX_829183fe026a0ce5fc8026b241" ON "accounts" ("account_reference") `, + ); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_ffd1ae96513bfb2c6eada0f7d3" ON "accounts" ("account_number") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_9a4b004902294416b096e7556e" ON "accounts" ("iban") `); + await queryRunner.query( + `CREATE TABLE "cards" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "card_reference" character varying NOT NULL, "vpan" character varying NOT NULL, "first_six_digits" character varying(6) NOT NULL, "last_four_digits" character varying(4) NOT NULL, "expiry" character varying NOT NULL, "customer_type" character varying NOT NULL, "color" character varying NOT NULL DEFAULT 'BLUE', "status" character varying NOT NULL DEFAULT 'PENDING', "statusDescription" character varying NOT NULL DEFAULT 'PENDING_ACTIVATION', "limit" numeric(10,2) NOT NULL DEFAULT '0', "scheme" character varying NOT NULL DEFAULT 'VISA', "issuer" character varying NOT NULL, "customer_id" uuid NOT NULL, "parent_id" uuid, "account_id" uuid NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), CONSTRAINT "PK_5f3269634705fdff4a9935860fc" PRIMARY KEY ("id"))`, + ); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_4f7df5c5dc950295dc417a11d8" ON "cards" ("card_reference") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_1ec2ef68b0370f26639261e87b" ON "cards" ("vpan") `); + await queryRunner.query(`ALTER TABLE "customers" DROP CONSTRAINT "REL_e7574892da11dd01de5cfc4649"`); + await queryRunner.query(`ALTER TABLE "customers" DROP COLUMN "profile_picture_id"`); + await queryRunner.query(`ALTER TABLE "users" ADD "first_name" character varying(255) NOT NULL`); + await queryRunner.query(`ALTER TABLE "users" ADD "last_name" character varying(255) NOT NULL`); + await queryRunner.query(`ALTER TABLE "users" ADD "profile_picture_id" uuid`); + await queryRunner.query( + `ALTER TABLE "users" ADD CONSTRAINT "UQ_02ec15de199e79a0c46869895f4" UNIQUE ("profile_picture_id")`, + ); + await queryRunner.query( + `ALTER TABLE "documents" ADD "upload_status" character varying(255) NOT NULL DEFAULT 'NOT_UPLOADED'`, + ); + await queryRunner.query(`ALTER TABLE "customers" ADD "country" character varying(255)`); + await queryRunner.query(`ALTER TABLE "customers" ADD "region" character varying(255)`); + await queryRunner.query(`ALTER TABLE "customers" ADD "city" character varying(255)`); + await queryRunner.query(`ALTER TABLE "customers" ADD "neighborhood" character varying(255)`); + await queryRunner.query(`ALTER TABLE "customers" ADD "street" character varying(255)`); + await queryRunner.query(`ALTER TABLE "customers" ADD "building" character varying(255)`); + await queryRunner.query( + `ALTER TABLE "users" ADD CONSTRAINT "FK_02ec15de199e79a0c46869895f4" FOREIGN KEY ("profile_picture_id") REFERENCES "documents"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "transactions" ADD CONSTRAINT "FK_80ad48141be648db2d84ff32f79" FOREIGN KEY ("card_id") REFERENCES "cards"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "transactions" ADD CONSTRAINT "FK_49c0d6e8ba4bfb5582000d851f0" FOREIGN KEY ("account_id") REFERENCES "accounts"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "cards" ADD CONSTRAINT "FK_8ba18e7060c38ddae12e5bdf907" FOREIGN KEY ("parent_id") REFERENCES "customers"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "cards" ADD CONSTRAINT "FK_2fd0ee722ec57594d2e448c73d7" FOREIGN KEY ("customer_id") REFERENCES "customers"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "cards" ADD CONSTRAINT "FK_b2874ef49ff7da2dee49e4bc6d3" FOREIGN KEY ("account_id") REFERENCES "accounts"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "cards" DROP CONSTRAINT "FK_b2874ef49ff7da2dee49e4bc6d3"`); + await queryRunner.query(`ALTER TABLE "cards" DROP CONSTRAINT "FK_2fd0ee722ec57594d2e448c73d7"`); + await queryRunner.query(`ALTER TABLE "cards" DROP CONSTRAINT "FK_8ba18e7060c38ddae12e5bdf907"`); + await queryRunner.query(`ALTER TABLE "transactions" DROP CONSTRAINT "FK_49c0d6e8ba4bfb5582000d851f0"`); + await queryRunner.query(`ALTER TABLE "transactions" DROP CONSTRAINT "FK_80ad48141be648db2d84ff32f79"`); + await queryRunner.query(`ALTER TABLE "users" DROP CONSTRAINT "FK_02ec15de199e79a0c46869895f4"`); + await queryRunner.query(`ALTER TABLE "customers" DROP COLUMN "building"`); + await queryRunner.query(`ALTER TABLE "customers" DROP COLUMN "street"`); + await queryRunner.query(`ALTER TABLE "customers" DROP COLUMN "neighborhood"`); + await queryRunner.query(`ALTER TABLE "customers" DROP COLUMN "city"`); + await queryRunner.query(`ALTER TABLE "customers" DROP COLUMN "region"`); + await queryRunner.query(`ALTER TABLE "customers" DROP COLUMN "country"`); + await queryRunner.query(`ALTER TABLE "documents" DROP COLUMN "upload_status"`); + await queryRunner.query(`ALTER TABLE "users" DROP CONSTRAINT "UQ_02ec15de199e79a0c46869895f4"`); + await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "profile_picture_id"`); + await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "last_name"`); + await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "first_name"`); + await queryRunner.query(`ALTER TABLE "customers" ADD "profile_picture_id" uuid`); + await queryRunner.query( + `ALTER TABLE "customers" ADD CONSTRAINT "REL_e7574892da11dd01de5cfc4649" UNIQUE ("profile_picture_id")`, + ); + await queryRunner.query(`DROP INDEX "public"."IDX_1ec2ef68b0370f26639261e87b"`); + await queryRunner.query(`DROP INDEX "public"."IDX_4f7df5c5dc950295dc417a11d8"`); + await queryRunner.query(`DROP TABLE "cards"`); + await queryRunner.query(`DROP INDEX "public"."IDX_9a4b004902294416b096e7556e"`); + await queryRunner.query(`DROP INDEX "public"."IDX_ffd1ae96513bfb2c6eada0f7d3"`); + await queryRunner.query(`DROP INDEX "public"."IDX_829183fe026a0ce5fc8026b241"`); + await queryRunner.query(`DROP TABLE "accounts"`); + await queryRunner.query(`DROP TABLE "transactions"`); + await queryRunner.query( + `ALTER TABLE "customers" ADD CONSTRAINT "FK_e7574892da11dd01de5cfc46499" FOREIGN KEY ("profile_picture_id") REFERENCES "documents"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } +} diff --git a/src/db/migrations/index.ts b/src/db/migrations/index.ts index 462234a..43207c9 100644 --- a/src/db/migrations/index.ts +++ b/src/db/migrations/index.ts @@ -1,2 +1,3 @@ export * from './1754913378460-initial-migration'; export * from './1754913378461-seed-default-avatar'; +export * from './1754915164809-create-neoleap-related-entities';