Skip to content

Commit

Permalink
Add route to create bank account
Browse files Browse the repository at this point in the history
  • Loading branch information
henriqueleite42 committed Nov 26, 2023
1 parent 53d53c7 commit c0daf8c
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 40 deletions.
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ model BankAccount {
recurrentTransactionFroms RecurrentTransaction[] @relation(name: "RecurrentTransactionBankAccountFrom")
recurrentTransactionTos RecurrentTransaction[] @relation(name: "RecurrentTransactionBankAccountTo")
@@unique([accountId, bankProviderId, accountNumber])
@@map("bank_accounts")
}

Expand Down
21 changes: 18 additions & 3 deletions src/delivery/bank.controller.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
import { Controller, Get, Query, UseGuards } from '@nestjs/common';
import { Body, Controller, Get, Post, Query, UseGuards } from '@nestjs/common';
import { AuthGuard } from './guards/auth.guard';
import { PaginatedDto } from './dtos';
import { PaginatedDto, UserDataDto } from './dtos';
import { BankService } from 'src/usecases/bank/bank.service';
import { UserData } from './decorators/user-data';
import { CreateDto } from './dtos/bank';

@Controller('banks')
@UseGuards(AuthGuard())
export class BankController {
constructor(private readonly bankService: BankService) {}

@Get('/providers')
async getDefault(
getDefault(
@Query()
pagination: PaginatedDto,
) {
return this.bankService.getProviders(pagination);
}

@Post('accounts')
create(
@UserData()
userData: UserDataDto,
@Body()
body: CreateDto,
) {
return this.bankService.create({
...body,
accountId: userData.accountId,
});
}
}
35 changes: 35 additions & 0 deletions src/delivery/dtos/bank.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
IsInt,
IsNumberString,
IsString,
Max,
MaxLength,
Min,
MinLength,
} from 'class-validator';
import { IsID } from '../validators/internal';

export class CreateDto {
@IsString()
@MinLength(1)
@MaxLength(20)
name: string;

@IsID()
bankProviderId: string;

@IsNumberString()
@MinLength(6)
@MaxLength(6)
accountNumber: string;

@IsNumberString()
@MinLength(3)
@MaxLength(3)
branch: string;

@IsInt()
@Min(0)
@Max(999_999_999_99)
balance: number;
}
10 changes: 10 additions & 0 deletions src/delivery/dtos/category.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { IconEnum } from '@prisma/client';
import { Type } from 'class-transformer';
import {
ArrayMaxSize,
ArrayMinSize,
IsArray,
IsEnum,
IsHexColor,
IsString,
MaxLength,
MinLength,
ValidateNested,
} from 'class-validator';

class CreateCategoryDto {
Expand All @@ -25,5 +30,10 @@ class CreateCategoryDto {
}

export class CreateManyDto {
@IsArray()
@ValidateNested({ each: true })
@ArrayMinSize(1)
@ArrayMaxSize(50)
@Type(() => CreateCategoryDto)
categories: Array<CreateCategoryDto>;
}
25 changes: 19 additions & 6 deletions src/models/bank.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import { BankAccount, BankProvider } from '@prisma/client';
import {
Paginated,
PaginatedItems,
PaginatedRepository,
} from 'src/types/paginated-items';

/**
*
*
Expand All @@ -6,15 +13,19 @@
*
*/

import { BankProvider } from '@prisma/client';
import {
Paginated,
PaginatedItems,
PaginatedRepository,
} from 'src/types/paginated-items';
export interface CreateInput {
accountId: string;
bankProviderId: string;
name: string;
accountNumber: string;
branch: string;
balance: number;
}

export abstract class BankRepository {
abstract getProviders(i: PaginatedRepository): Promise<Array<BankProvider>>;

abstract create(i: CreateInput): Promise<BankAccount>;
}

/**
Expand All @@ -27,4 +38,6 @@ export abstract class BankRepository {

export abstract class BankUseCase {
abstract getProviders(i: Paginated): Promise<PaginatedItems<BankProvider>>;

abstract create(i: CreateInput): Promise<void>;
}
5 changes: 3 additions & 2 deletions src/repositories/postgres/bank/bank-repository.module.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Module } from '@nestjs/common';
import { PostgresModule } from '..';
import { BankRepositoryService } from './bank-repository.service';
import { UIDAdapter } from 'src/adapters/implementations/uid.service';

@Module({
imports: [PostgresModule.forFeature(['bankProvider'])],
providers: [BankRepositoryService],
imports: [PostgresModule.forFeature(['bankProvider', 'bankAccount'])],
providers: [BankRepositoryService, UIDAdapter],
exports: [BankRepositoryService],
})
export class BankRepositoryModule {}
56 changes: 53 additions & 3 deletions src/repositories/postgres/bank/bank-repository.service.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import { Injectable } from '@nestjs/common';
import {
ConflictException,
Injectable,
InternalServerErrorException,
NotFoundException,
} from '@nestjs/common';
import { InjectRepository, Repository } from '..';
import { BankProvider } from '@prisma/client';
import { BankAccount, BankProvider } from '@prisma/client';
import { PaginatedRepository } from 'src/types/paginated-items';
import { BankRepository } from 'src/models/bank';
import { BankRepository, CreateInput } from 'src/models/bank';
import { UIDAdapter } from 'src/adapters/implementations/uid.service';

@Injectable()
export class BankRepositoryService extends BankRepository {
constructor(
@InjectRepository('bankProvider')
private readonly bankProviderRepository: Repository<'bankProvider'>,
@InjectRepository('bankAccount')
private readonly bankAccountRepository: Repository<'bankAccount'>,

private readonly idAdapter: UIDAdapter,
) {
super();
}
Expand All @@ -22,4 +32,44 @@ export class BankRepositoryService extends BankRepository {
take: limit,
});
}

async create({
accountId,
bankProviderId,
name,
accountNumber,
branch,
balance,
}: CreateInput): Promise<BankAccount> {
try {
const bankAccount = await this.bankAccountRepository.create({
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
data: {
id: this.idAdapter.gen(),
accountId,
bankProviderId,
name,
accountNumber,
branch,
balance,
},
});

return bankAccount;
} catch (err) {
// https://www.prisma.io/docs/reference/api-reference/error-reference#p2003
if (err.code === 'P2003') {
throw new NotFoundException("Bank provider doesn't exists");
}
// https://www.prisma.io/docs/reference/api-reference/error-reference#p2004
if (err.code === 'P2004') {
throw new ConflictException('Bank account already exists');
}

throw new InternalServerErrorException(
`Fail to create bank account: ${err.message}`,
);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { Injectable } from '@nestjs/common';
import {
ConflictException,
Injectable,
InternalServerErrorException,
NotFoundException,
} from '@nestjs/common';
import { InjectRepository, Repository } from '..';
import {
AcceptInput,
Expand Down Expand Up @@ -29,18 +34,26 @@ export class TermsAndPoliciesRepositoryService extends TermsAndPoliciesRepositor
} catch (err) {
// https://www.prisma.io/docs/reference/api-reference/error-reference#p2003
if (err.code === 'P2003') {
throw new Error("Version doesn't exists");
throw new NotFoundException("Version doesn't exists");
}
// https://www.prisma.io/docs/reference/api-reference/error-reference#p2004
if (err.code === 'P2004') {
throw new Error('Version already accepted');
throw new ConflictException('Version already accepted');
}

throw new Error(`Fail to accept version: ${err.message}`);
throw new InternalServerErrorException(
`Fail to accept version: ${err.message}`,
);
}
}

getLatest(): Promise<TermsAndPolicies | undefined> {
return this.termsAndPoliciesRepository.findFirst({
where: {
liveAt: {
lte: new Date(),
},
},
orderBy: {
liveAt: 'desc',
},
Expand Down
6 changes: 5 additions & 1 deletion src/usecases/bank/bank.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { BankProvider } from '@prisma/client';
import { UtilsAdapter } from 'src/adapters/implementations/utils.service';
import { BankUseCase } from 'src/models/bank';
import { BankUseCase, CreateInput } from 'src/models/bank';

import { BankRepositoryService } from 'src/repositories/postgres/bank/bank-repository.service';
import { Paginated, PaginatedItems } from 'src/types/paginated-items';
Expand All @@ -27,4 +27,8 @@ export class BankService extends BankUseCase {
data,
};
}

async create(i: CreateInput): Promise<void> {
await this.bankRepository.create(i);
}
}
23 changes: 5 additions & 18 deletions src/usecases/terms-and-policies/terms-and-policies.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
BadRequestException,
Inject,
Injectable,
NotFoundException,
} from '@nestjs/common';
import { BadRequestException, Inject, Injectable } from '@nestjs/common';

import { TermsAndPolicies } from '@prisma/client';
import {
Expand Down Expand Up @@ -42,18 +37,10 @@ export class TermsAndPoliciesService extends TermsAndPoliciesUseCase {
throw new BadRequestException('User already accepted terms');
}

await this.termsAndPoliciesRepository
.accept({
accountId,
semVer,
})
.catch((e) => {
if (e.message === "Version doesn't exists") {
throw new NotFoundException(e.message);
}

throw e;
});
await this.termsAndPoliciesRepository.accept({
accountId,
semVer,
});
}

async hasAcceptedLatest({
Expand Down
4 changes: 2 additions & 2 deletions tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "dist-lint", "**/*spec.ts"]
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false
},
"exclude": ["dist-lint"]
"exclude": ["dist", "dist-lint"]
}

0 comments on commit c0daf8c

Please sign in to comment.