From 43e792008a3d547a91d8ddb6f62d5bad40541279 Mon Sep 17 00:00:00 2001 From: luanavfg Date: Tue, 16 Jan 2024 08:40:07 -0300 Subject: [PATCH 01/19] adjust: change UpdateAppointmentInfoDto name --- .../repositories/database-in-memory-repository.ts | 4 ++-- .../domains/appointment/repositories/database-repository.ts | 4 ++-- .../update-appointment-info/update-appointment-info-dto.ts | 2 +- .../update-appointment-info.service.ts | 6 +++--- .../update-appointment-info/update-appointment-info.spec.ts | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-in-memory-repository.ts b/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-in-memory-repository.ts index e21861aa..a80eed93 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-in-memory-repository.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-in-memory-repository.ts @@ -3,7 +3,7 @@ import { APPOINTMENT_ERROR_MESSAGES } from '../../../../shared/errors/error-mess import { AppointmentEntity } from '../entities/appointment/entity'; import { CreateSingleAppointmentDto } from '../use-cases/create-single-appointment/create-single-appointment-dto'; import { UpdatedAppointmentDateDto } from '../use-cases/update-appointment-date/update-appointment-date-dto'; -import { UpdatedAppointmentInfoDto } from '../use-cases/update-appointment-info/update-appointment-info-dto'; +import { UpdateAppointmentInfoDto } from '../use-cases/update-appointment-info/update-appointment-info-dto'; import { AppointmentDatabaseRepository } from './database-repository'; export class InMemoryAppointmentDatabaseRepository @@ -49,7 +49,7 @@ export class InMemoryAppointmentDatabaseRepository } async updateAppointmentInfo( - newAppointmentInfo: UpdatedAppointmentInfoDto, + newAppointmentInfo: UpdateAppointmentInfoDto, ): Promise { const oldAppointmentInfo = await this.findSingleAppointmentById( newAppointmentInfo.id, diff --git a/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-repository.ts b/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-repository.ts index cb1af23f..b894895f 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-repository.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-repository.ts @@ -1,7 +1,7 @@ import { AppointmentEntity } from '../entities/appointment/entity'; import { CreateSingleAppointmentDto } from '../use-cases/create-single-appointment/create-single-appointment-dto'; import { UpdatedAppointmentDateDto } from '../use-cases/update-appointment-date/update-appointment-date-dto'; -import { UpdatedAppointmentInfoDto } from '../use-cases/update-appointment-info/update-appointment-info-dto'; +import { UpdateAppointmentInfoDto } from '../use-cases/update-appointment-info/update-appointment-info-dto'; export abstract class AppointmentDatabaseRepository { abstract createSingleAppointment( @@ -15,7 +15,7 @@ export abstract class AppointmentDatabaseRepository { ): Promise; abstract getAppointments(): Promise; abstract updateAppointmentInfo( - newAppointmentInfo: UpdatedAppointmentInfoDto + newAppointmentInfo: UpdateAppointmentInfoDto ): Promise; abstract updateAppointmentDate( newAppointmentInfo: UpdatedAppointmentDateDto diff --git a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/update-appointment-info/update-appointment-info-dto.ts b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/update-appointment-info/update-appointment-info-dto.ts index b4c418e2..cc4d5ad6 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/update-appointment-info/update-appointment-info-dto.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/update-appointment-info/update-appointment-info-dto.ts @@ -7,7 +7,7 @@ import { } from 'class-validator'; import { PaymentMethod } from '../../../../shared/interfaces/payments'; -export class UpdatedAppointmentInfoDto { +export class UpdateAppointmentInfoDto { @IsString() id!: string; diff --git a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/update-appointment-info/update-appointment-info.service.ts b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/update-appointment-info/update-appointment-info.service.ts index 25219793..06ded5b6 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/update-appointment-info/update-appointment-info.service.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/update-appointment-info/update-appointment-info.service.ts @@ -3,15 +3,15 @@ import { plainToInstance } from 'class-transformer'; import { APPOINTMENT_ERROR_MESSAGES } from '../../../../../shared/errors/error-messages'; import { applicationValidateOrReject } from '../../../../../shared/validators/validate-or-reject'; import { AppointmentDatabaseRepository } from '../../repositories/database-repository'; -import { UpdatedAppointmentInfoDto } from './update-appointment-info-dto'; +import { UpdateAppointmentInfoDto } from './update-appointment-info-dto'; export class UpdateAppointmentInfoService { constructor(private appointmentDatabaseRepository: AppointmentDatabaseRepository) {} - async execute(newAppointmentInfo: UpdatedAppointmentInfoDto): Promise { + async execute(newAppointmentInfo: UpdateAppointmentInfoDto): Promise { // Validate props types const updateAppointmentDtoInstance = plainToInstance( - UpdatedAppointmentInfoDto, + UpdateAppointmentInfoDto, newAppointmentInfo, ); diff --git a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/update-appointment-info/update-appointment-info.spec.ts b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/update-appointment-info/update-appointment-info.spec.ts index 4afda241..169b3060 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/update-appointment-info/update-appointment-info.spec.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/update-appointment-info/update-appointment-info.spec.ts @@ -6,7 +6,7 @@ import { PaymentMethod } from '../../../../shared/interfaces/payments'; import { InMemoryAppointmentDatabaseRepository } from '../../repositories/database-in-memory-repository'; import { AppointmentDatabaseRepository } from '../../repositories/database-repository'; import { CreateSingleAppointmentDto } from '../create-single-appointment/create-single-appointment-dto'; -import { UpdatedAppointmentInfoDto } from './update-appointment-info-dto'; +import { UpdateAppointmentInfoDto } from './update-appointment-info-dto'; import { UpdateAppointmentInfoService } from './update-appointment-info.service'; describe('[appointment] Update Appointment Info Service', () => { @@ -34,7 +34,7 @@ describe('[appointment] Update Appointment Info Service', () => { const createAppointment = await databaseRepository.createSingleAppointment(fakeAppointment); - const newAppointmentInfo: UpdatedAppointmentInfoDto = { + const newAppointmentInfo: UpdateAppointmentInfoDto = { id: createAppointment.id, paid: true, paymentMethod: PaymentMethod.PIX, @@ -57,7 +57,7 @@ describe('[appointment] Update Appointment Info Service', () => { }); it('should throw error if appointment does not exist', async () => { - const newAppointmentInfo: UpdatedAppointmentInfoDto = { + const newAppointmentInfo: UpdateAppointmentInfoDto = { id: randomUUID(), paid: true, paymentMethod: PaymentMethod.PIX, From 5aaa605d6297690ba659b9c4f7192ea0ad92fa04 Mon Sep 17 00:00:00 2001 From: luanavfg Date: Tue, 16 Jan 2024 08:41:11 -0300 Subject: [PATCH 02/19] feat: add create appointment controller --- .../create-appointment.controller.ts | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.controller.ts diff --git a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.controller.ts b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.controller.ts new file mode 100644 index 00000000..4246f665 --- /dev/null +++ b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.controller.ts @@ -0,0 +1,29 @@ +import { Body, Controller, Post } from "@nestjs/common"; +import { ApiBearerAuth, ApiOperation, ApiTags } from "@nestjs/swagger"; +import { CreateSingleAppointmentDto } from '../../../../../../core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto'; +import { GlobalAppHttpException } from '../../../../../../shared/errors/globalAppHttpException'; +import { postMethodDocs } from "../../patient/create-patient/docs"; +import { NestjsCreateAppointmentService } from "./nestjs-create-appointment.services"; + +@ApiTags('appointment') +@ApiBearerAuth() +@Controller({ + path: 'appointment', +}) +export class CreateAppointmentController { + constructor(private createAppointmentService: NestjsCreateAppointmentService) {} + + @Post('create') + @ApiOperation(postMethodDocs) + async execute(@Body() createAppointmentDto: CreateSingleAppointmentDto) { + try { + await this.createAppointmentService.execute(createAppointmentDto); + + return { + message: 'Appointment created successfully', + } + } catch (error) { + throw new GlobalAppHttpException(error); + } + } +} From 51b65cb06d0cc00f5c15dbe28322f012442066ab Mon Sep 17 00:00:00 2001 From: luanavfg Date: Tue, 16 Jan 2024 08:41:31 -0300 Subject: [PATCH 03/19] feat: add create appointment nestjs service --- .../nestjs-create-appointment.services.ts | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/nestjs-create-appointment.services.ts diff --git a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/nestjs-create-appointment.services.ts b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/nestjs-create-appointment.services.ts new file mode 100644 index 00000000..e5f80d26 --- /dev/null +++ b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/nestjs-create-appointment.services.ts @@ -0,0 +1,8 @@ +import { AppointmentDatabaseRepository } from '../../../../../../core/domains/appointment/repositories/database-repository'; +import { CreateSingleAppointmentService } from '../../../../../../core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.service'; + +export class NestjsCreateAppointmentService extends CreateSingleAppointmentService { + constructor(appointmentDatabaseRepository: AppointmentDatabaseRepository) { + super(appointmentDatabaseRepository); + } +} From ca55bdef820a0a95564db9d831160ee36d61558c Mon Sep 17 00:00:00 2001 From: luanavfg Date: Tue, 16 Jan 2024 08:42:26 -0300 Subject: [PATCH 04/19] feat: add postgres prisma orm repository --- ...tgres-prisma-orm-appointment-repository.ts | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 apps/core-rest-api/src/app/adapters/database/repositories/appointment/postgres-prisma-orm-appointment-repository.ts diff --git a/apps/core-rest-api/src/app/adapters/database/repositories/appointment/postgres-prisma-orm-appointment-repository.ts b/apps/core-rest-api/src/app/adapters/database/repositories/appointment/postgres-prisma-orm-appointment-repository.ts new file mode 100644 index 00000000..cd32e06f --- /dev/null +++ b/apps/core-rest-api/src/app/adapters/database/repositories/appointment/postgres-prisma-orm-appointment-repository.ts @@ -0,0 +1,102 @@ +import { ConflictException } from '@nestjs/common'; +import { AppointmentEntity } from '../../../../core/domains/appointment/entities/appointment/entity'; +import { AppointmentDatabaseRepository } from '../../../../core/domains/appointment/repositories/database-repository'; +import { CreateSingleAppointmentDto } from '../../../../core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto'; +import { UpdatedAppointmentDateDto } from '../../../../core/domains/appointment/use-cases/update-appointment-date/update-appointment-date-dto'; +import { UpdateAppointmentInfoDto } from '../../../../core/domains/appointment/use-cases/update-appointment-info/update-appointment-info-dto'; +import { APPOINTMENT_ERROR_MESSAGES } from '../../../../shared/errors/error-messages'; +import { PostgreSqlPrismaOrmService } from "../../infra/prisma/prisma.service"; +import { PostgresqlPrismaAppointmentMapper } from '../../mappers/postgresql-prisma-appointment-mapper'; + +export class PostgresqlPrismaOrmAppointmentRepository implements AppointmentDatabaseRepository { + constructor(private postgresqlPrismaOrmService: PostgreSqlPrismaOrmService) {} + + async findSingleAppointmentById(appointmentId: string): Promise { + const appointment = await this.postgresqlPrismaOrmService['appointment'].findUnique({where: { + id: appointmentId + }}) + if (!appointment) { + return null; + } + + return PostgresqlPrismaAppointmentMapper.toDomain(appointment); + } + + async findSingleAppointmentByDate(appointmentDate: Date): Promise { + const appointment = await this.postgresqlPrismaOrmService['appointment'].findFirst({ + where: { + date: appointmentDate, + } + }) + if (!appointment) { + return null; + } + + return PostgresqlPrismaAppointmentMapper.toDomain(appointment); + } + + async createSingleAppointment(appointment: CreateSingleAppointmentDto): Promise { + const isAppointmentExists = await this.findSingleAppointmentByDate(appointment.date); + + if (isAppointmentExists) { + throw new ConflictException(APPOINTMENT_ERROR_MESSAGES['CONFLICTING_DATE_TIME']); + } + + const toPrismaEntity = PostgresqlPrismaAppointmentMapper.toPrismaCreate({ + ...appointment, + }); + + const newAppointment = + await this.postgresqlPrismaOrmService['appointment'].create(toPrismaEntity); + + return PostgresqlPrismaAppointmentMapper.toDomain(newAppointment); + } + + async getAppointments(): Promise { + const appointments = await this.postgresqlPrismaOrmService['appointment'].findMany(); + + return appointments.map((appointment) => PostgresqlPrismaAppointmentMapper.toDomain(appointment)) + } + + async updateAppointmentInfo(newAppointmentInfo: UpdateAppointmentInfoDto): Promise { + const oldAppointmentInfo = await this.findSingleAppointmentById(newAppointmentInfo.id); + + if (!oldAppointmentInfo) { + throw new ConflictException(APPOINTMENT_ERROR_MESSAGES['APPOINTMENT_NOT_FOUND']); + } + + const toPrismaEntity = PostgresqlPrismaAppointmentMapper.toPrismaUpdate({ + ...newAppointmentInfo, + }); + + await this.postgresqlPrismaOrmService['appointment'].update(toPrismaEntity); + } + + async updateAppointmentDate(newAppointmentInfo: UpdatedAppointmentDateDto): Promise { + const oldAppointmentInfo = await this.findSingleAppointmentById(newAppointmentInfo.id); + + if (!oldAppointmentInfo) { + throw new ConflictException(APPOINTMENT_ERROR_MESSAGES['APPOINTMENT_NOT_FOUND']); + } + + const toPrismaEntity = PostgresqlPrismaAppointmentMapper.toPrismaUpdate({ + ...newAppointmentInfo, + }); + + await this.postgresqlPrismaOrmService['appointment'].update(toPrismaEntity); + } + + async deleteSingleAppointment(appointmentId: string): Promise { + const isAppointmentExists = await this.findSingleAppointmentById(appointmentId); + + if (!isAppointmentExists) { + throw new ConflictException(APPOINTMENT_ERROR_MESSAGES['APPOINTMENT_NOT_FOUND']); + } + + await this.postgresqlPrismaOrmService['appointment'].delete({ + where: { + id: appointmentId, + }, + }); + } +} From 8ae8d814810600f729969a107ed0e1cf85cc3edc Mon Sep 17 00:00:00 2001 From: luanavfg Date: Tue, 16 Jan 2024 08:42:44 -0300 Subject: [PATCH 05/19] feat: add appointment mapper --- .../postgresql-prisma-appointment-mapper.ts | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 apps/core-rest-api/src/app/adapters/database/mappers/postgresql-prisma-appointment-mapper.ts diff --git a/apps/core-rest-api/src/app/adapters/database/mappers/postgresql-prisma-appointment-mapper.ts b/apps/core-rest-api/src/app/adapters/database/mappers/postgresql-prisma-appointment-mapper.ts new file mode 100644 index 00000000..f7784838 --- /dev/null +++ b/apps/core-rest-api/src/app/adapters/database/mappers/postgresql-prisma-appointment-mapper.ts @@ -0,0 +1,40 @@ +import { + Prisma, + Appointment as PrismaAppointmentDto, + PaymentMethod as PrismaPaymentMethod, +} from '@prisma/client'; + +import { AppointmentEntity } from '../../../core/domains/appointment/entities/appointment/entity'; +import { CreateSingleAppointmentDto } from '../../../core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto'; +import { UpdateAppointmentInfoDto } from '../../../core/domains/appointment/use-cases/update-appointment-info/update-appointment-info-dto'; +import { PaymentMethod } from '../../../core/shared/interfaces/payments'; + +export class PostgresqlPrismaAppointmentMapper { + static toDomain(raw: PrismaAppointmentDto): AppointmentEntity { + return new AppointmentEntity({ + ...raw, + paymentMethod: raw.paymentMethod as unknown as PaymentMethod, + }); + } + + static toPrismaCreate(raw: CreateSingleAppointmentDto): Prisma.AppointmentCreateArgs { + return { + data: { + ...raw, + paymentMethod: raw.paymentMethod as unknown as PrismaPaymentMethod, + }, + }; + } + + static toPrismaUpdate(raw: UpdateAppointmentInfoDto): Prisma.AppointmentUpdateArgs { + return { + data: { + ...raw, + done: raw.done as boolean + }, + where: { + id: raw.id, + }, + }; + } +} From 266f723ef626266e0e46435afe7badf1c3a04497 Mon Sep 17 00:00:00 2001 From: luanavfg Date: Tue, 16 Jan 2024 08:43:07 -0300 Subject: [PATCH 06/19] feat: add appointment e2e tests file --- .../appointment/create-appointment/create-appointment.e2e-spec.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.e2e-spec.ts diff --git a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.e2e-spec.ts b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.e2e-spec.ts new file mode 100644 index 00000000..e69de29b From 3de5a9de3515219551cfabcc0b4765ead7f1cf43 Mon Sep 17 00:00:00 2001 From: luanavfg Date: Tue, 16 Jan 2024 08:43:45 -0300 Subject: [PATCH 07/19] feat: add create appointment route in api module --- .../src/app/adapters/controllers/api/api.module.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/core-rest-api/src/app/adapters/controllers/api/api.module.ts b/apps/core-rest-api/src/app/adapters/controllers/api/api.module.ts index c6bf9729..1319267e 100644 --- a/apps/core-rest-api/src/app/adapters/controllers/api/api.module.ts +++ b/apps/core-rest-api/src/app/adapters/controllers/api/api.module.ts @@ -20,6 +20,8 @@ import { AuthenticatePsychologistController } from './use-cases/psychologist/aut import { CreatePsychologistController } from './use-cases/psychologist/create-psychologist/create-psychologist.controller'; import { DeletePsychologistController } from './use-cases/psychologist/delete-psychologist/delete-psychologist.controller'; +import { CreateAppointmentController } from './use-cases/appointment/create-appointment/create-appointment.controller'; +import { NestjsCreateAppointmentService } from './use-cases/appointment/create-appointment/nestjs-create-appointment.services'; import { NestjsCreateClinicService } from './use-cases/clinic/create-clinic/nestjs-create-clinic.service'; import { NestjsDeleteClinicService } from './use-cases/clinic/delete-clinic/nestjs-delete-clinic.service'; import { NestjsUpdateClinicService } from './use-cases/clinic/update-clinic/nestjs-update-clinic.service'; @@ -51,6 +53,7 @@ import { NestjsUpdatePsychologistService } from './use-cases/psychologist/update DeleteClinicController, CreatePatientController, DeletePatientController, + CreateAppointmentController ], providers: [ BcryptHasherService, @@ -64,6 +67,7 @@ import { NestjsUpdatePsychologistService } from './use-cases/psychologist/update NestjsDeleteClinicService, NestjsCreatePatientService, NestjsDeletePatientService, + NestjsCreateAppointmentService ], }) export class ApiModule {} From 37e1eb6987ba6089bd253e20e8ecd3447c64f10e Mon Sep 17 00:00:00 2001 From: luanavfg Date: Thu, 18 Jan 2024 10:20:20 -0300 Subject: [PATCH 08/19] feat(CC-120): add appointment factory --- .../tests/factories/make-appointment.ts | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 apps/core-rest-api/tests/factories/make-appointment.ts diff --git a/apps/core-rest-api/tests/factories/make-appointment.ts b/apps/core-rest-api/tests/factories/make-appointment.ts new file mode 100644 index 00000000..b82337dc --- /dev/null +++ b/apps/core-rest-api/tests/factories/make-appointment.ts @@ -0,0 +1,42 @@ +import { fakerPT_BR as faker } from '@faker-js/faker'; +import { Injectable } from '@nestjs/common'; + +import { PostgreSqlPrismaOrmService } from '../../src/app/adapters/database/infra/prisma/prisma.service'; + +import { PostgresqlPrismaAppointmentMapper } from '../../src/app/adapters/database/mappers/postgresql-prisma-appointment-mapper'; +import { AppointmentEntity } from '../../src/app/core/domains/appointment/entities/appointment/entity'; +import { CreateSingleAppointmentDto } from '../../src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto'; +import { PaymentMethod } from '../../src/app/core/shared/interfaces/payments'; + +export function makeAppointment(override: Partial = {}): AppointmentEntity { + const newAppointment = new AppointmentEntity({ + psychologistId: faker.string.uuid(), + patientId: faker.string.uuid(), + date: faker.date.future(), + online: false, + clinicId: faker.string.uuid(), + confirmed: true, + paymentMethod: PaymentMethod.CREDIT_CARD, + cancelled: false, + ...override, + }); + + return newAppointment; +} + +@Injectable() +export class AppointmentFactory { + constructor(private postgreSqlPrismaOrmService: PostgreSqlPrismaOrmService) {} + + async makePrismaAppointment( + appointment: Partial = {}, + ): Promise { + const newPrismaAppointment = makeAppointment(appointment); + + await this.postgreSqlPrismaOrmService['appointment'].create( + PostgresqlPrismaAppointmentMapper.toPrismaCreate(newPrismaAppointment), + ); + + return newPrismaAppointment; + } +} From 8202ec7e8fbf47d808d1d8c80af189464fa48ae6 Mon Sep 17 00:00:00 2001 From: luanavfg Date: Thu, 18 Jan 2024 10:21:16 -0300 Subject: [PATCH 09/19] feat(CC-120): add appointment E2E test --- .../create-appointment.e2e-spec.ts | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.e2e-spec.ts b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.e2e-spec.ts index e69de29b..4aad9252 100644 --- a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.e2e-spec.ts +++ b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.e2e-spec.ts @@ -0,0 +1,64 @@ +import { faker } from "@faker-js/faker"; +import { INestApplication } from "@nestjs/common"; +import request from 'supertest'; +import { makeAppointment } from '../../../../../../../../tests/factories/make-appointment'; +import { setupE2ETest } from '../../../../../../../../tests/utils/e2e-tests-initial-setup'; +import { CreateSingleAppointmentDto } from '../../../../../../core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto'; +import { PaymentMethod } from '../../../../../../core/shared/interfaces/payments'; +import { PostgreSqlPrismaOrmService } from '../../../../../database/infra/prisma/prisma.service'; + +describe('[E2E] - Create New Appointment', () => { + let app: INestApplication; + let prisma: PostgreSqlPrismaOrmService; + + let access_token: string; + + let psychologistId: string; + let clinicId: string; + let patientId: string; + + // let patient: PatientEntity; + + beforeAll(async () => { + const setup = await setupE2ETest(); + + app = setup.app; + prisma = setup.prisma; + + access_token = setup.access_token; + + clinicId = setup.clinic.id; + psychologistId = setup.psychologist.id; + + patientId = setup.patient.id; + }); + + it('[POST] - Should successfully create a new appointment', async () => { + const newAppointment: CreateSingleAppointmentDto = makeAppointment({ + psychologistId, + clinicId, + patientId, + date: faker.date.recent({ days: 10 }), + cancelled: false, + confirmationDate: null, + confirmed: true, + online: false, + paymentMethod: PaymentMethod.CREDIT_CARD + }); + + const response = await request(app.getHttpServer()) + .post('/appointment/create') + .set('Authorization', `Bearer ${access_token}`) + .send(newAppointment); + + const appointmentOnDatabase = await prisma.appointment.findFirst({ + where: { + patientId: newAppointment.patientId, + }, + }); + + expect(response.statusCode).toBe(201); + expect(response.body.message).toBe('Appointment created successfully'); + expect(appointmentOnDatabase).toBeTruthy(); + }); +}) From e1d6571c6b6c0d49b26d982d7c3f5cdb296c6a68 Mon Sep 17 00:00:00 2001 From: luanavfg Date: Thu, 18 Jan 2024 10:21:38 -0300 Subject: [PATCH 10/19] chore(CC-120): remove console log --- .../use-cases/clinic/delete-clinic/delete-clinic.e2e-spec.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/clinic/delete-clinic/delete-clinic.e2e-spec.ts b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/clinic/delete-clinic/delete-clinic.e2e-spec.ts index 4e5d29f3..f96ad78a 100644 --- a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/clinic/delete-clinic/delete-clinic.e2e-spec.ts +++ b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/clinic/delete-clinic/delete-clinic.e2e-spec.ts @@ -69,9 +69,6 @@ describe('[E2E] - Delete Clinic', () => { const deletedClinic = await prisma['clinic'].findUnique({ where: { id: clinic.id }, }); - - console.log('DELETED CLINIC ---->', deletedClinic); - expect(deletedClinic).toBeNull(); }); }); From 0adfae98c1ce11b7e8b5e53ce823f46ead08b5e7 Mon Sep 17 00:00:00 2001 From: luanavfg Date: Thu, 18 Jan 2024 10:22:10 -0300 Subject: [PATCH 11/19] feat(CC-120): add repository in repositories module --- .../postgres-prisma-orm-appointment-repository.ts | 3 ++- .../database/repositories/repositories.module.ts | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/core-rest-api/src/app/adapters/database/repositories/appointment/postgres-prisma-orm-appointment-repository.ts b/apps/core-rest-api/src/app/adapters/database/repositories/appointment/postgres-prisma-orm-appointment-repository.ts index cd32e06f..59dc9806 100644 --- a/apps/core-rest-api/src/app/adapters/database/repositories/appointment/postgres-prisma-orm-appointment-repository.ts +++ b/apps/core-rest-api/src/app/adapters/database/repositories/appointment/postgres-prisma-orm-appointment-repository.ts @@ -1,4 +1,4 @@ -import { ConflictException } from '@nestjs/common'; +import { ConflictException, Injectable } from '@nestjs/common'; import { AppointmentEntity } from '../../../../core/domains/appointment/entities/appointment/entity'; import { AppointmentDatabaseRepository } from '../../../../core/domains/appointment/repositories/database-repository'; import { CreateSingleAppointmentDto } from '../../../../core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto'; @@ -8,6 +8,7 @@ import { APPOINTMENT_ERROR_MESSAGES } from '../../../../shared/errors/error-mess import { PostgreSqlPrismaOrmService } from "../../infra/prisma/prisma.service"; import { PostgresqlPrismaAppointmentMapper } from '../../mappers/postgresql-prisma-appointment-mapper'; +@Injectable() export class PostgresqlPrismaOrmAppointmentRepository implements AppointmentDatabaseRepository { constructor(private postgresqlPrismaOrmService: PostgreSqlPrismaOrmService) {} diff --git a/apps/core-rest-api/src/app/adapters/database/repositories/repositories.module.ts b/apps/core-rest-api/src/app/adapters/database/repositories/repositories.module.ts index 1b4b6a32..1ea62c71 100644 --- a/apps/core-rest-api/src/app/adapters/database/repositories/repositories.module.ts +++ b/apps/core-rest-api/src/app/adapters/database/repositories/repositories.module.ts @@ -4,7 +4,9 @@ import { ClinicDatabaseRepository } from '../../../core/domains/clinic/repositor import { PatientDatabaseRepository } from '../../../core/domains/patient/repositories/database-repository'; import { PsychologistDatabaseRepository } from '../../../core/domains/psychologist/repositories/database-repository'; +import { AppointmentDatabaseRepository } from '../../../core/domains/appointment/repositories/database-repository'; import { PostgreSqlPrismaOrmService } from '../infra/prisma/prisma.service'; +import { PostgresqlPrismaOrmAppointmentRepository } from './appointment/postgres-prisma-orm-appointment-repository'; import { PostgresqlPrismaOrmClinicRepository } from './clinic/postgres-prisma-orm-clinic-repository'; import { PostgresqlPrismaOrmPatientRepository } from './patient/postgres-prisma-orm-patient-repository'; import { PostgresqlPrismaOrmPsychologistRepository } from './psychologist/postgresql-prisma-orm-psychologist-repository'; @@ -26,6 +28,10 @@ import { PostgresqlPrismaOrmPsychologistRepository } from './psychologist/postgr provide: PatientDatabaseRepository, useClass: PostgresqlPrismaOrmPatientRepository, }, + { + provide: AppointmentDatabaseRepository, + useClass: PostgresqlPrismaOrmAppointmentRepository, + }, ], exports: [ PostgreSqlPrismaOrmService, @@ -41,6 +47,10 @@ import { PostgresqlPrismaOrmPsychologistRepository } from './psychologist/postgr provide: PatientDatabaseRepository, useClass: PostgresqlPrismaOrmPatientRepository, }, + { + provide: AppointmentDatabaseRepository, + useClass: PostgresqlPrismaOrmAppointmentRepository, + }, ], }) export class DatabaseRepositoriesModule {} From 0ce11604e47bfa13a9e3084848baed0d13b8d4ec Mon Sep 17 00:00:00 2001 From: luanavfg Date: Tue, 30 Jan 2024 08:43:48 -0300 Subject: [PATCH 12/19] feat(CC-120): add appointment fake client --- .../http/appointment-client.http | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 apps/core-rest-api/http/appointment-client.http diff --git a/apps/core-rest-api/http/appointment-client.http b/apps/core-rest-api/http/appointment-client.http new file mode 100644 index 00000000..428d4a8e --- /dev/null +++ b/apps/core-rest-api/http/appointment-client.http @@ -0,0 +1,21 @@ +@authToken = {{$dotenv AUTH_TOKEN}} +@apiKey = {{$dotenv API_KEY}} + +# @appointmentDate = {{require "./appointmentDate.js"}} +#### + +# @name create_appointment +POST http://localhost:3333/core/appointment/create HTTP/1.1 +Content-Type: application/json +Authorization: Bearer {{authToken}} + +{ + "psychologistId": "{{$dotenv PSYCHOLOGIST_ID}}", + "clinicId": "{{$dotenv CLINIC_ID}}", + "patientId": "{{$dotenv PATIENT_ID}}", + "paymentMethod": "CREDIT_CARD", + "online": false, + "confirmed": true, + "cancelled": false, + "date": "2024-01-19T08:30:54" +} From 171cd5fb1b2ec280dfca02a146fca07dfe2499fd Mon Sep 17 00:00:00 2001 From: luanavfg Date: Tue, 30 Jan 2024 08:45:03 -0300 Subject: [PATCH 13/19] chore(CC-120): adjust service name --- .../src/app/adapters/controllers/api/api.module.ts | 2 +- ...intment.services.ts => nestjs-create-appointment.service.ts} | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) rename apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/{nestjs-create-appointment.services.ts => nestjs-create-appointment.service.ts} (89%) diff --git a/apps/core-rest-api/src/app/adapters/controllers/api/api.module.ts b/apps/core-rest-api/src/app/adapters/controllers/api/api.module.ts index 1319267e..9ef8d2c0 100644 --- a/apps/core-rest-api/src/app/adapters/controllers/api/api.module.ts +++ b/apps/core-rest-api/src/app/adapters/controllers/api/api.module.ts @@ -21,7 +21,7 @@ import { CreatePsychologistController } from './use-cases/psychologist/create-ps import { DeletePsychologistController } from './use-cases/psychologist/delete-psychologist/delete-psychologist.controller'; import { CreateAppointmentController } from './use-cases/appointment/create-appointment/create-appointment.controller'; -import { NestjsCreateAppointmentService } from './use-cases/appointment/create-appointment/nestjs-create-appointment.services'; +import { NestjsCreateAppointmentService } from './use-cases/appointment/create-appointment/nestjs-create-appointment.service'; import { NestjsCreateClinicService } from './use-cases/clinic/create-clinic/nestjs-create-clinic.service'; import { NestjsDeleteClinicService } from './use-cases/clinic/delete-clinic/nestjs-delete-clinic.service'; import { NestjsUpdateClinicService } from './use-cases/clinic/update-clinic/nestjs-update-clinic.service'; diff --git a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/nestjs-create-appointment.services.ts b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/nestjs-create-appointment.service.ts similarity index 89% rename from apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/nestjs-create-appointment.services.ts rename to apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/nestjs-create-appointment.service.ts index e5f80d26..2f83cc1d 100644 --- a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/nestjs-create-appointment.services.ts +++ b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/nestjs-create-appointment.service.ts @@ -1,6 +1,8 @@ +import { Injectable } from '@nestjs/common'; import { AppointmentDatabaseRepository } from '../../../../../../core/domains/appointment/repositories/database-repository'; import { CreateSingleAppointmentService } from '../../../../../../core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.service'; +@Injectable() export class NestjsCreateAppointmentService extends CreateSingleAppointmentService { constructor(appointmentDatabaseRepository: AppointmentDatabaseRepository) { super(appointmentDatabaseRepository); From 7c0af01673a57c6a99fba9a69eba55661a5b500b Mon Sep 17 00:00:00 2001 From: luanavfg Date: Tue, 30 Jan 2024 08:48:32 -0300 Subject: [PATCH 14/19] refactor(CC-120): change date to string --- .../core/domains/appointment/interfaces/appointment.ts | 1 + .../create-single-appointment-dto.ts | 9 +++++---- apps/core-rest-api/tests/factories/make-appointment.ts | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/core-rest-api/src/app/core/domains/appointment/interfaces/appointment.ts b/apps/core-rest-api/src/app/core/domains/appointment/interfaces/appointment.ts index c1d5cda2..2e13cb2c 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/interfaces/appointment.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/interfaces/appointment.ts @@ -11,6 +11,7 @@ export type IAppointmentProps = Replace< missed?: boolean | null; cancellationDate?: Date | null; paid?: boolean | null; + date: string } >; export type ICreateAppointmentServiceProps = Replace< diff --git a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto.ts b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto.ts index 01951db4..c69f7eb1 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto.ts @@ -1,4 +1,4 @@ -import { IsBoolean, IsDate, IsEnum, IsString } from 'class-validator'; +import { IsBoolean, IsDate, IsEnum, IsOptional, IsString } from 'class-validator'; import { PaymentMethod } from '../../../../shared/interfaces/payments'; export class CreateSingleAppointmentDto { @@ -8,8 +8,8 @@ export class CreateSingleAppointmentDto { @IsString() patientId!: string; - @IsDate() - date!: Date; + @IsString() + date!: string; @IsBoolean() online!: boolean; @@ -21,7 +21,8 @@ export class CreateSingleAppointmentDto { confirmed!: boolean; @IsDate() - confirmationDate!: Date | null; + @IsOptional() + confirmationDate?: Date | null; @IsBoolean() cancelled!: boolean; diff --git a/apps/core-rest-api/tests/factories/make-appointment.ts b/apps/core-rest-api/tests/factories/make-appointment.ts index b82337dc..3b8259d0 100644 --- a/apps/core-rest-api/tests/factories/make-appointment.ts +++ b/apps/core-rest-api/tests/factories/make-appointment.ts @@ -12,7 +12,7 @@ export function makeAppointment(override: Partial = const newAppointment = new AppointmentEntity({ psychologistId: faker.string.uuid(), patientId: faker.string.uuid(), - date: faker.date.future(), + date: (faker.date.future()).toString(), online: false, clinicId: faker.string.uuid(), confirmed: true, @@ -34,7 +34,7 @@ export class AppointmentFactory { const newPrismaAppointment = makeAppointment(appointment); await this.postgreSqlPrismaOrmService['appointment'].create( - PostgresqlPrismaAppointmentMapper.toPrismaCreate(newPrismaAppointment), + PostgresqlPrismaAppointmentMapper.toPrismaCreate({...newPrismaAppointment, date: (newPrismaAppointment.date).toString()}), ); return newPrismaAppointment; From 1f1222a7de54435dee22e219f1ebfce772789fba Mon Sep 17 00:00:00 2001 From: luanavfg Date: Tue, 30 Jan 2024 08:49:45 -0300 Subject: [PATCH 15/19] refactor(CC-120): change date to string in repositories and mappers --- .../database/mappers/postgresql-prisma-appointment-mapper.ts | 2 ++ .../appointment/postgres-prisma-orm-appointment-repository.ts | 3 ++- .../appointment/repositories/database-in-memory-repository.ts | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/core-rest-api/src/app/adapters/database/mappers/postgresql-prisma-appointment-mapper.ts b/apps/core-rest-api/src/app/adapters/database/mappers/postgresql-prisma-appointment-mapper.ts index f7784838..427ccf93 100644 --- a/apps/core-rest-api/src/app/adapters/database/mappers/postgresql-prisma-appointment-mapper.ts +++ b/apps/core-rest-api/src/app/adapters/database/mappers/postgresql-prisma-appointment-mapper.ts @@ -14,6 +14,7 @@ export class PostgresqlPrismaAppointmentMapper { return new AppointmentEntity({ ...raw, paymentMethod: raw.paymentMethod as unknown as PaymentMethod, + date: (raw.date).toString() }); } @@ -22,6 +23,7 @@ export class PostgresqlPrismaAppointmentMapper { data: { ...raw, paymentMethod: raw.paymentMethod as unknown as PrismaPaymentMethod, + date: new Date(raw.date) }, }; } diff --git a/apps/core-rest-api/src/app/adapters/database/repositories/appointment/postgres-prisma-orm-appointment-repository.ts b/apps/core-rest-api/src/app/adapters/database/repositories/appointment/postgres-prisma-orm-appointment-repository.ts index 59dc9806..201770f6 100644 --- a/apps/core-rest-api/src/app/adapters/database/repositories/appointment/postgres-prisma-orm-appointment-repository.ts +++ b/apps/core-rest-api/src/app/adapters/database/repositories/appointment/postgres-prisma-orm-appointment-repository.ts @@ -29,6 +29,7 @@ export class PostgresqlPrismaOrmAppointmentRepository implements AppointmentData date: appointmentDate, } }) + if (!appointment) { return null; } @@ -37,7 +38,7 @@ export class PostgresqlPrismaOrmAppointmentRepository implements AppointmentData } async createSingleAppointment(appointment: CreateSingleAppointmentDto): Promise { - const isAppointmentExists = await this.findSingleAppointmentByDate(appointment.date); + const isAppointmentExists = await this.findSingleAppointmentByDate(new Date(appointment.date)); if (isAppointmentExists) { throw new ConflictException(APPOINTMENT_ERROR_MESSAGES['CONFLICTING_DATE_TIME']); diff --git a/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-in-memory-repository.ts b/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-in-memory-repository.ts index a80eed93..886551df 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-in-memory-repository.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-in-memory-repository.ts @@ -14,7 +14,7 @@ export class InMemoryAppointmentDatabaseRepository async createSingleAppointment( appointment: CreateSingleAppointmentDto, ): Promise { - const isAppointmentExist = await this.findSingleAppointmentByDate(appointment.date); + const isAppointmentExist = await this.findSingleAppointmentByDate(new Date(appointment.date)); if (isAppointmentExist) { throw new ConflictException(APPOINTMENT_ERROR_MESSAGES['CONFLICTING_DATE_TIME']); From 9b2cedd65c4cc95a305601e5d11297f4f3e1aea2 Mon Sep 17 00:00:00 2001 From: luanavfg Date: Tue, 30 Jan 2024 08:50:04 -0300 Subject: [PATCH 16/19] refactor(CC-120): change date to string in service and controller --- .../create-appointment.controller.ts | 14 ++++++++------ .../create-single-appointment.service.ts | 7 +++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.controller.ts b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.controller.ts index 4246f665..e63b4c6b 100644 --- a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.controller.ts +++ b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.controller.ts @@ -1,11 +1,13 @@ import { Body, Controller, Post } from "@nestjs/common"; -import { ApiBearerAuth, ApiOperation, ApiTags } from "@nestjs/swagger"; +import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; import { CreateSingleAppointmentDto } from '../../../../../../core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto'; import { GlobalAppHttpException } from '../../../../../../shared/errors/globalAppHttpException'; -import { postMethodDocs } from "../../patient/create-patient/docs"; -import { NestjsCreateAppointmentService } from "./nestjs-create-appointment.services"; +import { NestjsCreateAppointmentService } from "./nestjs-create-appointment.service"; -@ApiTags('appointment') +interface CreateAppointmentResponse { + message: string; +} +@ApiTags('Appointment') @ApiBearerAuth() @Controller({ path: 'appointment', @@ -14,8 +16,8 @@ export class CreateAppointmentController { constructor(private createAppointmentService: NestjsCreateAppointmentService) {} @Post('create') - @ApiOperation(postMethodDocs) - async execute(@Body() createAppointmentDto: CreateSingleAppointmentDto) { + // @ApiOperation(postMethodDocs) + async execute(@Body() createAppointmentDto: CreateSingleAppointmentDto): Promise{ try { await this.createAppointmentService.execute(createAppointmentDto); diff --git a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.service.ts b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.service.ts index cf4b6a62..68854906 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.service.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.service.ts @@ -18,15 +18,15 @@ export class CreateSingleAppointmentService { const createSingleAppointmentDtoInstance = plainToInstance( CreateSingleAppointmentDto, createSingleAppointmentDto - ); + ); await applicationValidateOrReject(createSingleAppointmentDtoInstance); + const appointmentDate = new Date(createSingleAppointmentDto.date) const isAppointmentExist = await this.appointmentDatabaseRepository.findSingleAppointmentByDate( - createSingleAppointmentDto.date + appointmentDate ); - if (isAppointmentExist) { throw new ConflictException(APPOINTMENT_ERROR_MESSAGES['CONFLICTING_DATE_TIME']); } @@ -36,7 +36,6 @@ export class CreateSingleAppointmentService { await this.appointmentDatabaseRepository.createSingleAppointment( createSingleAppointmentDto ); - return createSingleAppointment; } } From ca381deb2e68258c5b6239f07f34a3c0062b10bc Mon Sep 17 00:00:00 2001 From: luanavfg Date: Thu, 1 Feb 2024 10:31:28 -0300 Subject: [PATCH 17/19] refactor(CC-120): revert date transformation into date --- .../app/core/domains/appointment/interfaces/appointment.ts | 1 - .../repositories/database-in-memory-repository.ts | 2 +- .../create-single-appointment-dto.ts | 4 ++-- .../create-single-appointment.service.ts | 3 +-- .../create-single-appointment.spec.ts | 5 ++--- apps/core-rest-api/tests/factories/make-appointment.ts | 4 ++-- 6 files changed, 8 insertions(+), 11 deletions(-) diff --git a/apps/core-rest-api/src/app/core/domains/appointment/interfaces/appointment.ts b/apps/core-rest-api/src/app/core/domains/appointment/interfaces/appointment.ts index 2e13cb2c..c1d5cda2 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/interfaces/appointment.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/interfaces/appointment.ts @@ -11,7 +11,6 @@ export type IAppointmentProps = Replace< missed?: boolean | null; cancellationDate?: Date | null; paid?: boolean | null; - date: string } >; export type ICreateAppointmentServiceProps = Replace< diff --git a/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-in-memory-repository.ts b/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-in-memory-repository.ts index 886551df..a80eed93 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-in-memory-repository.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/repositories/database-in-memory-repository.ts @@ -14,7 +14,7 @@ export class InMemoryAppointmentDatabaseRepository async createSingleAppointment( appointment: CreateSingleAppointmentDto, ): Promise { - const isAppointmentExist = await this.findSingleAppointmentByDate(new Date(appointment.date)); + const isAppointmentExist = await this.findSingleAppointmentByDate(appointment.date); if (isAppointmentExist) { throw new ConflictException(APPOINTMENT_ERROR_MESSAGES['CONFLICTING_DATE_TIME']); diff --git a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto.ts b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto.ts index c69f7eb1..c267a108 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto.ts @@ -8,8 +8,8 @@ export class CreateSingleAppointmentDto { @IsString() patientId!: string; - @IsString() - date!: string; + @IsDate() + date!: Date; @IsBoolean() online!: boolean; diff --git a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.service.ts b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.service.ts index 68854906..0812c575 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.service.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.service.ts @@ -22,10 +22,9 @@ export class CreateSingleAppointmentService { await applicationValidateOrReject(createSingleAppointmentDtoInstance); - const appointmentDate = new Date(createSingleAppointmentDto.date) const isAppointmentExist = await this.appointmentDatabaseRepository.findSingleAppointmentByDate( - appointmentDate + createSingleAppointmentDto.date ); if (isAppointmentExist) { throw new ConflictException(APPOINTMENT_ERROR_MESSAGES['CONFLICTING_DATE_TIME']); diff --git a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.spec.ts b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.spec.ts index c15d7eda..7d86d46a 100644 --- a/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.spec.ts +++ b/apps/core-rest-api/src/app/core/domains/appointment/use-cases/create-single-appointment/create-single-appointment.spec.ts @@ -1,4 +1,3 @@ -import { fakerPT_BR as faker } from '@faker-js/faker'; import { CreateSingleAppointmentService } from './create-single-appointment.service'; import { ConflictException } from '@nestjs/common'; @@ -12,11 +11,11 @@ describe('[appointment] Create Single Appointment Service', () => { const fakeAppointment: CreateSingleAppointmentDto = { psychologistId: randomUUID(), patientId: randomUUID(), - date: faker.date.recent({ days: 10 }), + date: new Date(), online: false, clinicId: randomUUID(), confirmed: true, - confirmationDate: faker.date.recent({ days: 5 }), + confirmationDate: new Date(), cancelled: false, paymentMethod: PaymentMethod.CREDIT_CARD, }; diff --git a/apps/core-rest-api/tests/factories/make-appointment.ts b/apps/core-rest-api/tests/factories/make-appointment.ts index 3b8259d0..b82337dc 100644 --- a/apps/core-rest-api/tests/factories/make-appointment.ts +++ b/apps/core-rest-api/tests/factories/make-appointment.ts @@ -12,7 +12,7 @@ export function makeAppointment(override: Partial = const newAppointment = new AppointmentEntity({ psychologistId: faker.string.uuid(), patientId: faker.string.uuid(), - date: (faker.date.future()).toString(), + date: faker.date.future(), online: false, clinicId: faker.string.uuid(), confirmed: true, @@ -34,7 +34,7 @@ export class AppointmentFactory { const newPrismaAppointment = makeAppointment(appointment); await this.postgreSqlPrismaOrmService['appointment'].create( - PostgresqlPrismaAppointmentMapper.toPrismaCreate({...newPrismaAppointment, date: (newPrismaAppointment.date).toString()}), + PostgresqlPrismaAppointmentMapper.toPrismaCreate(newPrismaAppointment), ); return newPrismaAppointment; From a9ac72ef84760775576774190ab1d48071156349 Mon Sep 17 00:00:00 2001 From: luanavfg Date: Thu, 1 Feb 2024 10:33:17 -0300 Subject: [PATCH 18/19] refactor(CC-120): transform date string into date format in controller level --- .../create-appointment/create-appointment.controller.ts | 6 +++--- .../create-appointment/create-appointment.e2e-spec.ts | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.controller.ts b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.controller.ts index e63b4c6b..168009fe 100644 --- a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.controller.ts +++ b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.controller.ts @@ -1,7 +1,7 @@ import { Body, Controller, Post } from "@nestjs/common"; import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; -import { CreateSingleAppointmentDto } from '../../../../../../core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto'; import { GlobalAppHttpException } from '../../../../../../shared/errors/globalAppHttpException'; +import { CreateSingleAppointmentInputDto } from "./dto"; import { NestjsCreateAppointmentService } from "./nestjs-create-appointment.service"; interface CreateAppointmentResponse { @@ -17,9 +17,9 @@ export class CreateAppointmentController { @Post('create') // @ApiOperation(postMethodDocs) - async execute(@Body() createAppointmentDto: CreateSingleAppointmentDto): Promise{ + async execute(@Body() createAppointmentDto: CreateSingleAppointmentInputDto): Promise{ try { - await this.createAppointmentService.execute(createAppointmentDto); + await this.createAppointmentService.execute({...createAppointmentDto, date: new Date(createAppointmentDto.date)}); return { message: 'Appointment created successfully', diff --git a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.e2e-spec.ts b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.e2e-spec.ts index 4aad9252..bf50a88c 100644 --- a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.e2e-spec.ts +++ b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/create-appointment.e2e-spec.ts @@ -3,7 +3,7 @@ import { INestApplication } from "@nestjs/common"; import request from 'supertest'; import { makeAppointment } from '../../../../../../../../tests/factories/make-appointment'; import { setupE2ETest } from '../../../../../../../../tests/utils/e2e-tests-initial-setup'; -import { CreateSingleAppointmentDto } from '../../../../../../core/domains/appointment/use-cases/create-single-appointment/create-single-appointment-dto'; +import { AppointmentEntity } from '../../../../../../core/domains/appointment/entities/appointment/entity'; import { PaymentMethod } from '../../../../../../core/shared/interfaces/payments'; import { PostgreSqlPrismaOrmService } from '../../../../../database/infra/prisma/prisma.service'; @@ -17,7 +17,6 @@ describe('[E2E] - Create New Appointment', () => { let clinicId: string; let patientId: string; - // let patient: PatientEntity; beforeAll(async () => { const setup = await setupE2ETest(); @@ -34,7 +33,7 @@ describe('[E2E] - Create New Appointment', () => { }); it('[POST] - Should successfully create a new appointment', async () => { - const newAppointment: CreateSingleAppointmentDto = makeAppointment({ + const newAppointment: AppointmentEntity = makeAppointment({ psychologistId, clinicId, patientId, @@ -45,7 +44,6 @@ describe('[E2E] - Create New Appointment', () => { online: false, paymentMethod: PaymentMethod.CREDIT_CARD }); - const response = await request(app.getHttpServer()) .post('/appointment/create') .set('Authorization', `Bearer ${access_token}`) From 1f1ab0028f0d6948c9cd8793af01cf03673113af Mon Sep 17 00:00:00 2001 From: luanavfg Date: Thu, 1 Feb 2024 10:34:12 -0300 Subject: [PATCH 19/19] feat(CC-120): create input dto for appointment controller --- .../appointment/create-appointment/dto.ts | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/dto.ts diff --git a/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/dto.ts b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/dto.ts new file mode 100644 index 00000000..8fa9a73b --- /dev/null +++ b/apps/core-rest-api/src/app/adapters/controllers/api/use-cases/appointment/create-appointment/dto.ts @@ -0,0 +1,32 @@ +import { IsBoolean, IsDate, IsEnum, IsOptional, IsString } from 'class-validator'; +import { PaymentMethod } from '../../../../../../core/shared/interfaces/payments'; + +export class CreateSingleAppointmentInputDto { + @IsString() + psychologistId!: string; + + @IsString() + patientId!: string; + + @IsString() + date!: string; + + @IsBoolean() + online!: boolean; + + @IsString() + clinicId!: string; + + @IsBoolean() + confirmed!: boolean; + + @IsDate() + @IsOptional() + confirmationDate?: Date | null; + + @IsBoolean() + cancelled!: boolean; + + @IsEnum(PaymentMethod) + paymentMethod!: PaymentMethod; +}