From 627e646792cdae1ad89eaf820a2d4e6d199ac83a Mon Sep 17 00:00:00 2001 From: Anjula Shanaka Date: Wed, 5 Jun 2024 05:44:24 +0530 Subject: [PATCH] Add application validations (#119) Good Job --- src/entities/category.entity.ts | 5 ++--- src/entities/mentor.entity.ts | 13 ++++++------ src/services/admin/category.service.ts | 2 +- src/services/mentee.service.ts | 16 ++++++++++++++ src/services/mentor.service.ts | 29 ++++++++++++++++++++------ src/templates/emailTemplate.ejs | 18 ++++++++++++++-- src/utils.ts | 19 +++++++---------- 7 files changed, 72 insertions(+), 30 deletions(-) diff --git a/src/entities/category.entity.ts b/src/entities/category.entity.ts index a4205c9f..b02a961e 100644 --- a/src/entities/category.entity.ts +++ b/src/entities/category.entity.ts @@ -7,12 +7,11 @@ class Category extends BaseEntity { category: string @OneToMany(() => Mentor, (mentor) => mentor.category) - mentors: Mentor[] + mentors?: Mentor[] - constructor(category: string, mentors: Mentor[]) { + constructor(category: string) { super() this.category = category - this.mentors = mentors } } diff --git a/src/entities/mentor.entity.ts b/src/entities/mentor.entity.ts index 43a9f9b0..c9566952 100644 --- a/src/entities/mentor.entity.ts +++ b/src/entities/mentor.entity.ts @@ -1,5 +1,5 @@ import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from 'typeorm' -import profileEntity from './profile.entity' +import Profile from './profile.entity' import Mentee from './mentee.entity' import Category from './category.entity' import { ApplicationStatus } from '../enums' @@ -15,6 +15,7 @@ class Mentor extends BaseEntity { state: ApplicationStatus @ManyToOne(() => Category, (category) => category.mentors) + @JoinColumn() category: Category @Column({ type: 'json' }) @@ -23,20 +24,19 @@ class Mentor extends BaseEntity { @Column({ type: 'boolean' }) availability: boolean - @ManyToOne(() => profileEntity) + @ManyToOne(() => Profile) @JoinColumn() - profile: profileEntity + profile: Profile @OneToMany(() => Mentee, (mentee) => mentee.mentor) - mentees: Mentee[] + mentees?: Mentee[] constructor( state: ApplicationStatus, category: Category, application: Record, availability: boolean, - profile: profileEntity, - mentees: Mentee[] + profile: Profile ) { super() this.state = state @@ -44,7 +44,6 @@ class Mentor extends BaseEntity { this.application = application this.availability = availability this.profile = profile - this.mentees = mentees } } diff --git a/src/services/admin/category.service.ts b/src/services/admin/category.service.ts index 38feafd3..811843d1 100644 --- a/src/services/admin/category.service.ts +++ b/src/services/admin/category.service.ts @@ -11,7 +11,7 @@ export const createCategory = async ( try { const categoryRepository = dataSource.getRepository(Category) - const newCategory = new Category(categoryName, []) + const newCategory = new Category(categoryName) const saveCategory = await categoryRepository.save(newCategory) diff --git a/src/services/mentee.service.ts b/src/services/mentee.service.ts index 993daab9..80bd8e68 100644 --- a/src/services/mentee.service.ts +++ b/src/services/mentee.service.ts @@ -30,6 +30,22 @@ export const addMentee = async ( } } + const userMentorProfile = await mentorRepository.findOne({ + where: { + profile: { + uuid: user.uuid + } + } + }) + + if (userMentorProfile) { + return { + statusCode: 409, + message: + 'A mentor cannot become a mentee, Please contact sustainableeducationfoundation@gmail.com' + } + } + const existingMentees: Mentee[] = await menteeRepository.find({ where: { profile: { uuid: user.uuid } } }) diff --git a/src/services/mentor.service.ts b/src/services/mentor.service.ts index 88d7ff9a..9f307de5 100644 --- a/src/services/mentor.service.ts +++ b/src/services/mentor.service.ts @@ -5,6 +5,7 @@ import { ApplicationStatus } from '../enums' import Category from '../entities/category.entity' import { getEmailContent, getMentorPublicData } from '../utils' import { sendEmail } from './admin/email.service' +import Mentee from '../entities/mentee.entity' export const createMentor = async ( user: Profile, @@ -18,6 +19,23 @@ export const createMentor = async ( try { const mentorRepository = dataSource.getRepository(Mentor) const categoryRepository = dataSource.getRepository(Category) + const menteeRepository = dataSource.getRepository(Mentee) + + const mentee = await menteeRepository.findOne({ + where: { + profile: { + uuid: user.uuid + } + } + }) + + if (mentee) { + return { + statusCode: 409, + message: + 'A mentee cannot become a mentor, Please contact sustainableeducationfoundation@gmail.com' + } + } const existingMentorApplications = await mentorRepository.find({ where: { profile: { uuid: user.uuid } } @@ -58,11 +76,10 @@ export const createMentor = async ( category, application, true, - user, - [] + user ) - await mentorRepository.save(newMentor) + const savedMentor = await mentorRepository.save(newMentor) const content = getEmailContent( 'mentor', @@ -80,7 +97,7 @@ export const createMentor = async ( return { statusCode: 201, - mentor: newMentor, + mentor: savedMentor, message: 'Mentor application is successful' } } catch (err) { @@ -116,8 +133,8 @@ export const updateAvailability = async ( message: 'Mentor availability updated successfully' } } catch (err) { - console.error('Error creating mentor', err) - throw new Error('Error creating mentor') + console.error('Error updating mentor availability', err) + throw new Error('Error updating mentor availability') } } diff --git a/src/templates/emailTemplate.ejs b/src/templates/emailTemplate.ejs index 4002377b..07475d57 100644 --- a/src/templates/emailTemplate.ejs +++ b/src/templates/emailTemplate.ejs @@ -129,8 +129,22 @@ color: #363636; " > -

- <%- message %> +

<%- message %>

+

+ To ensure that you receive our emails and they do not go + to your spam folder, please add + sustainableedufoundation@gmail.com to your email + whitelist. +

+

+ Please join our slack channel + link + to provide any feedback on the platform. You may use the + #scholarx-feedback to provide any issues in the platform + so we can quickly fix them.

Best regards,
diff --git a/src/utils.ts b/src/utils.ts index b3ab6906..c0157f6c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -8,13 +8,11 @@ import ejs from 'ejs' import { ApplicationStatus } from './enums' export const signAndSetCookie = (res: Response, uuid: string): void => { - const token = jwt.sign({ userId: uuid }, JWT_SECRET ?? '', { - expiresIn: '10h' // To-Do: Change value in production - }) + const token = jwt.sign({ userId: uuid }, JWT_SECRET ?? '') res.cookie('jwt', token, { httpOnly: true, - maxAge: 24 * 60 * 60 * 1000, + maxAge: 5 * 24 * 60 * 60 * 1000, secure: false // TODO: Set to true when using HTTPS }) } @@ -93,7 +91,7 @@ export const getEmailContent = ( subject: 'Your ScholarX Mentor Application Status', message: `Dear ${name},

Thank you very much for applying to ScholarX. Your application has been received. Our team will soon review your application, and we will keep you posted on the progress via email. - Please reach out to us via sustainableedufoundation@gmail.com for any clarifications. To ensure that you receive our emails and they do not go to your spam folder, please add sustainableedufoundation@gmail.com to your email whitelist.` + Please reach out to us via sustainableedufoundation@gmail.com for any clarifications.` } case ApplicationStatus.APPROVED: return { @@ -104,8 +102,7 @@ export const getEmailContent = ( We received a large number of qualified applicants, and after a thorough review of all candidates, we are thrilled to invite you to accept a place in our program. Your profile stood out amongst the others, and we are confident that you will contribute positively to our program.

We understand that your hard work and dedication have brought you to this moment, and we recognize your exceptional talent, experience, and potential in your respective fields. We are excited to have you join our community of learners and scholars.

We look forward to seeing the unique perspective and insights you will bring to the mentees and to the program. We believe that you will flourish in this year's edition of ScholarX, and we are thrilled to be a part of your academic or professional journey.

- Once again, congratulations on your selection! We cannot wait to have you on board. We will keep you informed on the next steps, and in the meantime would like to invite you to go through some of the resources that would be useful to thrive as a great mentor in ScholarX.

- To ensure that you receive our emails and they do not go to your spam folder, please add sustainableedufoundation@gmail.com to your email whitelist.` + Once again, congratulations on your selection! We cannot wait to have you on board. We will keep you informed on the next steps, and in the meantime would like to invite you to go through some of the resources that would be useful to thrive as a great mentor in ScholarX.` } case ApplicationStatus.REJECTED: return { @@ -115,7 +112,7 @@ export const getEmailContent = ( After careful review of your application and considering all of the candidates, we regret to inform you that we are unable to make you part of the mentor base at this time. We received a large number of qualified applicants, and unfortunately, we could only accept a limited number of mentors.

We understand that this news may be disappointing, and we encourage you not to be discouraged by this decision. Please know that this does not reflect on your abilities, potential, or value as an individual. As you progress ahead on your academic or professional journey, we would be glad to have you as a mentor for future ScholarX programs.

We appreciate your interest in our program and would like to wish you all the best in your future endeavors. We are grateful for the opportunity to consider you for our program and encourage you to keep pursuing your goals and aspirations.

- Thank you again for considering our program and for the time you invested in your application. We hope you find success and fulfillment in your academic and professional pursuits. To ensure that you receive our emails and they do not go to your spam folder, please add sustainableedufoundation@gmail.com to your email whitelist.` + Thank you again for considering our program and for the time you invested in your application. We hope you find success and fulfillment in your academic and professional pursuits. ` } default: return undefined @@ -126,7 +123,7 @@ export const getEmailContent = ( return { subject: 'Your ScholarX Mentee Application Status', message: `Dear ${name},

- Thank you very much for applying to ScholarX. Your application has been received. Mentor will soon review your application and we will keep you posted on the progress via email. Until then, read more about student experience here and reach out to us via sustainableedufoundation@gmail.com for any clarifications. To ensure that you receive our emails and they do not go to your spam folder, please add sustainableedufoundation@gmail.com to your email whitelist.` + Thank you very much for applying to ScholarX. Your application has been received. Mentor will soon review your application and we will keep you posted on the progress via email. Until then, read more about student experience here and reach out to us via sustainableedufoundation@gmail.com for any clarifications. ` } case ApplicationStatus.APPROVED: return { @@ -136,7 +133,7 @@ export const getEmailContent = ( We received a large number of qualified applicants, and after a thorough review of all candidates, we are thrilled to offer you a place in our program. Your application stood out amongst the others, and we are confident that you will contribute positively to our program.

We believe that you have great potential to succeed in your academic and professional pursuits, and we are excited to have you join our community of learners and scholars.

To emphasize the importance of completing the program, you have received a valuable opportunity. If, for any reason, you are uncertain about completing the program within the 6-month timeline, please inform our admissions team as soon as possible, so we can provide the opportunity to another deserving student.

- Once again, congratulations on your selection! We cannot wait to have you on board. To ensure that you receive our emails and they do not go to your spam folder, please add sustainableedufoundation@gmail.com to your email whitelist.` + Once again, congratulations on your selection! We cannot wait to have you on board. ` } case ApplicationStatus.REJECTED: return { @@ -146,7 +143,7 @@ export const getEmailContent = ( After a careful review of your application and considering all of the candidates, we regret to inform you that we are unable to offer you admission at this time. We received a large number of qualified applicants, and unfortunately, we could only accept a limited number of students.

However, we want to encourage you not to be discouraged by this decision. We recognize that the admissions process can be competitive, and we understand that this news may be disappointing. Please know that this does not reflect on your abilities, potential, or value as an individual.

We do offer the possibility for you to apply again next time if you meet the eligibility criteria. We invite you to stay engaged with us by attending our events, reaching out to our admissions team, and taking advantage of any opportunities to connect with our current students and alumni.

- Thank you again for considering our program and for the time you invested in your application. We wish you all the best in your future endeavours. To ensure that you receive our emails and they do not go to your spam folder, please add sustainableedufoundation@gmail.com to your email whitelist.` + Thank you again for considering our program and for the time you invested in your application. We wish you all the best in your future endeavours. ` } default: return undefined