Skip to content

Commit

Permalink
Merge pull request #22 from SkinSightYnov/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
R-o-h-t authored Feb 22, 2024
2 parents 9d8f8d2 + 6a355a1 commit bbd8905
Show file tree
Hide file tree
Showing 22 changed files with 347 additions and 27 deletions.
22 changes: 11 additions & 11 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Ignore the node modules
/node_modules

# Ignore the build directory
/dist

# Ignore the coverage directory
/coverage

# Ignore the prisma migrations
/prisma/migrations
# Ignore the node modules
/node_modules

# Ignore the build directory
/dist

# Ignore the coverage directory
/coverage

# Ignore the prisma migrations
/prisma/migrations
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
Warnings:
- You are about to drop the column `criticity` on the `Appointment` table. All the data in the column will be lost.
- The `status` column on the `Consultation` table would be dropped and recreated. This will lead to data loss if there is data in the column.
- A unique constraint covering the columns `[idConsultation]` on the table `Appointment` will be added. If there are existing duplicate values, this will fail.
- Added the required column `idConsultation` to the `Appointment` table without a default value. This is not possible if the table is not empty.
*/
-- AlterEnum
ALTER TYPE "Role" ADD VALUE 'ADMIN';

-- AlterTable
ALTER TABLE "Appointment" DROP COLUMN "criticity",
ADD COLUMN "idConsultation" TEXT NOT NULL;

-- AlterTable
ALTER TABLE "Consultation" ADD COLUMN "informations" TEXT NOT NULL DEFAULT '',
ADD COLUMN "resultat" TEXT NOT NULL DEFAULT '',
DROP COLUMN "status",
ADD COLUMN "status" "statusConsultation" NOT NULL DEFAULT 'WAITING';

-- CreateIndex
CREATE UNIQUE INDEX "Appointment_idConsultation_key" ON "Appointment"("idConsultation");

-- AddForeignKey
ALTER TABLE "Appointment" ADD CONSTRAINT "Appointment_idConsultation_fkey" FOREIGN KEY ("idConsultation") REFERENCES "Consultation"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
Warnings:
- The `status` column on the `Appointment` table would be dropped and recreated. This will lead to data loss if there is data in the column.
*/
-- CreateEnum
CREATE TYPE "statusAppointment" AS ENUM ('WAITING', 'ACCEPTED', 'CANCELED', 'REFUSED');

-- AlterTable
ALTER TABLE "Appointment" DROP COLUMN "status",
ADD COLUMN "status" "statusAppointment" NOT NULL DEFAULT 'WAITING';
17 changes: 15 additions & 2 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum Role {
PATIENT
MEDECIN
DERMATOLOGUE
ADMIN
}

enum Sexe {
Expand All @@ -36,6 +37,8 @@ model User {
updatedAt DateTime @updatedAt
createdAt DateTime @default(now())
role Role
firstName String
lastName String
email String @unique
sexe String @default("M")
password String
Expand Down Expand Up @@ -66,6 +69,7 @@ model Consultation {
Files File[]
informations String @default("")
resultat String @default("")
appointment Appointment?
}

model File {
Expand All @@ -84,6 +88,14 @@ enum FileType {
FILE
}

// en attente, accepter, annuler, refuser
enum statusAppointment {
WAITING
ACCEPTED
CANCELED
REFUSED
}

model Appointment {
id String @id @default(uuid())
createdAt DateTime @default(now())
Expand All @@ -93,8 +105,9 @@ model Appointment {
patient User @relation("appointmentsPatient", fields: [idPatient], references: [id])
idPatient String
date DateTime
status String @default("WAITING")
criticity Int @default(0)
status statusAppointment @default(WAITING)
idConsultation String @unique
consultation Consultation @relation(fields: [idConsultation], references: [id])
}

model Conversation {
Expand Down
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { UsersModule } from './users/users.module';
import { PrismaModule } from './prisma/prisma.module';
import { ConsultationsModule } from './consultations/consultations.module';
import { MedecinsModule } from './medecins/medecins.module';
import { DermatologuesModule } from './dermatologues/dermatologues.module';

@Module({
imports: [
Expand All @@ -25,6 +26,7 @@ import { MedecinsModule } from './medecins/medecins.module';
PrismaModule,
ConsultationsModule,
MedecinsModule,
DermatologuesModule,
],
controllers: [AppController],
providers: [
Expand Down
13 changes: 7 additions & 6 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { AuthEntity } from './entity/auth.entity';
import * as bcrypt from 'bcrypt';
import { v4 as uuid } from 'uuid';
import { Response } from 'express';
import { Role } from '@prisma/client';

@Injectable()
export class AuthService {
Expand Down Expand Up @@ -39,8 +40,8 @@ export class AuthService {
throw new UnauthorizedException('Invalid password');
}

const accessToken = await this.createAccessToken(user.id);
const refreshToken = await this.createRefreshToken(user.id);
const accessToken = await this.createAccessToken(user.id, user.role);
const refreshToken = await this.createRefreshToken(user.id, user.role);

res.cookie('refreshToken', refreshToken, {
httpOnly: true,
Expand Down Expand Up @@ -71,15 +72,15 @@ export class AuthService {
throw new NotFoundException(`No user found for id: ${payload.userId}`);
}

const refreshToken = await this.createRefreshToken(user.id);
const refreshToken = await this.createRefreshToken(user.id, user.role);

res.cookie('refreshToken', refreshToken, {
httpOnly: true,
secure: true,
// sameSite: 'strict',
});

const accessToken = await this.createAccessToken(user.id);
const accessToken = await this.createAccessToken(user.id, user.role);

return {
accessToken: accessToken,
Expand All @@ -90,10 +91,10 @@ export class AuthService {
return this.jwtService.sign({ userId: userId }, { expiresIn: '15m' });
}

async createRefreshToken(userId: string) {
async createRefreshToken(userId: string, role: Role) {
const tokenId = uuid();
return this.jwtService.sign(
{ userId: userId, tokenId: tokenId },
{ userId: userId, tokenId: tokenId, role: role },
{ expiresIn: '7d' },
);
}
Expand Down
4 changes: 4 additions & 0 deletions src/auth/has-role.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { SetMetadata } from '@nestjs/common';
import { Role } from '@prisma/client';

export const HasRole = (...roles: Role[]) => SetMetadata('roles', roles);
3 changes: 2 additions & 1 deletion src/auth/jwt.strategy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//src/auth/jwt.strategy.ts
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Role } from '@prisma/client';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { UserEntity } from 'src/users/entities/user.entity';
import { UsersService } from 'src/users/users.service';
Expand All @@ -14,7 +15,7 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
});
}

async validate(payload: { userId: string }) {
async validate(payload: { userId: string; role: Role }) {
const user = new UserEntity(
await this.usersService.findOne(payload.userId),
);
Expand Down
22 changes: 22 additions & 0 deletions src/auth/roles.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Role } from '@prisma/client';

@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}

canActivate(context: ExecutionContext): boolean {
const requireRoles = this.reflector.getAllAndOverride<Role[]>('roles', [
context.getHandler(),
context.getClass(),
]);
if (!requireRoles) {
return true;
}

const { user } = context.switchToHttp().getRequest();
console.log('user', user);
return requireRoles.some((role) => user.role?.includes(role));
}
}
37 changes: 37 additions & 0 deletions src/dermatologues/dermatologues.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {
Controller,
Get,
Post,

Check failure on line 4 in src/dermatologues/dermatologues.controller.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

'Post' is defined but never used
Body,

Check failure on line 5 in src/dermatologues/dermatologues.controller.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

'Body' is defined but never used
Patch,

Check failure on line 6 in src/dermatologues/dermatologues.controller.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

'Patch' is defined but never used
Param,
Delete,

Check failure on line 8 in src/dermatologues/dermatologues.controller.ts

View workflow job for this annotation

GitHub Actions / tests (20.x)

'Delete' is defined but never used
} from '@nestjs/common';
import { DermatologuesService } from './dermatologues.service';
import { ApiTags } from '@nestjs/swagger';

@ApiTags('dermatologues')
@Controller('dermatologues')
export class DermatologuesController {
constructor(private readonly dermatologuesService: DermatologuesService) {}

@Get()
findAll() {
return this.dermatologuesService.findAll();
}

@Get(':id')
findOne(@Param('id') id: string) {
return this.dermatologuesService.findOne(id);
}

// @Patch(':id')
// update(@Param('id') id: string, @Body() updateDermatologueDto: ) {
// return this.dermatologuesService.update(+id, updateDermatologueDto);
// }

// @Delete(':id')
// remove(@Param('id') id: string) {
// return this.dermatologuesService.remove(+id);
// }
}
12 changes: 12 additions & 0 deletions src/dermatologues/dermatologues.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { DermatologuesService } from './dermatologues.service';
import { DermatologuesController } from './dermatologues.controller';
import { PrismaModule } from 'src/prisma/prisma.module';

@Module({
imports: [PrismaModule],
controllers: [DermatologuesController],
providers: [DermatologuesService],
exports: [DermatologuesService],
})
export class DermatologuesModule {}
43 changes: 43 additions & 0 deletions src/dermatologues/dermatologues.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';

@Injectable()
export class DermatologuesService {
constructor(private readonly prisma: PrismaService) {}

async findAll() {
return await this.prisma.user.findMany({
where: {
role: 'DERMATOLOGUE',
},
});
}

findOne(id: string) {
return this.prisma.user.findUnique({
where: {
id,
role: 'DERMATOLOGUE',
},
});
}

getAppointmentByDermatologueId(dermatologueId: string) {
return this.prisma.appointment.findMany({
where: {
idDermatologue: dermatologueId,
},
});
}

// changeAppointmentStatus(appointmentId: string, status: statusAppointment) {
// return this.prisma.appointment.update({
// where: {
// id: appointmentId,
// },
// data: {
// status: statusAppointment,
// },
// });
// }
}
1 change: 1 addition & 0 deletions src/dermatologues/dto/create-dermatologue.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export class CreateDermatologueDto {}
4 changes: 4 additions & 0 deletions src/dermatologues/dto/update-dermatologue.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { PartialType } from '@nestjs/swagger';
import { CreateDermatologueDto } from './create-dermatologue.dto';

export class UpdateDermatologueDto extends PartialType(CreateDermatologueDto) {}
54 changes: 54 additions & 0 deletions src/dermatologues/entities/dermatologue.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { ApiProperty } from '@nestjs/swagger';
import { Appointment, User } from '@prisma/client';
import { Exclude } from 'class-transformer';

export class Medecin implements User {
constructor(partial: Partial<Medecin>) {
Object.assign(this, partial);
}

@ApiProperty()
id: string;

@ApiProperty()
updatedAt: Date;

@ApiProperty()
createdAt: Date;

@ApiProperty()
firstName: string;

@ApiProperty()
lastName: string;

@ApiProperty()
role: 'DERMATOLOGUE';

@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()
appointmentsPatient: Appointment[];
}
1 change: 1 addition & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ declare const module: any;

async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors({ origin: '*' });
app.useGlobalInterceptors(new LoggingInterceptor());

app.useGlobalPipes(new ValidationPipe({ whitelist: true }));
Expand Down
Loading

0 comments on commit bbd8905

Please sign in to comment.