Skip to content

Commit

Permalink
Merge pull request #6 from arakakimath/integration-layer
Browse files Browse the repository at this point in the history
fix: prevent duplicate CPF registration and add findByCpf method
  • Loading branch information
arakakimath authored Feb 25, 2025
2 parents 7ae5757 + e991804 commit 90d1e14
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 10 deletions.
3 changes: 3 additions & 0 deletions src/core/errors/use-case-error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface UseCaseError {
message: string
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ import { DeliveryPerson } from '@/domain/enterprise/entities/delivery-person'

export abstract class DeliveryPeopleRepository {
abstract create(deliveryPerson: DeliveryPerson): Promise<void>
abstract findByCpf(cpf: string): Promise<DeliveryPerson | null>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { UseCaseError } from '@/core/errors/use-case-error'

export class DeliveryPersonAlreadyExistsError
extends Error
implements UseCaseError
{
constructor() {
super('Delivery person already registered.')
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ describe('Register Delivery Person', () => {
password: '123456',
})

expect(result.isRight).toBeTruthy()
expect(result.isRight()).toBeTruthy()
if (result.isLeft()) throw new Error()
expect(result.value?.deliveryPerson.id).toBeTruthy()
expect(result.value?.deliveryPerson.isAdmin()).toBeFalsy()
expect(deliveryPersonRepository.items[0]).toEqual(
Expand Down
12 changes: 10 additions & 2 deletions src/domain/application/use-cases/register-delivery-person.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Either, right } from '@/core/either'
import { Either, left, right } from '@/core/either'
import { DeliveryPerson } from '@/domain/enterprise/entities/delivery-person'
import { DeliveryPeopleRepository } from '../repositories/delivery-people.repository'
import { Injectable } from '@nestjs/common'
import { DeliveryPersonAlreadyExistsError } from './errors/delivery-person-already-exists.error'

interface RegisterDeliveryPersonUseCaseRequest {
name: string
Expand All @@ -11,7 +12,7 @@ interface RegisterDeliveryPersonUseCaseRequest {
}

type RegisterDeliveryPersonUseCaseResponse = Either<
null,
DeliveryPersonAlreadyExistsError,
{
deliveryPerson: DeliveryPerson
}
Expand All @@ -34,6 +35,13 @@ export class RegisterDeliveryPersonUseCase {
admin,
})

const deliveryPersonOnDatabase =
await this.deliveryPeopleRepository.findByCpf(cpf)

if (deliveryPersonOnDatabase) {
return left(new DeliveryPersonAlreadyExistsError())
}

await this.deliveryPeopleRepository.create(deliveryPerson)

return right({ deliveryPerson })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { DeliveryPerson } from '@/domain/enterprise/entities/delivery-person'
import { Injectable } from '@nestjs/common'
import { MongooseDeliveryPersonMapper } from '../mappers/mongoose-delivery-person.mapper'
import { MongooseService } from '../mongoose.service'
import { UniqueEntityID } from '@/core/entities/unique-entity-id'

@Injectable()
export class MongooseDeliveryPeopleRepository
Expand All @@ -15,4 +16,20 @@ export class MongooseDeliveryPeopleRepository

await this.mongoose.user.create(data)
}

async findByCpf(cpf: string) {
const deliveryPerson = await this.mongoose.user.findOne({ cpf })

return deliveryPerson
? DeliveryPerson.create(
{
name: deliveryPerson.name,
cpf: deliveryPerson.cpf,
admin: deliveryPerson.admin,
password: deliveryPerson.password,
},
new UniqueEntityID(deliveryPerson._id),
)
: null
}
}
22 changes: 15 additions & 7 deletions src/infra/http/controllers/create-user.controller.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { RegisterDeliveryPersonUseCase } from '@/domain/application/use-cases/register-delivery-person'
import { ZodValidationPipe } from '@/infra/pipes/zod-validation.pipe'
import { Body, Controller, Post, UsePipes } from '@nestjs/common'
import {
Body,
ConflictException,
Controller,
Post,
UsePipes,
} from '@nestjs/common'
import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'
import { MongooseService } from 'src/infra/database/mongoose/mongoose.service'
import { z } from 'zod'

const registerBodySchema = z.object({
Expand All @@ -17,10 +22,7 @@ type RegisterBodySchema = z.infer<typeof registerBodySchema>
@Controller('/users')
@ApiTags('Users')
export class CreateUserController {
constructor(
private mongoose: MongooseService,
private registerUseCase: RegisterDeliveryPersonUseCase,
) {}
constructor(private registerUseCase: RegisterDeliveryPersonUseCase) {}

@Post()
@ApiOperation({ summary: 'Register a delivery person.' })
Expand Down Expand Up @@ -65,11 +67,17 @@ export class CreateUserController {
@UsePipes(new ZodValidationPipe(registerBodySchema))
async handle(@Body() body: RegisterBodySchema) {
const { name, cpf, password, admin } = body
await this.registerUseCase.execute({

const result = await this.registerUseCase.execute({
name,
cpf,
password,
admin,
})

if (result.isLeft()) {
const error = result.value
throw new ConflictException(error.message)
}
}
}
4 changes: 4 additions & 0 deletions test/in-memory-repositories/delivery-people.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ export class InMemoryDeliveryPeopleRepository
async create(deliveryPerson: DeliveryPerson): Promise<void> {
this.items.push(deliveryPerson)
}

async findByCpf(cpf: string): Promise<DeliveryPerson | null> {
return this.items.filter((item) => item.cpf === cpf)[0]
}
}

0 comments on commit 90d1e14

Please sign in to comment.