diff --git a/client/lib/api/doctor/authorizedRoutes.ts b/client/lib/api/doctor/authorizedRoutes.ts index 60a76e60..c1392bc1 100644 --- a/client/lib/api/doctor/authorizedRoutes.ts +++ b/client/lib/api/doctor/authorizedRoutes.ts @@ -72,4 +72,9 @@ export const getPatientsOfDoctor = async (limit:number,offset:number) => { return response.data; } +export const getPatientMedicalHistory = async (patientId:string,limit:number,offset:number)=>{ + const response = await doctorAxiosInstance.get(`/medical-history/${patientId}?limit=${limit}&offset=${offset}`); + return response.data; +} + export default doctorAxiosInstance; diff --git a/client/lib/hooks/doctor/useDoctor.ts b/client/lib/hooks/doctor/useDoctor.ts index c362de5b..63a4204a 100644 --- a/client/lib/hooks/doctor/useDoctor.ts +++ b/client/lib/hooks/doctor/useDoctor.ts @@ -1,12 +1,19 @@ -import { getPatientsOfDoctor } from "@/lib/api/doctor/authorizedRoutes" +import { getPatientMedicalHistory, getPatientsOfDoctor } from "@/lib/api/doctor/authorizedRoutes" import { ErrorResponse, PaginatedResult } from "@/types" -import { IPatient } from "@/types/entities" +import { IExtendedAppointment, IPatient } from "@/types/entities" import { useQuery } from "@tanstack/react-query" import { AxiosError } from "axios" -export const useGetPatientsDoctor = (offset:number,limit:number)=>{ - return useQuery,AxiosError>({ - queryKey:["doctor-patients",offset,limit], - queryFn:()=>getPatientsOfDoctor(limit,offset) +export const useGetPatientsDoctor = (offset: number, limit: number) => { + return useQuery, AxiosError>({ + queryKey: ["doctor-patients", offset, limit], + queryFn: () => getPatientsOfDoctor(limit, offset) }); -}; \ No newline at end of file +}; + +export const useGetMedicalHistory = (patientId: string, offset: number, limit: number) => { + return useQuery, AxiosError>({ + queryKey: ["medical-history", offset, limit, patientId], + queryFn: () => getPatientMedicalHistory(patientId, limit, offset) + }); +} \ No newline at end of file diff --git a/server/src/domain/interface/repositories/IAppointmentRepository.ts b/server/src/domain/interface/repositories/IAppointmentRepository.ts index 18b9dae5..22266b37 100644 --- a/server/src/domain/interface/repositories/IAppointmentRepository.ts +++ b/server/src/domain/interface/repositories/IAppointmentRepository.ts @@ -4,7 +4,7 @@ import IPatient from "../../entities/IPatient"; import IRepository from "./IRepository"; export default interface IAppointmentRepository extends IRepository { - updateManyBySlotIdsNotInStatuses(slotIds: string[], fields: IAppointment, notInStatuses:AppointmentStatus[]): Promise; + updateManyBySlotIdsNotInStatuses(slotIds: string[], fields: IAppointment, notInStatuses: AppointmentStatus[]): Promise; findByDateAndSlot(appointmentDate: string, slotId: string): Promise; findManyByDateAndDoctorId(appointmentDate: string, doctorId: string): Promise; updateAppointmentStatusToConfirmed(appointmentId: string): Promise; @@ -15,12 +15,13 @@ export default interface IAppointmentRepository extends IRepository>; - findMayByPatientId( + findManyByPatientId( patientId: string, offset: number, limit: number, status?: AppointmentStatus ): Promise>; findManyByIds(ids: string[]): Promise; - findPatientsByDoctorId(doctorId:string, limit:number, offset:number):Promise>; + findPatientsByDoctorId(doctorId: string, limit: number, offset: number): Promise>; + findManyAsExtendedByPatientId(patientId: string, limit: number, offset: number): Promise> } diff --git a/server/src/infrastructure/repositories/AppointmentRepository.ts b/server/src/infrastructure/repositories/AppointmentRepository.ts index 6cd35b6e..16ad8e9a 100644 --- a/server/src/infrastructure/repositories/AppointmentRepository.ts +++ b/server/src/infrastructure/repositories/AppointmentRepository.ts @@ -25,53 +25,112 @@ export default class AppointmentRepository implements IAppointmentRepository { return await this.model.find({ _id: { $in: ids } }); } - async findPatientsByDoctorId(doctorId: string, limit:number, offset:number): Promise> { + async findManyAsExtendedByPatientId( + patientId: string, + limit: number, + offset: number + ): Promise> { + const result = await this.model.aggregate([ + { + $match: { patientId: new ObjectId(patientId) } + }, + { + $lookup: { + from: "patients", + localField: "patientId", + foreignField: "_id", + as: "patient" + } + }, + { + $lookup: { + from: "doctors", + localField: "doctorId", + foreignField: "_id", + as: "doctor" + } + }, + { + $unwind: "$patient" + }, + { + $unwind: "$doctor" + }, + { + $project: { + "patient.password": 0, + "patient.token": 0, + "doctor.password": 0, + "doctor.token": 0 + } + }, + { + $facet: { + paginatedResults: [ + { $skip: offset }, + { $limit: limit } + ], + totalCount: [ + { $count: "count" } + ] + } + } + ]).exec(); + + const appointments = result[0].paginatedResults; + const totalItems = result[0].totalCount.length > 0 ? result[0].totalCount[0].count : 0; + + return getPaginatedResult(totalItems, offset, limit, appointments); + } + + + async findPatientsByDoctorId(doctorId: string, limit: number, offset: number): Promise> { const result = await this.model.aggregate([ { - $match: { doctorId: new ObjectId(doctorId) } + $match: { doctorId: new ObjectId(doctorId) } }, { - $group: { _id: "$patientId" } + $group: { _id: "$patientId" } }, { - $lookup: { - from: "patients", - localField: "_id", - foreignField: "_id", - as: "patientInfo" - } + $lookup: { + from: "patients", + localField: "_id", + foreignField: "_id", + as: "patientInfo" + } }, { - $unwind: "$patientInfo" + $unwind: "$patientInfo" }, { - $replaceRoot: { newRoot: "$patientInfo" } + $replaceRoot: { newRoot: "$patientInfo" } }, { - $facet: { - paginatedResults: [ - { $skip: offset }, - { $limit: limit }, - { - $project: { - password: 0, - token: 0 - } + $facet: { + paginatedResults: [ + { $skip: offset }, + { $limit: limit }, + { + $project: { + password: 0, + token: 0 } - ], - totalCount: [ - { $count: "count" } - ] - } + } + ], + totalCount: [ + { $count: "count" } + ] + } } - ]).exec(); - - const patients = result[0].paginatedResults; - const totalItems = result[0].totalCount.length > 0 ? result[0].totalCount[0].count : 0; - - return getPaginatedResult(totalItems, offset, limit, patients); - } - + ]).exec(); + + const patients = result[0].paginatedResults; + const totalItems = result[0].totalCount.length > 0 ? result[0].totalCount[0].count : 0; + + return getPaginatedResult(totalItems, offset, limit, patients); + } + async findDetailsById(appointmentId: string): Promise { const objectId = new ObjectId(appointmentId); @@ -133,7 +192,7 @@ export default class AppointmentRepository implements IAppointmentRepository { return appointment[0] as IExtendedAppointment; } - async findMayByPatientId( + async findManyByPatientId( patientId: string, offset: number, limit: number, diff --git a/server/src/use_case/appointment/GetAppointmentUseCase.ts b/server/src/use_case/appointment/GetAppointmentUseCase.ts index 202c265b..2336544d 100644 --- a/server/src/use_case/appointment/GetAppointmentUseCase.ts +++ b/server/src/use_case/appointment/GetAppointmentUseCase.ts @@ -67,7 +67,7 @@ export default class GetAppointmentUseCase { limit: number, status?: AppointmentStatus ): Promise | null> { - return await this.appointmentRepository.findMayByPatientId(patientId, offset, limit, status); + return await this.appointmentRepository.findManyByPatientId(patientId, offset, limit, status); } async getSuccessPageDetails(paymentId: string): Promise { diff --git a/server/src/use_case/doctor/GetPatientUseCase.ts b/server/src/use_case/doctor/GetPatientUseCase.ts index ceb37bee..59c115fd 100644 --- a/server/src/use_case/doctor/GetPatientUseCase.ts +++ b/server/src/use_case/doctor/GetPatientUseCase.ts @@ -1,6 +1,6 @@ import IAppointmentRepository from "../../domain/interface/repositories/IAppointmentRepository"; import IValidatorService from '../../domain/interface/services/IValidatorService' -import IAppointment from "../../domain/entities/IAppointment"; +import { IExtendedAppointment } from "../../domain/entities/IAppointment"; import IPatient from "../../domain/entities/IPatient"; import { PaginatedResult } from "../../types"; @@ -15,8 +15,8 @@ export default class GetPatientUseCaseDoctor { return await this.appointmentRepository.findPatientsByDoctorId(doctorId, limit, offset); } - async getMedicalHistory(patientId: string, offset: number, limit: number): Promise> { + async getMedicalHistory(patientId: string, offset: number, limit: number): Promise> { this.validatorService.validateIdFormat(patientId) - return await this.appointmentRepository.findMayByPatientId(patientId, offset, limit) + return await this.appointmentRepository.findManyAsExtendedByPatientId(patientId, limit, offset) } } \ No newline at end of file