diff --git a/prisma/migrations/20240222105619_update_firstname_lastname/migration.sql b/prisma/migrations/20240222105619_update_firstname_lastname/migration.sql new file mode 100644 index 0000000..68c0107 --- /dev/null +++ b/prisma/migrations/20240222105619_update_firstname_lastname/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - Added the required column `firstName` to the `User` table without a default value. This is not possible if the table is not empty. + - Added the required column `lastName` to the `User` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "firstName" TEXT NOT NULL, +ADD COLUMN "lastName" TEXT NOT NULL; diff --git a/src/app.module.ts b/src/app.module.ts index ced3da4..b0d6b5b 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -13,6 +13,8 @@ import { PrismaModule } from './prisma/prisma.module'; import { ConsultationsModule } from './consultations/consultations.module'; import { MedecinsModule } from './medecins/medecins.module'; import { DermatologuesModule } from './dermatologues/dermatologues.module'; +import { AppointmentsModule } from './appointments/appointments.module'; +import { PatientsModule } from './patients/patients.module'; @Module({ imports: [ @@ -27,6 +29,8 @@ import { DermatologuesModule } from './dermatologues/dermatologues.module'; ConsultationsModule, MedecinsModule, DermatologuesModule, + AppointmentsModule, + PatientsModule, ], controllers: [AppController], providers: [ diff --git a/src/appointments/appointments.controller.ts b/src/appointments/appointments.controller.ts new file mode 100644 index 0000000..9f93575 --- /dev/null +++ b/src/appointments/appointments.controller.ts @@ -0,0 +1,45 @@ +import { + Controller, + Get, + Post, + Body, + Patch, + Param, + Delete, +} from '@nestjs/common'; +import { AppointmentsService } from './appointments.service'; +import { CreateAppointmentDto } from './dto/create-appointment.dto'; +import { UpdateAppointmentDto } from './dto/update-appointment.dto'; + +@Controller('appointments') +export class AppointmentsController { + constructor(private readonly appointmentsService: AppointmentsService) {} + + @Post() + create(@Body() createAppointmentDto: CreateAppointmentDto) { + return this.appointmentsService.create(createAppointmentDto); + } + + @Get() + findAll() { + return this.appointmentsService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.appointmentsService.findOne(+id); + } + + @Patch(':id') + update( + @Param('id') id: string, + @Body() updateAppointmentDto: UpdateAppointmentDto, + ) { + return this.appointmentsService.update(+id, updateAppointmentDto); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.appointmentsService.remove(+id); + } +} diff --git a/src/appointments/appointments.module.ts b/src/appointments/appointments.module.ts new file mode 100644 index 0000000..d70dbf0 --- /dev/null +++ b/src/appointments/appointments.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { AppointmentsService } from './appointments.service'; +import { AppointmentsController } from './appointments.controller'; +import { PrismaModule } from 'src/prisma/prisma.module'; + +@Module({ + imports: [PrismaModule], + controllers: [AppointmentsController], + providers: [AppointmentsService], + exports: [AppointmentsService], +}) +export class AppointmentsModule {} diff --git a/src/appointments/appointments.service.ts b/src/appointments/appointments.service.ts new file mode 100644 index 0000000..05fd45b --- /dev/null +++ b/src/appointments/appointments.service.ts @@ -0,0 +1,50 @@ +import { Injectable } from '@nestjs/common'; +import { CreateAppointmentDto } from './dto/create-appointment.dto'; +import { UpdateAppointmentDto } from './dto/update-appointment.dto'; +import { PrismaService } from 'src/prisma/prisma.service'; +import { Appointment } from '@prisma/client'; + +@Injectable() +export class AppointmentsService { + constructor(private readonly prismaService: PrismaService) {} + + create(createAppointmentDto: CreateAppointmentDto) { + this.prismaService.appointment.create({ + data: createAppointmentDto as Appointment, + }); + } + + findByPatientId(patientId: string) { + return this.prismaService.appointment.findMany({ + where: { + idPatient: patientId, + }, + }); + } + + findByDermatologueId(dermatologueId: string) { + return this.prismaService.appointment.findMany({ + where: { + idDermatologue: dermatologueId, + }, + }); + } + + // updateStatus(appointmentId: string, status: App) { + + findAll() { + return this.prismaService.appointment.findMany(); + } + + findOne(id: number) { + return `This action returns a #${id} appointment`; + } + + update(id: number, updateAppointmentDto: UpdateAppointmentDto) { + return `This action updates a #${id} appointment`; + } + + remove(id: number) { + return `This action removes a #${id} appointment`; + } +} diff --git a/src/appointments/dto/create-appointment.dto.ts b/src/appointments/dto/create-appointment.dto.ts new file mode 100644 index 0000000..f9bf696 --- /dev/null +++ b/src/appointments/dto/create-appointment.dto.ts @@ -0,0 +1 @@ +export class CreateAppointmentDto {} diff --git a/src/appointments/dto/update-appointment.dto.ts b/src/appointments/dto/update-appointment.dto.ts new file mode 100644 index 0000000..e743fb4 --- /dev/null +++ b/src/appointments/dto/update-appointment.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/swagger'; +import { CreateAppointmentDto } from './create-appointment.dto'; + +export class UpdateAppointmentDto extends PartialType(CreateAppointmentDto) {} diff --git a/src/appointments/entities/appointment.entity.ts b/src/appointments/entities/appointment.entity.ts new file mode 100644 index 0000000..4c84b13 --- /dev/null +++ b/src/appointments/entities/appointment.entity.ts @@ -0,0 +1,28 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Appointment, statusAppointment } from '@prisma/client'; + +export class AppointmentEntity implements Appointment { + @ApiProperty() + id: string; + + @ApiProperty() + updatedAt: Date; + + @ApiProperty() + createdAt: Date; + + @ApiProperty() + idDermatologue: string; + + @ApiProperty() + idPatient: string; + + @ApiProperty() + date: Date; + + @ApiProperty() + status: statusAppointment; + + @ApiProperty() + idConsultation: string; +} diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 92b98a3..4484c77 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -87,8 +87,11 @@ export class AuthService { }; } - async createAccessToken(userId: string) { - return this.jwtService.sign({ userId: userId }, { expiresIn: '15m' }); + async createAccessToken(userId: string, role: Role) { + return this.jwtService.sign( + { userId: userId, role: role }, + { expiresIn: '15m' }, + ); } async createRefreshToken(userId: string, role: Role) { diff --git a/src/patients/dto/create-patient.dto.ts b/src/patients/dto/create-patient.dto.ts new file mode 100644 index 0000000..f63454c --- /dev/null +++ b/src/patients/dto/create-patient.dto.ts @@ -0,0 +1 @@ +export class CreatePatientDto {} diff --git a/src/patients/dto/update-patient.dto.ts b/src/patients/dto/update-patient.dto.ts new file mode 100644 index 0000000..5d5f88c --- /dev/null +++ b/src/patients/dto/update-patient.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/swagger'; +import { CreatePatientDto } from './create-patient.dto'; + +export class UpdatePatientDto extends PartialType(CreatePatientDto) {} diff --git a/src/patients/entities/patient.entity.ts b/src/patients/entities/patient.entity.ts new file mode 100644 index 0000000..436ad1a --- /dev/null +++ b/src/patients/entities/patient.entity.ts @@ -0,0 +1,54 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Prisma, User } from '@prisma/client'; +import { Exclude } from 'class-transformer'; + +export class PatientEntity implements User { + constructor(partial: Partial) { + Object.assign(this, partial); + } + + @ApiProperty() + id: string; + + @ApiProperty() + updatedAt: Date; + + @ApiProperty() + createdAt: Date; + + @ApiProperty() + firstName: string; + + @ApiProperty() + lastName: string; + + @ApiProperty() + role: 'PATIENT'; + + @ApiProperty() + email: string; + + @ApiProperty() + sexe: string; + + @Exclude() + password: string; + + @ApiProperty() + rppsNumber: string; + + @ApiProperty() + address: string; + + @ApiProperty() + city: string; + + @ApiProperty() + zipCode: string; + + @ApiProperty() + secuNumber: string; + + @ApiProperty() + consultationPatient: Prisma.ConsultationCreateInput[]; +} diff --git a/src/patients/patients.controller.ts b/src/patients/patients.controller.ts new file mode 100644 index 0000000..54dd03f --- /dev/null +++ b/src/patients/patients.controller.ts @@ -0,0 +1,82 @@ +import { + Controller, + Get, + Param, + UseGuards, + Req, + HttpException, + Post, +} from '@nestjs/common'; +import { PatientsService } from './patients.service'; +import { ConsultationsService } from 'src/consultations/consultations.service'; +import { JwtAuthGuard } from 'src/auth/jwt-auth.guard'; +import { ApiBearerAuth, ApiOkResponse } from '@nestjs/swagger'; +import { Request } from 'express'; +import { User } from '@prisma/client'; +import { RolesGuard } from 'src/auth/roles.guard'; +import { HasRole } from 'src/auth/has-role.decorator'; +import { ConsultationEntity } from 'src/consultations/entities/consultation.entity'; + +@Controller('patients') +export class PatientsController { + constructor( + private readonly patientsService: PatientsService, + private readonly consultationService: ConsultationsService, + ) {} + + @Get() + findAll() { + return this.patientsService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.patientsService.findOne(+id); + } + + @ApiBearerAuth() + @HasRole('PATIENT', 'ADMIN') + @UseGuards(JwtAuthGuard, RolesGuard) + @Get(':id/consultations') + getConsultationsByPatientId(@Param('id') id: string) { + return this.consultationService.getConsultationsByPatientId(id); + } + + @ApiBearerAuth() + @HasRole('PATIENT', 'ADMIN') + @UseGuards(JwtAuthGuard, RolesGuard) + @Get(':id/consultations/:idConsultation') + @ApiOkResponse({ type: ConsultationEntity }) + async getConsultationByPatientId( + @Param('id') id: string, + @Param('idConsultation') idConsultation: string, + @Req() req: Request, + ) { + const userJwt = req.user as User; + if (userJwt.id !== id) { + throw new HttpException('Unauthorized', 401); + } + + const consultation = await this.consultationService.findOne(idConsultation); + if (consultation.idPatient !== userJwt.id) { + throw new HttpException('Unauthorized', 401); + } + + return consultation; + } + + // @Get() + // findAll() { + // return this.patientsService.findAll(); + // } + + // @Patch(':id') + // update(@Param('id') id: string, @Body() updatePatientDto: UpdatePatientDto) { + // return this.patientsService.update(+id, updatePatientDto); + // } + + // @Delete(':id') + // remove(@Param('id') id: string) { + // return this.patientsService.remove(+id); + // } +} diff --git a/src/patients/patients.module.ts b/src/patients/patients.module.ts new file mode 100644 index 0000000..f89c450 --- /dev/null +++ b/src/patients/patients.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; +import { PatientsService } from './patients.service'; +import { PatientsController } from './patients.controller'; +import { PrismaModule } from 'src/prisma/prisma.module'; +import { ConsultationsService } from 'src/consultations/consultations.service'; + +@Module({ + imports: [PrismaModule], + controllers: [PatientsController], + providers: [PatientsService, ConsultationsService], + exports: [PatientsService], +}) +export class PatientsModule {} diff --git a/src/patients/patients.service.ts b/src/patients/patients.service.ts new file mode 100644 index 0000000..e0a9940 --- /dev/null +++ b/src/patients/patients.service.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@nestjs/common'; +import { CreatePatientDto } from './dto/create-patient.dto'; +import { UpdatePatientDto } from './dto/update-patient.dto'; + +@Injectable() +export class PatientsService { + create(createPatientDto: CreatePatientDto) { + return 'This action adds a new patient'; + } + + findAll() { + return `This action returns all patients`; + } + + findOne(id: number) { + return `This action returns a #${id} patient`; + } + + update(id: number, updatePatientDto: UpdatePatientDto) { + return `This action updates a #${id} patient`; + } + + remove(id: number) { + return `This action removes a #${id} patient`; + } +} diff --git a/src/users/dto/create-user.dto.ts b/src/users/dto/create-user.dto.ts index 3ddddfc..acab218 100644 --- a/src/users/dto/create-user.dto.ts +++ b/src/users/dto/create-user.dto.ts @@ -1,4 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; +import { Role } from '@prisma/client'; import { IsEnum, IsNotEmpty, @@ -7,13 +8,12 @@ import { MinLength, } from 'class-validator'; -export enum Role { - PATIENT = 'PATIENT', - MEDECIN = 'MEDECIN', - DERMATOLOGUE = 'DERMATOLOGUE', -} +// export enum Role { +// PATIENT = 'PATIENT', +// MEDECIN = 'MEDECIN', +// DERMATOLOGUE = 'DERMATOLOGUE', +// } export class CreateUserDto { - @IsNotEmpty() @IsString() @ApiProperty()