From af2729baa27f33cefdd9ecac77c20bbfe1b43102 Mon Sep 17 00:00:00 2001 From: TiagoM13 Date: Mon, 4 Nov 2024 16:47:55 -0300 Subject: [PATCH 1/9] feat: update params and route --- src/modules/appointments/infra/http/routes.ts | 2 +- .../repositories/implementations/appointment-repository.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/appointments/infra/http/routes.ts b/src/modules/appointments/infra/http/routes.ts index 671634f..c533931 100644 --- a/src/modules/appointments/infra/http/routes.ts +++ b/src/modules/appointments/infra/http/routes.ts @@ -20,7 +20,7 @@ export const appointmentRoutes = async (app: FastifyInstance) => { app.addHook('preHandler', updateLastAccess(makeUserRepository())); app.get( - '/appointments/list-all', + '/appointments', { preHandler: verifyAuthorization([Role.ADMIN, Role.EDITOR, Role.CLINICAL]), }, diff --git a/src/shared/repositories/implementations/appointment-repository.ts b/src/shared/repositories/implementations/appointment-repository.ts index b84662f..988e9c3 100644 --- a/src/shared/repositories/implementations/appointment-repository.ts +++ b/src/shared/repositories/implementations/appointment-repository.ts @@ -19,7 +19,7 @@ export class AppointmentRepository implements IAppointmentRepository { const { name, skip, take, appointment_type, start_date, end_date } = params; const where: Prisma.AppointmentWhereInput = { - appointment_type, + ...(appointment_type && { appointment_type: appointment_type }), scheduled_date: { ...(start_date && { gte: start_date }), ...(end_date && { lte: end_date }), From c2ef1b0e5f0a3657490198f58b60ce2e8638e43e Mon Sep 17 00:00:00 2001 From: TiagoM13 Date: Tue, 5 Nov 2024 10:00:40 -0300 Subject: [PATCH 2/9] feat: add rules in schemas --- src/modules/appointments/schemas/index.ts | 47 ++++++++++++------- .../implementations/appointment-repository.ts | 4 +- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/modules/appointments/schemas/index.ts b/src/modules/appointments/schemas/index.ts index 6cec319..4155097 100644 --- a/src/modules/appointments/schemas/index.ts +++ b/src/modules/appointments/schemas/index.ts @@ -1,5 +1,7 @@ import z from 'zod'; +import { AppError } from '@app/errors/app-client'; + export const appointmentParamId = z.object({ patientId: z.string().uuid(), }); @@ -16,12 +18,37 @@ export const appointmentQuerySchema = z items_per_page: z.coerce.number().max(500).default(10), appointment_type: z.string().optional(), start_date: z.preprocess( - val => (typeof val === 'string' ? new Date(val) : val), - z.date().optional(), + val => { + if (typeof val === 'string' && val.trim() === '') return undefined; + + if (typeof val === 'string' && !/^\d{4}-\d{2}-\d{2}$/.test(val)) { + throw new AppError( + 'Data de início inválida. Use o formato YYYY-MM-DD', + ); + } + return typeof val === 'string' ? new Date(val) : val; + }, + z + .date({ + invalid_type_error: + 'Data de início inválida. Use o formato YYYY-MM-DD', + }) + .optional(), ), end_date: z.preprocess( - val => (typeof val === 'string' ? new Date(val) : val), - z.date().optional(), + val => { + if (typeof val === 'string' && val.trim() === '') return undefined; + + if (typeof val === 'string' && !/^\d{4}-\d{2}-\d{2}$/.test(val)) { + throw new AppError('Data de fim inválida. Use o formato YYYY-MM-DD'); + } + return typeof val === 'string' ? new Date(val) : val; + }, + z + .date({ + invalid_type_error: 'Data de fim inválida. Use o formato YYYY-MM-DD', + }) + .optional(), ), }) .refine( @@ -35,16 +62,4 @@ export const appointmentQuerySchema = z message: 'A data de início não pode ser maior que a data de fim', path: ['start_date'], }, - ) - .refine( - data => { - if (data.start_date && data.end_date) { - return data.end_date >= data.start_date; - } - return true; - }, - { - message: 'A data de fim não pode ser menor que a data de início', - path: ['end_date'], - }, ); diff --git a/src/shared/repositories/implementations/appointment-repository.ts b/src/shared/repositories/implementations/appointment-repository.ts index 988e9c3..e7f6cb7 100644 --- a/src/shared/repositories/implementations/appointment-repository.ts +++ b/src/shared/repositories/implementations/appointment-repository.ts @@ -19,7 +19,7 @@ export class AppointmentRepository implements IAppointmentRepository { const { name, skip, take, appointment_type, start_date, end_date } = params; const where: Prisma.AppointmentWhereInput = { - ...(appointment_type && { appointment_type: appointment_type }), + ...(appointment_type && { appointment_type }), scheduled_date: { ...(start_date && { gte: start_date }), ...(end_date && { lte: end_date }), @@ -57,7 +57,7 @@ export class AppointmentRepository implements IAppointmentRepository { const where: Prisma.AppointmentWhereInput = { patient_id: patient_id, - ...(appointment_type && { appointment_type: appointment_type }), + ...(appointment_type && { appointment_type }), scheduled_date: { ...(start_date && { gte: start_date }), ...(end_date && { lte: end_date }), From a630f306beb376f82b57c07ea794a2529dca9557 Mon Sep 17 00:00:00 2001 From: TiagoM13 Date: Wed, 27 Nov 2024 12:18:58 -0300 Subject: [PATCH 3/9] feat: update appointments routes --- src/modules/appointments/infra/http/routes.ts | 12 ++++++------ .../get-all-appointments-service.ts | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/modules/appointments/infra/http/routes.ts b/src/modules/appointments/infra/http/routes.ts index c533931..385f71c 100644 --- a/src/modules/appointments/infra/http/routes.ts +++ b/src/modules/appointments/infra/http/routes.ts @@ -27,35 +27,35 @@ export const appointmentRoutes = async (app: FastifyInstance) => { bindController(makeListAllAppointmentsController()), ); app.get( - '/patients/:patientId/appointments', + '/appointments/:patientId/list', { preHandler: verifyAuthorization([Role.ADMIN, Role.EDITOR, Role.CLINICAL]), }, bindController(makeGetAllAppointmentsController()), ); app.get( - '/patients/:patientId/appointments/:appointmentId', + '/appointments/:patientId/appointment/:appointmentId', { preHandler: verifyAuthorization([Role.ADMIN, Role.EDITOR, Role.CLINICAL]), }, bindController(makeGetAppointmentController()), ); app.post( - '/patients/:patientId/appointments', + '/appointments/:patientId', { preHandler: verifyAuthorization([Role.ADMIN, Role.EDITOR, Role.CLINICAL]), }, bindController(makeCreateAppointmentController()), ); app.put( - '/patients/:patientId/appointments/:appointmentId', + '/appointments/:patientId/appointment/:appointmentId', { preHandler: verifyAuthorization([Role.ADMIN, Role.CLINICAL]), }, bindController(makeUpdateAppointmentController()), ); - app.put( - '/patients/:patientId/appointments/:appointmentId/status', + app.patch( + '/appointments/:patientId/appointment/:appointmentId/status', { preHandler: verifyAuthorization([Role.ADMIN, Role.CLINICAL]), }, diff --git a/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts b/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts index 48d6518..9aa5ee2 100644 --- a/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts +++ b/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts @@ -8,7 +8,7 @@ import { import { validatePaginationParams } from '@shared/utils'; import { FindAndCountAll } from '@shared/utils/format-paginate'; -type IGetAllAppointmentsParams = IPaginateRequest & { +type IGetAllAppointmentsParams = Omit & { patient_id: string; end_date?: Date; start_date?: Date; From 36b6ed1ce2b814b474f67a2ef4dc2b46091c9790 Mon Sep 17 00:00:00 2001 From: TiagoM13 Date: Tue, 3 Dec 2024 11:06:34 -0300 Subject: [PATCH 4/9] feat: update get appointments by patient --- src/modules/appointments/infra/http/routes.ts | 4 ++-- .../get-appointments-by-patient-controller.ts} | 6 +++--- .../get-appointments-by-patient-service.ts} | 6 +++--- .../make-get-all-appointments-controller.ts | 7 ------- .../make-get-appointments-by-patient-controller.ts | 9 +++++++++ src/shared/factories/controllers/index.ts | 2 +- .../make-get-all-appointments-service.ts | 12 ------------ .../make-get-appointments-by-patient-service.ts | 13 +++++++++++++ 8 files changed, 31 insertions(+), 28 deletions(-) rename src/modules/appointments/useCases/{get-all-appointments/get-all-appointments-controller.ts => get-appointments-by-patient/get-appointments-by-patient-controller.ts} (72%) rename src/modules/appointments/useCases/{get-all-appointments/get-all-appointments-service.ts => get-appointments-by-patient/get-appointments-by-patient-service.ts} (88%) delete mode 100644 src/shared/factories/controllers/appointment/make-get-all-appointments-controller.ts create mode 100644 src/shared/factories/controllers/appointment/make-get-appointments-by-patient-controller.ts delete mode 100644 src/shared/factories/services/appointments/make-get-all-appointments-service.ts create mode 100644 src/shared/factories/services/appointments/make-get-appointments-by-patient-service.ts diff --git a/src/modules/appointments/infra/http/routes.ts b/src/modules/appointments/infra/http/routes.ts index 385f71c..a4367e7 100644 --- a/src/modules/appointments/infra/http/routes.ts +++ b/src/modules/appointments/infra/http/routes.ts @@ -8,7 +8,7 @@ import { import { Role } from '@shared/enums'; import { makeCreateAppointmentController, - makeGetAllAppointmentsController, + makeGetAppointmentsByPatientController, makeGetAppointmentController, makeListAllAppointmentsController, makeUpdateAppointmentController, @@ -31,7 +31,7 @@ export const appointmentRoutes = async (app: FastifyInstance) => { { preHandler: verifyAuthorization([Role.ADMIN, Role.EDITOR, Role.CLINICAL]), }, - bindController(makeGetAllAppointmentsController()), + bindController(makeGetAppointmentsByPatientController()), ); app.get( '/appointments/:patientId/appointment/:appointmentId', diff --git a/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-controller.ts b/src/modules/appointments/useCases/get-appointments-by-patient/get-appointments-by-patient-controller.ts similarity index 72% rename from src/modules/appointments/useCases/get-all-appointments/get-all-appointments-controller.ts rename to src/modules/appointments/useCases/get-appointments-by-patient/get-appointments-by-patient-controller.ts index 49ff04c..c75a24b 100644 --- a/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-controller.ts +++ b/src/modules/appointments/useCases/get-appointments-by-patient/get-appointments-by-patient-controller.ts @@ -6,11 +6,11 @@ import { appointmentQuerySchema, } from '@modules/appointments/schemas'; -import { GetAllAppointmentsService } from './get-all-appointments-service'; +import { GetAppointmentsByPatientService } from './get-appointments-by-patient-service'; -export class GetAllAppointmentsController extends BaseController { +export class GetAppointmentsByPatientController extends BaseController { constructor( - private readonly getAllAppointmentsService: GetAllAppointmentsService, + private readonly getAllAppointmentsService: GetAppointmentsByPatientService, ) { super(); } diff --git a/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts b/src/modules/appointments/useCases/get-appointments-by-patient/get-appointments-by-patient-service.ts similarity index 88% rename from src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts rename to src/modules/appointments/useCases/get-appointments-by-patient/get-appointments-by-patient-service.ts index 9aa5ee2..16b2cee 100644 --- a/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts +++ b/src/modules/appointments/useCases/get-appointments-by-patient/get-appointments-by-patient-service.ts @@ -8,14 +8,14 @@ import { import { validatePaginationParams } from '@shared/utils'; import { FindAndCountAll } from '@shared/utils/format-paginate'; -type IGetAllAppointmentsParams = Omit & { +type IGetAppointmentsByPatientParams = Omit & { patient_id: string; end_date?: Date; start_date?: Date; appointment_type?: string; }; -export class GetAllAppointmentsService { +export class GetAppointmentsByPatientService { constructor( private readonly appointmentRepository: AppointmentRepository, private readonly patientRepository: PatientRepository, @@ -25,7 +25,7 @@ export class GetAllAppointmentsService { } async execute( - params: IGetAllAppointmentsParams, + params: IGetAppointmentsByPatientParams, ): Promise> { const { patient_id, page, items_per_page } = params; const patient = await this.patientRepository.findById(patient_id); diff --git a/src/shared/factories/controllers/appointment/make-get-all-appointments-controller.ts b/src/shared/factories/controllers/appointment/make-get-all-appointments-controller.ts deleted file mode 100644 index 03d63cf..0000000 --- a/src/shared/factories/controllers/appointment/make-get-all-appointments-controller.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { GetAllAppointmentsController } from '@modules/appointments/useCases/get-all-appointments/get-all-appointments-controller'; -import { makeGetAllAppointmentsService } from '@shared/factories/services/appointments/make-get-all-appointments-service'; - -export const makeGetAllAppointmentsController = - (): GetAllAppointmentsController => { - return new GetAllAppointmentsController(makeGetAllAppointmentsService()); - }; diff --git a/src/shared/factories/controllers/appointment/make-get-appointments-by-patient-controller.ts b/src/shared/factories/controllers/appointment/make-get-appointments-by-patient-controller.ts new file mode 100644 index 0000000..be344bc --- /dev/null +++ b/src/shared/factories/controllers/appointment/make-get-appointments-by-patient-controller.ts @@ -0,0 +1,9 @@ +import { GetAppointmentsByPatientController } from '@modules/appointments/useCases/get-appointments-by-patient/get-appointments-by-patient-controller'; +import { makeGetAppointmentsByPatientService } from '@shared/factories/services/appointments/make-get-appointments-by-patient-service'; + +export const makeGetAppointmentsByPatientController = + (): GetAppointmentsByPatientController => { + return new GetAppointmentsByPatientController( + makeGetAppointmentsByPatientService(), + ); + }; diff --git a/src/shared/factories/controllers/index.ts b/src/shared/factories/controllers/index.ts index c3a648c..3b89a09 100644 --- a/src/shared/factories/controllers/index.ts +++ b/src/shared/factories/controllers/index.ts @@ -19,7 +19,7 @@ export * from './patient/make-update-patient-controller'; // appointements export * from './appointment/make-create-appointment-controller'; -export * from './appointment/make-get-all-appointments-controller'; +export * from './appointment/make-get-appointments-by-patient-controller'; export * from './appointment/make-list-all-appointments-controller'; export * from './appointment/make-get-appointment-controller'; export * from './appointment/make-update-appointment-controller'; diff --git a/src/shared/factories/services/appointments/make-get-all-appointments-service.ts b/src/shared/factories/services/appointments/make-get-all-appointments-service.ts deleted file mode 100644 index ecc2bee..0000000 --- a/src/shared/factories/services/appointments/make-get-all-appointments-service.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { GetAllAppointmentsService } from '@modules/appointments/useCases/get-all-appointments/get-all-appointments-service'; -import { - makeAppointmentRepository, - makePatientRepository, -} from '@shared/factories/repositories'; - -export const makeGetAllAppointmentsService = (): GetAllAppointmentsService => { - return new GetAllAppointmentsService( - makeAppointmentRepository(), - makePatientRepository(), - ); -}; diff --git a/src/shared/factories/services/appointments/make-get-appointments-by-patient-service.ts b/src/shared/factories/services/appointments/make-get-appointments-by-patient-service.ts new file mode 100644 index 0000000..058882b --- /dev/null +++ b/src/shared/factories/services/appointments/make-get-appointments-by-patient-service.ts @@ -0,0 +1,13 @@ +import { GetAppointmentsByPatientService } from '@modules/appointments/useCases/get-appointments-by-patient/get-appointments-by-patient-service'; +import { + makeAppointmentRepository, + makePatientRepository, +} from '@shared/factories/repositories'; + +export const makeGetAppointmentsByPatientService = + (): GetAppointmentsByPatientService => { + return new GetAppointmentsByPatientService( + makeAppointmentRepository(), + makePatientRepository(), + ); + }; From 4418c5dffbfbbc86011829dda1711b86c7b77153 Mon Sep 17 00:00:00 2001 From: TiagoM13 Date: Tue, 3 Dec 2024 11:20:53 -0300 Subject: [PATCH 5/9] feat: update get all appointments --- src/modules/appointments/infra/http/routes.ts | 4 ++-- .../get-all-appointments-controller.ts} | 8 ++++---- .../get-all-appointments-service.ts} | 6 +++--- .../appointment/make-get-all-appointments-controller.ts | 7 +++++++ .../appointment/make-list-all-appointments-controller.ts | 7 ------- src/shared/factories/controllers/index.ts | 2 +- .../appointments/make-get-all-appointments-service.ts | 6 ++++++ .../appointments/make-list-all-appointments-service.ts | 7 ------- 8 files changed, 23 insertions(+), 24 deletions(-) rename src/modules/appointments/useCases/{list-all-appointments/list-all-appointments-controller.ts => get-all-appointments/get-all-appointments-controller.ts} (60%) rename src/modules/appointments/useCases/{list-all-appointments/list-all-appointments-service.ts => get-all-appointments/get-all-appointments-service.ts} (87%) create mode 100644 src/shared/factories/controllers/appointment/make-get-all-appointments-controller.ts delete mode 100644 src/shared/factories/controllers/appointment/make-list-all-appointments-controller.ts create mode 100644 src/shared/factories/services/appointments/make-get-all-appointments-service.ts delete mode 100644 src/shared/factories/services/appointments/make-list-all-appointments-service.ts diff --git a/src/modules/appointments/infra/http/routes.ts b/src/modules/appointments/infra/http/routes.ts index a4367e7..8b51b91 100644 --- a/src/modules/appointments/infra/http/routes.ts +++ b/src/modules/appointments/infra/http/routes.ts @@ -10,7 +10,7 @@ import { makeCreateAppointmentController, makeGetAppointmentsByPatientController, makeGetAppointmentController, - makeListAllAppointmentsController, + makeGetAllAppointmentsController, makeUpdateAppointmentController, makeUpdateAppointmentStatusController, } from '@shared/factories/controllers'; @@ -24,7 +24,7 @@ export const appointmentRoutes = async (app: FastifyInstance) => { { preHandler: verifyAuthorization([Role.ADMIN, Role.EDITOR, Role.CLINICAL]), }, - bindController(makeListAllAppointmentsController()), + bindController(makeGetAllAppointmentsController()), ); app.get( '/appointments/:patientId/list', diff --git a/src/modules/appointments/useCases/list-all-appointments/list-all-appointments-controller.ts b/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-controller.ts similarity index 60% rename from src/modules/appointments/useCases/list-all-appointments/list-all-appointments-controller.ts rename to src/modules/appointments/useCases/get-all-appointments/get-all-appointments-controller.ts index d83d394..e103d59 100644 --- a/src/modules/appointments/useCases/list-all-appointments/list-all-appointments-controller.ts +++ b/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-controller.ts @@ -3,11 +3,11 @@ import { type FastifyReply } from 'fastify'; import { BaseController } from '@app/infra/http/controller/baseController'; import { appointmentQuerySchema } from '@modules/appointments/schemas'; -import { ListAllAppointmentsService } from './list-all-appointments-service'; +import { GetAllAppointmentsService } from './get-all-appointments-service'; -export class ListAllAppointmentsController extends BaseController { +export class GetAllAppointmentsController extends BaseController { constructor( - private readonly listAllAppointmentsService: ListAllAppointmentsService, + private readonly listAllAppointmentsService: GetAllAppointmentsService, ) { super(); } @@ -17,6 +17,6 @@ export class ListAllAppointmentsController extends BaseController { const results = await this.listAllAppointmentsService.execute(query); - return this.paginate(results, 'list-all-appointments'); + return this.paginate(results, 'get-all-appointments'); } } diff --git a/src/modules/appointments/useCases/list-all-appointments/list-all-appointments-service.ts b/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts similarity index 87% rename from src/modules/appointments/useCases/list-all-appointments/list-all-appointments-service.ts rename to src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts index 1967add..cd63fb2 100644 --- a/src/modules/appointments/useCases/list-all-appointments/list-all-appointments-service.ts +++ b/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts @@ -3,19 +3,19 @@ import { AppointmentRepository } from '@shared/repositories/implementations/appo import { validatePaginationParams } from '@shared/utils'; import { FindAndCountAll } from '@shared/utils/format-paginate'; -type IListAllAppointmentsParams = IPaginateRequest & { +type IGetAllAppointmentsParams = IPaginateRequest & { end_date?: Date; start_date?: Date; appointment_type?: string; }; -export class ListAllAppointmentsService { +export class GetAllAppointmentsService { constructor(private readonly appointmentRepository: AppointmentRepository) { this.appointmentRepository = appointmentRepository; } async execute( - params: IListAllAppointmentsParams, + params: IGetAllAppointmentsParams, ): Promise> { const { page, items_per_page } = params; validatePaginationParams(page, items_per_page); diff --git a/src/shared/factories/controllers/appointment/make-get-all-appointments-controller.ts b/src/shared/factories/controllers/appointment/make-get-all-appointments-controller.ts new file mode 100644 index 0000000..03d63cf --- /dev/null +++ b/src/shared/factories/controllers/appointment/make-get-all-appointments-controller.ts @@ -0,0 +1,7 @@ +import { GetAllAppointmentsController } from '@modules/appointments/useCases/get-all-appointments/get-all-appointments-controller'; +import { makeGetAllAppointmentsService } from '@shared/factories/services/appointments/make-get-all-appointments-service'; + +export const makeGetAllAppointmentsController = + (): GetAllAppointmentsController => { + return new GetAllAppointmentsController(makeGetAllAppointmentsService()); + }; diff --git a/src/shared/factories/controllers/appointment/make-list-all-appointments-controller.ts b/src/shared/factories/controllers/appointment/make-list-all-appointments-controller.ts deleted file mode 100644 index 3b5c077..0000000 --- a/src/shared/factories/controllers/appointment/make-list-all-appointments-controller.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ListAllAppointmentsController } from '@modules/appointments/useCases/list-all-appointments/list-all-appointments-controller'; -import { makeListAllAppointmentsService } from '@shared/factories/services/appointments/make-list-all-appointments-service'; - -export const makeListAllAppointmentsController = - (): ListAllAppointmentsController => { - return new ListAllAppointmentsController(makeListAllAppointmentsService()); - }; diff --git a/src/shared/factories/controllers/index.ts b/src/shared/factories/controllers/index.ts index 3b89a09..101bd22 100644 --- a/src/shared/factories/controllers/index.ts +++ b/src/shared/factories/controllers/index.ts @@ -20,7 +20,7 @@ export * from './patient/make-update-patient-controller'; // appointements export * from './appointment/make-create-appointment-controller'; export * from './appointment/make-get-appointments-by-patient-controller'; -export * from './appointment/make-list-all-appointments-controller'; +export * from './appointment/make-get-all-appointments-controller'; export * from './appointment/make-get-appointment-controller'; export * from './appointment/make-update-appointment-controller'; export * from './appointment/make-update-appointment-status-controller'; diff --git a/src/shared/factories/services/appointments/make-get-all-appointments-service.ts b/src/shared/factories/services/appointments/make-get-all-appointments-service.ts new file mode 100644 index 0000000..26a7bbe --- /dev/null +++ b/src/shared/factories/services/appointments/make-get-all-appointments-service.ts @@ -0,0 +1,6 @@ +import { GetAllAppointmentsService } from '@modules/appointments/useCases/get-all-appointments/get-all-appointments-service'; +import { makeAppointmentRepository } from '@shared/factories/repositories'; + +export const makeGetAllAppointmentsService = (): GetAllAppointmentsService => { + return new GetAllAppointmentsService(makeAppointmentRepository()); +}; diff --git a/src/shared/factories/services/appointments/make-list-all-appointments-service.ts b/src/shared/factories/services/appointments/make-list-all-appointments-service.ts deleted file mode 100644 index 5a2ff47..0000000 --- a/src/shared/factories/services/appointments/make-list-all-appointments-service.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ListAllAppointmentsService } from '@modules/appointments/useCases/list-all-appointments/list-all-appointments-service'; -import { makeAppointmentRepository } from '@shared/factories/repositories'; - -export const makeListAllAppointmentsService = - (): ListAllAppointmentsService => { - return new ListAllAppointmentsService(makeAppointmentRepository()); - }; From 3d1ef83747682f80495b819ce45e91fced146861 Mon Sep 17 00:00:00 2001 From: TiagoM13 Date: Fri, 20 Dec 2024 10:29:48 -0300 Subject: [PATCH 6/9] feat: add configs and add permissions --- src/app/app.ts | 6 +++--- src/app/infra/http/middleware/update-last-access.ts | 4 ++-- src/modules/doctors/infra/http/routes.ts | 5 ++++- src/shared/entities/index.ts | 1 - 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/app/app.ts b/src/app/app.ts index b921921..92b3832 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -1,9 +1,9 @@ import cors from '@fastify/cors'; import jwt from '@fastify/jwt'; -import multipart from '@fastify/multipart'; +import { fastifyMultipart } from '@fastify/multipart'; import { fastifyStatic } from '@fastify/static'; import { fastify } from 'fastify'; -import fastifyBcrypt from 'fastify-bcrypt'; +import { fastifyBcrypt } from 'fastify-bcrypt'; import { resolve } from 'node:path'; import { @@ -27,7 +27,7 @@ app.setErrorHandler(errorHandler); app.register(cors, { origin: '*', }); -app.register(multipart); +app.register(fastifyMultipart); app.register(fastifyStatic, { root: resolve(__dirname, '../uploads'), prefix: '/uploads', diff --git a/src/app/infra/http/middleware/update-last-access.ts b/src/app/infra/http/middleware/update-last-access.ts index 2415cfb..f02052e 100644 --- a/src/app/infra/http/middleware/update-last-access.ts +++ b/src/app/infra/http/middleware/update-last-access.ts @@ -1,9 +1,9 @@ import { FastifyReply, FastifyRequest } from 'fastify'; import { app } from '@app/app'; -import { UserRepository } from '@shared/repositories/implementations'; +import { IUserRepository } from '@shared/repositories/interfaces/user'; -export const updateLastAccess = (userRepository: UserRepository) => { +export const updateLastAccess = (userRepository: IUserRepository) => { return async (req: FastifyRequest, res: FastifyReply) => { try { const authorization = req.headers.authorization; diff --git a/src/modules/doctors/infra/http/routes.ts b/src/modules/doctors/infra/http/routes.ts index d21e912..262c124 100644 --- a/src/modules/doctors/infra/http/routes.ts +++ b/src/modules/doctors/infra/http/routes.ts @@ -17,7 +17,10 @@ import { import { makeUserRepository } from '@shared/factories/repositories'; export const doctorRoutes = async (app: FastifyInstance) => { - app.addHook('preHandler', verifyAuthorization([Role.ADMIN])); + app.addHook( + 'preHandler', + verifyAuthorization([Role.ADMIN, Role.EDITOR, Role.CLINICAL]), + ); app.addHook('preHandler', updateLastAccess(makeUserRepository())); app.get('/doctors', bindController(makeGetAllDoctorsController())); diff --git a/src/shared/entities/index.ts b/src/shared/entities/index.ts index 987fa57..ba37221 100644 --- a/src/shared/entities/index.ts +++ b/src/shared/entities/index.ts @@ -2,7 +2,6 @@ export * from './patient'; export * from './appointment'; export * from './user'; export * from './metadata'; -export * from './params'; export * from './paginate'; export * from './entities'; export * from './doctor'; From 282c9e946ed440851e29aaba1b32972fdcaf969b Mon Sep 17 00:00:00 2001 From: TiagoM13 Date: Fri, 20 Dec 2024 16:51:59 -0300 Subject: [PATCH 7/9] chore: update columns in table users --- src/app/infra/http/middleware/authenticate.ts | 2 +- .../20241220142228_updat_tables/migration.sql | 30 +++++++++++++ src/app/infra/prisma/schema.prisma | 43 ++++++++++++++++++- src/app/infra/prisma/seed.ts | 16 +++---- src/modules/appointments/infra/http/routes.ts | 2 +- .../forgot-password-service.ts | 5 ++- .../auth/useCases/login/login-service.ts | 4 +- src/modules/doctors/infra/http/routes.ts | 2 +- src/modules/patients/infra/http/routes.ts | 2 +- src/modules/upload/infra/http/routes.ts | 2 +- src/modules/users/infra/http/routes.ts | 2 +- .../create-user/create-user-schema.ts | 2 +- .../update-user-status-schema.ts | 3 +- .../update-user/update-user-schema.ts | 2 +- src/shared/entities/user.ts | 6 ++- src/shared/enums/index.ts | 1 - src/shared/enums/role.ts | 5 --- .../implementations/user-repository.ts | 3 +- src/shared/repositories/interfaces/user.ts | 3 +- 19 files changed, 102 insertions(+), 33 deletions(-) create mode 100644 src/app/infra/prisma/migrations/20241220142228_updat_tables/migration.sql delete mode 100644 src/shared/enums/role.ts diff --git a/src/app/infra/http/middleware/authenticate.ts b/src/app/infra/http/middleware/authenticate.ts index dd83493..6e86ac6 100644 --- a/src/app/infra/http/middleware/authenticate.ts +++ b/src/app/infra/http/middleware/authenticate.ts @@ -1,7 +1,7 @@ +import { Role, Status } from '@prisma/client'; import { FastifyReply, FastifyRequest } from 'fastify'; import { app } from '@app/app'; -import { Status, Role } from '@shared/enums'; interface TokenData { id: number; diff --git a/src/app/infra/prisma/migrations/20241220142228_updat_tables/migration.sql b/src/app/infra/prisma/migrations/20241220142228_updat_tables/migration.sql new file mode 100644 index 0000000..038d083 --- /dev/null +++ b/src/app/infra/prisma/migrations/20241220142228_updat_tables/migration.sql @@ -0,0 +1,30 @@ +/* + Warnings: + + - The `status` column on the `users` table would be dropped and recreated. This will lead to data loss if there is data in the column. + - Changed the type of `role` on the `users` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + +*/ +-- CreateEnum +CREATE TYPE "Status" AS ENUM ('ACTIVE', 'INACTIVE'); + +-- CreateEnum +CREATE TYPE "Role" AS ENUM ('ADMIN', 'EDITOR', 'CLINICAL'); + +-- CreateEnum +CREATE TYPE "Sex" AS ENUM ('MALE', 'FEMALE', 'OTHER'); + +-- CreateEnum +CREATE TYPE "MaritalStatus" AS ENUM ('SINGLE', 'MARRIED', 'DIVORCED', 'WIDOWED', 'SEPARATED'); + +-- CreateEnum +CREATE TYPE "AppointmentStatus" AS ENUM ('COMPLETED', 'CANCELLED', 'PENDING'); + +-- CreateEnum +CREATE TYPE "AppointmentType" AS ENUM ('QUERY', 'OTHER', 'ACCIDENT', 'FIREARM_INJURY', 'WHITE_WEAPON_INJURY'); + +-- AlterTable +ALTER TABLE "users" DROP COLUMN "role", +ADD COLUMN "role" "Role" NOT NULL, +DROP COLUMN "status", +ADD COLUMN "status" "Status" NOT NULL DEFAULT 'ACTIVE'; diff --git a/src/app/infra/prisma/schema.prisma b/src/app/infra/prisma/schema.prisma index aa5abdb..7cd5e93 100644 --- a/src/app/infra/prisma/schema.prisma +++ b/src/app/infra/prisma/schema.prisma @@ -7,13 +7,52 @@ datasource db { url = env("DATABASE_URL") } +enum Status { + ACTIVE + INACTIVE +} + +enum Role { + ADMIN + EDITOR + CLINICAL +} + +enum Sex { + MALE + FEMALE + OTHER +} + +enum MaritalStatus { + SINGLE + MARRIED + DIVORCED + WIDOWED + SEPARATED +} + +enum AppointmentStatus { + COMPLETED + CANCELLED + PENDING +} + +enum AppointmentType { + QUERY + OTHER + ACCIDENT + FIREARM_INJURY + WHITE_WEAPON_INJURY +} + model User { id Int @id @default(autoincrement()) name String email String @unique - role String + role Role image_url String? - status String @default("ativo") + status Status @default(ACTIVE) last_access DateTime? password String created_at DateTime @default(now()) diff --git a/src/app/infra/prisma/seed.ts b/src/app/infra/prisma/seed.ts index 2cb4d6d..9081a2f 100644 --- a/src/app/infra/prisma/seed.ts +++ b/src/app/infra/prisma/seed.ts @@ -1,25 +1,23 @@ -import { PrismaClient } from '@prisma/client'; - -import { Role } from '@shared/enums'; +import { PrismaClient, Role } from '@prisma/client'; const prisma = new PrismaClient(); const users = [ { - name: 'Ana Silva', - email: 'ana.silva@hospital.com', + name: 'Admin Tester', + email: 'admin.tester@hospital.com', password: 'admin123', role: Role.ADMIN, }, { - name: 'Carlos Pereira', - email: 'carlos.pereira@hospital.com', + name: 'Editor Tester', + email: 'editor.tester@hospital.com', password: 'editor123', role: Role.EDITOR, }, { - name: 'Fernanda Costa', - email: 'fernanda.costa@hospital.com', + name: 'Clínico Tester', + email: 'clinico.tester@hospital.com', password: 'clinico123', role: Role.CLINICAL, }, diff --git a/src/modules/appointments/infra/http/routes.ts b/src/modules/appointments/infra/http/routes.ts index 8b51b91..893d6a3 100644 --- a/src/modules/appointments/infra/http/routes.ts +++ b/src/modules/appointments/infra/http/routes.ts @@ -1,3 +1,4 @@ +import { Role } from '@prisma/client'; import { FastifyInstance } from 'fastify'; import { bindController } from '@app/infra/http/controller/bindController'; @@ -5,7 +6,6 @@ import { updateLastAccess, verifyAuthorization, } from '@app/infra/http/middleware'; -import { Role } from '@shared/enums'; import { makeCreateAppointmentController, makeGetAppointmentsByPatientController, diff --git a/src/modules/auth/useCases/forgot-password/forgot-password-service.ts b/src/modules/auth/useCases/forgot-password/forgot-password-service.ts index 57e3e4d..fc76f2d 100644 --- a/src/modules/auth/useCases/forgot-password/forgot-password-service.ts +++ b/src/modules/auth/useCases/forgot-password/forgot-password-service.ts @@ -1,3 +1,4 @@ +import { Status } from '@prisma/client'; import nodemailer from 'nodemailer'; import { AppError } from '@app/errors/app-client'; @@ -23,7 +24,7 @@ export class ForgotPasswordService { throw new AppError(USER_NOT_FOUND, 404); } - if (user.status === 'inativo') { + if (user.status === Status.INACTIVE) { throw new AppError(USER_INACTIVE, 403); } @@ -35,6 +36,8 @@ export class ForgotPasswordService { password: hashedPassword, }); + console.log({ provisionalPassword }); + const mail = await getMailClient(); const message = await mail.sendMail({ diff --git a/src/modules/auth/useCases/login/login-service.ts b/src/modules/auth/useCases/login/login-service.ts index 7fea436..6425dc1 100644 --- a/src/modules/auth/useCases/login/login-service.ts +++ b/src/modules/auth/useCases/login/login-service.ts @@ -1,4 +1,6 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ +import { Status } from '@prisma/client'; + import { app } from '@app/app'; import { AppError } from '@app/errors/app-client'; import { @@ -31,7 +33,7 @@ export class LoginService { throw new AppError(PASSWORD_INVALID); } - if (user.status === 'inativo') { + if (user.status === Status.INACTIVE) { throw new AppError(USER_INACTIVE, 403); } diff --git a/src/modules/doctors/infra/http/routes.ts b/src/modules/doctors/infra/http/routes.ts index 262c124..87c0dd2 100644 --- a/src/modules/doctors/infra/http/routes.ts +++ b/src/modules/doctors/infra/http/routes.ts @@ -1,3 +1,4 @@ +import { Role } from '@prisma/client'; import { FastifyInstance } from 'fastify'; import { bindController } from '@app/infra/http/controller/bindController'; @@ -5,7 +6,6 @@ import { updateLastAccess, verifyAuthorization, } from '@app/infra/http/middleware'; -import { Role } from '@shared/enums'; import { makeCreateDoctorController, makeDeleteDoctorController, diff --git a/src/modules/patients/infra/http/routes.ts b/src/modules/patients/infra/http/routes.ts index 4f93501..e8e0b63 100644 --- a/src/modules/patients/infra/http/routes.ts +++ b/src/modules/patients/infra/http/routes.ts @@ -1,3 +1,4 @@ +import { Role } from '@prisma/client'; import { FastifyInstance } from 'fastify'; import { bindController } from '@app/infra/http/controller/bindController'; @@ -5,7 +6,6 @@ import { updateLastAccess, verifyAuthorization, } from '@app/infra/http/middleware'; -import { Role } from '@shared/enums'; import { makeGetAllPatientsController, makeGetPatientController, diff --git a/src/modules/upload/infra/http/routes.ts b/src/modules/upload/infra/http/routes.ts index f6997aa..a8e51a1 100644 --- a/src/modules/upload/infra/http/routes.ts +++ b/src/modules/upload/infra/http/routes.ts @@ -1,9 +1,9 @@ +import { Role } from '@prisma/client'; import { FastifyInstance } from 'fastify'; import { bindController } from '@app/infra/http/controller/bindController'; import { verifyAuthorization } from '@app/infra/http/middleware'; import { makeUploadController } from '@modules/upload/useCases/upload/upload-factory'; -import { Role } from '@shared/enums'; export const uploadRoutes = async (app: FastifyInstance) => { app.post( diff --git a/src/modules/users/infra/http/routes.ts b/src/modules/users/infra/http/routes.ts index 16efa6a..e24c013 100644 --- a/src/modules/users/infra/http/routes.ts +++ b/src/modules/users/infra/http/routes.ts @@ -1,3 +1,4 @@ +import { Role } from '@prisma/client'; import { FastifyInstance } from 'fastify'; import { bindController } from '@app/infra/http/controller/bindController'; @@ -5,7 +6,6 @@ import { updateLastAccess, verifyAuthorization, } from '@app/infra/http/middleware'; -import { Role } from '@shared/enums'; import { makeChangePasswordUserController, makeCreateUserController, diff --git a/src/modules/users/useCases/create-user/create-user-schema.ts b/src/modules/users/useCases/create-user/create-user-schema.ts index 5cd2026..b9c93d3 100644 --- a/src/modules/users/useCases/create-user/create-user-schema.ts +++ b/src/modules/users/useCases/create-user/create-user-schema.ts @@ -1,6 +1,6 @@ +import { Role } from '@prisma/client'; import z from 'zod'; -import { Role } from '@shared/enums'; import { NAME_FIELD_REQUIRED } from '@shared/utils'; export const createUserSchema = z diff --git a/src/modules/users/useCases/update-user-status/update-user-status-schema.ts b/src/modules/users/useCases/update-user-status/update-user-status-schema.ts index 6f839f8..147e829 100644 --- a/src/modules/users/useCases/update-user-status/update-user-status-schema.ts +++ b/src/modules/users/useCases/update-user-status/update-user-status-schema.ts @@ -1,7 +1,6 @@ +import { Status } from '@prisma/client'; import z from 'zod'; -import { Status } from '@shared/enums'; - export const updateUserStatusSchema = z .object({ status: z.nativeEnum(Status), diff --git a/src/modules/users/useCases/update-user/update-user-schema.ts b/src/modules/users/useCases/update-user/update-user-schema.ts index d06e329..3119636 100644 --- a/src/modules/users/useCases/update-user/update-user-schema.ts +++ b/src/modules/users/useCases/update-user/update-user-schema.ts @@ -1,6 +1,6 @@ +import { Role } from '@prisma/client'; import z from 'zod'; -import { Role } from '@shared/enums'; import { NAME_FIELD_REQUIRED } from '@shared/utils'; export const updateUserSchema = z diff --git a/src/shared/entities/user.ts b/src/shared/entities/user.ts index 61c43c5..ddf3c4c 100644 --- a/src/shared/entities/user.ts +++ b/src/shared/entities/user.ts @@ -1,10 +1,12 @@ +import { Role, Status } from '@prisma/client'; + export type IUser = { id?: number; name: string; email: string; - role: string; + role: Role; image_url?: string | null; - status?: string; + status?: Status; last_access?: Date | null; password?: string; }; diff --git a/src/shared/enums/index.ts b/src/shared/enums/index.ts index 16d13ee..b734eb5 100644 --- a/src/shared/enums/index.ts +++ b/src/shared/enums/index.ts @@ -1,6 +1,5 @@ export * from './material-status'; export * from './appointment-type'; export * from './appointment-status'; -export * from './role'; export * from './sex'; export * from './status'; diff --git a/src/shared/enums/role.ts b/src/shared/enums/role.ts deleted file mode 100644 index 86cb225..0000000 --- a/src/shared/enums/role.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum Role { - ADMIN = 'administrador', - EDITOR = 'editor', - CLINICAL = 'clínico', -} diff --git a/src/shared/repositories/implementations/user-repository.ts b/src/shared/repositories/implementations/user-repository.ts index 20118ee..9f63de2 100644 --- a/src/shared/repositories/implementations/user-repository.ts +++ b/src/shared/repositories/implementations/user-repository.ts @@ -1,10 +1,11 @@ +import { Status } from '@prisma/client'; + import { prisma } from '@app/infra/prisma/client'; import { type FindEntitiesAndCountParams, type FindEntitiesAndCountResult, IUser, } from '@shared/entities'; -import { Status } from '@shared/enums'; import { IUserRepository } from '../interfaces/user'; diff --git a/src/shared/repositories/interfaces/user.ts b/src/shared/repositories/interfaces/user.ts index f835515..3917823 100644 --- a/src/shared/repositories/interfaces/user.ts +++ b/src/shared/repositories/interfaces/user.ts @@ -1,9 +1,10 @@ +import { Status } from '@prisma/client'; + import { type FindEntitiesAndCountParams, type FindEntitiesAndCountResult, IUser, } from '@shared/entities'; -import { Status } from '@shared/enums'; export interface IUserRepository { findAndCountAll( From c8148f574c841972c5689f81473069876e2fccfc Mon Sep 17 00:00:00 2001 From: TiagoM13 Date: Sat, 21 Dec 2024 17:24:45 -0300 Subject: [PATCH 8/9] chore: update data in table columns --- .../migration.sql | 42 +++++++++++++++++++ src/app/infra/prisma/schema.prisma | 31 +++++++------- src/app/infra/prisma/seed.ts | 32 +++++++------- src/modules/appointments/schemas/index.ts | 3 +- .../create-appointment-schema.ts | 3 +- .../create-appointment-service.ts | 5 ++- .../get-all-appointments-service.ts | 4 +- .../get-appointments-by-patient-service.ts | 4 +- .../update-appointment-status-schema.ts | 3 +- .../update-appointment-status-service.ts | 3 +- .../update-appointment-schema.ts | 2 +- .../update-appointment-service.ts | 3 +- .../create-doctor/create-doctor-schema.ts | 2 +- .../update-doctor-status-schema.ts | 3 +- .../update-doctor/update-doctor-schema.ts | 2 +- .../create-patient/create-patient-schema.ts | 4 +- .../update-patient/update-patient-schema.ts | 4 +- src/shared/entities/appointment.ts | 6 ++- src/shared/entities/doctor.ts | 6 ++- src/shared/entities/entities.ts | 6 ++- src/shared/entities/patient.ts | 7 ++-- src/shared/enums/appointment-status.ts | 5 --- src/shared/enums/appointment-type.ts | 7 ---- src/shared/enums/index.ts | 5 --- src/shared/enums/material-status.ts | 7 ---- src/shared/enums/sex.ts | 4 -- src/shared/enums/status.ts | 4 -- .../implementations/appointment-repository.ts | 3 +- .../implementations/doctor-repository.ts | 3 +- .../implementations/patient-repository.ts | 3 ++ .../repositories/interfaces/appointment.ts | 3 +- src/shared/repositories/interfaces/doctor.ts | 3 +- 32 files changed, 124 insertions(+), 98 deletions(-) create mode 100644 src/app/infra/prisma/migrations/20241220200534_update_columns_in_all_tables/migration.sql delete mode 100644 src/shared/enums/appointment-status.ts delete mode 100644 src/shared/enums/appointment-type.ts delete mode 100644 src/shared/enums/index.ts delete mode 100644 src/shared/enums/material-status.ts delete mode 100644 src/shared/enums/sex.ts delete mode 100644 src/shared/enums/status.ts diff --git a/src/app/infra/prisma/migrations/20241220200534_update_columns_in_all_tables/migration.sql b/src/app/infra/prisma/migrations/20241220200534_update_columns_in_all_tables/migration.sql new file mode 100644 index 0000000..89f8cde --- /dev/null +++ b/src/app/infra/prisma/migrations/20241220200534_update_columns_in_all_tables/migration.sql @@ -0,0 +1,42 @@ +/* + Warnings: + + - The values [OTHER] on the enum `Sex` will be removed. If these variants are still used in the database, this will fail. + - The `appointment_type` column on the `appointments` table would be dropped and recreated. This will lead to data loss if there is data in the column. + - The `status` column on the `appointments` table would be dropped and recreated. This will lead to data loss if there is data in the column. + - The `status` column on the `doctors` table would be dropped and recreated. This will lead to data loss if there is data in the column. + - You are about to drop the column `material_status` on the `patients` table. All the data in the column will be lost. + - The `status` column on the `patients` table would be dropped and recreated. This will lead to data loss if there is data in the column. + - Changed the type of `sex` on the `doctors` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `sex` on the `patients` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + +*/ +-- AlterEnum +BEGIN; +CREATE TYPE "Sex_new" AS ENUM ('MALE', 'FEMALE'); +ALTER TABLE "patients" ALTER COLUMN "sex" TYPE "Sex_new" USING ("sex"::text::"Sex_new"); +ALTER TABLE "doctors" ALTER COLUMN "sex" TYPE "Sex_new" USING ("sex"::text::"Sex_new"); +ALTER TYPE "Sex" RENAME TO "Sex_old"; +ALTER TYPE "Sex_new" RENAME TO "Sex"; +DROP TYPE "Sex_old"; +COMMIT; + +-- AlterTable +ALTER TABLE "appointments" DROP COLUMN "appointment_type", +ADD COLUMN "appointment_type" "AppointmentType" NOT NULL DEFAULT 'QUERY', +DROP COLUMN "status", +ADD COLUMN "status" "AppointmentStatus" NOT NULL DEFAULT 'PENDING'; + +-- AlterTable +ALTER TABLE "doctors" DROP COLUMN "sex", +ADD COLUMN "sex" "Sex" NOT NULL, +DROP COLUMN "status", +ADD COLUMN "status" "Status" NOT NULL DEFAULT 'ACTIVE'; + +-- AlterTable +ALTER TABLE "patients" DROP COLUMN "material_status", +ADD COLUMN "marital_status" "MaritalStatus", +DROP COLUMN "sex", +ADD COLUMN "sex" "Sex" NOT NULL, +DROP COLUMN "status", +ADD COLUMN "status" "Status" NOT NULL DEFAULT 'ACTIVE'; diff --git a/src/app/infra/prisma/schema.prisma b/src/app/infra/prisma/schema.prisma index 7cd5e93..c63074b 100644 --- a/src/app/infra/prisma/schema.prisma +++ b/src/app/infra/prisma/schema.prisma @@ -21,7 +21,6 @@ enum Role { enum Sex { MALE FEMALE - OTHER } enum MaritalStatus { @@ -62,41 +61,41 @@ model User { } model Patient { - id String @id @default(uuid()) + id String @id @default(uuid()) name String birth_date DateTime - cpf String? @unique - cns String? @unique - sex String + cpf String? @unique + cns String? @unique + sex Sex address String? mother_name String? father_name String? - material_status String? + marital_status MaritalStatus? occupation String? email String? phone String? contact_emergency String? name_contact_emergency String? health_agent String? - status String @default("ativo") + status Status @default(ACTIVE) height Decimal? weight Decimal? - created_at DateTime @default(now()) - updated_at DateTime @updatedAt + created_at DateTime @default(now()) + updated_at DateTime @updatedAt appointments Appointment[] @@map("patients") } model Appointment { - id Int @id @default(autoincrement()) - appointment_type String @default("consulta") + id String @id @default(uuid()) + appointment_type AppointmentType @default(QUERY) examination String? diagnosis_summary String? scheduled_date DateTime - status String @default("pendente") - created_at DateTime @default(now()) - updated_at DateTime @updatedAt() + status AppointmentStatus @default(PENDING) + created_at DateTime @default(now()) + updated_at DateTime @updatedAt() doctor_id Int doctor Doctor @relation(fields: [doctor_id], references: [id]) @@ -109,7 +108,7 @@ model Appointment { model Doctor { id Int @id @default(autoincrement()) name String - sex String + sex Sex crm String @unique cbo String? cns String? @unique @@ -119,7 +118,7 @@ model Doctor { avatar_url String? specialty String working_days Int[] - status String @default("ativo") + status Status @default(ACTIVE) appointments Appointment[] created_at DateTime @default(now()) updated_at DateTime @updatedAt diff --git a/src/app/infra/prisma/seed.ts b/src/app/infra/prisma/seed.ts index 9081a2f..e34fa37 100644 --- a/src/app/infra/prisma/seed.ts +++ b/src/app/infra/prisma/seed.ts @@ -1,4 +1,4 @@ -import { PrismaClient, Role } from '@prisma/client'; +import { PrismaClient, Role, Sex } from '@prisma/client'; const prisma = new PrismaClient(); @@ -27,55 +27,55 @@ const pacientes = [ { name: 'Alice Souza', birth_date: new Date('1993-05-15'), - sex: 'feminino', + sex: Sex.FEMALE, }, { name: 'Bob Oliveira', birth_date: new Date('1980-11-22'), - sex: 'masculino', + sex: Sex.MALE, }, { name: 'Carlos Martins', birth_date: new Date('1975-01-10'), - sex: 'masculino', + sex: Sex.MALE, }, - { name: 'Diana Lima', birth_date: new Date('1998-03-05'), sex: 'feminino' }, + { name: 'Diana Lima', birth_date: new Date('1998-03-05'), sex: Sex.FEMALE }, { name: 'Eduardo Rocha', birth_date: new Date('1990-09-30'), - sex: 'masculino', + sex: Sex.MALE, }, { name: 'Fernanda Gonçalves', birth_date: new Date('1988-07-12'), - sex: 'feminino', + sex: Sex.FEMALE, }, { name: 'Gabriel Santos', birth_date: new Date('1983-02-18'), - sex: 'masculino', + sex: Sex.MALE, }, { name: 'Helena Ferreira', birth_date: new Date('1992-06-25'), - sex: 'feminino', + sex: Sex.FEMALE, }, { name: 'Igor Almeida', birth_date: new Date('1985-12-15'), - sex: 'masculino', + sex: Sex.MALE, }, { name: 'Júlia Ribeiro', birth_date: new Date('1996-04-20'), - sex: 'feminino', + sex: Sex.FEMALE, }, ]; const doctors = [ { name: 'Dr. João Martins', - sex: 'masculino', + sex: Sex.MALE, crm: '123456-SP', phone: '5511999990001', email: 'joao.martins@hospital.com', @@ -86,7 +86,7 @@ const doctors = [ }, { name: 'Dra. Maria Souza', - sex: 'feminino', + sex: Sex.FEMALE, crm: '654321-RJ', phone: '5511999990002', email: 'maria.souza@hospital.com', @@ -98,7 +98,7 @@ const doctors = [ }, { name: 'Dr. Ricardo Alves', - sex: 'masculino', + sex: Sex.MALE, crm: '789012-MG', phone: '5511999990003', email: 'ricardo.alves@hospital.com', @@ -109,7 +109,7 @@ const doctors = [ }, { name: 'Dra. Fernanda Oliveira', - sex: 'feminino', + sex: Sex.FEMALE, crm: '321654-BA', phone: '5511999990004', email: 'fernanda.oliveira@hospital.com', @@ -121,7 +121,7 @@ const doctors = [ }, { name: 'Dr. Lucas Lima', - sex: 'masculino', + sex: Sex.MALE, crm: '987654-RS', phone: '5511999990005', email: 'lucas.lima@hospital.com', diff --git a/src/modules/appointments/schemas/index.ts b/src/modules/appointments/schemas/index.ts index 4155097..300bd71 100644 --- a/src/modules/appointments/schemas/index.ts +++ b/src/modules/appointments/schemas/index.ts @@ -1,3 +1,4 @@ +import { AppointmentType } from '@prisma/client'; import z from 'zod'; import { AppError } from '@app/errors/app-client'; @@ -16,7 +17,7 @@ export const appointmentQuerySchema = z name: z.string().optional(), page: z.coerce.number().default(1), items_per_page: z.coerce.number().max(500).default(10), - appointment_type: z.string().optional(), + appointment_type: z.nativeEnum(AppointmentType).optional(), start_date: z.preprocess( val => { if (typeof val === 'string' && val.trim() === '') return undefined; diff --git a/src/modules/appointments/useCases/create-appointment/create-appointment-schema.ts b/src/modules/appointments/useCases/create-appointment/create-appointment-schema.ts index 9d62d20..6a62e01 100644 --- a/src/modules/appointments/useCases/create-appointment/create-appointment-schema.ts +++ b/src/modules/appointments/useCases/create-appointment/create-appointment-schema.ts @@ -1,7 +1,6 @@ +import { AppointmentType } from '@prisma/client'; import z from 'zod'; -import { AppointmentType } from '@shared/enums'; - export const createAppointmentSchema = z .object({ appointment_type: z.nativeEnum(AppointmentType), diff --git a/src/modules/appointments/useCases/create-appointment/create-appointment-service.ts b/src/modules/appointments/useCases/create-appointment/create-appointment-service.ts index 3c58aa3..23371ad 100644 --- a/src/modules/appointments/useCases/create-appointment/create-appointment-service.ts +++ b/src/modules/appointments/useCases/create-appointment/create-appointment-service.ts @@ -1,15 +1,16 @@ +import { Status } from '@prisma/client'; + import { AppError } from '@app/errors/app-client'; import { DOCTOR_INACTIVE, DOCTOR_NOT_FOUND, PATIENT_NOT_FOUND, } from '@shared/constants/messages'; -import { Status } from '@shared/enums'; import { PatientRepository, AppointmentRepository, + DoctorRepository, } from '@shared/repositories/implementations'; -import { DoctorRepository } from '@shared/repositories/implementations/doctor-repository'; import { CreateAppointmentDTO } from './create-appointment-schema'; diff --git a/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts b/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts index cd63fb2..6bffb0b 100644 --- a/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts +++ b/src/modules/appointments/useCases/get-all-appointments/get-all-appointments-service.ts @@ -1,3 +1,5 @@ +import { AppointmentType } from '@prisma/client'; + import { IAppointment, IPaginateRequest } from '@shared/entities'; import { AppointmentRepository } from '@shared/repositories/implementations/appointment-repository'; import { validatePaginationParams } from '@shared/utils'; @@ -6,7 +8,7 @@ import { FindAndCountAll } from '@shared/utils/format-paginate'; type IGetAllAppointmentsParams = IPaginateRequest & { end_date?: Date; start_date?: Date; - appointment_type?: string; + appointment_type?: AppointmentType; }; export class GetAllAppointmentsService { diff --git a/src/modules/appointments/useCases/get-appointments-by-patient/get-appointments-by-patient-service.ts b/src/modules/appointments/useCases/get-appointments-by-patient/get-appointments-by-patient-service.ts index 16b2cee..551425b 100644 --- a/src/modules/appointments/useCases/get-appointments-by-patient/get-appointments-by-patient-service.ts +++ b/src/modules/appointments/useCases/get-appointments-by-patient/get-appointments-by-patient-service.ts @@ -1,3 +1,5 @@ +import { AppointmentType } from '@prisma/client'; + import { AppError } from '@app/errors/app-client'; import { PATIENT_NOT_FOUND } from '@shared/constants/messages'; import { IAppointment, IPaginateRequest } from '@shared/entities'; @@ -12,7 +14,7 @@ type IGetAppointmentsByPatientParams = Omit & { patient_id: string; end_date?: Date; start_date?: Date; - appointment_type?: string; + appointment_type?: AppointmentType; }; export class GetAppointmentsByPatientService { diff --git a/src/modules/appointments/useCases/update-appointment-status/update-appointment-status-schema.ts b/src/modules/appointments/useCases/update-appointment-status/update-appointment-status-schema.ts index 9a47c4f..bf25a9d 100644 --- a/src/modules/appointments/useCases/update-appointment-status/update-appointment-status-schema.ts +++ b/src/modules/appointments/useCases/update-appointment-status/update-appointment-status-schema.ts @@ -1,7 +1,6 @@ +import { AppointmentStatus } from '@prisma/client'; import z from 'zod'; -import { AppointmentStatus } from '@shared/enums'; - export const updateAppointmentStatusSchema = z .object({ status: z.nativeEnum(AppointmentStatus), diff --git a/src/modules/appointments/useCases/update-appointment-status/update-appointment-status-service.ts b/src/modules/appointments/useCases/update-appointment-status/update-appointment-status-service.ts index a39d3e0..93c2ce7 100644 --- a/src/modules/appointments/useCases/update-appointment-status/update-appointment-status-service.ts +++ b/src/modules/appointments/useCases/update-appointment-status/update-appointment-status-service.ts @@ -1,10 +1,11 @@ +import { AppointmentStatus } from '@prisma/client'; + import { AppError } from '@app/errors/app-client'; import { APPOINTMENT_NOT_FOUND, APPOINTMENT_STATUS_CANNOT_BE_CHANGED, PATIENT_NOT_FOUND, } from '@shared/constants/messages'; -import { AppointmentStatus } from '@shared/enums'; import { AppointmentRepository, PatientRepository, diff --git a/src/modules/appointments/useCases/update-appointment/update-appointment-schema.ts b/src/modules/appointments/useCases/update-appointment/update-appointment-schema.ts index 5b5f6ab..ace9660 100644 --- a/src/modules/appointments/useCases/update-appointment/update-appointment-schema.ts +++ b/src/modules/appointments/useCases/update-appointment/update-appointment-schema.ts @@ -1,6 +1,6 @@ +import { AppointmentType } from '@prisma/client'; import z from 'zod'; -import { AppointmentType } from '@shared/enums'; import { MIN_LENGTH_TEXT, MAX_LENGTH_TEXT } from '@shared/utils'; export const updateAppointmentSchema = z diff --git a/src/modules/appointments/useCases/update-appointment/update-appointment-service.ts b/src/modules/appointments/useCases/update-appointment/update-appointment-service.ts index 0faf2f2..0576675 100644 --- a/src/modules/appointments/useCases/update-appointment/update-appointment-service.ts +++ b/src/modules/appointments/useCases/update-appointment/update-appointment-service.ts @@ -1,3 +1,5 @@ +import { Status } from '@prisma/client'; + import { AppError } from '@app/errors/app-client'; import { APPOINTMENT_NOT_FOUND, @@ -5,7 +7,6 @@ import { DOCTOR_NOT_FOUND, PATIENT_NOT_FOUND, } from '@shared/constants/messages'; -import { Status } from '@shared/enums'; import { PatientRepository, AppointmentRepository, diff --git a/src/modules/doctors/useCases/create-doctor/create-doctor-schema.ts b/src/modules/doctors/useCases/create-doctor/create-doctor-schema.ts index 54592e2..44d2b87 100644 --- a/src/modules/doctors/useCases/create-doctor/create-doctor-schema.ts +++ b/src/modules/doctors/useCases/create-doctor/create-doctor-schema.ts @@ -1,7 +1,7 @@ +import { Sex } from '@prisma/client'; import z from 'zod'; import { WORKING_DAY_MIN, WORKING_DAY_MAX } from '@shared/constants/messages'; -import { Sex } from '@shared/enums'; import { INVALID_DATE_FIELD, REQUIRED_FIELD, diff --git a/src/modules/doctors/useCases/update-doctor-status/update-doctor-status-schema.ts b/src/modules/doctors/useCases/update-doctor-status/update-doctor-status-schema.ts index 3467d64..3734048 100644 --- a/src/modules/doctors/useCases/update-doctor-status/update-doctor-status-schema.ts +++ b/src/modules/doctors/useCases/update-doctor-status/update-doctor-status-schema.ts @@ -1,7 +1,6 @@ +import { Status } from '@prisma/client'; import z from 'zod'; -import { Status } from '@shared/enums'; - export const updateDoctorStatusSchema = z .object({ status: z.nativeEnum(Status), diff --git a/src/modules/doctors/useCases/update-doctor/update-doctor-schema.ts b/src/modules/doctors/useCases/update-doctor/update-doctor-schema.ts index a233f06..660dd19 100644 --- a/src/modules/doctors/useCases/update-doctor/update-doctor-schema.ts +++ b/src/modules/doctors/useCases/update-doctor/update-doctor-schema.ts @@ -1,7 +1,7 @@ +import { Sex } from '@prisma/client'; import z from 'zod'; import { WORKING_DAY_MIN, WORKING_DAY_MAX } from '@shared/constants/messages'; -import { Sex } from '@shared/enums'; import { INVALID_DATE_FIELD, REQUIRED_FIELD, diff --git a/src/modules/patients/useCases/create-patient/create-patient-schema.ts b/src/modules/patients/useCases/create-patient/create-patient-schema.ts index cb47acd..375977f 100644 --- a/src/modules/patients/useCases/create-patient/create-patient-schema.ts +++ b/src/modules/patients/useCases/create-patient/create-patient-schema.ts @@ -1,6 +1,6 @@ +import { MaritalStatus, Sex } from '@prisma/client'; import z from 'zod'; -import { Sex, MaterialStatus } from '@shared/enums'; import { calculateAge, NAME_FIELD_REQUIRED, @@ -50,7 +50,7 @@ export const createPatientSchema = z address: OPTIONAL_STRING_FIELD, mother_name: OPTIONAL_STRING_FIELD, father_name: OPTIONAL_STRING_FIELD, - material_status: z.nativeEnum(MaterialStatus).nullable().optional(), + marital_status: z.nativeEnum(MaritalStatus).nullable().optional(), occupation: OPTIONAL_STRING_FIELD, email: OPTIONAL_STRING_FIELD, phone: OPTIONAL_STRING_FIELD.refine( diff --git a/src/modules/patients/useCases/update-patient/update-patient-schema.ts b/src/modules/patients/useCases/update-patient/update-patient-schema.ts index dab4d38..19db99b 100644 --- a/src/modules/patients/useCases/update-patient/update-patient-schema.ts +++ b/src/modules/patients/useCases/update-patient/update-patient-schema.ts @@ -1,6 +1,6 @@ +import { MaritalStatus, Sex } from '@prisma/client'; import z from 'zod'; -import { Sex, MaterialStatus } from '@shared/enums'; import { calculateAge, NAME_FIELD_REQUIRED, @@ -50,7 +50,7 @@ export const updatePatientSchema = z address: OPTIONAL_STRING_FIELD, mother_name: OPTIONAL_STRING_FIELD, father_name: OPTIONAL_STRING_FIELD, - material_status: z.nativeEnum(MaterialStatus).nullable().optional(), + marital_status: z.nativeEnum(MaritalStatus).nullable().optional(), occupation: OPTIONAL_STRING_FIELD, email: OPTIONAL_STRING_FIELD, phone: OPTIONAL_STRING_FIELD.refine( diff --git a/src/shared/entities/appointment.ts b/src/shared/entities/appointment.ts index f04484b..77c735f 100644 --- a/src/shared/entities/appointment.ts +++ b/src/shared/entities/appointment.ts @@ -1,12 +1,14 @@ +import { AppointmentStatus, AppointmentType } from '@prisma/client'; + export type IAppointment = { id?: number; - appointment_type: string; + appointment_type: AppointmentType; examination?: string | null; diagnosis_summary?: string | null; scheduled_date: Date; created_at?: Date; updated_at?: Date; patient_id?: string; - status?: string; + status?: AppointmentStatus; doctor_id: number; }; diff --git a/src/shared/entities/doctor.ts b/src/shared/entities/doctor.ts index eadfae7..d8135e4 100644 --- a/src/shared/entities/doctor.ts +++ b/src/shared/entities/doctor.ts @@ -1,7 +1,9 @@ +import { Sex, Status } from '@prisma/client'; + export type IDoctor = { id?: number; name: string; - sex: string; + sex: Sex; birth_date: Date; crm: string; phone?: string | null; @@ -10,7 +12,7 @@ export type IDoctor = { specialty: string; appointment_id?: string | null; working_days: number[]; - status?: string; + status?: Status; created_at?: Date; updated_at?: Date; diff --git a/src/shared/entities/entities.ts b/src/shared/entities/entities.ts index 91cf9e3..27a77d8 100644 --- a/src/shared/entities/entities.ts +++ b/src/shared/entities/entities.ts @@ -1,3 +1,5 @@ +import { AppointmentType } from '@prisma/client'; + export interface FindEntitiesAndCountParams { name?: string; take: number; @@ -12,14 +14,14 @@ export interface FindEntitiesAndCountResult { export interface FindAppointmentsAndCountParams extends Omit { patient_id: string; - appointment_type?: string; + appointment_type?: AppointmentType; start_date?: Date; end_date?: Date; } export interface FindAllAppointmentsAndCountParams extends FindEntitiesAndCountParams { - appointment_type?: string; + appointment_type?: AppointmentType; start_date?: Date; end_date?: Date; } diff --git a/src/shared/entities/patient.ts b/src/shared/entities/patient.ts index 4d15609..076b2b1 100644 --- a/src/shared/entities/patient.ts +++ b/src/shared/entities/patient.ts @@ -1,16 +1,17 @@ +import { MaritalStatus, Sex, Status } from '@prisma/client'; import { Decimal } from '@prisma/client/runtime/library'; export type IPatient = { id?: string; name: string; birth_date: Date; - sex: string; + sex: Sex; cpf?: string | null; cns?: string | null; address?: string | null; mother_name?: string | null; father_name?: string | null; - material_status?: string | null; + marital_status?: MaritalStatus | null; occupation?: string | null; email?: string | null; phone?: string | null; @@ -19,7 +20,7 @@ export type IPatient = { health_agent?: string | null; height?: number | Decimal | null; weight?: number | Decimal | null; - status?: string; + status?: Status; created_at?: Date; updated_at?: Date; diff --git a/src/shared/enums/appointment-status.ts b/src/shared/enums/appointment-status.ts deleted file mode 100644 index bd38d8e..0000000 --- a/src/shared/enums/appointment-status.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum AppointmentStatus { - COMPLETED = 'concluída', - CANCELLED = 'cancelada', - PENDING = 'pendente', -} diff --git a/src/shared/enums/appointment-type.ts b/src/shared/enums/appointment-type.ts deleted file mode 100644 index bc5cc78..0000000 --- a/src/shared/enums/appointment-type.ts +++ /dev/null @@ -1,7 +0,0 @@ -export enum AppointmentType { - QUERY = 'consulta', - OTHER = 'outros', - ACCIDENT = 'acidente de trânsito', - FIREARM_INJURY = 'ferimento por arma de fogo', - WHITE_WEAPON_INJURY = 'ferimento por arma branca', -} diff --git a/src/shared/enums/index.ts b/src/shared/enums/index.ts deleted file mode 100644 index b734eb5..0000000 --- a/src/shared/enums/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './material-status'; -export * from './appointment-type'; -export * from './appointment-status'; -export * from './sex'; -export * from './status'; diff --git a/src/shared/enums/material-status.ts b/src/shared/enums/material-status.ts deleted file mode 100644 index e358b7b..0000000 --- a/src/shared/enums/material-status.ts +++ /dev/null @@ -1,7 +0,0 @@ -export enum MaterialStatus { - SINGLE = 'solteiro(a)', - MARRIED = 'casado(a)', - WIDOWER = 'viúvo(a)', - DIVORCE = 'divorciado(a)', - SEPARATED = 'separado(a)', -} diff --git a/src/shared/enums/sex.ts b/src/shared/enums/sex.ts deleted file mode 100644 index 161ad4c..0000000 --- a/src/shared/enums/sex.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum Sex { - male = 'masculino', - females = 'feminino', -} diff --git a/src/shared/enums/status.ts b/src/shared/enums/status.ts deleted file mode 100644 index a7e93b2..0000000 --- a/src/shared/enums/status.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum Status { - ACTIVE = 'ativo', - INACTIVE = 'inativo', -} diff --git a/src/shared/repositories/implementations/appointment-repository.ts b/src/shared/repositories/implementations/appointment-repository.ts index e7f6cb7..ec459c9 100644 --- a/src/shared/repositories/implementations/appointment-repository.ts +++ b/src/shared/repositories/implementations/appointment-repository.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { Prisma } from '@prisma/client'; +import { AppointmentStatus, Prisma } from '@prisma/client'; import { prisma } from '@app/infra/prisma/client'; import { @@ -8,7 +8,6 @@ import { FindAppointmentsAndCountParams, FindAllAppointmentsAndCountParams, } from '@shared/entities'; -import { AppointmentStatus } from '@shared/enums'; import { IAppointmentRepository } from '../interfaces/appointment'; diff --git a/src/shared/repositories/implementations/doctor-repository.ts b/src/shared/repositories/implementations/doctor-repository.ts index bdfccbe..13edc7d 100644 --- a/src/shared/repositories/implementations/doctor-repository.ts +++ b/src/shared/repositories/implementations/doctor-repository.ts @@ -1,10 +1,11 @@ +import { Status } from '@prisma/client'; + import { prisma } from '@app/infra/prisma/client'; import { FindEntitiesAndCountParams, FindEntitiesAndCountResult, IDoctor, } from '@shared/entities'; -import { Status } from '@shared/enums'; import { IDoctorRepository } from '../interfaces/doctor'; diff --git a/src/shared/repositories/implementations/patient-repository.ts b/src/shared/repositories/implementations/patient-repository.ts index 7f3afcd..99a2896 100644 --- a/src/shared/repositories/implementations/patient-repository.ts +++ b/src/shared/repositories/implementations/patient-repository.ts @@ -47,6 +47,9 @@ export class PatientRepository implements IPatientRepository { orderBy: { scheduled_date: 'desc', }, + include: { + doctor: true, + }, }, }, }); diff --git a/src/shared/repositories/interfaces/appointment.ts b/src/shared/repositories/interfaces/appointment.ts index e0db948..109191c 100644 --- a/src/shared/repositories/interfaces/appointment.ts +++ b/src/shared/repositories/interfaces/appointment.ts @@ -1,10 +1,11 @@ +import { AppointmentStatus } from '@prisma/client'; + import { type FindEntitiesAndCountResult, type FindAppointmentsAndCountParams, type FindAllAppointmentsAndCountParams, IAppointment, } from '@shared/entities'; -import { AppointmentStatus } from '@shared/enums'; export interface IAppointmentRepository { findAndCountAll( diff --git a/src/shared/repositories/interfaces/doctor.ts b/src/shared/repositories/interfaces/doctor.ts index a6adf95..2dca3da 100644 --- a/src/shared/repositories/interfaces/doctor.ts +++ b/src/shared/repositories/interfaces/doctor.ts @@ -1,9 +1,10 @@ +import { Status } from '@prisma/client'; + import { type FindEntitiesAndCountParams, type FindEntitiesAndCountResult, IDoctor, } from '@shared/entities'; -import { Status } from '@shared/enums'; export interface IDoctorRepository { findAndCountAll( From f85f5b0b6c246a2671295cb6f774a9ebafa8605a Mon Sep 17 00:00:00 2001 From: TiagoM13 Date: Thu, 26 Dec 2024 10:31:37 -0300 Subject: [PATCH 9/9] feat: add filters in get patients route --- src/modules/appointments/schemas/index.ts | 4 +++- .../get-all-patients-controller.ts | 4 ++-- .../get-all-patients-schema.ts | 21 ++++++++++++++++ .../get-all-patients-service.ts | 11 ++++----- src/shared/entities/entities.ts | 9 ++++++- src/shared/entities/patient.ts | 9 +++++++ .../implementations/patient-repository.ts | 24 ++++++++++++------- src/shared/repositories/interfaces/patient.ts | 4 ++-- src/shared/utils/schemas.ts | 3 +++ 9 files changed, 67 insertions(+), 22 deletions(-) create mode 100644 src/modules/patients/useCases/get-all-patients/get-all-patients-schema.ts diff --git a/src/modules/appointments/schemas/index.ts b/src/modules/appointments/schemas/index.ts index 300bd71..3acba51 100644 --- a/src/modules/appointments/schemas/index.ts +++ b/src/modules/appointments/schemas/index.ts @@ -17,7 +17,9 @@ export const appointmentQuerySchema = z name: z.string().optional(), page: z.coerce.number().default(1), items_per_page: z.coerce.number().max(500).default(10), - appointment_type: z.nativeEnum(AppointmentType).optional(), + appointment_type: z + .union([z.nativeEnum(AppointmentType), z.undefined(), z.string()]) + .optional(), start_date: z.preprocess( val => { if (typeof val === 'string' && val.trim() === '') return undefined; diff --git a/src/modules/patients/useCases/get-all-patients/get-all-patients-controller.ts b/src/modules/patients/useCases/get-all-patients/get-all-patients-controller.ts index a5eec53..e8f9645 100644 --- a/src/modules/patients/useCases/get-all-patients/get-all-patients-controller.ts +++ b/src/modules/patients/useCases/get-all-patients/get-all-patients-controller.ts @@ -1,8 +1,8 @@ import { FastifyReply } from 'fastify'; import { BaseController } from '@app/infra/http/controller/baseController'; -import { paginateSchema } from '@shared/utils'; +import { patientsFilterSchema } from './get-all-patients-schema'; import { GetAllPatientsService } from './get-all-patients-service'; export class GetAllPatientsController extends BaseController { @@ -11,7 +11,7 @@ export class GetAllPatientsController extends BaseController { } protected async handle(): Promise { - const query = paginateSchema.parse(this.request.query); + const query = patientsFilterSchema.parse(this.request.query); const results = await this.getAllPatientsService.execute(query); diff --git a/src/modules/patients/useCases/get-all-patients/get-all-patients-schema.ts b/src/modules/patients/useCases/get-all-patients/get-all-patients-schema.ts new file mode 100644 index 0000000..48cd1e0 --- /dev/null +++ b/src/modules/patients/useCases/get-all-patients/get-all-patients-schema.ts @@ -0,0 +1,21 @@ +import { Status } from '@prisma/client'; +import { z } from 'zod'; + +import { MUST_CONTAIN_CPF_SIZE, MUST_CONTAIN_CNS_SIZE } from '@shared/utils'; + +export const patientsFilterSchema = z.object({ + name: z.string().optional(), + page: z + .string() + .transform(val => parseInt(val, 10)) + .default('1'), + items_per_page: z + .string() + .transform(val => parseInt(val, 10)) + .default('10'), + cpf: z.string().max(11, MUST_CONTAIN_CPF_SIZE).optional(), + cns: z.string().max(15, MUST_CONTAIN_CNS_SIZE).optional(), + status: z.nativeEnum(Status).optional(), +}); + +export type PatientsFilterType = z.infer; diff --git a/src/modules/patients/useCases/get-all-patients/get-all-patients-service.ts b/src/modules/patients/useCases/get-all-patients/get-all-patients-service.ts index 22f7266..0020932 100644 --- a/src/modules/patients/useCases/get-all-patients/get-all-patients-service.ts +++ b/src/modules/patients/useCases/get-all-patients/get-all-patients-service.ts @@ -1,4 +1,4 @@ -import { IPatient, IPaginateRequest } from '@shared/entities'; +import { IPatient, IPatientFilters } from '@shared/entities'; import { PatientRepository } from '@shared/repositories/implementations'; import { FindAndCountAll } from '@shared/utils/format-paginate'; import { validatePaginationParams } from '@shared/utils/validate-paginate'; @@ -8,16 +8,13 @@ export class GetAllPatientsService { this.patientRepository = patientRepository; } - async execute({ - name, - page, - items_per_page, - }: IPaginateRequest): Promise> { + async execute(params: IPatientFilters): Promise> { + const { page, items_per_page } = params; validatePaginationParams(page, items_per_page); const offset = (page - 1) * items_per_page; const { rows, count } = await this.patientRepository.findAndCountAll({ - name, + ...params, skip: offset, take: items_per_page, }); diff --git a/src/shared/entities/entities.ts b/src/shared/entities/entities.ts index 27a77d8..ed789c1 100644 --- a/src/shared/entities/entities.ts +++ b/src/shared/entities/entities.ts @@ -1,4 +1,4 @@ -import { AppointmentType } from '@prisma/client'; +import { AppointmentType, Status } from '@prisma/client'; export interface FindEntitiesAndCountParams { name?: string; @@ -25,3 +25,10 @@ export interface FindAllAppointmentsAndCountParams start_date?: Date; end_date?: Date; } + +export interface FindAllPatientsAndCountParams + extends FindEntitiesAndCountParams { + cpf?: string; + cns?: string; + status?: Status; +} diff --git a/src/shared/entities/patient.ts b/src/shared/entities/patient.ts index 076b2b1..a1149e1 100644 --- a/src/shared/entities/patient.ts +++ b/src/shared/entities/patient.ts @@ -1,6 +1,8 @@ import { MaritalStatus, Sex, Status } from '@prisma/client'; import { Decimal } from '@prisma/client/runtime/library'; +import { IPaginateRequest } from './paginate'; + export type IPatient = { id?: string; name: string; @@ -24,5 +26,12 @@ export type IPatient = { created_at?: Date; updated_at?: Date; + // TO-DO // conditions: [] }; + +export interface IPatientFilters extends IPaginateRequest { + cpf?: string; + cns?: string; + status?: Status; +} diff --git a/src/shared/repositories/implementations/patient-repository.ts b/src/shared/repositories/implementations/patient-repository.ts index 99a2896..1f3ea7d 100644 --- a/src/shared/repositories/implementations/patient-repository.ts +++ b/src/shared/repositories/implementations/patient-repository.ts @@ -1,7 +1,9 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +import { Prisma } from '@prisma/client'; + import { prisma } from '@app/infra/prisma/client'; import { - type FindEntitiesAndCountParams, + type FindAllPatientsAndCountParams, type FindEntitiesAndCountResult, IPatient, } from '@shared/entities'; @@ -11,18 +13,22 @@ import { IPatientRepository } from '../interfaces/patient'; export class PatientRepository implements IPatientRepository { async findAndCountAll( - params: FindEntitiesAndCountParams, + params: FindAllPatientsAndCountParams, ): Promise> { - const { name, take, skip } = params; - const count = await prisma.patient.count({ - where: { name: name ? { contains: name } : undefined }, - }); + const { name, take, skip, cpf, cns, status } = params; + + const where: Prisma.PatientWhereInput = { + ...(name && { name: { contains: name } }), + ...(cpf && { cpf }), + ...(cns && { cns }), + ...(status && { status }), + }; + + const count = await prisma.patient.count({ where }); const patients = await prisma.patient.findMany({ skip, take, - where: { - name: name ? { contains: name } : undefined, - }, + where, orderBy: { created_at: 'desc', }, diff --git a/src/shared/repositories/interfaces/patient.ts b/src/shared/repositories/interfaces/patient.ts index b4020cf..5ef64da 100644 --- a/src/shared/repositories/interfaces/patient.ts +++ b/src/shared/repositories/interfaces/patient.ts @@ -1,12 +1,12 @@ import { - type FindEntitiesAndCountParams, + type FindAllPatientsAndCountParams, type FindEntitiesAndCountResult, IPatient, } from '@shared/entities'; export interface IPatientRepository { findAndCountAll( - params: FindEntitiesAndCountParams, + params: FindAllPatientsAndCountParams, ): Promise>; findById(id: string): Promise; findByCPF(cpf: string): Promise; diff --git a/src/shared/utils/schemas.ts b/src/shared/utils/schemas.ts index 946e8e5..9e1d8f0 100644 --- a/src/shared/utils/schemas.ts +++ b/src/shared/utils/schemas.ts @@ -31,3 +31,6 @@ export const MIN_WEIGHT = 'Peso mínimo permitido é 0.5 kg'; export const MAX_WEIGHT = 'Peso máximo permitido é 500 kg'; export const MIN_HEIGHT = 'Altura mínima permitida é 50 cm'; export const MAX_HEIGHT = 'Altura máxima permitida é 300 cm'; + +export const MUST_CONTAIN_CPF_SIZE = 'O CPF deve conter 11 dígitos.'; +export const MUST_CONTAIN_CNS_SIZE = 'O CNS deve conter 15 dígitos.';