Skip to content

Commit

Permalink
doctor upload docs
Browse files Browse the repository at this point in the history
  • Loading branch information
NairuzY committed Nov 12, 2023
1 parent 33e60fe commit bd68e19
Show file tree
Hide file tree
Showing 6 changed files with 306 additions and 70 deletions.
14 changes: 11 additions & 3 deletions backend/src/app/controllers/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,17 @@ import {
GetUserByUsernameResponse,
type UserType,
} from 'clinic-common/types/user.types'
import { RegisterDoctorRequestValidator } from 'clinic-common/validators/doctor.validator'

import {
type DoctorStatus,
RegisterDoctorRequestResponse,
} from 'clinic-common/types/doctor.types'
import { getModelIdForUsername } from '../services/auth.service'
import multer from 'multer'

const storage = multer.memoryStorage() // You can choose a different storage method

const upload = multer({ storage })

export const authRouter = Router()

Expand Down Expand Up @@ -97,9 +102,12 @@ authRouter.get(
// Submit a Request to Register as a Doctor
authRouter.post(
'/request-doctor',
validate(RegisterDoctorRequestValidator),
upload.array('documents', 50),
asyncWrapper(async (req, res) => {
const doctor = await submitDoctorRequest(req.body)
const doctor = await submitDoctorRequest({
...req.body,
documents: req.files as Express.Multer.File[],
})
res.send(
new RegisterDoctorRequestResponse(
doctor.id,
Expand Down
27 changes: 22 additions & 5 deletions backend/src/app/services/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ import { type HydratedDocument } from 'mongoose'
import { PatientModel } from '../models/patient.model'
import {
DoctorStatus,
type RegisterDoctorRequest,
type IRegisterDoctorRequest,
} from 'clinic-common/types/doctor.types'
import { type DoctorDocument, DoctorModel } from '../models/doctor.model'
import { hash } from 'bcrypt'
import { type WithUser } from '../utils/typeUtils'
import { AppointmentModel } from '../models/appointment.model'
import { AdminModel } from '../models/admin.model'

import FireBase from '../../../../firebase.config'
import { getStorage, ref, uploadBytes } from 'firebase/storage'
import { getDownloadURL } from 'firebase/storage'
const jwtSecret = process.env.JWT_TOKEN ?? 'secret'
const bcryptSalt = process.env.BCRYPT_SALT ?? '$2b$10$13bXTGGukQXsCf5hokNe2u'

Expand Down Expand Up @@ -149,8 +151,10 @@ export async function getUserByUsername(
}

export async function submitDoctorRequest(
doctor: RegisterDoctorRequest
doctor: IRegisterDoctorRequest
): Promise<WithUser<DoctorDocument>> {
console.log(doctor)

if (await isUsernameTaken(doctor.username)) {
throw new UsernameAlreadyTakenError()
}
Expand All @@ -167,17 +171,30 @@ export async function submitDoctorRequest(
type: UserType.Doctor,
})
await user.save()
const documentsPaths: string[] = []
const storage = getStorage(FireBase)
const storageRef = ref(storage, 'doctors/')

for (let i = 0; i < doctor.documents.length; i++) {
const fileRef = ref(storageRef, doctor.name + [i])
await uploadBytes(fileRef, doctor.documents[i].buffer, {
contentType: doctor.documents[i].mimetype,
})
const fullPath = await getDownloadURL(fileRef)
documentsPaths.push(fullPath.toString())
}

const newDoctor = await DoctorModel.create({
user: user.id,
name: doctor.name,
email: doctor.email,
dateOfBirth: doctor.dateOfBirth,
hourlyRate: doctor.hourlyRate,
hourlyRate: parseInt(doctor.hourlyRate),
affiliation: doctor.affiliation,
educationalBackground: doctor.educationalBackground,
speciality: doctor.speciality,
requestStatus: DoctorStatus.Pending,
documents: doctor.documents,
documents: documentsPaths,
})
await newDoctor.save()

Expand Down
29 changes: 24 additions & 5 deletions clinic-common/types/doctor.types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { z } from 'zod'
import type {
UpdateDoctorRequestValidator,
RegisterDoctorRequestValidator,
AddAvailableTimeSlotsRequestValidator,
} from '../validators/doctor.validator'

Expand Down Expand Up @@ -172,10 +171,6 @@ export class GetApprovedDoctorsResponse {

export type UpdateDoctorRequest = z.infer<typeof UpdateDoctorRequestValidator>

export type RegisterDoctorRequest = z.infer<
typeof RegisterDoctorRequestValidator
>

export type AddAvailableTimeSlotsRequest = z.infer<
typeof AddAvailableTimeSlotsRequestValidator
>
Expand All @@ -189,3 +184,27 @@ export class AddAvailableTimeSlotsResponse extends GetApprovedDoctorResponse {}
export class GetWalletMoneyResponse {
constructor(public money: number) {}
}

export type IRegisterDoctorRequest = {
username: string
password: string
name: string
email: string
mobileNumber: string
dateOfBirth: Date
hourlyRate: string
affiliation: string
educationalBackground: string
speciality: string

documents: MulterFile[]
}

type MulterFile = {
fieldname: string
originalname: string
encoding: string
mimetype: string
buffer: Buffer
size: number
}
18 changes: 0 additions & 18 deletions clinic-common/validators/doctor.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,3 @@ export const UpdateDoctorRequestValidator = zod.object({
export const AddAvailableTimeSlotsRequestValidator = zod.object({
time: zod.coerce.date(),
})

export const RegisterDoctorRequestValidator = zod.object({
username: zod
.string()
.min(3)
.max(255)
.regex(/^[a-zA-Z0-9_]+$/),
password: zod.string().min(6).max(255),
name: zod.string().min(3).max(255),
email: zod.string().email(),
mobileNumber: zod.string().min(11).max(11),
dateOfBirth: zod.coerce.date(),
hourlyRate: zod.number(),
affiliation: zod.string().min(1),
educationalBackground: zod.string().min(1),
speciality: zod.string().min(1),
documents: zod.array(zod.string()),
})
9 changes: 0 additions & 9 deletions frontend/src/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
LoginResponse,
RegisterRequest,
} from 'clinic-common/types/auth.types'
import { RegisterDoctorRequest } from 'clinic-common/types/doctor.types'

export async function login(request: LoginRequest): Promise<LoginResponse> {
return await api.post<LoginResponse>('/auth/login', request).then((res) => {
Expand All @@ -21,14 +20,6 @@ export async function registerPatient(request: RegisterRequest): Promise<void> {
})
}

export async function requestDoctor(
request: RegisterDoctorRequest
): Promise<void> {
return await api.post('/auth/request-doctor', request).then((res) => {
console.log('requested successfully', res.data)
})
}

export async function getCurrentUser(): Promise<GetCurrentUserResponse> {
if (!localStorage.getItem('token')) {
return Promise.reject('No token found')
Expand Down
Loading

0 comments on commit bd68e19

Please sign in to comment.