diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7793ac01..75000b5b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,6 +10,7 @@ on: env: TOKEN_SECRET: ${{ secrets.TOKEN_SECRET }} DB_URL: ${{ secrets.DB_URL }} + ENVIRONMENT: ${{ secrets.ENVIRONMENT }} permissions: contents: read diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 00000000..a69ae896 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,13 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +# npm test +npx lint-staged + +if [ "$(uname)" == "Darwin" ]; then + npm run test +elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then + npm run test +elif [ "$(expr substr $(uname -s) 1 5)" == "MINGW" ]; then + npm run testWin +fi diff --git a/.lintstagedrc.json b/.lintstagedrc.json new file mode 100644 index 00000000..c56c2a5a --- /dev/null +++ b/.lintstagedrc.json @@ -0,0 +1,6 @@ +{ + "*.js": [ + "prettier --write", + "eslint --fix" + ] +} diff --git a/README.md b/README.md index 63e1942f..ade87511 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,9 @@ node -e "console.log(require('crypto').randomBytes(256).toString('base64')); You don't need to assign values to these parameters in double or single quotes, just write directly, .env automatically converts it into quoted string. Once you are done with this, install the packages through `npm ci` which stands for clean install. -Also, you need to run 'setup.js' file. You can do that by running following command in your terminal +Also you need to run the following command to check for you eslint and jest testcases: ``` -node setup.js +npm run prepare ``` And finally, run the server with `npm run serverstart` or `npm run serverstartWin` depending on your operating system. diff --git a/SECURITY.md b/SECURITY.md index 3db6ca96..57614503 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -6,4 +6,4 @@ The project is still in its development phase, so plase report issues only if th ## Reporting a Vulnerability -Please report (suspected) security vulnerabilities to **[me](mailto:tejasnair2002@gmail.com)**. You will probably receive a response from me within 48 hours. If the issue is confirmed, we will release a patch as soon as possible depending on complexity but historically within a few days. +Please report (suspected) security vulnerabilities to **[me](mailto:tejasnair2002@gmail.com)**. You will probably receive a response from me within 48 hours. If the issue is confirmed, we will release a patch as soon as possible depending on complexity but historically within a few days. \ No newline at end of file diff --git a/_apidoc.js b/_apidoc.js index e0aaaee1..6d4f53cc 100644 --- a/_apidoc.js +++ b/_apidoc.js @@ -214,11 +214,12 @@ * */ /** - * @api {post} /infrastructure/update Update infrastructure details + * @api {post} /infrastructure/update/:id Update infrastructure details * @apiName UpdateInfrastructure * @apiGroup Infrastructure * @apiDescription update Existing Infrastructure details * + * @apiParam {String} id The infrastructure document to update. * @apiBody {String} id Id of the infrastructure to be updated * @apiBody {String} [name] The name of the infrastructure. * @apiBody {String} [type] The type of the infrastructure. @@ -276,11 +277,12 @@ * */ /** - * @api {post} /accreditation/update update accreditation details + * @api {post} /accreditation/update/:id update accreditation details * @apiName UpdateAccreditation * @apiGroup Accreditation * @apiDescription update Existing accreditation * + * @apiParam {String} id The accreditation document to update. * @apiBody {String} id Id of the accreditation to be updated * @apiBody {String} [name] Accreditation name. * @apiBody {String} [agencyName] Agency name. @@ -361,11 +363,12 @@ * * */ /** - * @api {post} /tutorial/update Update tutorial details + * @api {post} /tutorial/update/:id Update tutorial details * @apiName UpdateTutorial * @apiGroup Tutorial * @apiDescription update Existing Tutorial details * + * @apiParam {String} id The tutorial document to update. * @apiBody {String} id Id of the tutorial to be updated * @apiBody {Number} [no] The no of tutorial. * @apiBody {String} [title] The title of tutorial. @@ -473,11 +476,12 @@ * */ /** - * @api {post} /department/update Update department + * @api {post} /department/update/:id Update department * @apiName UpdateDepartment * @apiGroup Department - * @apiDescription Update Existing Department details except [yearOfStarting],[acronym] + * @apiDescription Update Existing Department details except yearOfStarting, acronym * + * @apiParam {String} id The department document to update. * @apiSuccess {String} department._id ID of document given by database. * @apiSuccess {String} department.name Name of Infrastructure * @apiSuccess {String} department.acronym The acronym of the Department. @@ -548,11 +552,12 @@ */ /** - * @api {post} /timetable/update Update Timetable + * @api {post} /timetable/update/:id Update Timetable * @apiName UpdateTimetable * @apiGroup Timetable * @apiDescription Update existing timetable data. * + * @apiParam {String} id The timetable document to update. * @apiBody {String} id ID of the timetable to be updated. * @apiBody {Date} [startDate] Start date of the timetable. * @apiBody {Date} [endDate] End date of the timetable. @@ -568,11 +573,12 @@ */ /** - * @api {post} /coursework/update Update Coursework + * @api {post} /coursework/update/:id Update Coursework * @apiName UpdateCoursework * @apiGroup Coursework * @apiDescription Update existing coursework data. * + * @apiParam {String} id The coursework document to update. * @apiBody {String} id ID of the Coursework to be updated. * @apiBody {ObjectId} student ID of the student (ObjectId). * @apiBody {String} Coursework type that is either onCampus or offCampus. @@ -666,6 +672,116 @@ * attainment as per Bloom's Taxanomy (L1-L6). */ +// ------------------------------------------------------------------------------------------ +// Attendance. +// ------------------------------------------------------------------------------------------ + +/** + * @api {post} /attendance/add Add Attendance + * @apiName AddAttendance + * @apiGroup Attendance + * @apiDescription Add a new attendance. + * + * @apiBody {String} student Student name. + * @apiBody {String} course Course name. + * @apiBody {Number} monthlyAttended Monthly attendance of student. + * @apiBody {Number} monthlyOccured Monthly occured. + * @apiBody {Number} cumulativeAttended sum of attendance of student. + * @apiBody {Number} cumulativeOccured sum of occured. + * + * @apiSuccess {String} res Response message. + * @apiError (Error 500) UserNotFound The of the User was not found + * + * @apiSuccessExample Success-Response: + * HTTP/1.1 200 OK + * { + * "res": "added attendance Example Attendance" + * } + * + * @apiErrorExample Error-Response: + * HTTP/1.1 500 Internal Server Error + * { + * "err": "Error while inserting in DB" + * } + */ + +// ------------------------------------------------------------------------------------------ +// Exam. +// ------------------------------------------------------------------------------------------ + +/** + * @api {post} /exam/add Add Exam + * @apiName AddExam + * @apiExam Exam + * @apiDescription Add a new exam. + * + * @apiBody {String} title Exam title. + * @apiBody {ObjectId[]} students Array of student ObjectIDs. + * + * @apiSuccess {String} res Response message. + * @apiError (Error 500) ExamAddError Error while adding the exam + * + * @apiSuccessExample Success-Response: + * HTTP/1.1 200 OK + * { + * "res": "added exam Example Exam" + * } + * + * @apiErrorExample Error-Response: + * HTTP/1.1 500 Internal Server Error + * { + * "err": "Error while inserting in DB" + * } + */ + +/** + * @api {post} /module/add Add Module + * @apiName AddModule + * @apiGroup Module + * + * @apiBody {Number} [no] Module number. + * @apiBody {String} [name] Name of the module. + * @apiBody {String} [outcome] Module outcome. + * @apiBody {String[]} [contents] Array of contents of the module. + * @apiBody {Number} [hrsPerModule] Number of hours required per module. + * @apiBody {String[]} [cognitiveLevels] Array of cognitive levels + * of attainment as per Bloom's Taxanomy (L1-L6). + * + * @apiSuccess {String} res added Module + * @apiError (Error 500) Error while inserting in DB + */ + +/** + * @api {delete} /module/delete/:moduleId Delete Module + * @apiName DeleteModule + * @apiGroup Module + * + * @apiParam {String} moduleId The ID of the Module document to delete. + * + * @apiSuccess {String} res Success message indicating the deletion. + * + * @apiError (Error 500) DatabaseError Error message if there was an error during the deletion. + */ + +/** + * @api {post} /module/update/:moduleId Update Module + * @apiName UpdateModule + * @apiGroup Module + * @apiDescription Update existing module data. + * + * @apiParam {String} moduleId The ID of the Module document to update. + * @apiBody {Number} [no] Module number. + * @apiBody {String} [name] Name of the module. + * @apiBody {String} [outcome] Module outcome. + * @apiBody {String[]} [contents] Array of contents of the module. + * @apiBody {Number} [hrsPerModule] Number of hours required per module. + * @apiBody {String[]} [cognitiveLevels] Array of cognitive levels + * of attainment as per Bloom's Taxanomy (L1-L6). + * + * @apiSuccess {String} res Module updated. + * @apiError (Error 500) DatabaseError Error in updating the database. + */ + //----------------------------------------------------------------------------- // Organization //----------------------------------------------------------------------------- @@ -674,12 +790,12 @@ * @api {get} /organization/list Get Organisation List * @apiName GetOrganizationList * @apiGroup Organization - * + * * @apiQuery [parent] Id of the parent of the organization * @apiQuery [startDate] starting date of the organization * @apiQuery [name] name of the organization * @apiQuery [accreditations] accreditation Id of the organization - * + * * @apiSuccess {Orgaization[]} res array of filtered organization Doc * @apiSuccess {ObjectId} organization.parent Id of the parent of the organization * @apiSuccess {Date} organization.startDate starting date of the organization @@ -691,12 +807,12 @@ * @api {post} /organization/add Add Organisation * @apiName AddOrganization * @apiGroup Organization - * + * * @apiBody {ObjectId} [parent] Id of the parent of the organization * @apiBody {Date} [startDate] starting date of the organization * @apiBody {String} [name] name of the organization * @apiBody {ObjectId} [accreditations] accreditation Id of the organization - * + * * @apiSuccess {String} res added organization * @apiError (Error 500) Error while inserting in DB */ @@ -705,7 +821,7 @@ * @api {delete} /organization/delete/:organizationId Delete Organization * @apiName DeleteOrganization * @apiGroup Organization - * + * * @apiParam {String} organizationId The ID of the Organization document to delete. * * @apiSuccess {String} res Success message indicating the deletion. @@ -763,7 +879,7 @@ * @apiDescription Remove the existing Paper. * @apiGroup Paper * - * @apiParam {String} answersheetID The ID of the answersheet to delete. + * @apiParam {String} id The ID of the Paper document to delete. * * @apiSuccess {String} res Paper deleted successfully. * @@ -777,7 +893,7 @@ /** * @api {post} /assignment/add Add assignment * @apiName Addassignment - * @apiGroup assignment + * @apiGroup Assignment * @apiDescription Add a new assignment. * * @apiBody {String} no Assignment number. @@ -800,6 +916,20 @@ * "err": "Error while inserting in DB" * } */ + +/** + * @api {delete} /attendance/delete/:attendanceId To delete Attendance + * @apiName DeleteAttendance + * @apiGroup Attendance + * + * @apiParam {String} attendanceId The ID of the attendance document to delete. + * + * @apiSuccess {String} res Success message indicating the deletion. + * + * @apiError (Error 500) err Error message if there was an error during the deletion. + * +* */ + // ------------------------------------------------------------------------------------------ // Practical. // ------------------------------------------------------------------------------------------ @@ -849,6 +979,7 @@ * @apiName UpdatePractical * @apiGroup Practical * + * @apiParam {String} id The ID of the Practical document to delete. * @apiBody {String} id ID of the Practical entity to update. * @apiBody {Number} [no] New Practical number. * @apiBody {String} [title] New title. @@ -928,6 +1059,18 @@ * } */ +/** + * @api {delete} /exam/delete/:id Delete Exam + * @apiName DeleteExam + * @apiExam Exam + * + * @apiParam {ObjectId} id The ObjectID of the exam to delete. + * + * @apiSuccess {String} res Success message indicating the deletion. + * @apiError (Error 500) ExamDeleteError Error while deleting the exam + * + */ + /** * @api {delete} /assignment/delete/:assignmentId To delete Assignment * @apiName DeleteAssignment @@ -942,11 +1085,30 @@ * */ /** - * @api {post} /paper/update/ Update Paper + * @api {post} /attendance/update update attendance details + * @apiName UpdateAttendance + * @apiGroup Attendance + * @apiDescription update Existing attendance + * + * @apiBody {String} [student] Student name. + * @apiBody {String} [course] Course name. + * @apiBody {Number} [monthlyAttended] Monthly attendance of student. + * @apiBody {Number} [monthlyOccured] Monthly occured. + * @apiBody {Number} [cumulativeAttended] sum of attendance of student. + * @apiBody {Number} [cumulativeOccured] sum of occured. + * + * @apiSuccess {String} res Attendance updated. + * @apiError (Error 500) err Error in updating database + * + */ + +/** + * @api {post} /paper/update/:id Update Paper * @apiName UpdatePaper * @apiGroup Paper - * @apiDescription Update Existing Paper details except + * @apiDescription Update Existing Paper details except * + * @apiParam {String} id The paper document to update. * @apiSuccess {Paper[]} res Array of Filtered Paper Doc . * @apiSuccess {String} paper._id ID of paper given by database. * @apiSuccess {String} paper.answersheetID Name of Infrastructure @@ -954,29 +1116,66 @@ * @apiSuccess {connector.Schema.Types.ObjectId} paper.student associated Student. * @apiSuccess {connector.Schema.Types.ObjectId} paper.faculty associated Faculty. * @apiSuccess {Number} paper.marks The marks in the Paper. - * + * * @apiSuccess {String} res Paper updated successfully. - * + * * @apiError (Error 500) err Error while updating the data.s */ /** - * @api {post} /assignment/update update assignment details + * @api {post} /assignment/update/:id update assignment details * @apiName UpdateAssignment * @apiGroup Assignment * @apiDescription update Existing assignment * + * @apiParam {String} id The assignment document to update. * @apiBody {String} id Id of the assignment to be updated * @apiBody {String} [no] Assignment number. * @apiBody {String} [title] assignment title. * @apiBody {String} [type] type of assignment. - * @apiBody {Number} [marks] marks in assignment. + * @apiBody {Number} [marks] marks in assignment. * * @apiSuccess {String} res Assignment updated. * @apiError (Error 500) err Error in updating database * */ +/** + * @api {get} attendance/list Get Attendance List + * @apiName GetAttendance + * @apiGroup Attendance + * + * @apiBody {String} [student] Student name. + * @apiBody {String} [course] Course name. + * @apiBody {Number} [monthlyAttended] Monthly attendance of student. + * @apiBody {Number} [monthlyOccured] Monthly occured. + * @apiBody {Number} [cumulativeAttended] sum of attendance of student. + * @apiBody {Number} [cumulativeOccured] sum of occured. + * + * @apiSuccess {attendance[]} res Array of Filtered attendance Doc. + * @apiSuccess {String} attendance._id ID of document given by database. + * @apiSuccess {String} attendance.student Name of student. + * @apiSuccess {String} attendance.course Name of course. + * @apiSuccess {Number} attendance.monthlyAttended Monthly attendance of student. + * @apiSuccess {Number} attendance.cumulativeAttended sum of attendance of student. + * @apiSuccess {Number} attendance.cumulativeOccured sum of occured. + */ + +/** + * @api {post} /exam/update/:id Update Exam Details + * @apiName UpdateExam + * @apiExam Exam + * @apiDescription Update existing exam details. + * + * @apiParam {ObjectId} id The ObjectID of the exam to update. + * @apiBody {String} [title] Exam title. + * @apiBody {ObjectId[]} [students] Array of student ObjectIDs. + * + * @apiSuccess {String} res Exam updated. + * @apiError (Error 500) ExamUpdateError Error in updating database + * + */ + /** * @api {get} assignment/list Get Assignment List * @apiName GetAssignment @@ -985,14 +1184,14 @@ * @apiBody {String} [no] Number of assignment. * @apiBody {String} [title] Title of assignment. * @apiBody {String} [type] type of assignment. - * @apiBody {Number} [marks] marks in assignment. + * @apiBody {Number} [marks] marks in assignment. * * @apiSuccess {assignment[]} res Array of Filtered assignment Doc. * @apiSuccess {String} assignment._id ID of document given by database. * @apiBody {String} [no] Number of assignment. * @apiBody {String} [title] Title of assignment. * @apiBody {String} [type] type of assignment. - * @apiBody {Number} [marks] marks in assignment. + * @apiBody {Number} [marks] marks in assignment. */ // ------------------------------------------------------------------------------------------ @@ -1035,17 +1234,18 @@ */ /** - * @api {update} /semester/update/:id Request to list Semester information + * @api {update} /semester/update/:id Request to update Semester information * @apiName Updatesemester * @apiGroup Semester * + * @apiParam {String} id The ID of the Semester document to update. * @apiBody {Number} [number] Number of semester * @apiBody {String} [academicYear] To show the current academic year * @apiBody {String} [type] Stores the enum ODD or EVEN for semester * @apiBody {Date} [startDate] Start date of the semester * @apiBody {Date} [endDate] End date of the semester * - *@apiSuccess {String} res Semester updated. + * @apiSuccess {String} res Semester updated. * @apiError (Error 500) DatabaseError Error in updating the database. * */ @@ -1127,6 +1327,19 @@ * */ +/** + * @api {get} /exam/list Get Exam List + * @apiName GetExamList + * @apiExam Exam + * + * @apiQuery {String} [title] Title of the exam. + * + * @apiSuccess {Exam[]} res Array of filtered exam documents. + * @apiSuccess {ObjectId} exam._id ObjectID of the exam document in the database. + * @apiSuccess {String} exam.title Title of the exam. + * @apiSuccess {ObjectId[]} exam.students Array of student ObjectIDs in the exam. + */ + /** * @api {get} /group/list Get Group List * @apiName GetGroupList @@ -1155,13 +1368,13 @@ * @api {post} /organization/update/:organizationId Update Organisation * @apiName UpdateOrganization * @apiGroup Organization - * - * @apiBody {String} organizationId The ID of the Organization document to update + * + * @apiParam {String} organizationId The ID of the organization document to update. * @apiBody {ObjectId} [parent] Id of the parent of the organization * @apiBody {Date} [startDate] starting date of the organization * @apiBody {String} [name] name of the organization * @apiBody {ObjectId} [accreditations] accreditation Id of the organization - * + * * @apiSuccess {String} res organization updated * @apiError (Error 500) Error while inserting in DB */ @@ -1171,7 +1384,7 @@ * @apiName DeleteActivity * @apiGroup Activity * - * @apiParam {String} Activity The activity document to delete. + * @apiParam {String} activity The activity document to delete. * * @apiSuccess {String} res Success message indicating the deletion. * @@ -1179,11 +1392,12 @@ */ /** - * @api {post} /timetable/update Update Timetable + * @api {post} /activity/update/:id Update Activity * @apiName UpdateTimetable * @apiGroup Timetable * @apiDescription Update existing timetable data. * + * @apiParam {String} id The timetable document to update. * @apiBody {Date} startTime The startTime of the activity. * @apiBody {Number} duration The duration of the activity (in minutes). * @apiBody {ObjectId} course The course of the activity (ObjectId). @@ -1197,11 +1411,12 @@ */ /** - * @api {post} /activity/update Update Activity. + * @api {post} /activity/update/:id Update Activity. * @apiName UpdateActivity * @apiGroup Activity * @apiDescription Update existing activity data. * + * @apiParam {String} id The activity document to update. * @apiBody {Date} startTime The startTime of the activity. * @apiBody {Number} duration The duration of the activity (in minutes). * @apiBody {ObjectId} course The course of the activity (ObjectId). @@ -1236,7 +1451,7 @@ * @apiSuccess {String} type The type of activity.One of possible LECTURE, PRACTICAL, TUTORIAL. * @apiSuccess {ObjectId} task The task of the activity (ObjectId).One of possible Topic,Practical,Tutorial. * @apiSuccess {ObjectId} group The group of the activity (ObjectId). - * @apiSucess {ObjectId} students the students who gonna attend the activity(ObjectId). + * @apiSuccess {ObjectId} students the students who gonna attend the activity(ObjectId). */ /** @@ -1260,7 +1475,7 @@ * @apiSuccess {String} type The type of activity.One of possible LECTURE, PRACTICAL, TUTORIAL. * @apiSuccess {ObjectId} task The task of the activity (ObjectId).One of possible Topic,Practical,Tutorial. * @apiSuccess {ObjectId} group The group of the activity (ObjectId). - * @apiSucess {ObjectId} students the students who gonna attend the activity(ObjectId). + * @apiSuccess {ObjectId} students the students who gonna attend the activity(ObjectId). */ // ------------------------------------------------------------------------------------------ @@ -1310,11 +1525,12 @@ */ /** - * @api {post} /student/update Update Student + * @api {post} /student/update/:id Update Student * @apiName UpdateStudent * @apiGroup Student * @apiDescription Update existing student data. * + * @apiParam {String} id The student document to update. * @apiBody {String} ERP ID of the student. * @apiBody {String} name of the student. * @apiBody {Number} joining year of the student. @@ -1349,4 +1565,313 @@ * @apiSuccess {String} student.division of the student. * @apiSuccess {Number} student.roll no of the student. * @apiSuccess {ObjectId} student.coursesOpted by the student(ObjectId). - */ + */ + +// ------------------------------------------------------------------------------------------ +// notification +// ------------------------------------------------------------------------------------------ + +/** + * @api {post} /notification/add Add Notification + * @apiName AddNotification + * @apiGroup Notification + * @apiDescription Adds a new notification to the system. + * + * @apiBody {String} data Notification data. + * @apiBody {String} title Notification title. + * @apiBody {String} from User ID of the sender (Faculty). + * @apiBody {String} type Notification type (Student/Faculty). + * @apiBody {String[]} filter Array of targeted User IDs. + * + * @apiSuccess {String} res Success message with the ID of the added notification. + * + * @apiError (Error 500) DatabaseError Error while inserting in the database. + * + */ + +/** + * @api {get} /notification/list Get Notification List + * @apiName GetNotification + * @apiGroup Notification + * + * @apiQuery {String} [from] User ID of the sender (Faculty). + * @apiQuery {String} [type] Notification type (Student/Faculty). + * @apiQuery {String} [title] notification title. + * @apiQuery {String} [data] notification data. + * @apiQuery {String[]} [filter] array of targeted User IDs. + * + * @apiSuccess {Notification[]} res Array of filtered Notification documents. + * @apiSuccess {String} notification._id ID of the document given by the database. + * @apiSuccess {String} notification.data Notification data. + * @apiSuccess {String} notification.title Notification title. + * @apiSuccess {String} notification.from User ID of the sender (Faculty). + * @apiSuccess {String} notification.type Notification type (Student/Faculty). + * @apiSuccess {String[]} notification.filter Array of targeted User IDs. + */ + +/** + * @api {delete} /notification/delete/:notificationId Delete Notification + * @apiName DeleteNotification + * @apiGroup Notification + * + * @apiParam {String} notificationId The ID of the notification document to delete. + * + * @apiSuccess {String} res Success message indicating the deletion. + * + * @apiError (Error 500) err Error message if there was an error during the deletion. + */ + +/** + * @api {post} /notification/update Update Notification Details + * @apiName UpdateNotification + * @apiGroup Notification + * + * @apiBody {String} id ID of the notification to be updated. + * @apiBody {String} [data] Updated notification data. + * @apiBody {String} [title] Updated notification title. + * @apiBody {String} [from] Updated User ID of the sender (Faculty). + * @apiBody {String} [type] Updated notification type (Student/Faculty). + * @apiBody {String[]} [filter] Updated array of targeted User IDs. + * + * @apiSuccess {String} res Notification updated. + * @apiError (Error 500) err Error in updating the database. + +// ------------------------------------------------------------------------------------------ +// Topic. +// ------------------------------------------------------------------------------------------ + +/** + * @api {post} /topic/add Add topic + * @apiName AddTopic + * @apiGroup Topic + * @apiDescription Add a new Topic. + * + * @apiBody {String} Title of the content(topic). + * + * @apiSuccess {String} res Response message. + * @apiError (Error 500) DatabaseError Err message if there is an error inserting into the database. + * + * @apiSuccessExample Success-Response: + * HTTP/1.1 200 OK + * { + * "res": "Added topic" + * } + * + * @apiErrorExample Error-Response: + * HTTP/1.1 500 Internal Server Error + * { + * "err": "Error while inserting in DB" + * } + */ + +// ------------------------------------------------------------------------------------------ +// Faculty +// ------------------------------------------------------------------------------------------ +/** + * @api {post} /faculty/add Add Faculty + * @apiName AddFaculty + * @apiGroup Faculty + * @apiDescription Add a new faculty member. + * + * @apiBody {String} ERPID Employee ID of the faculty. + * @apiBody {Date} dateOfJoining Date of joining the institution. + * @apiBody {Date} dateOfLeaving Date of leaving the institution. + * @apiBody {String} profileLink Link to faculty member's profile. + * @apiBody {String[]} qualifications List of qualifications. + * @apiBody {Number} totalExperience Total years of experience. + * @apiBody {String[]} achievements List of achievements. + * @apiBody {String[]} areaOfSpecialization List of areas of specialization. + * @apiBody {Number} papersPublishedPG Number of papers published at the PG level. + * @apiBody {Number} papersPublishedUG Number of papers published at the UG level. + * @apiBody {ObjectId} department ID of the department (ObjectId). + * @apiBody {ObjectId[]} preferredSubjects List of preferred subjects (ObjectId). + * @apiBody {String[]} designation Faculty member's designation (one of the possible values: "HOD", "Assistant Professor", "Associate Professor", "Activity Head"). + * @apiBody {String} natureOfAssociation Nature of association with the institution (one of the possible values: "Regular", "Contract", "Adjunct"). + * @apiBody {String} additionalResponsibilities Additional responsibilities of the faculty. + * + * @apiSuccess {String} res Response message. + * @apiError (Error 500) DatabaseError Err message if there is an error inserting into the database. + * + * @apiSuccessExample Success-Response: + * HTTP/1.1 200 OK + * { + * "res": "Added faculty" + * } + * + * @apiErrorExample Error-Response: + * HTTP/1.1 500 Internal Server Error + * { + * "err": "Error while inserting in DB" + * } + */ + +/** + * @api {delete} /topic/delete/:topicId Delete Topic + * @apiName DeleteTopic + * @apiGroup Topic + * + * @apiParam {String} topicId The ID of the Topic document to delete. + * + * @apiSuccess {String} res Success message indicating the deletion. + * + * @apiError (Error 500) DatabaseError Error message if there was an error during the deletion. + */ + +/** + * @api {delete} /faculty/delete/:facultyId Delete Faculty + * @apiName DeleteFaculty + * @apiGroup Faculty + * + * @apiParam {String} facultyId The ID of the faculty member to delete. + * + * @apiSuccess {String} res Success message indicating the deletion. + * + * @apiError (Error 500) DatabaseError Error message if there was an error during the deletion. + */ + +/** + * @api {post} /topic/update/:id Update Topic + * @apiName UpdateTopic + * @apiGroup Topic + * @apiDescription Update existing topic data. + * + * @apiParam {String} id The topic document to update. + * + * @apiSuccess {String} res Topic updated. + * @apiError (Error 500) DatabaseError Error in updating the database. + */ + +/** + * @api {post} /faculty/update/:id Update Faculty + * @apiName UpdateFaculty + * @apiGroup Faculty + * @apiDescription Update existing faculty member's data. + * + * @apiParam {String} id The faculty member's document to update. + * @apiBody {String} id ID of the faculty member to be updated. + * @apiBody {String} ERPID Employee ID of the faculty. + * @apiBody {Date} dateOfJoining Date of joining the institution. + * @apiBody {Date} dateOfLeaving Date of leaving the institution. + * @apiBody {String} profileLink Link to faculty member's profile. + * @apiBody {String[]} qualifications List of qualifications. + * @apiBody {Number} totalExperience Total years of experience. + * @apiBody {String[]} achievements List of achievements. + * @apiBody {String[]} areaOfSpecialization List of areas of specialization. + * @apiBody {Number} papersPublishedPG Number of papers published at the PG level. + * @apiBody {Number} papersPublishedUG Number of papers published at the UG level. + * @apiBody {ObjectId} department ID of the department (ObjectId). + * @apiBody {ObjectId[]} preferredSubjects List of preferred subjects (ObjectId). + * @apiBody {String[]} designation Faculty member's designation (one of the possible values: "HOD", "Assistant Professor", "Associate Professor", "Activity Head"). + * @apiBody {String} natureOfAssociation Nature of association with the institution (one of the possible values: "Regular", "Contract", "Adjunct"). + * @apiBody {String} additionalResponsibilities Additional responsibilities of the faculty. + * + * @apiSuccess {String} res Faculty member's data updated. + * @apiError (Error 500) DatabaseError Error in updating the database. + */ + +/** + * @api {get} /topic/list Get Topic List + * @apiName GetTopicList + * @apiGroup Topic + * + * @apiQuery {String} Title of the content(topic). + * + * @apiSuccess {Topic[]} res Array of filtered topic documents. + * @apiSuccess {String} topic._id ID of the topic document given by the database. + */ + +/** + * @api {get} /faculty/list Get Faculty List + * @apiName GetFacultyList + * @apiGroup Faculty + * + * @apiQuery {String} ERPID Employee ID of the faculty. + * @apiQuery {Date} dateOfJoining Date of joining the institution. + * @apiQuery {Date} dateOfLeaving Date of leaving the institution. + * @apiQuery {String} profileLink Link to faculty member's profile. + * @apiQuery {String[]} qualifications List of qualifications. + * @apiQuery {Number} totalExperience Total years of experience. + * @apiQuery {String[]} achievements List of achievements. + * @apiQuery {String[]} areaOfSpecialization List of areas of specialization. + * @apiQuery {Number} papersPublishedPG Number of papers published at the PG level. + * @apiQuery {Number} papersPublishedUG Number of papers published at the UG level. + * @apiQuery {ObjectId} department ID of the department (ObjectId). + * @apiQuery {ObjectId[]} preferredSubjects List of preferred subjects (ObjectId). + * @apiQuery {String[]} designation Faculty member's designation (one of the possible values: "HOD", "Assistant Professor", "Associate Professor", "Activity Head"). + * @apiQuery {String} natureOfAssociation Nature of association with the institution (one of the possible values: "Regular", "Contract", "Adjunct"). + * @apiQuery {String} additionalResponsibilities Additional responsibilities of the faculty. + * + * @apiSuccess {Faculty[]} res Array of filtered faculty member documents. + * @apiSuccess {String} faculty._id ID of the faculty member document given by the database. + * @apiSuccess {String} faculty.ERPID Employee ID of the faculty. + * @apiSuccess {Date} faculty.dateOfJoining Date of joining the institution. + * @apiSuccess {Date} faculty.dateOfLeaving Date of leaving the institution. + * @apiSuccess {String} faculty.profileLink Link to faculty member's profile. + * @apiSuccess {String[]} faculty.qualifications List of qualifications. + * @apiSuccess {Number} faculty.totalExperience Total years of experience. + * @apiSuccess {String[]} faculty.achievements List of achievements. + * @apiSuccess {String[]} faculty.areaOfSpecialization List of areas of specialization. + * @apiSuccess {Number} faculty.papersPublishedPG Number of papers published at the PG level. + * @apiSuccess {Number} faculty.papersPublishedUG Number of papers published at the UG level. + * @apiSuccess {ObjectId} faculty.department ID of the department. + * @apiSuccess {ObjectId[]} faculty.preferredSubjects List of preferred subjects. + * @apiSuccess {String[]} faculty.designation Faculty member's designation. + * @apiSuccess {String} faculty.natureOfAssociation Nature of association with the institution. + * @apiSuccess {String} faculty.additionalResponsibilities Additional responsibilities of the faculty. + */ + +//------------------------------------------------------------------------------------------ +// Topics. +// ------------------------------------------------------------------------------------------ + +/** + * @api {post} /topic/add Add Topic + * @apiName AddTopic + * @apiGroup Topic + * + * @apiBody {String} title The title of topic. + * + * @apiSuccess {String} res Success message with the ID of the added topic. + * + * @apiError (Error 500) DatabaseError Error while inserting in the database. + * + * @apiDescription Adds a new topic to the system. + */ + +/** + * @api {get} topic/list Get Topic List + * @apiName GetTopic + * @apiGroup Topic + * + * @apiQuery {String} [title] Title of Topic. + * + * @apiSuccess {String} topic.title Title of Topic. + */ + +/** + * @api {delete} /topic/delete/:topicId Delete Topic + * @apiName DeleteTopic, + * @apiGroup Topic + * + * @apiParam {String} topicId The ID of the topic document to delete. + * + * @apiSuccess {String} res Success message indicating the deletion. + * + * @apiError (Error 500) err Error message if there was an error during the deletion. + * +* */ +/** + * @api {post} /topic/update/:id Update topic details + * @apiName UpdateTopic + * @apiGroup Topic + * @apiDescription update Existing Topic details + * + * @apiParam {String} id The topic document to update. + * @apiBody {String} id Id of the topic to be updated + * @apiBody {String} [title] The title of topic. + + * + * @apiSuccess {String} res topic updated. + * @apiError (Error 500) err Error in updating database + * + */ diff --git a/app.js b/app.js index 3fb76827..856457f8 100644 --- a/app.js +++ b/app.js @@ -23,8 +23,13 @@ import moduleRouter from "#routes/module"; import facultyRouter from "#routes/faculty"; import { identifyUser } from "#middleware/identifyUser"; import departmentRouter from "#routes/department"; +import attendanceRouter from "#routes/attendance"; +import examRouter from "#routes/exam"; import paperRouter from "#routes/paper"; import groupRouter from "#routes/group"; +import performarouter from "#routes/performance"; +import notificationRouter from "#routes/notification"; +import topicRouter from "#routes/topic"; const app = express(); const currDirName = dirname(fileURLToPath(import.meta.url)); @@ -58,9 +63,14 @@ app.use("/timetable", timetableRouter); app.use("/department", departmentRouter); app.use("/coursework", courseworkRouter); app.use("/module", moduleRouter); +app.use("/attendance", attendanceRouter); +app.use("/exam", examRouter); app.use("/paper", paperRouter); app.use("/group", groupRouter); app.use("/semester", semesterRouter); app.use("/faculty", facultyRouter); +app.use("/performance", performarouter); +app.use("/notification", notificationRouter); +app.use("/topic",topicRouter); export default app; diff --git a/backup/erpbackup.js b/backup/erpbackup.js new file mode 100644 index 00000000..4708343d --- /dev/null +++ b/backup/erpbackup.js @@ -0,0 +1,43 @@ +import { spawn } from "child_process"; +// import { error } from "console"; +import path from "path"; +// import { exit } from "process"; +import cron from "node-cron"; + +const databasename = "test"; +// in future it will be replaced by the actual databasename + +const archivedPath = path.join(path.resolve(), "..", `${databasename}.gzip`); + +// console.log(archivedPath); + +// erpBackup(); + +function erpBackup() { + const childProcess1 = spawn("mongodump", [ + `--db=${databasename}`, + `--archive=${archivedPath}`, + "--gzip", + ]); + childProcess1.stdout.on("data", (data) => { + console.log("stdout:\n", Buffer.from(data).toString()); + }); + childProcess1.stderr.on("data", (data) => { + console.log("stderr:\n", Buffer.from(data).toString()); + }); + childProcess1.on("error", (error) => { + console.log(error); + }); + childProcess1.on("exit", (code, signal) => { + if (code) { + console.log("process ends with a code:", code); + } else if (signal) { + console.log("process ends with a signal:", signal); + } else { + console.log("process ends successfully"); + } + }); +} +// backup after every 24 hour +// cron.schedule("0 0 * * *", () => erpBackup()); +cron.schedule("*/10 * * * * *", () => erpBackup()); diff --git a/backup/erprestore.js b/backup/erprestore.js new file mode 100644 index 00000000..467d8871 --- /dev/null +++ b/backup/erprestore.js @@ -0,0 +1,41 @@ +import { spawn } from "child_process"; +// import { error } from "console"; +import path from "path"; +// import { exit } from "process"; + +const databasename = "test"; +// in future it will be replaced by the actual databasename + +const archivedPath = path.join(path.resolve(), "..", `${databasename}.gzip`); + +// console.log(archivedPath); + +// erpBackup(); + +function erpRestore() { + const childProcess1 = spawn("mongorestore", [ + `--db=${databasename}`, + `--archive=${archivedPath}`, + "--gzip", + ]); + childProcess1.stdout.on("data", (data) => { + console.log("stdout:\n", Buffer.from(data).toString()); + }); + childProcess1.stderr.on("data", (data) => { + console.log("stderr:\n", Buffer.from(data).toString()); + }); + childProcess1.on("error", (error) => { + console.log(error); + }); + childProcess1.on("exit", (code, signal) => { + if (code) { + console.log("process ends with a code:", code); + } else if (signal) { + console.log("process ends with a signal:", signal); + } else { + console.log("Database Restored successfully"); + } + }); +} + +erpRestore(); diff --git a/controller/accreditation.js b/controller/accreditation.js index d643255d..bebaeea1 100644 --- a/controller/accreditation.js +++ b/controller/accreditation.js @@ -1,16 +1,25 @@ import { - addNewAccreditation, deleteAccreditationById, updateAccreditationById, getAccreditations, + addNewAccreditation, + deleteAccreditationById, + updateAccreditationById, + getAccreditations, } from "#services/accreditation"; import { logger } from "#util"; async function addAccreditation(req, res) { - const { - name, agencyName, dateofAccreditation, dateofExpiry, - } = req.body; + const { name, agencyName, dateofAccreditation, dateofExpiry } = req.body; try { // eslint-disable-next-line max-len - const accreditation = await addNewAccreditation(name, agencyName, dateofAccreditation, dateofExpiry); - res.json({ res: `added accreditation ${accreditation.name}`, id: accreditation.id }); + const accreditation = await addNewAccreditation( + name, + agencyName, + dateofAccreditation, + dateofExpiry, + ); + res.json({ + res: `added accreditation ${accreditation.name}`, + id: accreditation.id, + }); } catch (error) { logger.error("Error while inserting", error); res.status(500); @@ -31,9 +40,7 @@ async function deleteAccreditation(req, res) { async function updateAccreditation(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updateAccreditationById(id, data); @@ -47,7 +54,9 @@ async function updateAccreditation(req, res) { async function showAccreditation(req, res) { try { - const accreditation = await getAccreditations(req.query); + const filter = req.body; + const { limit, page } = req.query; + const accreditation = await getAccreditations(filter, limit, page); return res.json({ res: accreditation }); } catch (error) { logger.error("Error while fetching", error); @@ -57,5 +66,8 @@ async function showAccreditation(req, res) { } export default { - addAccreditation, updateAccreditation, deleteAccreditation, showAccreditation, + addAccreditation, + updateAccreditation, + deleteAccreditation, + showAccreditation, }; diff --git a/controller/activity.js b/controller/activity.js index 2e1ceb35..a2762674 100644 --- a/controller/activity.js +++ b/controller/activity.js @@ -1,64 +1,86 @@ import { - createActivity,deleteActivityById, activityList ,updateActivityById, -}from "#services/activity"; -import {logger} from "#util" ; + createActivity, + deleteActivityById, + activityList, + updateActivityById, +} from "#services/activity"; +import { logger } from "#util"; -async function addActivity(req,res) { - const{ - activityBlueprint, - startTime, - duration, - course, - faculty, - type, - task, - group, - students, - }=req.body; - try{ - const newActivity = await createActivity(activityBlueprint,startTime,duration,course,faculty,type,task,group,students); - res.json ({res: `added activity ${newActivity.id}`, id: newActivity.id}); - } catch (error){ - logger.error ("Error while inserting",error); - res.status(500); - res.json({err:"Error while inserting in DB"}); - } +async function addActivity(req, res) { + const { + activityBlueprint, + startTime, + duration, + course, + faculty, + type, + task, + group, + students, + } = req.body; + try { + const newActivity = await createActivity( + activityBlueprint, + startTime, + duration, + course, + faculty, + type, + task, + group, + students, + ); + return res.json({ + res: `added activity ${newActivity.id}`, + id: newActivity.id, + }); + } catch (error) { + logger.error("Error while inserting", error); + res.status(500); + return res.json({ err: "Error while inserting in DB" }); + } } -async function updateActivity(req,res){ - const { id }=req.params; - const { - ...data - }=req.body; - try { - await updateActivityById(id,data); - res.json({res:`updated activity with id ${id}`}); - }catch (error){ - logger.error("Error while updating",error); - res.status(500); - res.json({err:"Error while updating in DB"}); - } +async function updateActivity(req, res) { + const { id } = req.params; + const { ...data } = req.body; + try { + await updateActivityById(id, data); + return res.json({ res: `updated activity with id ${id}` }); + } catch (error) { + logger.error("Error while updating", error); + res.status(500); + return res.json({ err: "Error while updating in DB" }); + } } -async function getActivity(req,res){ - const filter = req.query; - const activitylist =await activityList(filter); - res.json({res:activitylist}); +async function getActivity(req, res) { + try { + const filter = req.body; + const { limit, page } = req.query; + const activitylist = await activityList(filter, limit, page); + return res.json({ res: activitylist }); + } catch (error) { + logger.error("Error while fetching", error); + res.status(500); + return res.json({ err: "Error while fetching the data" }); + } } - -async function deleteActivity(res,req){ - const { id }=req.params; - try{ - await deleteActivityById(id); - - res.json({res:`Deleted activity with ID ${id}`}); - }catch(error){ - logger.error ("Error while deleting",error); - res.status(500).json({error:"Error while deleting from DB"}); - } +async function deleteActivity(res, req) { + const { id } = req.params; + try { + await deleteActivityById(id); + return res.json({ res: `Deleted activity with ID ${id}` }); + } catch (error) { + logger.error("Error while deleting", error); + return res.status(500).json({ error: "Error while deleting from DB" }); + } } export default { - addActivity, deleteActivity ,getActivity ,updateActivity, -}; \ No newline at end of file + addActivity, + deleteActivity, + getActivity, + updateActivity, +}; diff --git a/controller/assignment.js b/controller/assignment.js index 221d4487..6ff363fc 100644 --- a/controller/assignment.js +++ b/controller/assignment.js @@ -1,15 +1,19 @@ import { - createAssignment, deleteAssignmentById, assignmentList, updateAssignmentById, + createAssignment, + deleteAssignmentById, + assignmentList, + updateAssignmentById, } from "#services/assignment"; import { logger } from "#util"; async function addAssignment(req, res) { - const { - no, title, type, marks, - } = req.body; + const { no, title, type, marks } = req.body; try { const newAssignment = await createAssignment(no, title, type, marks); - res.json({ res: `added assignment ${newAssignment.id}`, id: newAssignment.id }); + res.json({ + res: `added assignment ${newAssignment.id}`, + id: newAssignment.id, + }); } catch (error) { logger.error("Error while inserting", error); res.status(500); @@ -19,9 +23,7 @@ async function addAssignment(req, res) { async function updateAssignment(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updateAssignmentById(id, data); res.json({ res: `updated assignment ${id}` }); @@ -33,22 +35,31 @@ async function updateAssignment(req, res) { } async function getAssignment(req, res) { - const filter = req.query; - const assingmentlist = await assignmentList(filter); - res.json({ res: assingmentlist }); + try { + const filter = req.body; + const { limit, page } = req.query; + const assingmentlist = await assignmentList(filter, limit, page); + return res.json({ res: assingmentlist }); + } catch (error) { + logger.error("Error while fetching", error); + res.status(500); + return res.json({ err: "Error while fetching the data" }); + } } async function deleteAssignment(req, res) { const { id } = req.params; try { await deleteAssignmentById(id); - - res.json({ res: `Deleted assignment with ID ${id}` }); + return res.json({ res: `Deleted assignment with ID ${id}` }); } catch (error) { logger.error("Error while deleting", error); - res.status(500).json({ error: "Error while deleting from DB" }); + return res.status(500).json({ error: "Error while deleting from DB" }); } } export default { - addAssignment, deleteAssignment, getAssignment, updateAssignment, + addAssignment, + deleteAssignment, + getAssignment, + updateAssignment, }; diff --git a/controller/attendance.js b/controller/attendance.js new file mode 100644 index 00000000..ce86ab94 --- /dev/null +++ b/controller/attendance.js @@ -0,0 +1,82 @@ +import { + addNewAttendance, + deleteAttendanceById, + updateAttendanceById, + getAttendances, +} from "#services/attendance"; +import { logger } from "#util"; + +async function addAttendance(req, res) { + const { + student, + course, + monthlyAttended, + monthlyOccured, + cumulativeAttended, + cumulativeOccured, + } = req.body; + try { + // eslint-disable-next-line max-len + const attendance = await addNewAttendance( + student, + course, + monthlyAttended, + monthlyOccured, + cumulativeAttended, + cumulativeOccured, + ); + res.json({ + res: `added attendance ${attendance.student}`, + id: attendance.id, + }); + } catch (error) { + logger.error("Error while inserting", error); + res.status(500); + res.json({ err: "Error while inserting in DB" }); + } +} +async function deleteAttendance(req, res) { + const { id } = req.params; + try { + await deleteAttendanceById(id); + res.json({ res: "Attendance deleted successfully" }); + } catch (error) { + logger.error("Error while deleting", error); + res.status(500); + res.json({ err: "Error while deleting from DB" }); + } +} + +async function updateAttendance(req, res) { + const { id } = req.params; + const { ...data } = req.body; + + try { + await updateAttendanceById(id, data); + res.json({ res: `${id} attendance updated` }); + } catch (error) { + logger.error("Error while inserting", error); + res.status(500); + res.json({ err: "Error while inserting in DB" }); + } +} + +async function showAttendance(req, res) { + try { + const filter = req.body; + const { limit, page } = req.query; + const attendance = await getAttendances(filter, limit, page); + return res.json({ res: attendance }); + } catch (error) { + logger.error("Error while fetching", error); + res.status(500); + return res.json({ err: "Error while fetching the data" }); + } +} + +export default { + addAttendance, + updateAttendance, + deleteAttendance, + showAttendance, +}; diff --git a/controller/auth.js b/controller/auth.js index 184d21de..3dbca612 100644 --- a/controller/auth.js +++ b/controller/auth.js @@ -31,7 +31,9 @@ function validateUser(req, res) { if (req.user) { res.json({ res: req.user, msg: "user validated", err: null }); } else { - res.status(401).json({ res: null, msg: "unauthorised", err: "User not authorised" }); + res + .status(401) + .json({ res: null, msg: "unauthorised", err: "User not authorised" }); } } @@ -57,7 +59,8 @@ async function resetPassword(req, res) { } catch (error) { logger.error("Error while updating", error); res.status(500); - if (error.name === "UpdateError") res.json({ err: "Something went wrong while updating password" }); + if (error.name === "UpdateError") + res.json({ err: "Something went wrong while updating password" }); else res.json({ err: "something went wrong" }); } } else { @@ -66,5 +69,8 @@ async function resetPassword(req, res) { } export default { - validateUser, sendOTP, resetPassword, login, + validateUser, + sendOTP, + resetPassword, + login, }; diff --git a/controller/coursework.js b/controller/coursework.js index 1a6188bc..6f0cba09 100644 --- a/controller/coursework.js +++ b/controller/coursework.js @@ -10,14 +10,21 @@ import { logger } from "#util"; // Import the logger utility // Controller function to add a new Coursework entity async function addCoursework(req, res) { - const { - student, type, course, task, objectID, activity, marks, - } = req.body; + const { student, type, course, task, objectID, activity, marks } = req.body; try { const newCoursework = await createCoursework({ - student, type, course, task, objectID, activity, marks, + student, + type, + course, + task, + objectID, + activity, + marks, + }); + res.json({ + res: `Added Coursework with ID ${newCoursework.id}`, + id: newCoursework.id, }); - res.json({ res: `Added Coursework with ID ${newCoursework.id}`, id: newCoursework.id }); } catch (error) { logger.error("Error while inserting Coursework", error); res.status(500); @@ -28,9 +35,7 @@ async function addCoursework(req, res) { // Controller function to update a Coursework entity async function updateCoursework(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updateCourseworkById(id, data); res.json({ res: "/Updated Coursework/" }); @@ -43,9 +48,16 @@ async function updateCoursework(req, res) { // Controller function to get a list of Coursework entities async function getCoursework(req, res) { - const filter = req.query; - const courseworkList = await listCoursework(filter); - res.json({ res: courseworkList }); + try { + const filter = req.body; + const { limit, page } = req.query; + const courseworkList = await listCoursework(filter, limit, page); + res.json({ res: courseworkList }); + } catch (error) { + logger.error("Error while fetching", error); + res.status(500); + res.json({ err: "Error while fetching the data" }); + } } // Controller function to delete a Coursework entity diff --git a/controller/department.js b/controller/department.js index f03b190c..259d8b8f 100644 --- a/controller/department.js +++ b/controller/department.js @@ -1,17 +1,15 @@ import { - updateDepartmentbyid, createnewdepartment, listdepartment, deletedepartment, + updateDepartmentbyid, + createnewdepartment, + listdepartment, + deletedepartment, } from "#services/department"; import { logger } from "#util"; async function addDepartment(req, res) { - const { - name, - acronym, - yearOfStarting, - accreditations, - infrastructures, - } = req.body; + const { name, acronym, yearOfStarting, accreditations, infrastructures } = + req.body; try { const department = await createnewdepartment( name, @@ -47,7 +45,9 @@ async function removedepartmentbyid(req, res) { async function showdepartments(req, res) { try { - const departments = await listdepartment(req.query); + const filter = req.body; + const { limit, page } = req.query; + const departments = await listdepartment(filter, limit, page); return res.json({ res: departments, }); @@ -60,9 +60,7 @@ async function showdepartments(req, res) { async function updatedDepartment(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updateDepartmentbyid(id, data); res.json({ @@ -76,5 +74,8 @@ async function updatedDepartment(req, res) { } export default { - updatedDepartment, showdepartments, removedepartmentbyid, addDepartment, + updatedDepartment, + showdepartments, + removedepartmentbyid, + addDepartment, }; diff --git a/controller/exam.js b/controller/exam.js new file mode 100644 index 00000000..2f5c3201 --- /dev/null +++ b/controller/exam.js @@ -0,0 +1,71 @@ +import { + createExam, + deleteExamById, + examList, + updateExamById, +} from "#services/exam"; +import { logger } from "#util"; + +async function addExam(req, res) { + const { date, startTime, duration, infrastructure, supervisor, course } = + req.body; + try { + const exam = await createExam( + date, + startTime, + duration, + supervisor, + infrastructure, + course, + ); + res.json({ res: `added exam ${exam.id}`, id: exam.id }); + } catch (error) { + logger.error("Error while inserting", error); + res.status(500); + res.json({ err: "Error while inserting in DB" }); + } +} + +async function updateExam(req, res) { + const { id } = req.params; + const { ...data } = req.body; + try { + await updateExamById(id, data); + res.json({ res: `updated exam with id ${id}` }); + } catch (error) { + logger.error("Error while updating", error); + res.status(500); + res.json({ err: "Error while updaing in DB" }); + } +} + +async function getExam(req, res) { + try { + const filter = req.body; + const { limit, page } = req.query; + const exam = await examList(filter, limit, page); + res.json({ res: exam }); + } catch (error) { + logger.error("Error while fetching", error); + res.status(500); + res.json({ err: "Error while fetching the data" }); + } +} + +async function deleteExam(req, res) { + const { id } = req.params; + try { + await deleteExamById(id); + res.json({ res: `Deleted exam with ID ${id}` }); + } catch (error) { + logger.error("Error while deleting", error); + res.status(500).json({ error: "Error while deleting from DB" }); + } +} + +export default { + addExam, + deleteExam, + getExam, + updateExam, +}; diff --git a/controller/faculty.js b/controller/faculty.js index 47e17775..696ddfe6 100644 --- a/controller/faculty.js +++ b/controller/faculty.js @@ -1,5 +1,8 @@ import { - createFaculty, facultyList, deleteFacultyById, updateFacultyById, + createFaculty, + facultyList, + deleteFacultyById, + updateFacultyById, } from "#services/faculty"; import { logger } from "#util"; @@ -48,9 +51,16 @@ async function addFaculty(req, res) { } async function getFaculty(req, res) { - const filter = req.query; - const facultylist = await facultyList(filter); - res.json({ res: facultylist }); + try { + const filter = req.body; + const { limit, page } = req.query; + const facultylist = await facultyList(filter, limit, page); + res.json({ res: facultylist }); + } catch (error) { + logger.error("Error while fetching", error); + res.status(500); + res.json({ err: "Error while fetching the data" }); + } } async function deleteFaculty(req, res) { @@ -66,9 +76,7 @@ async function deleteFaculty(req, res) { } async function updateFaculty(req, res) { - const { - id, ...data - } = req.body; + const { id, ...data } = req.body; try { await updateFacultyById(id, data); res.json({ res: `updated faculty with id ${id}` }); @@ -80,5 +88,8 @@ async function updateFaculty(req, res) { } export default { - addFaculty, getFaculty, deleteFaculty, updateFaculty, + addFaculty, + getFaculty, + deleteFaculty, + updateFaculty, }; diff --git a/controller/group.js b/controller/group.js index a0284fc3..3fd2f9b5 100644 --- a/controller/group.js +++ b/controller/group.js @@ -1,12 +1,13 @@ import { - createGroup, deleteGroupById, groupList, updateGroupById, + createGroup, + deleteGroupById, + groupList, + updateGroupById, } from "#services/group"; import { logger } from "#util"; async function addGroup(req, res) { - const { - title, student, - } = req.body; + const { title, student } = req.body; try { const group = await createGroup(title, student); res.json({ res: `added group ${group.id}`, id: group.id }); @@ -19,9 +20,7 @@ async function addGroup(req, res) { async function updateGroup(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updateGroupById(id, data); res.json({ res: `updated group with id ${id}` }); @@ -33,9 +32,16 @@ async function updateGroup(req, res) { } async function getGroup(req, res) { - const filter = req.query; - const group = await groupList(filter); - res.json({ res: group }); + try { + const filter = req.body; + const { limit, page } = req.query; + const group = await groupList(filter, limit, page); + res.json({ res: group }); + } catch (error) { + logger.error("Error while fetching", error); + res.status(500); + res.json({ err: "Error while fetching the data" }); + } } async function deleteGroup(req, res) { @@ -50,5 +56,8 @@ async function deleteGroup(req, res) { } export default { - addGroup, deleteGroup, getGroup, updateGroup, + addGroup, + deleteGroup, + getGroup, + updateGroup, }; diff --git a/controller/infrastructure.js b/controller/infrastructure.js index ee588d71..ae1b55a0 100644 --- a/controller/infrastructure.js +++ b/controller/infrastructure.js @@ -1,15 +1,25 @@ import { - createInfrastructure, deleteInfrastructureById, infrastructureList, updateInfrastructureById, + createInfrastructure, + deleteInfrastructureById, + infrastructureList, + updateInfrastructureById, } from "#services/infrastructure"; import { logger } from "#util"; async function addInfrastructure(req, res) { - const { - name, type, wing, floor, capacity, - } = req.body; + const { name, type, wing, floor, capacity } = req.body; try { - const newInfrastructure = await createInfrastructure(name, type, wing, floor, capacity); - res.json({ res: `added infrastructure ${newInfrastructure.id}`, id: newInfrastructure.id }); + const newInfrastructure = await createInfrastructure( + name, + type, + wing, + floor, + capacity, + ); + res.json({ + res: `added infrastructure ${newInfrastructure.id}`, + id: newInfrastructure.id, + }); } catch (error) { logger.error("Error while inserting", error); res.status(500); @@ -19,9 +29,7 @@ async function addInfrastructure(req, res) { async function updateInfrastructure(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updateInfrastructureById(id, data); res.json({ res: `updated infrastructure with id ${id}` }); @@ -33,9 +41,16 @@ async function updateInfrastructure(req, res) { } async function getInfrastructure(req, res) { - const filter = req.query; - const infralist = await infrastructureList(filter); - res.json({ res: infralist }); + try { + const filter = req.body; + const { limit, page } = req.query; + const infralist = await infrastructureList(filter, limit, page); + res.json({ res: infralist }); + } catch (error) { + logger.error("Error while fetching", error); + res.status(500); + res.json({ err: "Error while fetching the data" }); + } } async function deleteInfrastructure(req, res) { @@ -50,5 +65,8 @@ async function deleteInfrastructure(req, res) { } } export default { - addInfrastructure, deleteInfrastructure, getInfrastructure, updateInfrastructure, + addInfrastructure, + deleteInfrastructure, + getInfrastructure, + updateInfrastructure, }; diff --git a/controller/module.js b/controller/module.js index d455bf84..4f6a8776 100644 --- a/controller/module.js +++ b/controller/module.js @@ -1,9 +1,16 @@ -import { getModule, addNewModule, updateModuleById, deleteModuleById } from "#services/module"; +import { + getModule, + addNewModule, + updateModuleById, + deleteModuleById, +} from "#services/module"; import { logger } from "#util"; async function showModule(req, res) { try { - const modules = await getModule(req.query); + const filter = req.body; + const { limit, page } = req.query; + const modules = await getModule(filter, limit, page); return res.json({ res: modules }); } catch (error) { logger.error("Error while fetching", error); @@ -13,9 +20,8 @@ async function showModule(req, res) { } async function addModule(req, res) { - const { - no, name, outcome, contents, hrsPerModule, cognitiveLevels, - } = req.body; + const { no, name, outcome, contents, hrsPerModule, cognitiveLevels } = + req.body; try { const newModule = await addNewModule( no, @@ -35,9 +41,7 @@ async function addModule(req, res) { async function updateModule(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updateModuleById(id, data); res.json({ res: `updated Module with id ${id}` }); @@ -61,5 +65,8 @@ async function deleteModule(req, res) { } export default { - showModule, addModule, updateModule, deleteModule, + showModule, + addModule, + updateModule, + deleteModule, }; diff --git a/controller/notification.js b/controller/notification.js new file mode 100644 index 00000000..ad20f95f --- /dev/null +++ b/controller/notification.js @@ -0,0 +1,66 @@ +import { + createNotification, + deleteNotificationById, + listNotifications, + updateNotificationById, +} from "#services/notification"; +import { logger } from "#util"; + +async function addNotification(req, res) { + const { data, title, type, from, filter } = req.body; + try { + const newNotification = await createNotification({ + data, + title, + type, + from, + filter, + }); + res.json({ + res: `Added notification with ID: ${newNotification.id}`, + id: newNotification.id, + }); + } catch (error) { + logger.error("Error while inserting", error); + res.status(500); + res.json({ error: "Error while inserting in DB" }); + } +} + +async function updateNotification(req, res) { + const { id } = req.params; + const { ...data } = req.body; + try { + await updateNotificationById(id, data); + res.json({ res: `Updated notification with ID: ${id}` }); + } catch (error) { + logger.error("Error while updating", error); + res.status(500); + res.json({ error: "Error while updating in DB" }); + } +} + +async function getNotifications(req, res) { + const filter = req.body; + const { limit, page } = req.query; + const notificationList = await listNotifications(filter, limit, page); + res.json({ res: notificationList }); +} + +async function deleteNotification(req, res) { + const { id } = req.params; + try { + await deleteNotificationById(id); + res.json({ res: `Deleted notification with ID: ${id}` }); + } catch (error) { + logger.error("Error while deleting", error); + res.status(500).json({ error: "Error while deleting from DB" }); + } +} + +export default { + addNotification, + deleteNotification, + getNotifications, + updateNotification, +}; diff --git a/controller/organization.js b/controller/organization.js index c6e56732..b89c9212 100644 --- a/controller/organization.js +++ b/controller/organization.js @@ -1,15 +1,24 @@ import { - addNewOrganization, deleteOrganizationById, updateOrganizationById, getOrganizations, + addNewOrganization, + deleteOrganizationById, + updateOrganizationById, + getOrganizations, } from "#services/organization"; import { logger } from "#util"; async function addOrganization(req, res) { - const { - parent, startDate, name, accreditation, - } = req.body; + const { parent, startDate, name, accreditation } = req.body; try { - const organization = await addNewOrganization(parent, startDate, name, accreditation); - res.json({ res: `added organization${organization.name}`, id: organization.id }); + const organization = await addNewOrganization( + parent, + startDate, + name, + accreditation, + ); + res.json({ + res: `added organization${organization.name}`, + id: organization.id, + }); } catch (error) { logger.error("Error while inserting", error); res.status(500); @@ -30,9 +39,7 @@ async function deleteOrganization(req, res) { async function updateOrganization(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updateOrganizationById(id, data); @@ -46,7 +53,9 @@ async function updateOrganization(req, res) { async function showOrganization(req, res) { try { - const organization = await getOrganizations(req.query); + const filter = req.body; + const { limit, page } = req.query; + const organization = await getOrganizations(filter, limit, page); return res.json({ res: organization }); } catch (error) { logger.error("Error while fetching", error); @@ -56,5 +65,8 @@ async function showOrganization(req, res) { } export default { - addOrganization, updateOrganization, deleteOrganization, showOrganization, + addOrganization, + updateOrganization, + deleteOrganization, + showOrganization, }; diff --git a/controller/paper.js b/controller/paper.js index 6a6e6888..e659bf61 100644 --- a/controller/paper.js +++ b/controller/paper.js @@ -1,16 +1,13 @@ import { - createPaper, updatePaperById, listPaper, deletePaperById, + createPaper, + updatePaperById, + listPaper, + deletePaperById, } from "#services/paper"; import { logger } from "#util"; async function addPaper(req, res) { - const { - answerSheetID, - exam, - student, - checkedBy, - mark, - } = req.body; + const { answerSheetID, exam, student, checkedBy, mark } = req.body; try { const newPaper = await createPaper( answerSheetID, @@ -19,7 +16,10 @@ async function addPaper(req, res) { checkedBy, mark, ); - res.json({ res: `added paper for: ${newPaper.answerSheetID}`, id: newPaper.id }); + res.json({ + res: `added paper for: ${newPaper.answerSheetID}`, + id: newPaper.id, + }); } catch (error) { logger.error("Error while inserting", error); res.status(500); @@ -29,9 +29,7 @@ async function addPaper(req, res) { async function updatePaper(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updatePaperById(id, data); res.json({ res: "Paper updated" }); @@ -43,9 +41,16 @@ async function updatePaper(req, res) { } async function showPaper(req, res) { - const filter = req.query; - const paper = await listPaper(filter); - res.json({ res: paper }); + try { + const filter = req.body; + const { limit, page } = req.query; + const paper = await listPaper(filter, limit, page); + res.json({ res: paper }); + } catch (error) { + logger.error("Error while fetching", error); + res.status(500); + res.json({ err: "Error while fetching the data" }); + } } async function deletePaper(req, res) { @@ -60,5 +65,8 @@ async function deletePaper(req, res) { } export default { - addPaper, updatePaper, showPaper, deletePaper, + addPaper, + updatePaper, + showPaper, + deletePaper, }; diff --git a/controller/performance.js b/controller/performance.js new file mode 100644 index 00000000..b62c6c50 --- /dev/null +++ b/controller/performance.js @@ -0,0 +1,26 @@ +import os from "os"; +import dotenv from "dotenv"; +import semesterModel from "#models/semester"; + +dotenv.config(); +const { PORT } = process.env; + +async function performance(req, res) { + const startTimeDb = new Date().getTime(); + const testDB = await semesterModel.read({}) + .then(() => { + const time = new Date().getTime() - startTimeDb; + return time; + }); + + const startTime = new Date().getTime(); + fetch(`http://localhost:${PORT}/semester/list`) + .then(() => { + const time = new Date().getTime() - startTime; + res.json({ + responseTime: time, cpu: os.cpus(), maxMem: os.totalmem(), freeMem: os.freemem(), dbTime: testDB + }); + }); +} + +export default performance; diff --git a/controller/practical.js b/controller/practical.js index 9eb55f24..a5f36cb4 100644 --- a/controller/practical.js +++ b/controller/practical.js @@ -10,14 +10,19 @@ import { logger } from "#util"; // Import the logger utility // Controller function to add a new Practical entity async function addPractical(req, res) { - const { - no, title, type, hours, cognitiveLevels, - } = req.body; + const { no, title, type, hours, cognitiveLevels } = req.body; try { const newPractical = await createPractical({ - no, title, type, hours, cognitiveLevels, + no, + title, + type, + hours, + cognitiveLevels, + }); + res.json({ + res: `Added Practical with ID ${newPractical.id}`, + id: newPractical.id, }); - res.json({ res: `Added Practical with ID ${newPractical.id}`, id: newPractical.id }); } catch (error) { logger.error("Error while inserting Practical", error); res.status(500); @@ -28,9 +33,7 @@ async function addPractical(req, res) { // Controller function to update a Practical entity async function updatePractical(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updatePracticalById(id, data); res.json({ res: `Updated Practical with ID ${id}` }); @@ -43,8 +46,9 @@ async function updatePractical(req, res) { // Controller function to get a list of Practical entities async function getPractical(req, res) { - const filter = req.query; - const practicalList = await listPractical(filter); + const filter = req.body; + const { limit, page } = req.query; + const practicalList = await listPractical(filter, limit, page); res.json({ res: practicalList }); } diff --git a/controller/semester.js b/controller/semester.js index 79be1fd3..3b2363c6 100644 --- a/controller/semester.js +++ b/controller/semester.js @@ -1,15 +1,22 @@ import { - createSemester, updateSemesterById, semesterList, deleteSemesterById, + createSemester, + updateSemesterById, + semesterList, + deleteSemesterById, } from "#services/semester"; import { logger } from "#util"; async function addSemester(req, res) { - const { - number, academicYear, type, startDate, endDate, - } = req.body; + const { number, academicYear, type, startDate, endDate } = req.body; try { - const newSemester = await createSemester(number, academicYear, type, startDate, endDate); + const newSemester = await createSemester( + number, + academicYear, + type, + startDate, + endDate, + ); res.json({ res: `added semester ${newSemester.id} `, id: newSemester.id }); } catch (error) { logger.error("Error while inserting", error); @@ -20,9 +27,7 @@ async function addSemester(req, res) { async function updateSemester(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updateSemesterById(id, data); res.json({ res: `Updated Semester with id ${id}` }); @@ -34,8 +39,9 @@ async function updateSemester(req, res) { } async function getSemester(req, res) { - const filter = req.query; - const semlist = await semesterList(filter); + const filter = req.body; + const { limit, page } = req.query; + const semlist = await semesterList(filter, limit, page); res.json({ res: semlist }); } @@ -50,5 +56,8 @@ async function deleteSemester(req, res) { } } export default { - addSemester, deleteSemester, getSemester, updateSemester, + addSemester, + deleteSemester, + getSemester, + updateSemester, }; diff --git a/controller/student.js b/controller/student.js index ea4bbaf3..68d81d46 100644 --- a/controller/student.js +++ b/controller/student.js @@ -1,12 +1,14 @@ import { - createStudent, deleteStudentById, studentList, updateStudentById, + createStudent, + deleteStudentById, + studentList, + updateStudentById, } from "#services/student"; import { logger } from "#util"; async function addStudent(req, res) { - const { - ERPID, name, joiningYear, branch, division, rollNo, coursesOpted, - } = req.body; + const { ERPID, name, joiningYear, branch, division, rollNo, coursesOpted } = + req.body; try { const newStudent = await createStudent( ERPID, @@ -27,9 +29,7 @@ async function addStudent(req, res) { async function updateStudent(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updateStudentById(id, data); res.json({ res: `updated Student with id ${id}` }); @@ -41,8 +41,9 @@ async function updateStudent(req, res) { } async function getStudent(req, res) { - const filter = req.query; - const StudList = await studentList(filter); + const filter = req.body; + const { limit, page } = req.query; + const StudList = await studentList(filter, limit, page); res.json({ res: StudList }); } @@ -58,5 +59,8 @@ async function deleteStudent(req, res) { } } export default { - addStudent, deleteStudent, getStudent, updateStudent, + addStudent, + deleteStudent, + getStudent, + updateStudent, }; diff --git a/controller/timetable.js b/controller/timetable.js index ecabef68..e13ea39a 100644 --- a/controller/timetable.js +++ b/controller/timetable.js @@ -1,5 +1,8 @@ import { - createTimetable, deleteTimetableById, timetableList, updateTimetableById, + createTimetable, + deleteTimetableById, + timetableList, + updateTimetableById, } from "#services/timetable"; import { logger } from "#util"; @@ -27,7 +30,10 @@ async function addTimetable(req, res) { teabreakStartTime, teabreakDuration, ); - res.json({ res: `added timetable for: ${newTimetable.startDate} to ${newTimetable.endDate}`, id: newTimetable.id }); + res.json({ + res: `added timetable for: ${newTimetable.startDate} to ${newTimetable.endDate}`, + id: newTimetable.id, + }); } catch (error) { logger.error("Error while inserting", error); res.status(500); @@ -37,9 +43,7 @@ async function addTimetable(req, res) { async function updateTimetable(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updateTimetableById(id, data); res.json({ res: "timetable updated" }); @@ -51,8 +55,9 @@ async function updateTimetable(req, res) { } async function getTimetable(req, res) { - const filter = req.query; - const timetable = await timetableList(filter); + const filter = req.body; + const { limit, page } = req.query; + const timetable = await timetableList(filter, limit, page); res.json({ res: timetable }); } @@ -68,5 +73,8 @@ async function deleteTimetable(req, res) { } export default { - addTimetable, deleteTimetable, getTimetable, updateTimetable, + addTimetable, + deleteTimetable, + getTimetable, + updateTimetable, }; diff --git a/controller/topic.js b/controller/topic.js new file mode 100644 index 00000000..88dd11e3 --- /dev/null +++ b/controller/topic.js @@ -0,0 +1,65 @@ +import { + addNewTopic, + deleteTopicById, + updateTopicById, + getTopics, +} from "#services/topic"; +import { logger } from "#util"; + +async function addTopic(req, res) { + const { title } = req.body; + try { + // eslint-disable-next-line max-len + const topic = await addNewTopic(title); + res.json({ res: `added topic ${topic.name}`, id: topic.id }); + } catch (error) { + logger.error("Error while inserting", error); + res.status(500); + res.json({ err: "Error while inserting in DB" }); + } +} +async function deleteTopic(req, res) { + const { id } = req.params; + try { + await deleteTopicById(id); + res.json({ res: "Topic deleted successfully" }); + } catch (error) { + logger.error("Error while deleting", error); + res.status(500); + res.json({ err: "Error while deleting from DB" }); + } +} + +async function updateTopic(req, res) { + const { id } = req.params; + const { ...data } = req.body; + + try { + await updateTopicById(id, data); + res.json({ res: `${id} topic updated` }); + } catch (error) { + logger.error("Error while inserting", error); + res.status(500); + res.json({ err: "Error while inserting in DB" }); + } +} + +async function showTopic(req, res) { + try { + const filter = req.body; + const { limit, page } = req.query; + const topic = await getTopics(filter, limit, page); + return res.json({ res: topic }); + } catch (error) { + logger.error("Error while fetching", error); + res.status(500); + return res.json({ err: "Error while fetching the data" }); + } +} + +export default { + addTopic, + updateTopic, + deleteTopic, + showTopic, +}; diff --git a/controller/tutorial.js b/controller/tutorial.js index 6a29830b..43c83055 100644 --- a/controller/tutorial.js +++ b/controller/tutorial.js @@ -1,12 +1,13 @@ import { - addNewTutorial, deleteTutorialById, updateTutorialById, getTutorials, + addNewTutorial, + deleteTutorialById, + updateTutorialById, + getTutorials, } from "#services/tutorial"; import { logger } from "#util"; async function addTutorial(req, res) { - const { - no, title, hours, cognitiveLevel, - } = req.body; + const { no, title, hours, cognitiveLevel } = req.body; try { // eslint-disable-next-line max-len const tutorial = await addNewTutorial(no, title, hours, cognitiveLevel); @@ -31,9 +32,7 @@ async function deleteTutorial(req, res) { async function updateTutorial(req, res) { const { id } = req.params; - const { - ...data - } = req.body; + const { ...data } = req.body; try { await updateTutorialById(id, data); @@ -47,7 +46,9 @@ async function updateTutorial(req, res) { async function showTutorial(req, res) { try { - const tutorial = await getTutorials(req.query); + const filter = req.body; + const { limit, page } = req.query; + const tutorial = await getTutorials(filter, limit, page); return res.json({ res: tutorial }); } catch (error) { logger.error("Error while fetching", error); @@ -57,5 +58,8 @@ async function showTutorial(req, res) { } export default { - addTutorial, updateTutorial, deleteTutorial, showTutorial, + addTutorial, + updateTutorial, + deleteTutorial, + showTutorial, }; diff --git a/controller/user.js b/controller/user.js index 20efc5c8..97b02ae3 100644 --- a/controller/user.js +++ b/controller/user.js @@ -2,9 +2,7 @@ import { allUsers, createUser } from "#services/user"; import { logger } from "#util"; async function addUser(req, res) { - const { - name, password, emailId, uid, userType, - } = req.body; + const { name, password, emailId, uid, userType } = req.body; try { const newUser = await createUser(name, password, emailId, uid, userType); res.json({ res: `added user ${newUser.id}` }); @@ -16,7 +14,8 @@ async function addUser(req, res) { } async function getAllUser(req, res) { - const allUser = await allUsers(); + const { limit, page } = req.query; + const allUser = await allUsers(limit, page); res.json({ res: allUser }); } diff --git a/hooks/pre-commit b/hooks/pre-commit deleted file mode 100644 index d3dc8072..00000000 --- a/hooks/pre-commit +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -# Store staged files in an array -staged_files=($(git diff --diff-filter=d --cached --name-only | grep -E '\.(js|jsx)$')) -flag=0 -# Loop through staged files and run ESLint on each -for file in "${staged_files[@]}" -do - # Get staged content of the file - staged_content=$(git show ":$file") - - # Format staged files - npx prettier --write $file - - # Run ESLint with the staged content and filename - # echo "$staged_content" | npm run eslint -- --stdin - npx eslint $file - if [ $? -ne 0 ]; then - echo "ESLint failed on staged file '$file'. Please check your code and try again. You can run ESLint manually via npm run eslint." - flag=1 - fi -done - -if [ $flag -eq 1 ]; then - exit 1 -fi diff --git a/middleware/auth.js b/middleware/auth.js index 016483db..50dc9162 100644 --- a/middleware/auth.js +++ b/middleware/auth.js @@ -2,25 +2,36 @@ import jwt from "jsonwebtoken"; import util from "#util"; async function authenticateToken(req, res, next) { - const authHeader = req.headers.authorization; - const token = authHeader && authHeader.split(" ")[1]; - if (token == null) return res.sendStatus(401); - try { - const payload = jwt.verify(token, process.env.TOKEN_SECRET); - const decryptedIP = util.decrypt(payload.ip); - if (decryptedIP !== req.ip) { + if (process.env.ENVIRONMENT === "local") { + return next(); + } + const authHeader = req.headers.authorization || req.headers.Authorization; + // Inside header when we are going to provide the value for key authentication we have + // to start it with 'Bearer acesstoken' + if (authHeader && authHeader.startsWith("Bearer")) { + const token = authHeader.split(" ")[1]; + if (token == null) return res.sendStatus(401); + try { + const payload = jwt.verify(token, process.env.TOKEN_SECRET); + const decryptedIP = util.decrypt(payload.ip); + if (decryptedIP !== req.ip) { + res.status(403); + res.send({ err: "Unauthorized" }); + } + + req.user = payload.data; + next(); + return true; + } catch (error) { res.status(403); res.send({ err: "Unauthorized" }); + return false; } - - req.user = payload.data; - next(); - return true; - } catch (error) { - res.status(403); - res.send({ err: "Unauthorized" }); - return false; + } else { + res.json({ + msg: "Kindly login", + }); } + return null; } - -export default { authenticateToken }; +export default authenticateToken; diff --git a/middleware/authorization.js b/middleware/authorization.js new file mode 100644 index 00000000..1f745da6 --- /dev/null +++ b/middleware/authorization.js @@ -0,0 +1,14 @@ +function authorization(access = []) { + return (req, res, next) => { + // remove this in production + if (process.env.ENVIRONMENT === "local") { + return next(); + } + if (!req.user) return res.json({ msg: "kindly login first" }); + if (!access.includes(req.user.type)) + return res.json({ msg: "Unauthorized request" }); + return next(); + }; +} + +export default authorization; diff --git a/models/accreditation.js b/models/accreditation.js index 2c81583f..32cdb2ca 100644 --- a/models/accreditation.js +++ b/models/accreditation.js @@ -15,9 +15,8 @@ async function remove(filter) { } async function create(accreditationData) { - const { - name, agencyName, dateofAccreditation, dateofExpiry, - } = accreditationData; + const { name, agencyName, dateofAccreditation, dateofExpiry } = + accreditationData; const accreditation = new Accreditation({ name, agencyName, @@ -28,16 +27,28 @@ async function create(accreditationData) { return accreditationDoc; } -async function read(filter, limit = 1) { - const accreditationDoc = await Accreditation.find(filter).limit(limit); - return accreditationDoc; +async function read(filter, limit = 0, page = 1) { + const accreditationDoc = await Accreditation.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Accreditation.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: accreditationDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const deleteResult = await Accreditation.updateMany(filter, { $set: updateObject }, options); + const deleteResult = await Accreditation.updateMany( + filter, + { $set: updateObject }, + options, + ); return deleteResult.acknowledged; } export default { - create, read, update, remove, + create, + read, + update, + remove, }; diff --git a/models/activity.js b/models/activity.js index f55c464a..e581be76 100644 --- a/models/activity.js +++ b/models/activity.js @@ -1,23 +1,43 @@ import connector from "#models/databaseUtil"; const activitySchema = { - activityBlueprint: { type: connector.Schema.Types.ObjectId, ref: "ActivityBlueprint", required: true }, + activityBlueprint: { + type: connector.Schema.Types.ObjectId, + ref: "ActivityBlueprint", + required: true, + }, startTime: { type: Date, required: true }, duration: { type: Number, required: true }, - course: { type: connector.Schema.Types.ObjectId, ref: "Course", required: true }, - faculty: { type: connector.Schema.Types.ObjectId, ref: "Faculty", required: true }, + course: { + type: connector.Schema.Types.ObjectId, + ref: "Course", + required: true, + }, + faculty: { + type: connector.Schema.Types.ObjectId, + ref: "Faculty", + required: true, + }, type: { type: String, required: true, enum: ["LECTURE", "PRACTICAL", "TUTORIAL"], }, - task: [{ + task: [ + { + type: connector.Schema.Types.ObjectId, + ref: ["Topic", "Practical", "Tutorial"], + required: true, + }, + ], + group: { type: connector.Schema.Types.ObjectId, - ref: ["Topic", "Practical", "Tutorial"], + ref: "Group", required: true, - }], - group: { type: connector.Schema.Types.ObjectId, ref: "Group", required: true }, - students: [{ type: connector.Schema.Types.ObjectId, ref: "Student", required: true }], + }, + students: [ + { type: connector.Schema.Types.ObjectId, ref: "Student", required: true }, + ], }; const Activity = connector.model("Activity", activitySchema); @@ -25,38 +45,65 @@ const Activity = connector.model("Activity", activitySchema); /// crud operation/// // add a activity to the database -async function create(activityData){ +async function create(activityData) { const { - activityBlueprint, startTime,duration,course,faculty,type,task,group,students, - }=activityData; - const activity= new Activity({ - activityBlueprint, startTime,duration,course,faculty,type,task,group,students, + activityBlueprint, + startTime, + duration, + course, + faculty, + type, + task, + group, + students, + } = activityData; + const activity = new Activity({ + activityBlueprint, + startTime, + duration, + course, + faculty, + type, + task, + group, + students, }); - const activityDoc =await activity.save(); + const activityDoc = await activity.save(); return activityDoc; } // Retrieve activity based on a given filter and limit -async function read(filter,limit=1){ - const activityDoc = await Activity.find (filter).limit(limit); - return activityDoc ; +async function read(filter, limit = 0, page = 1) { + const activityDoc = await Activity.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Activity.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: activityDoc }; } -// update activity based on a given filter -async function update(filter,updateObject,options={multi:true}){ - const updateActivity= await Activity.updateMany(filter,{$set:updateObject},options); -return updateActivity.acknowledged; +// update activity based on a given filter +async function update(filter, updateObject, options = { multi: true }) { + const updateActivity = await Activity.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateActivity.acknowledged; } // Delete activity based on a given filter -async function remove(filter){ - const deleteActivity= await Activity.deleteMany(filter).exec(); +async function remove(filter) { + const deleteActivity = await Activity.deleteMany(filter).exec(); return deleteActivity.acknowledged; } // export crud functions -export default{ - create,read,update,remove, +export default { + create, + read, + update, + remove, }; - diff --git a/models/activityBlueprint.js b/models/activityBlueprint.js index c5c5831f..5f6d5575 100644 --- a/models/activityBlueprint.js +++ b/models/activityBlueprint.js @@ -7,7 +7,8 @@ const activityBluePrintSchema = { required: true, validate: { validator: (value) => /^20\d{2}$/.test(value), // changed the valid year format starting from "20" !! - message: (props) => `${props.value} is not a valid year format starting with "2"!`, + message: (props) => + `${props.value} is not a valid year format starting with "2"!`, }, }, type: { enum: ["ODD", "EVEN"], required: true }, @@ -16,7 +17,10 @@ const activityBluePrintSchema = { }; // eslint-disable-next-line no-unused-vars -const ActivityBlueprint = connector.model("ActivityBlueprint", activityBluePrintSchema); +const ActivityBlueprint = connector.model( + "ActivityBlueprint", + activityBluePrintSchema, +); async function remove(filter) { const deleteResult = await ActivityBlueprint.deleteMany(filter); @@ -24,9 +28,8 @@ async function remove(filter) { } async function create(activityBlueprintData) { - const { - number, academicYear, type, startDate, endDate, - } = activityBlueprintData; + const { number, academicYear, type, startDate, endDate } = + activityBlueprintData; const activityblueprint = new ActivityBlueprint({ number, academicYear, @@ -38,16 +41,28 @@ async function create(activityBlueprintData) { return activityblueprintDoc; } -async function read(filter, limit = 1) { - const activityblueprintDoc = await ActivityBlueprint.find(filter).limit(limit); - return activityblueprintDoc; +async function read(filter, limit = 0, page = 1) { + const activityblueprintDoc = await ActivityBlueprint.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await ActivityBlueprint.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: activityblueprintDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await ActivityBlueprint.updateMany(filter, { $set: updateObject }, options); + const updateResult = await ActivityBlueprint.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } export default { - create, read, update, remove, + create, + read, + update, + remove, }; diff --git a/models/assignment.js b/models/assignment.js index 3f87c05e..d1ebd921 100644 --- a/models/assignment.js +++ b/models/assignment.js @@ -18,13 +18,22 @@ async function create(assignmentData) { return assignmentDoc; } -async function read(filter, limit = 1) { - const assignmentDoc = await Assignment.find(filter).limit(limit); - return assignmentDoc; +async function read(filter, limit = 0, page = 1) { + const assignmentDoc = await Assignment.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Assignment.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: assignmentDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Assignment.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Assignment.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } diff --git a/models/attendance.js b/models/attendance.js index 1fa5f495..c1ef29c0 100644 --- a/models/attendance.js +++ b/models/attendance.js @@ -3,8 +3,16 @@ import connector from "#models/databaseUtil"; connector.set("debug", true); const attendanceSchema = { - student: { type: connector.Schema.Types.ObjectId, ref: "Student", required: "true" }, - course: { type: connector.Schema.Types.ObjectId, ref: "Course", required: "true" }, + student: { + type: connector.Schema.Types.ObjectId, + ref: "Student", + required: "true", + }, + course: { + type: connector.Schema.Types.ObjectId, + ref: "Course", + required: "true", + }, monthlyAttended: { type: Number, default: 0 }, monthlyOccured: { type: Number, default: 0 }, cumulativeAttended: { type: Number, default: 0 }, @@ -15,7 +23,12 @@ const Attendance = connector.model("Attendance", attendanceSchema); async function create(attendanceData) { const { - student, course, monthlyAttended, monthlyOccured, cumulativeAttended, cumulativeOccured, + student, + course, + monthlyAttended, + monthlyOccured, + cumulativeAttended, + cumulativeOccured, } = attendanceData; const attendance = new Attendance({ student, @@ -29,13 +42,22 @@ async function create(attendanceData) { return attendanceDoc; } -async function read(filter, limit = 1) { - const attendanceDoc = await Attendance.find(filter).limit(limit); - return attendanceDoc; +async function read(filter, limit = 0, page = 1) { + const attendanceDoc = await Attendance.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Attendance.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: attendanceDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Attendance.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Attendance.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } @@ -44,5 +66,8 @@ async function remove(filter) { return deleteResult.acknowledged; } export default { - create, remove, update, read, + create, + remove, + update, + read, }; diff --git a/models/course.js b/models/course.js index 413aaa0e..fda2aa0e 100644 --- a/models/course.js +++ b/models/course.js @@ -39,13 +39,17 @@ const courseSchema = { }; // virtual for total hours -courseSchema.virtual("totalHours").get(() => this.theoryHours + this.tutorialHours + this.practicalHours); +courseSchema + .virtual("totalHours") + .get(() => this.theoryHours + this.tutorialHours + this.practicalHours); // virtual for theory marks courseSchema.virtual("theoryMarks").get(() => this.ISAMarks + this.ESEMarks); // virtual for total marks -courseSchema.virtual("totalMarks").get(() => this.theoryMarks + this.tutorialMarks + this.practicalMarks); +courseSchema + .virtual("totalMarks") + .get(() => this.theoryMarks + this.tutorialMarks + this.practicalMarks); const Course = connector.model("Course", courseSchema); @@ -57,13 +61,22 @@ async function create(courseData) { return courseDoc; } -async function read(filter, limit = 1) { - const courseDoc = await Course.find(filter).limit(limit); - return courseDoc; +async function read(filter, limit = 0, page = 1) { + const courseDoc = await Course.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Course.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: courseDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Course.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Course.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } diff --git a/models/coursework.js b/models/coursework.js index 1348def7..52a36f81 100644 --- a/models/coursework.js +++ b/models/coursework.js @@ -1,12 +1,32 @@ import connector from "#models/databaseUtil"; const courseworkSchema = { - student: { type: connector.Schema.Types.ObjectId, ref: "Student", required: true }, + student: { + type: connector.Schema.Types.ObjectId, + ref: "Student", + required: true, + }, type: { type: String, enum: ["onCampus", "offCampus"], required: true }, - course: { type: connector.Schema.Types.ObjectId, ref: "Course", required: true }, - task: { type: connector.Schema.Types.ObjectId, refPath: "objectID", required: true }, - objectID: { type: String, enum: ["Practical", "Tutorial", "Assignment"], required: true }, - activity: { type: connector.Schema.Types.ObjectId, ref: "Activity", required: true }, + course: { + type: connector.Schema.Types.ObjectId, + ref: "Course", + required: true, + }, + task: { + type: connector.Schema.Types.ObjectId, + refPath: "objectID", + required: true, + }, + objectID: { + type: String, + enum: ["Practical", "Tutorial", "Assignment"], + required: true, + }, + activity: { + type: connector.Schema.Types.ObjectId, + ref: "Activity", + required: true, + }, marks: { type: Number, required: true }, }; @@ -18,9 +38,8 @@ async function remove(filter) { } async function create(courseworkData) { - const { - student, type, course, task, objectID, activity, marks, - } = courseworkData; + const { student, type, course, task, objectID, activity, marks } = + courseworkData; const coursework = new Coursework({ student, type, @@ -34,13 +53,22 @@ async function create(courseworkData) { return courseworkDoc; } -async function read(filter, limit = 1) { - const courseworkDoc = await Coursework.find(filter).limit(limit); - return courseworkDoc; +async function read(filter, limit = 0, page = 1) { + const courseworkDoc = await Coursework.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Coursework.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: courseworkDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Coursework.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Coursework.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } diff --git a/models/department.js b/models/department.js index 3df770bc..24ec40e8 100644 --- a/models/department.js +++ b/models/department.js @@ -4,25 +4,28 @@ const departmentSchema = { name: { type: String, required: true }, acronym: { type: String, required: true, immutable: true }, yearOfStarting: { type: Date, immutable: true, required: true }, - accreditations: [{ - type: connector.Schema.Types.ObjectId, - ref: "Accreditation", - required: true, - }], - infrastructures: [{ - type: connector.Schema.Types.ObjectId, - ref: "Infrastructure", - required: true, - }], + accreditations: [ + { + type: connector.Schema.Types.ObjectId, + ref: "Accreditation", + required: true, + }, + ], + infrastructures: [ + { + type: connector.Schema.Types.ObjectId, + ref: "Infrastructure", + required: true, + }, + ], }; const Department = connector.model("Department", departmentSchema); // for creating async function create(departmentData) { - const { - name, acronym, yearOfStarting, accreditations, infrastructures, - } = departmentData; + const { name, acronym, yearOfStarting, accreditations, infrastructures } = + departmentData; const department = new Department({ name, acronym, @@ -34,13 +37,22 @@ async function create(departmentData) { return departmentDoc; } -async function read(filter, limit = 1) { - const departmentDoc = await Department.find(filter).limit(limit); - return departmentDoc; +async function read(filter, limit = 0, page = 1) { + const departmentDoc = await Department.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Department.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: departmentDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Department.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Department.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } diff --git a/models/employee/empBank.js b/models/employee/empBank.js new file mode 100644 index 00000000..a7b495be --- /dev/null +++ b/models/employee/empBank.js @@ -0,0 +1,100 @@ +import connector from "#models/databaseUtil"; + +const employeeBankSchema = { + uid: { + type: String, + required: true, + unique: true, + }, + bank_name: { + type: String, + required: true, + minLength: 7, + }, + bank_acc: { + type: String, + required: true, + unique: true, + }, + bank_branch: { + type: String, + required: true, + }, + bank_ifsc: { + type: String, + required: true, + maxLength: 11, + minLength: 11, + }, + bank_micr: { + type: String, + required: true, + maxLength: 9, + minLength: 9, + }, + appointment_approve_sg_dte: { + type: String, + }, +}; + +// eslint-disable-next-line no-unused-vars +const EmployeeBank = connector.model("Employee bank", employeeBankSchema); + +/// crud operation/// + +// employee personal details to the database +async function create(employeeBankData) { + const { + uid, + bankName, + bankAcc, + bankBranch, + bankIfsc, + bankMicr, + appointmentApproveSgDte, + } = employeeBankData; + + const empBank = new EmployeeBank({ + uid, + bankName, + bankAcc, + bankBranch, + bankIfsc, + bankMicr, + appointmentApproveSgDte, + }); + + const empBankDoc = await empBank.save(); + return empBankDoc; +} + +async function read(filter, limit = 0, page = 1) { + const empBankDoc = await EmployeeBank.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await EmployeeBank.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: empBankDoc }; +} + +async function update(filter, updateObject, options = { multi: true }) { + const updateResult = await EmployeeBank.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateResult.acknowledged; +} + +async function remove(empBankId) { + const deleteResult = await EmployeeBank.deleteMany(empBankId); + return deleteResult.acknowledged; +} + +export default { + create, + read, + update, + remove, +}; diff --git a/models/employee/empCurrentDetail.js b/models/employee/empCurrentDetail.js new file mode 100644 index 00000000..1a7a91ea --- /dev/null +++ b/models/employee/empCurrentDetail.js @@ -0,0 +1,74 @@ +import connector from "#models/databaseUtil"; + +const employeeCurrentEmploymentSchema = { + uid: { type: String, require: true }, + date_of_joining: { type: Date, required: true }, + department_name: { type: String, required: true }, + designation: { type: String, required: true }, + job_status: { type: String, required: true }, + job_profile: { type: String, required: true }, + current_ctc: { type: Number, required: true }, +}; + +// eslint-disable-next-line no-unused-vars +const EmployeeCurrentEmployment = connector.model( + "EmployeeCurrentEmployement", + employeeCurrentEmploymentSchema, +); + +async function create(employeeCurrentEmploymentData) { + const { + uid, + dateOfJoining, + departmentName, + designation, + jobStatus, + jobProfile, + currentCtc, + } = employeeCurrentEmploymentData; + + const empCurEmp = new EmployeeCurrentEmployment({ + uid, + dateOfJoining, + departmentName, + designation, + jobStatus, + jobProfile, + currentCtc, + }); + + const empCurrentEmploymentDoc = await empCurEmp.save(); + return empCurrentEmploymentDoc; +} + +async function read(filter, limit = 0, page = 1) { + const empCurrentEmploymentDoc = await EmployeeCurrentEmployment.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await EmployeeCurrentEmployment.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: empCurrentEmploymentDoc }; +} + +async function update(filter, updateObject, options = { multi: true }) { + const updateResult = await EmployeeCurrentEmployment.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateResult.acknowledged; +} + +async function remove(filter) { + const deleteResult = + await EmployeeCurrentEmployment.deleteMany(filter).exec(); + return deleteResult.acknowledged; +} + +export default { + create, + read, + update, + remove, +}; diff --git a/models/employee/empEduHistory.js b/models/employee/empEduHistory.js new file mode 100644 index 00000000..ed43b886 --- /dev/null +++ b/models/employee/empEduHistory.js @@ -0,0 +1,128 @@ +import connector from "#models/databaseUtil"; + +const Education = { + educationType: { type: String, required: true }, + educationName: { type: String, required: true }, + specialization: { type: String, required: true }, + period: { type: String, required: true }, + institutionName: { type: String, required: true }, + university: { type: String, required: true }, + passingDivision: { type: String, required: true }, + fromYear: { type: String, required: true }, + uptoYear: { type: String, required: true }, + registrationNumber: { type: String, required: true }, + aggregatePct: { type: String, required: true }, + finalYearPct: { type: String, required: true }, + numberOfAttempts: { type: Number, required: true }, + rank: { type: Number, required: true }, + passingYear: { type: String, required: true }, +}; +const employeeEducationHistorySchema = { + uid: { type: String, require: true }, + ssc: { type: Education, required: true }, + hsc: { type: Education, required: true }, + dip: { type: Education }, + iti: { type: Education }, + deg: { type: Education }, + pgd: { type: Education }, + phd: { type: Education }, + pdoc: { type: Education }, +}; + +// eslint-disable-next-line no-unused-vars +const EmployeeEducationHistory = connector.model( + "Employee education history", + employeeEducationHistorySchema, +); + +// CRUD Operations + +async function create(employeeEducationHistoryData) { + const { + educationType, + educationName, + specialization, + period, + institutionName, + university, + passingDivision, + fromYear, + uptoYear, + registrationNumber, + aggregatePct, + finalYearPct, + numberOfAttempts, + rank, + passingYear, + uid, + ssc, + hsc, + dip, + iti, + deg, + pgd, + phd, + pdoc, + } = employeeEducationHistoryData; + + const empEduHistory = new EmployeeEducationHistory({ + educationType, + educationName, + specialization, + period, + institutionName, + university, + passingDivision, + fromYear, + uptoYear, + registrationNumber, + aggregatePct, + finalYearPct, + numberOfAttempts, + rank, + passingYear, + uid, + ssc, + hsc, + dip, + iti, + deg, + pgd, + phd, + pdoc, + }); + + const empEduHistoryDoc = await empEduHistory.save(); + return empEduHistoryDoc; +} + +async function read(filter, limit = 0, page = 1) { + const empEduHistoryDoc = await EmployeeEducationHistory.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await EmployeeEducationHistory.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: empEduHistoryDoc }; +} + +async function update(filter, updateObject, options = { multi: true }) { + const updateResult = await EmployeeEducationHistory.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateResult.acknowledged; +} + +async function remove(filter) { + const deleteResult = await EmployeeEducationHistory.deleteMany(filter).exec(); + return deleteResult.acknowledged; +} + +export default { + create, + read, + update, + remove, +}; diff --git a/models/employee/emp_personal.js b/models/employee/empPersonal.js similarity index 71% rename from models/employee/emp_personal.js rename to models/employee/empPersonal.js index 6f23d9fe..d4e3d485 100644 --- a/models/employee/emp_personal.js +++ b/models/employee/empPersonal.js @@ -55,11 +55,50 @@ const employeePersonalSchema = { maidenFirstName: { type: String }, maidenMiddleName: { type: String }, maidenLastName: { type: String }, - isNameChangedBefrore: { type: Boolean, required: true }, + isNameChangedBefore: { type: Boolean, required: true }, previousFirstName: { type: String }, previousMiddleName: { type: String }, previousLastName: { type: String }, }; +const EmployeePersonal = connector.model( + "EmplyeePersonalData", + employeePersonalSchema, +); +/// CRUD operations /// -// eslint-disable-next-line no-unused-vars -const empPersonal = connector.model("Employee personal", employeePersonalSchema); +async function create(employeePersonalData) { + const employeePersonal = new EmployeePersonal(employeePersonalData); + const employeePersonalDoc = await employeePersonal.save(); + return employeePersonalDoc; +} + +async function read(filter, limit = 0, page = 1) { + const employeePersonalDoc = await EmployeePersonal.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await EmployeePersonal.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: employeePersonalDoc }; +} + +async function update(filter, updateObject, options = { multi: true }) { + const updateResult = await EmployeePersonal.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateResult.acknowledged; +} + +async function remove(filter) { + const deleteResult = await EmployeePersonal.deleteMany(filter).exec(); + return deleteResult.acknowledged; +} + +export default { + create, + read, + update, + remove, +}; diff --git a/models/employee/emp_bank.js b/models/employee/emp_bank.js deleted file mode 100644 index 8e1ab1e6..00000000 --- a/models/employee/emp_bank.js +++ /dev/null @@ -1,41 +0,0 @@ -import connector from "#models/databaseUtil"; - -const employeeBankSchema = { - uid: { - type: String, - required: true, - unique: true, - }, - bank_name: { - type: String, - required: true, - minLength: 7, - }, - bank_acc: { - type: String, - required: true, - unique: true, - }, - bank_branch: { - type: String, - required: true, - }, - bank_ifsc: { - type: String, - required: true, - maxLength: 11, - minLength: 11, - }, - bank_micr: { - type: String, - required: true, - maxLength: 9, - minLength: 9, - }, - appointment_approve_sg_dte: { - type: String, - }, -}; - -// eslint-disable-next-line no-unused-vars -const empBank = connector.model("Employee bank", employeeBankSchema); diff --git a/models/employee/emp_cur_detail.js b/models/employee/emp_cur_detail.js deleted file mode 100644 index fa2d96ef..00000000 --- a/models/employee/emp_cur_detail.js +++ /dev/null @@ -1,17 +0,0 @@ -import connector from "#models/databaseUtil"; - -const employeeCurrentEmployementSchema = { - uid: { type: String, require: true }, - date_of_joining: { type: Date, required: true }, - department_name: { type: String, required: true }, - designation: { type: String, required: true }, - job_status: { type: String, required: true }, - job_profile: { type: String, required: true }, - current_ctc: { type: Number, required: true }, -}; - -// eslint-disable-next-line no-unused-vars -const employeeCurrentEmployement = connector.model( - "Employee current Employement", - employeeCurrentEmployementSchema, -); diff --git a/models/employee/emp_edu_history.js b/models/employee/emp_edu_history.js deleted file mode 100644 index c242879a..00000000 --- a/models/employee/emp_edu_history.js +++ /dev/null @@ -1,33 +0,0 @@ -import connector from "#models/databaseUtil"; - -const Education = { - education_type: { type: String, required: true }, - education_name: { type: String, required: true }, - specialization: { type: String, required: true }, - period: { type: String, required: true }, - institution_name: { type: String, required: true }, - university: { type: String, required: true }, - passing_division: { type: String, required: true }, - from_year: { type: String, required: true }, - upto_year: { type: String, required: true }, - registration_number: { type: String, required: true }, - aggregate_pct: { type: String, required: true }, - final_year_pct: { type: String, required: true }, - number_of_attempts: { type: Number, required: true }, - rank: { type: Number, required: true }, - passing_year: { type: String, required: true }, -}; -const employeeEducationHistorySchema = { - uid: { type: String, require: true }, - ssc: { type: Education, required: true }, - hsc: { type: Education, required: true }, - dip: { type: Education }, - iti: { type: Education }, - deg: { type: Education }, - pgd: { type: Education }, - phd: { type: Education }, - pdoc: { type: Education }, -}; - -// eslint-disable-next-line no-unused-vars -const employeeEducationHistory = connector.model("Employee education history", employeeEducationHistorySchema); diff --git a/models/exam.js b/models/exam.js index cd267282..e5c2c0be 100644 --- a/models/exam.js +++ b/models/exam.js @@ -4,9 +4,21 @@ const examSchema = { date: { type: Date, required: true }, startTime: { type: Date, required: true }, duration: { type: Number, required: true }, - supervisor: { type: connector.Schema.Types.ObjectId, ref: "Faculty", required: "true" }, - infrastructure: { type: connector.Schema.Types.ObjectId, ref: "Infrastructure", required: "true" }, - course: { type: connector.Schema.Types.ObjectId, ref: "Course", required: "true" }, + supervisor: { + type: connector.Schema.Types.ObjectId, + ref: "Faculty", + required: "true", + }, + infrastructure: { + type: connector.Schema.Types.ObjectId, + ref: "Infrastructure", + required: "true", + }, + course: { + type: connector.Schema.Types.ObjectId, + ref: "Course", + required: "true", + }, }; const Exam = connector.model("Exam", examSchema); @@ -17,18 +29,27 @@ async function create(examData) { return examDoc; } -async function read(filter, limit = 1) { - const examDoc = await Exam.find(filter).limit(limit); - return examDoc; +async function read(filter, limit = 0, page = 1) { + const examDoc = await Exam.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Exam.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: examDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Exam.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Exam.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } async function remove(filter) { - const deleteResult = await Exam.deleteMany(filter).exec(); + const deleteResult = await Exam.deleteMany(filter); return deleteResult.acknowledged; } diff --git a/models/faculty.js b/models/faculty.js index 74bae6e6..c63a316e 100644 --- a/models/faculty.js +++ b/models/faculty.js @@ -1,48 +1,79 @@ -import connector from "#models/databaseUtil"; - -const facultySchema = { - ERPID: { type: String, required: true }, - dateOfJoining: { type: Date, required: true, default: Date.now }, - dateOfLeaving: { type: Date, required: false }, - profileLink: { type: String, required: true }, - qualifications: { type: [String], required: true }, - totalExperience: { type: Number, required: true }, - achievements: { type: [String], required: true }, - areaOfSpecialization: { type: [String], required: true }, - papersPublishedPG: { type: Number, required: true }, - papersPublishedUG: { type: Number, required: true }, - department: { type: connector.Schema.Types.ObjectId, ref: "Department", required: true }, - preferredSubjects: [{ type: connector.Schema.Types.ObjectId, ref: "Course", required: true }], - designation: { type: [String], enum: ["HOD", "Assistant Professor", "Associate Professor", "Activity Head"], required: true }, - natureOfAssociation: { type: String, enum: ["Regular", "Contract", "Adjunct"], required: true }, - additionalResponsibilities: { type: String, required: true }, -}; - -const Faculty = connector.model("Faculty", facultySchema); - -// CRUD Operations - -async function remove(filter) { - const deleteResult = await Faculty.deleteMany(filter); - return deleteResult.acknowledged; -} - -async function create(facultyData) { - const faculty = new Faculty(facultyData); - const facultyDoc = await faculty.save(); - return facultyDoc; -} - -async function read(filter, limit = 1) { - const facultyDoc = await Faculty.find(filter).limit(limit); - return facultyDoc; -} - -async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Faculty.updateMany(filter, { $set: updateObject }, options); - return updateResult.acknowledged; -} - -export default { - create, read, update, remove, -}; +import connector from "#models/databaseUtil"; + +const facultySchema = { + ERPID: { type: String, required: true }, + dateOfJoining: { type: Date, required: true, default: Date.now }, + dateOfLeaving: { type: Date, required: false }, + profileLink: { type: String, required: true }, + qualifications: { type: [String], required: true }, + totalExperience: { type: Number, required: true }, + achievements: { type: [String], required: true }, + areaOfSpecialization: { type: [String], required: true }, + papersPublishedPG: { type: Number, required: true }, + papersPublishedUG: { type: Number, required: true }, + department: { + type: connector.Schema.Types.ObjectId, + ref: "Department", + required: true, + }, + preferredSubjects: [ + { type: connector.Schema.Types.ObjectId, ref: "Course", required: true }, + ], + designation: { + type: [String], + enum: [ + "HOD", + "Assistant Professor", + "Associate Professor", + "Activity Head", + ], + required: true, + }, + natureOfAssociation: { + type: String, + enum: ["Regular", "Contract", "Adjunct"], + required: true, + }, + additionalResponsibilities: { type: String, required: true }, +}; + +const Faculty = connector.model("Faculty", facultySchema); + +// CRUD Operations + +async function remove(filter) { + const deleteResult = await Faculty.deleteMany(filter); + return deleteResult.acknowledged; +} + +async function create(facultyData) { + const faculty = new Faculty(facultyData); + const facultyDoc = await faculty.save(); + return facultyDoc; +} + +async function read(filter, limit = 0, page = 1) { + const facultyDoc = await Faculty.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Faculty.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: facultyDoc }; +} + +async function update(filter, updateObject, options = { multi: true }) { + const updateResult = await Faculty.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateResult.acknowledged; +} + +export default { + create, + read, + update, + remove, +}; diff --git a/models/group.js b/models/group.js index 57cfed1a..3a62f778 100644 --- a/models/group.js +++ b/models/group.js @@ -2,7 +2,9 @@ import connector from "#models/databaseUtil"; const groupSchema = { title: { type: String, required: true }, - students: [{ type: connector.Schema.Types.ObjectId, ref: "Student", required: true }], + students: [ + { type: connector.Schema.Types.ObjectId, ref: "Student", required: true }, + ], }; const Group = connector.model("Group", groupSchema); @@ -13,13 +15,22 @@ async function create(groupData) { return groupDoc; } -async function read(filter, limit = 1) { - const groupDoc = await Group.find(filter).limit(limit); - return groupDoc; +async function read(filter, limit = 0, page = 1) { + const groupDoc = await Group.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Group.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: groupDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Group.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Group.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } async function remove(groupId) { diff --git a/models/infrastructure.js b/models/infrastructure.js index b954f67e..299fb17b 100644 --- a/models/infrastructure.js +++ b/models/infrastructure.js @@ -16,9 +16,7 @@ async function remove(filter) { } async function create(infrastructureData) { - const { - name, type, wing, floor, capacity, - } = infrastructureData; + const { name, type, wing, floor, capacity } = infrastructureData; const infrastructure = new Infrastructure({ name, type, @@ -30,16 +28,28 @@ async function create(infrastructureData) { return infrastructureDoc; } -async function read(filter, limit = 1) { - const infrastructureDoc = await Infrastructure.find(filter).limit(limit); - return infrastructureDoc; +async function read(filter, limit = 0, page = 1) { + const infrastructureDoc = await Infrastructure.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Infrastructure.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: infrastructureDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Infrastructure.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Infrastructure.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } export default { - create, read, update, remove, + create, + read, + update, + remove, }; diff --git a/models/module.js b/models/module.js index 8aa1a941..c72c5857 100644 --- a/models/module.js +++ b/models/module.js @@ -6,11 +6,13 @@ const moduleSchema = { outcome: { type: String, required: true }, contents: [{ type: String, required: true }], hrsPerModule: { type: Number, required: true }, - cognitiveLevels: [{ - type: String, - required: true, - enum: ["L1", "L2", "L3", "L4", "L5", "L6"], - }], + cognitiveLevels: [ + { + type: String, + required: true, + enum: ["L1", "L2", "L3", "L4", "L5", "L6"], + }, + ], }; const Module = connector.model("Module", moduleSchema); @@ -21,9 +23,8 @@ async function remove(filter) { } async function create(moduleData) { - const { - no, name, outcome, contents, hrsPerModule, cognitiveLevels, - } = moduleData; + const { no, name, outcome, contents, hrsPerModule, cognitiveLevels } = + moduleData; const module = new Module({ no, name, @@ -36,13 +37,22 @@ async function create(moduleData) { return moduleDoc; } -async function read(filter, limit = 1) { - const moduleDoc = await Module.find(filter).limit(limit); - return moduleDoc; +async function read(filter, limit = 0, page = 1) { + const moduleDoc = await Module.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Module.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: moduleDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Module.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Module.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } diff --git a/models/notification.js b/models/notification.js new file mode 100644 index 00000000..8cac4fe9 --- /dev/null +++ b/models/notification.js @@ -0,0 +1,76 @@ +import connector from "#models/databaseUtil"; + +const notificationSchema = { + data: { + type: String, + required: true, + }, + title: { + type: String, + required: true, + }, + from: { + type: connector.Schema.Types.ObjectId, + ref: "Faculty", // Reference to the Faculty model + required: true, + }, + type: { + type: String, + enum: ["Student", "Faculty"], + required: true, + }, + filter: [ + { + type: connector.Schema.Types.ObjectId, + ref: "User", // You might have a User model for storing IDs + }, + ], +}; + +const Notification = connector.model("Notification", notificationSchema); + +// CRUD Operations + +async function create(notificationData) { + const { data, title, from, type, filter } = notificationData; + const notification = new Notification({ + data, + title, + from, + type, + filter, + }); + const notificationDOC = await notification.save(); + return notificationDOC; +} + +async function read(filter, limit = 0, page = 1) { + const notificationDoc = await Notification.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Notification.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: notificationDoc }; +} + +async function update(filter, updateObject, options = { multi: true }) { + const updateResult = await Notification.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateResult.acknowledged; +} + +async function remove(filter) { + const deleteResult = await Notification.deleteMany(filter); + return deleteResult.acknowledged; +} + +export default { + create, + read, + update, + remove, +}; diff --git a/models/organization.js b/models/organization.js index acd6bfe4..615857e8 100644 --- a/models/organization.js +++ b/models/organization.js @@ -1,10 +1,20 @@ import connector from "#models/databaseUtil"; const organizationSchema = { - parent: { type: connector.Schema.Types.ObjectId, ref: "Organization", required: "true" }, + parent: { + type: connector.Schema.Types.ObjectId, + ref: "Organization", + required: "true", + }, startDate: { type: Date, required: true }, name: { type: String, required: true }, - accreditations: [{ type: connector.Schema.Types.ObjectId, ref: "Accrediation", required: "true" }], + accreditations: [ + { + type: connector.Schema.Types.ObjectId, + ref: "Accrediation", + required: "true", + }, + ], }; const Organization = connector.model("Organization", organizationSchema); @@ -15,9 +25,7 @@ async function remove(filter) { } async function create(organizationData) { - const { - parent, startDate, name, accreditation, - } = organizationData; + const { parent, startDate, name, accreditation } = organizationData; const organization = new Organization({ parent, startDate, @@ -28,16 +36,28 @@ async function create(organizationData) { return organizationDoc; } -async function read(filter, limit = 1) { - const organizationDoc = await Organization.find(filter).limit(limit); - return organizationDoc; +async function read(filter, limit = 0, page = 1) { + const organizationDoc = await Organization.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Organization.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: organizationDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Organization.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Organization.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } export default { - create, read, update, remove, + create, + read, + update, + remove, }; diff --git a/models/paper.js b/models/paper.js index 1bb2d467..29785c04 100644 --- a/models/paper.js +++ b/models/paper.js @@ -2,9 +2,15 @@ import connector from "#models/databaseUtil"; const paperSchema = { answerSheetID: { type: String, required: true }, - exam: [{ type: connector.Schema.Types.ObjectId, ref: "Exam", required: true }], - student: [{ type: connector.Schema.Types.ObjectId, ref: "Student", required: true }], - checkedBy: [{ type: connector.Schema.Types.ObjectId, ref: "Faculty", required: true }], + exam: [ + { type: connector.Schema.Types.ObjectId, ref: "Exam", required: true }, + ], + student: [ + { type: connector.Schema.Types.ObjectId, ref: "Student", required: true }, + ], + checkedBy: [ + { type: connector.Schema.Types.ObjectId, ref: "Faculty", required: true }, + ], mark: { type: Number, required: true }, }; @@ -18,9 +24,7 @@ async function remove(filter) { } async function create(paperData) { - const { - answerSheetID, exam, student, checkedBy, mark, - } = paperData; + const { answerSheetID, exam, student, checkedBy, mark } = paperData; const paper = new Paper({ answerSheetID, exam, @@ -32,16 +36,28 @@ async function create(paperData) { return paperDoc; } -async function read(filter, limit = 1) { - const paperDoc = await Paper.find(filter).limit(limit); - return paperDoc; +async function read(filter, limit = 0, page = 1) { + const paperDoc = await Paper.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Paper.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: paperDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Paper.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Paper.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } export default { - create, read, update, remove, + create, + read, + update, + remove, }; diff --git a/models/practical.js b/models/practical.js index 01037892..199e97c5 100644 --- a/models/practical.js +++ b/models/practical.js @@ -5,11 +5,13 @@ const practicalSchema = { type: { type: String, required: true }, title: { type: String, required: true }, hours: { type: Number, required: true }, - cognitiveLevels: [{ - type: String, - required: true, - enum: ["L1", "L2", "L3", "L4", "L5", "L6"], - }], + cognitiveLevels: [ + { + type: String, + required: true, + enum: ["L1", "L2", "L3", "L4", "L5", "L6"], + }, + ], }; // eslint-disable-next-line no-unused-vars @@ -22,9 +24,7 @@ async function remove(filter) { } async function create(practicalData) { - const { - no, type, title, hours, cognitiveLevels, - } = practicalData; + const { no, type, title, hours, cognitiveLevels } = practicalData; const practical = new Practical({ no, type, @@ -36,16 +36,31 @@ async function create(practicalData) { return practicalDoc; } -async function read(filter, limit = 1) { - const practicalDoc = await Practical.find(filter).limit(limit); - return practicalDoc; +async function read(filter, limit = 0, page = 1) { + const practicalDoc = await Practical.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Practical.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: practicalDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Practical.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Practical.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } +// create({no: 2, type: 'test4', title: 'test4', hours: 2, cognitiveLevels: ['L3']}) +// read({title: 'test1'}) + export default { - create, read, update, remove, + create, + read, + update, + remove, }; diff --git a/models/semester.js b/models/semester.js index fb43dd72..b3406261 100644 --- a/models/semester.js +++ b/models/semester.js @@ -7,7 +7,8 @@ const semesterSchema = { required: true, validate: { validator: (value) => /^20\d{2}$/.test(value), - message: (props) => `${props.value} is not a valid year format starting with "2"!`, + message: (props) => + `${props.value} is not a valid year format starting with "2"!`, }, }, type: { type: String, enum: ["ODD", "EVEN"], required: true }, @@ -21,32 +22,34 @@ const Semester = connector.model("Semester", semesterSchema); // CURD operations async function create(semesterData) { - const { - number, - academicYear, - type, - startDate, - endDate, - } = semesterData; + const { number, academicYear, type, startDate, endDate } = semesterData; const semester = new Semester({ number, academicYear, type, startDate, endDate, - }); const semesterDoc = await semester.save(); return semesterDoc; } -async function read(filter, limit = 1) { - const semesterDoc = await Semester.find(filter).limit(limit); - return semesterDoc; +async function read(filter, limit = 0, page = 1) { + const semesterDoc = await Semester.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Semester.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: semesterDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Semester.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Semester.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } @@ -55,5 +58,8 @@ async function remove(filter) { return deleteResult.acknowledged; } export default { - create, remove, update, read, + create, + remove, + update, + read, }; diff --git a/models/student.js b/models/student.js index c07c2645..afdab1f3 100644 --- a/models/student.js +++ b/models/student.js @@ -4,10 +4,16 @@ const studentSchema = { ERPID: { type: String, required: true }, name: { type: String, required: true }, joiningYear: { type: Number, required: true }, - branch: { type: connector.Schema.Types.ObjectId, ref: "Department", required: true }, + branch: { + type: connector.Schema.Types.ObjectId, + ref: "Department", + required: true, + }, division: { type: String, enum: ["A", "B", "C"], default: "A" }, rollNo: { type: Number, required: true }, - coursesOpted: [{ type: connector.Schema.Types.ObjectId, ref: "Course", required: true }], + coursesOpted: [ + { type: connector.Schema.Types.ObjectId, ref: "Course", required: true }, + ], }; // eslint-disable-next-line no-unused-vars @@ -22,9 +28,8 @@ async function remove(filter) { } async function create(studentData) { - const { - ERPID, name, joiningYear, branch, division, rollNo, coursesOpted, - } = studentData; + const { ERPID, name, joiningYear, branch, division, rollNo, coursesOpted } = + studentData; const student = new Student({ ERPID, name, @@ -38,16 +43,28 @@ async function create(studentData) { return studentDoc; } -async function read(filter, limit = 1) { - const studentDoc = await Student.find(filter).limit(limit); - return studentDoc; +async function read(filter, limit = 0, page = 1) { + const studentDoc = await Student.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Student.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: studentDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Student.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Student.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } export default { - create, read, update, remove, + create, + read, + update, + remove, }; diff --git a/models/student/stdBank.js b/models/student/stdBank.js new file mode 100644 index 00000000..f998afbc --- /dev/null +++ b/models/student/stdBank.js @@ -0,0 +1,85 @@ +import connector from "#models/databaseUtil"; + +const studentBankSchema = { + uid: { + type: String, + required: true, + unique: true, + }, + bankName: { + type: String, + required: true, + minLength: 7, + }, + bankAccount: { + type: String, + required: true, + unique: true, + }, + bankBranch: { + type: String, + required: true, + }, + bankIfsc: { + type: String, + required: true, + maxLength: 11, + minLength: 11, + }, + bankMicr: { + type: String, + required: true, + maxLength: 9, + minLength: 9, + }, +}; + +const StudentBank = connector.model("Student bank", studentBankSchema); + +async function create(studentBankData) { + const { uid, bankName, bankAccount, bankBranch, bankIfsc, bankMicr } = + studentBankData; + + const stdBank = new StudentBank({ + uid, + bankName, + bankAccount, + bankBranch, + bankIfsc, + bankMicr, + }); + + const stdBankDoc = await stdBank.save(); + return stdBankDoc; +} + +async function read(filter, limit = 0, page = 1) { + const stdBankDoc = await StudentBank.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await StudentBank.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: stdBankDoc }; +} + +async function update(filter, updateObject, options = { multi: true }) { + const updateResult = await StudentBank.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateResult.acknowledged; +} + +async function remove(stdBankId) { + const deleteResult = await StudentBank.deleteMany(stdBankId); + return deleteResult.acknowledged; +} + +export default { + create, + read, + update, + remove, +}; diff --git a/models/student/stdCollege.js b/models/student/stdCollege.js new file mode 100644 index 00000000..8ef0fba7 --- /dev/null +++ b/models/student/stdCollege.js @@ -0,0 +1,129 @@ +import connector from "#models/databaseUtil"; + +const studentCollegeSchema = { + uid: { + type: String, + required: true, + unique: true, + }, + admissionYear: { + type: String, + required: true, + }, + studentCode: { + type: String, + }, + rollNo: { + type: String, + }, + admissionStatus: { + type: String, + required: true, + }, + admissionPattern: { + type: String, + }, + admissionCategory: { + type: String, + required: true, + }, + seatDesc: { + type: String, + }, + quotaType: { + type: String, + required: true, + }, + isBoarderStudent: { + type: Boolean, + }, + seatType: { + type: String, + required: true, + }, + seatSubType: { + type: String, + required: true, + }, + eligibilityNo: { + type: String, + required: true, + }, + enrollmentNo: { + type: String, + required: true, + unique: true, + }, +}; + +const StudentCollege = connector.model("Student college", studentCollegeSchema); + +async function create(studentCollegeData) { + const { + uid, + admissionYear, + studentCode, + rollNo, + admissionStatus, + admissionPattern, + admissionCategory, + seatDesc, + quotaType, + isBoarderStudent, + seatType, + seatSubType, + eligibilityNo, + enrollmentNo, + } = studentCollegeData; + + const stdCollege = new StudentCollege({ + uid, + admissionYear, + studentCode, + rollNo, + admissionStatus, + admissionPattern, + admissionCategory, + seatDesc, + quotaType, + isBoarderStudent, + seatType, + seatSubType, + eligibilityNo, + enrollmentNo, + }); + + const stdCollegeDoc = await stdCollege.save(); + return stdCollegeDoc; +} + +async function read(filter, limit = 0, page = 1) { + const stdCollegeDoc = await StudentCollege.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await StudentCollege.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: stdCollegeDoc }; +} + +async function update(filter, updateObject, options = { multi: true }) { + const updateResult = await StudentCollege.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateResult.acknowledged; +} + +async function remove(stdCollegeId) { + const deleteResult = await StudentCollege.deleteMany(stdCollegeId); + return deleteResult.acknowledged; +} + +export default { + create, + read, + update, + remove, +}; diff --git a/models/student/stdEduHistory.js b/models/student/stdEduHistory.js new file mode 100644 index 00000000..9fca7c04 --- /dev/null +++ b/models/student/stdEduHistory.js @@ -0,0 +1,204 @@ +import connector from "#models/databaseUtil"; + +const studentEducationSchema = { + uid: { type: String, required: true }, + // tenth_details + tenth: { + marks: { type: String, required: true }, + percentage: { type: Number, required: true }, + seatNumber: { type: String, required: true }, + examName: { type: String, required: true }, + examBoard: { type: String, required: true }, + msOms: { type: String, required: true }, + meritNumberInQualifyingExam: { type: String, required: true }, + admittedNumber: { type: String, required: true }, + }, + cetHscDetails: { + cetRollNo: { type: String, required: true }, + cetMarks: { type: String, required: true }, + qualifyingExamForAdmission: { type: String, required: true }, + stdType: { type: String, required: true }, + streamOpted: { type: String, required: true }, + mediumOfInstruction: { type: String, required: true }, + aggTotalMarks: { type: Number, required: true }, + totalMarksOutOf: { type: Number, required: true }, + percentOfMarks: { type: String, required: true }, + attemptNo: { type: String, required: true }, + passingMonth: { type: String, required: true }, + passingYear: { type: String, required: true }, + institutionName: { type: String, required: true }, + educBoardName: { type: String, required: true }, + pcmPercent: { type: String, required: true }, + pbmPercent: { type: String, required: true }, + stuQualifyingExam: { type: String, required: true }, + marksObtained: { type: String, required: true }, + stateRank: { type: String, required: true }, + prevExamSeatNumber: { type: String, required: false }, + prevTcNumber: { type: String, required: false }, + hscPassedSchoolName: { type: String, required: true }, + boardPattern: { type: String, required: true }, + scholarshipName: { type: String, required: false }, + scholarshipType: { type: String, required: false }, + dteSeatType: { type: String, required: true }, + dteUserPassword: { type: String, required: true }, + dteUserId: { type: String, required: true }, + }, + graduationDetails: { + graduationInstitute: { type: String, required: true }, + graduationBranch: { type: String, required: true }, + graduationDegree: { type: String, required: true }, + graduationMarksPct: { type: Number, required: true }, + graduationsPassingYear: { type: String, required: true }, + urbanRural: { type: String, required: true }, + scholarshipNumber: { type: String, required: false }, + lastSchoolCollegeAttended: { type: String, required: true }, + }, +}; + +const StudentEducation = connector.model( + "Student education", + studentEducationSchema, +); + +async function create(studentEducationData) { + const { + uid, + tenth: { + marks, + percentage, + seatNumber, + examName, + examBoard, + msOms, + meritNumberInQualifyingExam, + admittedNumber, + }, + cetHscDetails: { + cetRollNo, + cetMarks, + qualifyingExamForAdmission, + stdType, + streamOpted, + mediumOfInstruction, + aggTotalMarks, + totalMarksOutOf, + percentOfMarks, + attemptNo, + passingMonth, + passingYear, + institutionName, + educBoardName, + pcmPercent, + pbmPercent, + stuQualifyingExam, + marksObtained, + stateRank, + prevExamSeatNumber, + prevTcNumber, + hscPassedSchoolName, + boardPattern, + scholarshipName, + scholarshipType, + dteSeatType, + dteUserPassword, + dteUserId, + }, + graduationDetails: { + graduationInstitute, + graduationBranch, + graduationDegree, + graduationMarksPct, + graduationsPassingYear, + urbanRural, + scholarshipNumber, + lastSchoolCollegeAttended, + }, + } = studentEducationData; + + const stdEducation = new StudentEducation({ + uid, + tenth: { + marks, + percentage, + seatNumber, + examName, + examBoard, + msOms, + meritNumberInQualifyingExam, + admittedNumber, + }, + cetHscDetails: { + cetRollNo, + cetMarks, + qualifyingExamForAdmission, + stdType, + streamOpted, + mediumOfInstruction, + aggTotalMarks, + totalMarksOutOf, + percentOfMarks, + attemptNo, + passingMonth, + passingYear, + institutionName, + educBoardName, + pcmPercent, + pbmPercent, + stuQualifyingExam, + marksObtained, + stateRank, + prevExamSeatNumber, + prevTcNumber, + hscPassedSchoolName, + boardPattern, + scholarshipName, + scholarshipType, + dteSeatType, + dteUserPassword, + dteUserId, + }, + graduationDetails: { + graduationInstitute, + graduationBranch, + graduationDegree, + graduationMarksPct, + graduationsPassingYear, + urbanRural, + scholarshipNumber, + lastSchoolCollegeAttended, + }, + }); + const stdEducationDoc = await stdEducation.save(); + return stdEducationDoc; +} + +async function read(filter, limit = 0, page = 1) { + const stdEducationDoc = await StudentEducation.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await StudentEducation.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: stdEducationDoc }; +} + +async function update(filter, updateObject, options = { multi: true }) { + const updateResult = await studentEducationSchema.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateResult.acknowledged; +} + +async function remove(stdEducationId) { + const deleteResult = await studentEducationSchema.deleteMany(stdEducationId); + return deleteResult.acknowledged; +} + +export default { + create, + read, + update, + remove, +}; diff --git a/models/student/stdMedHistory.js b/models/student/stdMedHistory.js new file mode 100644 index 00000000..4d3f63ad --- /dev/null +++ b/models/student/stdMedHistory.js @@ -0,0 +1,72 @@ +import connector from "#models/databaseUtil"; + +const studentMedicalSchema = { + uid: { type: String, required: true }, + bloodGroup: { type: String, required: true }, + pastMedicalHistory: { type: String, required: true }, + immunisationHistory: { type: String, required: true }, + chronicMedicalConditions: { type: String }, + parentsEmailId: { type: String, required: true }, + parentsContact: { type: Number, required: true }, + relativeContacts: { type: Number, required: true }, +}; + +const MedicalHistory = connector.model("StudentMedical", studentMedicalSchema); + +// CRUD OPERATIONS + +async function remove(filter) { + const deleteResult = await MedicalHistory.deleteMany(filter); + return deleteResult.acknowledged; +} + +async function create(studentMedicalData) { + const { + uid, + bloodGroup, + pastMedicalHistory, + immunisationHistory, + chronicMedicalConditions, + parentsEmailId, + parentsContact, + relativeContacts, + } = studentMedicalData; + const medicalHistory = new MedicalHistory({ + uid, + bloodGroup, + pastMedicalHistory, + immunisationHistory, + chronicMedicalConditions, + parentsEmailId, + parentsContact, + relativeContacts, + }); + const medicalHistoryDoc = await medicalHistory.save(); + return medicalHistoryDoc; +} + +async function read(filter, limit = 0, page = 1) { + const medicalHistoryDoc = await MedicalHistory.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await MedicalHistory.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: medicalHistoryDoc }; +} + +async function update(filter, updateObject, options = { multi: true }) { + const updateResult = await MedicalHistory.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateResult.acknowledged; +} + +export default { + create, + read, + update, + remove, +}; diff --git a/models/student/stdPersonal.js b/models/student/stdPersonal.js new file mode 100644 index 00000000..36591096 --- /dev/null +++ b/models/student/stdPersonal.js @@ -0,0 +1,289 @@ +import connector from "#models/databaseUtil"; + +const studentPersonalSchema = { + uid: { type: String, require: true }, + title: { type: String, required: true }, + firstName: { type: String, required: true }, + middleName: { type: String, required: true }, + motherName: { type: String, required: true }, + gender: { type: String, required: true }, + dob: { type: Date, required: true }, + age: { type: Number, required: true }, + birthPlace: { type: String, required: true }, + nationality: { type: String, required: true }, + motherTongue: { type: String, required: true }, + domicileState: { type: String, required: true }, + religion: { type: String, required: true }, + castCategory: { type: String, required: true }, + maharashtraKarnatakaBorderCandidate: { type: Boolean, required: true }, + castDescription: { type: String, required: true }, + subCasteDescription: { type: String, required: true }, + nonCreamyLayerCertificateAttached: { type: Boolean, required: true }, + hobby: { type: String, required: true }, + passportNo: { type: Number }, + bloodGroup: { type: String, required: true }, + physicallyHandicapped: { type: Boolean, required: true }, + studentMobNo: { type: Number, required: true }, + studentMail: { type: String, required: true }, + parentMobNo: { type: Number, required: true }, + parentMail: { type: String, required: true }, + perAddrDescr: { type: String, required: true }, + perPlotNo: { type: Number, required: true }, + perStreetName: { type: String, required: true }, + perStuAddr1: { type: String, required: true }, + perStuAddr2: { type: String }, + city: { type: String, required: true }, + percellphone: { type: Number, required: true }, + perpincode: { type: Number, required: true }, + perresiphone: { type: Number, required: true }, + permailaddress: { type: String, required: true }, + country: { type: String, required: true }, + state: { type: String, required: true }, + district: { type: String, required: true }, + tahsil: { type: String, required: true }, + correspondanceAddrDescr: { type: String }, + correspondancePlotNo: { type: Number }, + correspondanceStreetName: { type: String }, + correspondanceStuAddr1: { type: String }, + correspondanceStuAddr2: { type: String }, + correspondanceCity: { type: String }, + correspondanceCellPhone: { type: Number }, + correspondancePincode: { type: Number }, + correspondanceResiPhone: { type: Number }, + correspondanceMailAddress: { type: String }, + correspondanceCountry: { type: String }, + correspondanceState: { type: String }, + correspondanceDistrict: { type: String }, + correspondanceTahsil: { type: String }, + fatherDetails: { type: String, required: true }, + fathersOccupation: { type: String, required: true }, + parentsFirstName: { type: String, required: true }, + parentsMiddleName: { type: String, required: true }, + parentsLastName: { type: String, required: true }, + guardianMobNo: { type: Number }, + guardianMailId: { type: String }, + nameAsPerTc: { type: String }, + casteAsPerTc: { type: String }, + birthStatus: { type: String, required: true }, + maritalStatus: { type: Boolean, required: true }, + panCardNo: { type: Number }, + passportExpiry: { type: Date }, + drivingLicNo: { type: Number }, + drivingLicValidTo: { type: Date }, + aadharCardNo: { type: Number, required: true }, + electionCardNo: { type: Number }, + motherMobNo: { type: Number }, + motherEmailId: { type: String }, + parentIncome: { type: Number, required: true }, + photoUploaded: { type: Boolean, required: true }, + signUploaded: { type: Boolean, required: true }, + thumbUploaded: { type: Boolean, required: true }, + noOfDocumentsUploaded: { type: Number, required: true }, +}; + +// eslint-disable-next-line no-unused-vars +const StdPersonal = connector.model("Student personal", studentPersonalSchema); + +/// crud operation/// + +// student personal details to the database +async function create(studentData) { + const { + uid, + title, + firstName, + middleName, + motherName, + gender, + dob, + age, + birthPlace, + nationality, + motherTongue, + domicileState, + religion, + castCategory, + maharashtraKarnatakaBorderCandidate, + castDescription, + subCasteDescription, + nonCreamyLayerCertificateAttached, + hobby, + passportNo, + bloodGroup, + physicallyHandicapped, + studentMobNo, + studentMail, + parentMobNo, + parentMail, + perAddrDescr, + perPlotNo, + perStreetName, + perStuAddr1, + perStuAddr2, + city, + percellphone, + perpincode, + perresiphone, + permailaddress, + country, + state, + district, + tahsil, + correspondanceAddrDescr, + correspondancePlotNo, + correspondanceStreetName, + correspondanceStuAddr1, + correspondanceStuAddr2, + correspondanceCity, + correspondanceCellPhone, + correspondancePincode, + correspondanceResiPhone, + correspondanceMailAddress, + correspondanceCountry, + correspondanceState, + correspondanceDistrict, + correspondanceTahsil, + fatherDetails, + fathersOccupation, + parentsFirstName, + parentsMiddleName, + parentsLastName, + guardianMobNo, + guardianMailId, + nameAsPerTc, + casteAsPerTc, + birthStatus, + maritalStatus, + panCardNo, + passportExpiry, + drivingLicNo, + drivingLicValidTo, + aadharCardNo, + electionCardNo, + motherMobNo, + motherEmailId, + parentIncome, + photoUploaded, + signUploaded, + thumbUploaded, + noOfDocumentsUploaded, + } = studentData; + const student = new StdPersonal({ + uid, + title, + firstName, + middleName, + motherName, + gender, + dob, + age, + birthPlace, + nationality, + motherTongue, + domicileState, + religion, + castCategory, + maharashtraKarnatakaBorderCandidate, + castDescription, + subCasteDescription, + nonCreamyLayerCertificateAttached, + hobby, + passportNo, + bloodGroup, + physicallyHandicapped, + studentMobNo, + studentMail, + parentMobNo, + parentMail, + perAddrDescr, + perPlotNo, + perStreetName, + perStuAddr1, + perStuAddr2, + city, + percellphone, + perpincode, + perresiphone, + permailaddress, + country, + state, + district, + tahsil, + correspondanceAddrDescr, + correspondancePlotNo, + correspondanceStreetName, + correspondanceStuAddr1, + correspondanceStuAddr2, + correspondanceCity, + correspondanceCellPhone, + correspondancePincode, + correspondanceResiPhone, + correspondanceMailAddress, + correspondanceCountry, + correspondanceState, + correspondanceDistrict, + correspondanceTahsil, + fatherDetails, + fathersOccupation, + parentsFirstName, + parentsMiddleName, + parentsLastName, + guardianMobNo, + guardianMailId, + nameAsPerTc, + casteAsPerTc, + birthStatus, + maritalStatus, + panCardNo, + passportExpiry, + drivingLicNo, + drivingLicValidTo, + aadharCardNo, + electionCardNo, + motherMobNo, + motherEmailId, + parentIncome, + photoUploaded, + signUploaded, + thumbUploaded, + noOfDocumentsUploaded, + }); + const studentDoc = await student.save(); + return studentDoc; +} + +// Retrieve student personal details based on a given filter and limit +async function read(filter, limit = 0, page = 1) { + const studentDoc = await StdPersonal.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await StdPersonal.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: studentDoc }; +} + +// update student personal details based on a given filter +async function update(filter, updateObject, options = { multi: true }) { + const updateStudent = await StdPersonal.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateStudent.acknowledged; +} + +// Delete student personal details based on a given filter +async function remove(filter) { + const deleteStudent = await StdPersonal.deleteMany(filter).exec(); + return deleteStudent.acknowledged; +} + +// export crud functions + +export default { + create, + read, + update, + remove, +}; diff --git a/models/student/std_bank.js b/models/student/std_bank.js deleted file mode 100644 index dbee9843..00000000 --- a/models/student/std_bank.js +++ /dev/null @@ -1,38 +0,0 @@ -import connector from "#models/databaseUtil"; - -const studentBankSchema = { - uid: { - type: String, - required: true, - unique: true, - }, - bank_name: { - type: String, - required: true, - minLength: 7, - }, - bank_acc: { - type: String, - required: true, - unique: true, - }, - bank_branch: { - type: String, - required: true, - }, - bank_ifsc: { - type: String, - required: true, - maxLength: 11, - minLength: 11, - }, - bank_micr: { - type: String, - required: true, - maxLength: 9, - minLength: 9, - }, -}; - -// eslint-disable-next-line no-unused-vars -const stdBank = connector.model("Student bank", studentBankSchema); diff --git a/models/student/std_college.js b/models/student/std_college.js deleted file mode 100644 index 39e52899..00000000 --- a/models/student/std_college.js +++ /dev/null @@ -1,60 +0,0 @@ -import connector from "#models/databaseUtil"; - -const studentCollegeSchema = { - uid: { - type: String, - required: true, - unique: true, - }, - admission_year: { - type: String, - required: true, - }, - student_code: { - type: String, - }, - roll_no: { - type: String, - }, - admission_status: { - type: String, - required: true, - }, - admission_pattern: { - type: String, - }, - admission_category: { - type: String, - required: true, - }, - seat_desc: { - type: String, - }, - quota_type: { - type: String, - required: true, - }, - is_boarder_student: { - type: Boolean, - }, - seat_type: { - type: String, - required: true, - }, - seat_sub_type: { - type: String, - required: true, - }, - eligibility_no: { - type: String, - required: true, - }, - enrollment_no: { - type: String, - required: true, - unique: true, - }, -}; - -// eslint-disable-next-line no-unused-vars -const studenCollege = connector.model("Student college", studentCollegeSchema); diff --git a/models/student/std_edu_history.js b/models/student/std_edu_history.js deleted file mode 100644 index 4b5153e7..00000000 --- a/models/student/std_edu_history.js +++ /dev/null @@ -1,59 +0,0 @@ -import connector from "#models/databaseUtil"; - -const studentEducationSchema = { - uid: { type: String, require: true }, - // tenth_details - tenth: { - marks: { type: String, required: true }, - percentage: { type: Number, required: true }, - seat_number: { type: String, required: true }, - exam_name: { type: String, required: true }, - exam_board: { type: String, required: true }, - ms_oms: { type: String, required: true }, - merit_number_in_qualifying_exam: { type: String, required: true }, - admitted_number: { type: String, required: true }, - }, - cet_hsc_details: { - cet_roll_no: { type: String, required: true }, - cet_marks: { type: String, required: true }, - qualifying_exam_for_admission: { type: String, required: true }, - std_type: { type: String, required: true }, - stream_opted: { type: String, required: true }, - medium_of_instruction: { type: String, required: true }, - agg_total_marks: { type: Number, required: true }, - total_marks_out_of: { type: Number, required: true }, - percent_of_marks: { type: String, required: true }, - attempt_no: { type: String, required: true }, - passing_month: { type: String, required: true }, - passing_year: { type: String, required: true }, - institution_name: { type: String, required: true }, - educ_board_name: { type: String, required: true }, - pcm_percent: { type: String, required: true }, - pbm_percent: { type: String, required: true }, - stu_qualifying_exam: { type: String, required: true }, - marks_obtained: { type: String, required: true }, - state_rank: { type: String, required: true }, - prev_exam_seat_number: { type: String, required: false }, - prev_tc_number: { type: String, required: false }, - hsc_passed_school_name: { type: String, required: true }, - board_pattern: { type: String, required: true }, - scholarship_name: { type: String, required: false }, - scholarship_type: { type: String, required: false }, - dte_seat_type: { type: String, required: true }, - dte_user_password: { type: String, required: true }, - dte_user_id: { type: String, required: true }, - }, - graduation_details: { - graduation_institute: { type: String, required: true }, - graduation_branch: { type: String, required: true }, - graduation_degree: { type: String, required: true }, - graduation_marks_pct: { type: Number, required: true }, - graduations_passing_year: { type: String, required: true }, - urban_rural: { type: String, required: true }, - scholarship_number: { type: String, required: false }, - last_school_college_attended: { type: String, required: true }, - }, -}; - -// eslint-disable-next-line no-unused-vars -const studentEducation = connector.model("Student education", studentEducationSchema); diff --git a/models/student/std_med_history.js b/models/student/std_med_history.js deleted file mode 100644 index d6792847..00000000 --- a/models/student/std_med_history.js +++ /dev/null @@ -1,15 +0,0 @@ -import connector from "#models/databaseUtil"; - -const studentMedicalSchema = { - uid: { type: String, require: true }, - blood_group: { type: String, required: true }, - past_medical_history: { type: String, required: true }, - immunisation_history: { type: String, required: true }, - chronic_medical_conditions: { type: String }, - parents_emailId: { type: String, required: true }, - parents_contact: { type: Number, required: true }, - relative_contacts: { type: Number, required: true }, -}; - -// eslint-disable-next-line no-unused-vars -const medicalHistory = connector.model("Student medical", studentMedicalSchema); diff --git a/models/student/std_personal.js b/models/student/std_personal.js deleted file mode 100644 index 56c382b7..00000000 --- a/models/student/std_personal.js +++ /dev/null @@ -1,85 +0,0 @@ -import connector from "#models/databaseUtil"; - -const studentPersonalSchema = { - uid: { type: String, require: true }, - title: { type: String, required: true }, - firstName: { type: String, required: true }, - middleName: { type: String, required: true }, - motherName: { type: String, required: true }, - gender: { type: String, required: true }, - dob: { type: Date, required: true }, - age: { type: Number, required: true }, - birthPlace: { type: String, required: true }, - nationality: { type: String, required: true }, - motherTongue: { type: String, required: true }, - domicileState: { type: String, required: true }, - religion: { type: String, required: true }, - castCategory: { type: String, required: true }, - maharashtraKarnatakaBorderCandidate: { type: Boolean, required: true }, - castDescription: { type: String, required: true }, - subCasteDescription: { type: String, required: true }, - nonCreamyLayerCertificateAttached: { type: Boolean, required: true }, - hobby: { type: String, required: true }, - passportNo: { type: Number }, - bloodGroup: { type: String, required: true }, - physicallyHandicapped: { type: Boolean, required: true }, - studentMobNo: { type: Number, required: true }, - studentMail: { type: String, required: true }, - parentMobNo: { type: Number, required: true }, - parentMail: { type: String, required: true }, - perAddrDescr: { type: String, required: true }, - perPlotNo: { type: Number, required: true }, - perStreetName: { type: String, required: true }, - perStuAddr1: { type: String, required: true }, - perStuAddr2: { type: String }, - city: { type: String, required: true }, - percellphone: { type: Number, required: true }, - perpincode: { type: Number, required: true }, - perresiphone: { type: Number, required: true }, - permailaddress: { type: String, required: true }, - country: { type: String, required: true }, - state: { type: String, required: true }, - district: { type: String, required: true }, - tahsil: { type: String, required: true }, - correspondanceAddrDescr: { type: String }, - correspondancePlotNo: { type: Number }, - correspondanceStreetName: { type: String }, - correspondanceStuAddr1: { type: String }, - correspondanceStuAddr2: { type: String }, - correspondanceCity: { type: String }, - correspondanceCellPhone: { type: Number }, - correspondancePincode: { type: Number }, - correspondanceResiPhone: { type: Number }, - correspondanceMailAddress: { type: String }, - correspondanceCountry: { type: String }, - correspondanceState: { type: String }, - correspondanceDistrict: { type: String }, - correspondanceTahsil: { type: String }, - fatherDetails: { type: String, required: true }, - fathersOccupation: { type: String, required: true }, - parentsFirstName: { type: String, required: true }, - parentsMiddleName: { type: String, required: true }, - parentsLastName: { type: String, required: true }, - guardianMobNo: { type: Number }, - guardianMailId: { type: String }, - nameAsPerTc: { type: String }, - casteAsPerTc: { type: String }, - birthStatus: { type: String, required: true }, - maritalStatus: { type: Boolean, required: true }, - panCardNo: { type: Number }, - passportExpiry: { type: Date }, - drivingLicNo: { type: Number }, - drivingLicValidTo: { type: Date }, - aadharCardNo: { type: Number, required: true }, - electionCardNo: { type: Number }, - motherMobNo: { type: Number }, - motherEmailId: { type: String }, - parentIncome: { type: Number, required: true }, - photoUploaded: { type: Boolean, required: true }, - signUploaded: { type: Boolean, required: true }, - thumbUploaded: { type: Boolean, required: true }, - noOfDocumentsUploaded: { type: Number, required: true }, -}; - -// eslint-disable-next-line no-unused-vars -const stdPersonal = connector.model("Student personal", studentPersonalSchema); diff --git a/models/timetable.js b/models/timetable.js index 854bf9b0..44d1510d 100644 --- a/models/timetable.js +++ b/models/timetable.js @@ -58,13 +58,22 @@ async function create(timetableData) { return timetableDoc; } -async function read(filter, limit = 1) { - const timetableDoc = await Timetable.find(filter).limit(limit); - return timetableDoc; +async function read(filter, limit = 0, page = 1) { + const timetableDoc = await Timetable.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Timetable.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: timetableDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Timetable.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Timetable.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } diff --git a/models/topic.js b/models/topic.js index 6cca60a6..848962b8 100644 --- a/models/topic.js +++ b/models/topic.js @@ -8,9 +8,7 @@ const Topic = connector.model("Topic", topicSchema); // CURD operations async function create(topicData) { - const { - title, - } = topicData; + const { title } = topicData; const topic = new Topic({ title, }); @@ -18,13 +16,22 @@ async function create(topicData) { return topicDoc; } -async function read(filter, limit = 1) { - const topicDoc = await Topic.find(filter).limit(limit); - return topicDoc; +async function read(filter, limit = 0, page = 1) { + const topicDoc = await Topic.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Topic.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: topicDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Topic.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Topic.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } @@ -33,5 +40,8 @@ async function remove(filter) { return deleteResult.acknowledged; } export default { - create, remove, update, read, + create, + remove, + update, + read, }; diff --git a/models/tutorial.js b/models/tutorial.js index 7554012d..a03584e6 100644 --- a/models/tutorial.js +++ b/models/tutorial.js @@ -4,11 +4,13 @@ const tutorialSchema = { no: { type: Number, required: true }, title: { type: String, unique: true, required: true }, hours: { type: Number, required: true }, - cognitiveLevel: [{ - type: String, - enum: ["L1", "L2", "L3", "L4", "L5", "L6"], - default: "L1", - }], + cognitiveLevel: [ + { + type: String, + enum: ["L1", "L2", "L3", "L4", "L5", "L6"], + default: "L1", + }, + ], }; // eslint-disable-next-line no-unused-vars @@ -24,14 +26,23 @@ async function create(tutorialData) { } // Retrieve tutorials based on a given filter and limit -async function read(filter, limit = 1) { - const tutorialDoc = await Tutorial.find(filter).limit(limit); - return tutorialDoc; +async function read(filter, limit = 0, page = 1) { + const tutorialDoc = await Tutorial.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await Tutorial.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: tutorialDoc }; } // Update tutorials based on a given filter and update data async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Tutorial.updateMany(filter, { $set: updateObject }, options); + const updateResult = await Tutorial.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } diff --git a/models/user.js b/models/user.js index 38ecbe62..00c2f24d 100644 --- a/models/user.js +++ b/models/user.js @@ -7,7 +7,13 @@ const userSchema = { emailId: { type: String, unique: true, required: true }, password: { type: String, required: true }, uid: { type: String, unique: true, required: true }, - userType: { type: String, required: true }, + userType: { + type: String, + required: true, + enum: ["ADMIN", "FACULTY", "EMPLOYEE", "STUDENT"], + default: "ADMIN", + // for now we are keeping the default usertype as ADMIN + }, }; const User = connector.model("User", userSchema); @@ -18,9 +24,7 @@ async function remove(filter) { } async function create(userData) { - const { - name, password, emailId, uid, userType, - } = userData; + const { name, password, emailId, uid, userType } = userData; const hashedPassword = await hashPassword(password); const user = new User({ name, @@ -33,16 +37,28 @@ async function create(userData) { return userDoc; } -async function read(filter, limit = 1) { - const userDoc = await User.find(filter).limit(limit); - return userDoc; +async function read(filter, limit = 0, page = 1) { + const userDoc = await User.find(filter) + .limit(limit) + .skip((page - 1) * limit) + .exec(); + const count = await User.count(); + const totalPages = Math.ceil(count / limit); + return { totalPages, data: userDoc }; } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await User.updateMany(filter, { $set: updateObject }, options); + const updateResult = await User.updateMany( + filter, + { $set: updateObject }, + options, + ); return updateResult.acknowledged; } export default { - create, read, update, remove, + create, + read, + update, + remove, }; diff --git a/package-lock.json b/package-lock.json index 0a8ea29a..167289dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "jsonwebtoken": "^9.0.0", "mongoose": "^6.9.0", "morgan": "~1.9.1", + "node-cron": "^3.0.2", "nodemailer": "^6.9.1", "supertest": "^6.3.3", "winston": "^3.8.2", @@ -31,7 +32,9 @@ "eslint-import-resolver-alias": "^1.1.2", "eslint-plugin-import": "^2.27.5", "eslint-plugin-prettier": "^5.0.0", + "husky": "^8.0.0", "jest": "^29.5.0", + "lint-staged": "^14.0.1", "nodemon": "^3.0.1", "prettier": "^3.0.3" } @@ -4115,6 +4118,87 @@ "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", "dev": true }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -4650,6 +4734,12 @@ "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -5314,6 +5404,12 @@ "node": ">= 0.6" } }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -6135,6 +6231,21 @@ "node": ">=10.17.0" } }, + "node_modules/husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", + "dev": true, + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -7482,6 +7593,15 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -7496,6 +7616,291 @@ "uc.micro": "^1.0.1" } }, + "node_modules/lint-staged": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-14.0.1.tgz", + "integrity": "sha512-Mw0cL6HXnHN1ag0mN/Dg4g6sr8uf8sn98w2Oc1ECtFto9tvRF7nkXGJRbx8gPlHyoR0pLyBr2lQHbWwmUHe1Sw==", + "dev": true, + "dependencies": { + "chalk": "5.3.0", + "commander": "11.0.0", + "debug": "4.3.4", + "execa": "7.2.0", + "lilconfig": "2.1.0", + "listr2": "6.6.1", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.1" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/commander": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", + "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/lint-staged/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/lint-staged/node_modules/execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/lint-staged/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/lint-staged/node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-6.6.1.tgz", + "integrity": "sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==", + "dev": true, + "dependencies": { + "cli-truncate": "^3.1.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^5.0.1", + "rfdc": "^1.3.0", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -7543,6 +7948,131 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/log-update": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", + "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^5.0.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^5.0.0", + "strip-ansi": "^7.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", + "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", + "dev": true, + "dependencies": { + "type-fest": "^1.0.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/log-update/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/logform": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/logform/-/logform-2.5.1.tgz", @@ -7943,6 +8473,17 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" }, + "node_modules/node-cron": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.2.tgz", + "integrity": "sha512-iP8l0yGlNpE0e6q1o185yOApANRe47UPbLf4YxfbiNHt/RU5eBcGB/e0oudruheSf+LQeDMezqC5BVAb5wwRcQ==", + "dependencies": { + "uuid": "8.3.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/node-fetch": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", @@ -8426,6 +8967,18 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/pirates": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", @@ -8813,6 +9366,22 @@ "node": ">=10" } }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -8823,6 +9392,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -9138,6 +9713,46 @@ "node": ">=8" } }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -9243,6 +9858,15 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -9979,7 +10603,6 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "optional": true, "bin": { "uuid": "dist/bin/uuid" } @@ -10378,6 +11001,15 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index 50a0e9f7..f776a4ba 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,10 @@ "testWin": "SET NODE_OPTIONS=--experimental-vm-modules && npx jest", "testWin:watch": "SET NODE_OPTIONS=--experimental-vm-modules && npx jest --watch", "testWin:openHandles": "SET NODE_OPTIONS=--experimental-vm-modules && npx jest --detectOpenHandles", - "eslint": "eslint" + "eslint": "eslint", + "backup": "node ./backup/erpbackup", + "restore": "node ./backup/erprestore", + "prepare": "husky install" }, "dependencies": { "apidoc": "^1.1.0", @@ -39,6 +42,7 @@ "jsonwebtoken": "^9.0.0", "mongoose": "^6.9.0", "morgan": "~1.9.1", + "node-cron": "^3.0.2", "nodemailer": "^6.9.1", "supertest": "^6.3.3", "winston": "^3.8.2", @@ -51,7 +55,9 @@ "eslint-import-resolver-alias": "^1.1.2", "eslint-plugin-import": "^2.27.5", "eslint-plugin-prettier": "^5.0.0", + "husky": "^8.0.0", "jest": "^29.5.0", + "lint-staged": "^14.0.1", "nodemon": "^3.0.1", "prettier": "^3.0.3" } diff --git a/routes/accreditation.js b/routes/accreditation.js index c39b85bd..b8613b1e 100644 --- a/routes/accreditation.js +++ b/routes/accreditation.js @@ -1,9 +1,21 @@ import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import accreditationController from "#controller/accreditation"; const router = express.Router(); -router.get("/list", accreditationController.showAccreditation); -router.post("/add", accreditationController.addAccreditation); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN"]), + accreditationController.showAccreditation, +); +router.post( + "/add", + authenticateToken, + authorization(["ADMIN"]), + accreditationController.addAccreditation, +); router.delete("/delete/:id", accreditationController.deleteAccreditation); router.post("/update/:id", accreditationController.updateAccreditation); diff --git a/routes/activity.js b/routes/activity.js index f5c40a24..1d68d36d 100644 --- a/routes/activity.js +++ b/routes/activity.js @@ -1,10 +1,32 @@ import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import activityController from "#controller/activity"; -const router=express.Router(); -router.post("/add",activityController.addActivity); -router.get("/list",activityController.getActivity); -router.post("/update/:id",activityController.updateActivity); -router.delete("/delete/:id",activityController.deleteActivity); +const router = express.Router(); +router.post( + "/add", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + activityController.addActivity, +); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + activityController.getActivity, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + activityController.updateActivity, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + activityController.deleteActivity, +); -export default router; \ No newline at end of file +export default router; diff --git a/routes/assignment.js b/routes/assignment.js index 3b9c8e91..85b18588 100644 --- a/routes/assignment.js +++ b/routes/assignment.js @@ -1,10 +1,32 @@ import express from "express"; import assingmentController from "#controller/assignment"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; const router = express.Router(); -router.post("/add", assingmentController.addAssignment); -router.get("/list", assingmentController.getAssignment); -router.post("/update/:id", assingmentController.updateAssignment); -router.delete("/delete/:id", assingmentController.deleteAssignment); +router.post( + "/add", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + assingmentController.addAssignment, +); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + assingmentController.getAssignment, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + assingmentController.updateAssignment, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + assingmentController.deleteAssignment, +); export default router; diff --git a/routes/attendance.js b/routes/attendance.js new file mode 100644 index 00000000..849649ae --- /dev/null +++ b/routes/attendance.js @@ -0,0 +1,10 @@ +import express from "express"; +import attendanceController from "#controller/attendance"; + +const router = express.Router(); +router.get("/list", attendanceController.showAttendance); +router.post("/add", attendanceController.addAttendance); +router.delete("/delete/:id", attendanceController.deleteAttendance); +router.post("/update/:id", attendanceController.updateAttendance); + +export default router; \ No newline at end of file diff --git a/routes/coursework.js b/routes/coursework.js index 5a6aeb1b..5b9109d4 100644 --- a/routes/coursework.js +++ b/routes/coursework.js @@ -1,10 +1,32 @@ import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import courseworkController from "#controller/coursework"; const router = express.Router(); -router.post("/add", courseworkController.addCoursework); -router.get("/list", courseworkController.getCoursework); -router.post("/update/:id", courseworkController.updateCoursework); -router.delete("/delete/:id", courseworkController.deleteCoursework); +router.post( + "/add", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + courseworkController.addCoursework, +); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + courseworkController.getCoursework, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + courseworkController.updateCoursework, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + courseworkController.deleteCoursework, +); export default router; diff --git a/routes/department.js b/routes/department.js index cc15b44f..fbbb274d 100644 --- a/routes/department.js +++ b/routes/department.js @@ -1,11 +1,33 @@ import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import departmentContoller from "#controller/department"; const router = express.Router(); -router.get("/list", departmentContoller.showdepartments); -router.post("/create", departmentContoller.addDepartment); -router.delete("/delete/:id", departmentContoller.removedepartmentbyid); -router.post("/update/:id", departmentContoller.updatedDepartment); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN"]), + departmentContoller.showdepartments, +); +router.post( + "/create", + authenticateToken, + authorization(["ADMIN"]), + departmentContoller.addDepartment, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN"]), + departmentContoller.removedepartmentbyid, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN"]), + departmentContoller.updatedDepartment, +); export default router; diff --git a/routes/exam.js b/routes/exam.js new file mode 100644 index 00000000..1746cea6 --- /dev/null +++ b/routes/exam.js @@ -0,0 +1,10 @@ +import express from "express"; +import examController from "#controller/exam"; + +const router = express.Router(); +router.post("/add", examController.addExam); +router.get("/list", examController.getExam); +router.post("/update/:id", examController.updateExam); +router.delete("/delete/:id", examController.deleteExam); + +export default router; diff --git a/routes/faculty.js b/routes/faculty.js index aacc1669..ae58f4dd 100644 --- a/routes/faculty.js +++ b/routes/faculty.js @@ -1,10 +1,32 @@ import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import facultyController from "#controller/faculty"; const router = express.Router(); -router.post("/create", facultyController.addFaculty); -router.get("/list", facultyController.getFaculty); -router.post("/update/:id", facultyController.updateFaculty); -router.delete("/delete/:id", facultyController.deleteFaculty); +router.post( + "/create", + authenticateToken, + authorization(["ADMIN"]), + facultyController.addFaculty, +); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN"]), + facultyController.getFaculty, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN"]), + facultyController.updateFaculty, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN"]), + facultyController.deleteFaculty, +); export default router; diff --git a/routes/group.js b/routes/group.js index e9f20a51..0a403533 100644 --- a/routes/group.js +++ b/routes/group.js @@ -1,10 +1,32 @@ import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import groupController from "#controller/group"; const router = express.Router(); -router.post("/add", groupController.addGroup); -router.get("/list", groupController.getGroup); -router.post("/update/:id", groupController.updateGroup); -router.delete("/delete/:id", groupController.deleteGroup); +router.post( + "/add", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + groupController.addGroup, +); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + groupController.getGroup, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + groupController.updateGroup, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + groupController.deleteGroup, +); export default router; diff --git a/routes/infrastructure.js b/routes/infrastructure.js index 8048ccb1..0b732460 100644 --- a/routes/infrastructure.js +++ b/routes/infrastructure.js @@ -1,10 +1,33 @@ import express from "express"; + +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import infrastructureController from "#controller/infrastructure"; const router = express.Router(); -router.post("/add", infrastructureController.addInfrastructure); -router.get("/list", infrastructureController.getInfrastructure); -router.post("/update/:id", infrastructureController.updateInfrastructure); -router.delete("/delete/:id", infrastructureController.deleteInfrastructure); +router.post( + "/add", + authenticateToken, + authorization(["ADMIN"]), + infrastructureController.addInfrastructure, +); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN"]), + infrastructureController.getInfrastructure, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN"]), + infrastructureController.updateInfrastructure, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN"]), + infrastructureController.deleteInfrastructure, +); export default router; diff --git a/routes/module.js b/routes/module.js index fb373668..4bda2c95 100644 --- a/routes/module.js +++ b/routes/module.js @@ -1,11 +1,33 @@ import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import moduleController from "#controller/module"; const router = express.Router(); -router.get("/list", moduleController.showModule); -router.post("/add", moduleController.addModule); -router.post("/update/:id",moduleController.updateModule); -router.delete("/delete/:id",moduleController.deleteModule); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + moduleController.showModule, +); +router.post( + "/add", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + moduleController.addModule, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + moduleController.updateModule, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + moduleController.deleteModule, +); export default router; diff --git a/routes/notification.js b/routes/notification.js new file mode 100644 index 00000000..938bebf6 --- /dev/null +++ b/routes/notification.js @@ -0,0 +1,18 @@ +import express from "express"; +import notificationController from "#controller/notification"; + +const router = express.Router(); + +// Create a new Notification +router.post("/add", notificationController.addNotification); + +// List Notification entities with optional filters +router.get("/list", notificationController.getNotifications); + +// Update Notification entities based on filters and update data +router.post("/update/:id", notificationController.updateNotification); + +// Delete Notification entities based on ID +router.delete("/delete/:id", notificationController.deleteNotification); + +export default router; diff --git a/routes/organization.js b/routes/organization.js index 10c412fc..79d2e8a9 100644 --- a/routes/organization.js +++ b/routes/organization.js @@ -1,10 +1,32 @@ import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import organizationController from "#controller/organization"; const router = express.Router(); -router.get("/list", organizationController.showOrganization); -router.post("/add", organizationController.addOrganization); -router.delete("/delete/:id", organizationController.deleteOrganization); -router.post("/update/:id", organizationController.updateOrganization); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN"]), + organizationController.showOrganization, +); +router.post( + "/add", + authenticateToken, + authorization(["ADMIN"]), + organizationController.addOrganization, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN"]), + organizationController.deleteOrganization, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN"]), + organizationController.updateOrganization, +); export default router; diff --git a/routes/paper.js b/routes/paper.js index f754ea35..c7ec770a 100644 --- a/routes/paper.js +++ b/routes/paper.js @@ -1,11 +1,33 @@ import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import paperController from "#controller/paper"; const router = express.Router(); -router.post("/add", paperController.addPaper); -router.get("/list", paperController.showPaper); -router.post("/update/:id", paperController.updatePaper); -router.delete("/delete/:id", paperController.deletePaper); +router.post( + "/add", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + paperController.addPaper, +); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + paperController.showPaper, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + paperController.updatePaper, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + paperController.deletePaper, +); export default router; diff --git a/routes/performance.js b/routes/performance.js new file mode 100644 index 00000000..1f96db33 --- /dev/null +++ b/routes/performance.js @@ -0,0 +1,15 @@ +import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; +import performacontroller from "#controller/performance"; + +const router = express.Router(); + +router.get( + "/test", + authenticateToken, + authorization(["ADMIN"]), + performacontroller, +); + +export default router; diff --git a/routes/practical.js b/routes/practical.js index 6a6ad9d9..af468b51 100644 --- a/routes/practical.js +++ b/routes/practical.js @@ -1,18 +1,40 @@ import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import practicalController from "#controller/practical"; const router = express.Router(); // Create a new Practical -router.post("/create", practicalController.addPractical); +router.post( + "/create", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + practicalController.addPractical, +); // List Practical entities with optional filters -router.get("/list", practicalController.getPractical); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + practicalController.getPractical, +); // Update Practical entities based on filters and update data -router.post("/update/:id", practicalController.updatePractical); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + practicalController.updatePractical, +); // Delete Practical entities based on filters -router.delete("/delete/:id", practicalController.deletePractical); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + practicalController.deletePractical, +); export default router; diff --git a/routes/semester.js b/routes/semester.js index 5d23936a..05321882 100644 --- a/routes/semester.js +++ b/routes/semester.js @@ -1,10 +1,32 @@ import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import semesterController from "#controller/semester"; const router = express.Router(); -router.post("/add", semesterController.addSemester); -router.get("/list", semesterController.getSemester); -router.post("/update/:id", semesterController.updateSemester); -router.delete("/delete/:id", semesterController.deleteSemester); +router.post( + "/add", + authenticateToken, + authorization(["ADMIN"]), + semesterController.addSemester, +); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN"]), + semesterController.getSemester, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN"]), + semesterController.updateSemester, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN"]), + semesterController.deleteSemester, +); export default router; diff --git a/routes/student.js b/routes/student.js index 70fc5f4c..db686df9 100644 --- a/routes/student.js +++ b/routes/student.js @@ -1,10 +1,32 @@ import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import studentController from "#controller/student"; const router = express.Router(); -router.post("/create", studentController.addStudent); -router.get("/list", studentController.getStudent); -router.post("/update/:id", studentController.updateStudent); -router.delete("/delete/:id", studentController.deleteStudent); +router.post( + "/create", + authenticateToken, + authorization(["ADMIN"]), + studentController.addStudent, +); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN"]), + studentController.getStudent, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN"]), + studentController.updateStudent, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN"]), + studentController.deleteStudent, +); export default router; diff --git a/routes/timetable.js b/routes/timetable.js index 868f66b2..e1f0d8fd 100644 --- a/routes/timetable.js +++ b/routes/timetable.js @@ -1,10 +1,33 @@ import express from "express"; + +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import timetableController from "#controller/timetable"; const router = express.Router(); -router.post("/add", timetableController.addTimetable); -router.get("/list", timetableController.getTimetable); -router.post("/update/:id", timetableController.updateTimetable); -router.delete("/delete/:id", timetableController.deleteTimetable); +router.post( + "/add", + authenticateToken, + authorization(["ADMIN"]), + timetableController.addTimetable, +); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN"]), + timetableController.getTimetable, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN"]), + timetableController.updateTimetable, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN"]), + timetableController.deleteTimetable, +); export default router; diff --git a/routes/topic.js b/routes/topic.js new file mode 100644 index 00000000..268e070f --- /dev/null +++ b/routes/topic.js @@ -0,0 +1,10 @@ +import express from "express"; +import topicController from "#controller/topic"; + +const router = express.Router(); +router.get("/list", topicController.showTopic); +router.post("/add", topicController.addTopic); +router.delete("/delete/:id", topicController.deleteTopic); +router.post("/update/:id", topicController.updateTopic); + +export default router; diff --git a/routes/tutorial.js b/routes/tutorial.js index 81634f26..a1bd30fc 100644 --- a/routes/tutorial.js +++ b/routes/tutorial.js @@ -1,10 +1,32 @@ import express from "express"; +import authenticateToken from "#middleware/auth"; +import authorization from "#middleware/authorization"; import tutorialController from "#controller/tutorial"; const router = express.Router(); -router.post("/add", tutorialController.addTutorial); -router.get("/list", tutorialController.showTutorial); -router.post("/update/:id", tutorialController.updateTutorial); -router.delete("/delete/:id", tutorialController.deleteTutorial); +router.post( + "/add", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + tutorialController.addTutorial, +); +router.get( + "/list", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + tutorialController.showTutorial, +); +router.post( + "/update/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + tutorialController.updateTutorial, +); +router.delete( + "/delete/:id", + authenticateToken, + authorization(["ADMIN", "FACULTY"]), + tutorialController.deleteTutorial, +); export default router; diff --git a/services/accreditation.js b/services/accreditation.js index ae7e5ba9..310d505a 100644 --- a/services/accreditation.js +++ b/services/accreditation.js @@ -1,7 +1,12 @@ import Accreditation from "#models/accreditation"; import databaseError from "#error/database"; -export async function addNewAccreditation(name, agencyName, dateofAccreditation, dateofExpiry) { +export async function addNewAccreditation( + name, + agencyName, + dateofAccreditation, + dateofExpiry, +) { const newAccreditation = await Accreditation.create({ name, agencyName, @@ -14,8 +19,8 @@ export async function addNewAccreditation(name, agencyName, dateofAccreditation, throw new databaseError.DataEntryError("Add Accreditation"); } -export async function getAccreditations(filter) { - const accreditations = await Accreditation.read(filter); +export async function getAccreditations(filter, limit, page) { + const accreditations = await Accreditation.read(filter, limit, page); if (accreditations) { return accreditations; } diff --git a/services/activity.js b/services/activity.js index 0c3a3a18..10ceab83 100644 --- a/services/activity.js +++ b/services/activity.js @@ -1,33 +1,51 @@ -import Activity from "#models/activity" ; +import Activity from "#models/activity"; import databaseError from "#error/database"; -export async function createActivity (activityBlueprint,startTime,duration,course,faculty,type,task,group,students){ - const newActivity = await Activity.create({ - activityBlueprint,startTime,duration,course,faculty,task,type,group,students, - }); - if (newActivity){ - return newActivity; - } - throw new databaseError.DataEntryError("actvity"); +export async function createActivity( + activityBlueprint, + startTime, + duration, + course, + faculty, + type, + task, + group, + students, +) { + const newActivity = await Activity.create({ + activityBlueprint, + startTime, + duration, + course, + faculty, + task, + type, + group, + students, + }); + if (newActivity) { + return newActivity; + } + throw new databaseError.DataEntryError("actvity"); } -export async function updateActivityById(id,data){ -const updated= await Activity.update({_id:id},data); -if (updated){ +export async function updateActivityById(id, data) { + const updated = await Activity.update({ _id: id }, data); + if (updated) { return updated; -} -throw new databaseError.DataEntryError("activity"); + } + throw new databaseError.DataEntryError("activity"); } -export async function activityList(filter){ - const activitylist = await Activity.read(filter,0); - return activitylist; +export async function activityList(filter, limit, page) { + const activitylist = await Activity.read(filter, limit, page); + return activitylist; } -export async function deleteActivityById(id){ - const deleted = await Activity.remove({_id:id}); - if(deleted){ - return deleted; - } - throw new databaseError.DataDeleteError("activity"); -} \ No newline at end of file +export async function deleteActivityById(id) { + const deleted = await Activity.remove({ _id: id }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("activity"); +} diff --git a/services/assignment.js b/services/assignment.js index 575a4dbc..688de184 100644 --- a/services/assignment.js +++ b/services/assignment.js @@ -3,7 +3,10 @@ import databaseError from "#error/database"; export async function createAssignment(no, title, type, marks) { const newAssignment = await Assignment.create({ - no, title, type, marks, + no, + title, + type, + marks, }); if (newAssignment.title === title) { return newAssignment; @@ -19,8 +22,8 @@ export async function updateAssignmentById(id, data) { throw new databaseError.DataEntryError("assignment"); } -export async function assignmentList(filter) { - const assignmentlist = await Assignment.read(filter, 0); +export async function assignmentList(filter, limit, page) { + const assignmentlist = await Assignment.read(filter, limit, page); return assignmentlist; } diff --git a/services/attendance.js b/services/attendance.js new file mode 100644 index 00000000..62dc4f5c --- /dev/null +++ b/services/attendance.js @@ -0,0 +1,48 @@ +import Attendance from "#models/attendance"; +import databaseError from "#error/database"; + +export async function addNewAttendance( + student, + course, + monthlyAttended, + monthlyOccured, + cumulativeAttended, + cumulativeOccured, +) { + const newAttendance = await Attendance.create({ + student, + course, + monthlyAttended, + monthlyOccured, + cumulativeAttended, + cumulativeOccured, + }); + if (String(newAttendance.student) === student) { + return newAttendance; + } + throw new databaseError.DataEntryError("Add Attendance"); +} + +export async function getAttendances(filter, limit, page) { + const attendances = await Attendance.read(filter, limit, page); + if (attendances) { + return attendances; + } + throw new databaseError.DataNotFoundError("Attendance"); +} + +export async function deleteAttendanceById(attendanceId) { + const deleted = await Attendance.remove({ _id: attendanceId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("Attendance"); +} + +export async function updateAttendanceById(id, data) { + const updated = await Attendance.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("Attendance"); +} diff --git a/services/coursework.js b/services/coursework.js index b4b16205..5d6120a8 100644 --- a/services/coursework.js +++ b/services/coursework.js @@ -4,11 +4,23 @@ import databaseError from "#error/database"; // Service function to create a new Coursework entity export async function createCoursework({ - student, type, course, task, objectID, activity, marks, + student, + type, + course, + task, + objectID, + activity, + marks, }) { try { const newCoursework = await Coursework.create({ - student, type, course, task, objectID, activity, marks, + student, + type, + course, + task, + objectID, + activity, + marks, }); return newCoursework; } catch (error) { @@ -30,9 +42,9 @@ export async function updateCourseworkById(id, data) { } // Service function to retrieve a list of Coursework entities based on filters -export async function listCoursework(filter) { +export async function listCoursework(filter, limit, page) { try { - const courseworkList = await Coursework.read(filter, 0); + const courseworkList = await Coursework.read(filter, limit, page); return courseworkList; } catch (error) { throw new databaseError.DataRetrievalError("coursework"); diff --git a/services/department.js b/services/department.js index 1b72e6d7..878a3298 100644 --- a/services/department.js +++ b/services/department.js @@ -21,8 +21,8 @@ export async function createnewdepartment( throw new databaseError.DataEntryError("Add department"); } -export async function listdepartment(filter) { - const listeddepartment = await department.read(filter); +export async function listdepartment(filter, limit, page) { + const listeddepartment = await department.read(filter, limit, page); if (listeddepartment) { return listeddepartment; } @@ -40,9 +40,12 @@ export async function deletedepartment(departmentId) { } export async function updateDepartmentbyid(id, data) { - const updatedDepartment = await department.update({ - _id: id, - }, data); + const updatedDepartment = await department.update( + { + _id: id, + }, + data, + ); if (updatedDepartment) { return updatedDepartment; } @@ -50,5 +53,8 @@ export async function updateDepartmentbyid(id, data) { } export default { - updateDepartmentbyid, createnewdepartment, listdepartment, deletedepartment, + updateDepartmentbyid, + createnewdepartment, + listdepartment, + deletedepartment, }; diff --git a/services/employee/empBank.js b/services/employee/empBank.js new file mode 100644 index 00000000..a0daef97 --- /dev/null +++ b/services/employee/empBank.js @@ -0,0 +1,47 @@ +import EmployeeBank from "#models/employee/empBank"; +import databaseError from "#error/database"; + +export async function createEmployeeBank( + uid, + bankName, + bankAcc, + bankBranch, + bankIfsc, + bankMicr, + appointmentApproveSgDte, +) { + const newEmployeeBank = await EmployeeBank.create({ + uid, + bankName, + bankAcc, + bankBranch, + bankIfsc, + bankMicr, + appointmentApproveSgDte, + }); + if (newEmployeeBank.uid === uid) { + return newEmployeeBank; + } + throw new databaseError.DataEntryError("employee bank"); +} + +export async function updateEmployeeBankById(id, data) { + const updated = await EmployeeBank.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("employee bank"); +} + +export async function employeeBankList(filter, limit, page) { + const employeeBank = await EmployeeBank.read(filter, limit, page); + return employeeBank; +} + +export async function deleteEmployeeBankById(employeeBankId) { + const deleted = await EmployeeBank.remove({ _id: employeeBankId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("employee bank"); +} diff --git a/services/employee/empCurrentDetail.js b/services/employee/empCurrentDetail.js new file mode 100644 index 00000000..8b094963 --- /dev/null +++ b/services/employee/empCurrentDetail.js @@ -0,0 +1,50 @@ +import databaseError from "#error/database"; +import EmployeeCurrent from "#models/employee/empPersonal"; + +export async function addNewEmployeeCurrent( + uid, + dateOfJoining, + departmentName, + designation, + jobStatus, + jobProfile, + currentCtc, +) { + const newEmployeeCurrent = await EmployeeCurrent.create({ + uid, + dateOfJoining, + departmentName, + designation, + jobStatus, + jobProfile, + currentCtc, + }); + if (newEmployeeCurrent.uid === uid) { + return newEmployeeCurrent; + } + throw new databaseError.DataEntryError("Add EmployeeCurrent"); +} + +export async function getEmployeeCurrent(filter, limit, page) { + const employeeCurrent = await EmployeeCurrent.read(filter, limit, page); + if (employeeCurrent) { + return employeeCurrent; + } + throw new databaseError.DataNotFoundError("EmployeeCurrent"); +} + +export async function deleteEmployeeCurrentById(EmployeeCurrentId) { + const deleted = await EmployeeCurrent.remove({ _id: EmployeeCurrentId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("EmployeeCurrent"); +} + +export async function updateEmployeeCurrentById(id, data) { + const updated = await EmployeeCurrent.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("EmployeeCurrent"); +} diff --git a/services/employee/empEduHistory.js b/services/employee/empEduHistory.js new file mode 100644 index 00000000..736cd6cb --- /dev/null +++ b/services/employee/empEduHistory.js @@ -0,0 +1,89 @@ +import EmployeeEducationHistory from "#models/employee/empEduHistory"; +import databaseError from "#error/database"; + +export async function createEmployeeEducationHistory( + educationType, + educationName, + specialization, + period, + institutionName, + university, + passingDivision, + fromYear, + uptoYear, + registrationNumber, + aggregatePct, + finalYearPct, + numberOfAttempts, + rank, + passingYear, + uid, + ssc, + hsc, + dip, + iti, + deg, + pgd, + phd, + pdoc, +) { + const newEmployeeEducationHistory = await EmployeeEducationHistory.create({ + educationType, + educationName, + specialization, + period, + institutionName, + university, + passingDivision, + fromYear, + uptoYear, + registrationNumber, + aggregatePct, + finalYearPct, + numberOfAttempts, + rank, + passingYear, + uid, + ssc, + hsc, + dip, + iti, + deg, + pgd, + phd, + pdoc, + }); + if (newEmployeeEducationHistory.uid === uid) { + return newEmployeeEducationHistory; + } + throw new databaseError.DataEntryError("Employee Education History"); +} + +export async function employeeEducationHistoryList(filter, limit, page) { + const empEduHistory = await EmployeeEducationHistory.read( + filter, + limit, + page, + ); + return empEduHistory; +} + +export async function updateEmployeeEducationHistoryById(id, data) { + const updated = await EmployeeEducationHistory.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("Employee Education History"); +} + +export async function deleteEmployeeEducationHistoryById( + employeeEducationHistoryId, +) { + const deleted = await EmployeeEducationHistory.remove({ + _id: employeeEducationHistoryId, + }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("Employee Education History"); +} diff --git a/services/employee/empPersonal.js b/services/employee/empPersonal.js new file mode 100644 index 00000000..6d071ad0 --- /dev/null +++ b/services/employee/empPersonal.js @@ -0,0 +1,150 @@ +import databaseError from "#error/database"; +import EmployeePersonal from "#models/employee/empPersonal"; + +export async function addNewEmployeePersonal( + uid, + title, + empFirstName, + empLastName, + bloodGroup, + dob, + birthPlace, + motherTongue, + gender, + religion, + numOfChildren, + originalCastCategory, + caste, + subCaste, + spouseMailAddress, + spouseMobileNo, + emrgContactNo, + emrgContactPersonName, + empMobileNo, + panNumber, + aadharCardNo, + creditCardNumber, + drivingLicenceNo, + drivingLicenceExpiry, + passportNumber, + licId, + identificationMark, + addressTypePermanant, + permanantPlotNo, + permanantStreet, + permanantAddress, + permanantAddress2, + permanantCity, + permanantTahshil, + permanantDistrict, + permanantState, + permanantCountry, + permanantPincode, + addressTypeCorrespondance, + correspondancePlotNo, + correspondanceStreet, + correspondanceAddress, + correspondanceAddress2, + correspondanceCity, + correspondanceTahshil, + correspondanceDistrict, + correspondanceState, + correspondanceCountry, + correspondancePincode, + maritalStatus, + maidenFirstName, + maidenMiddleName, + maidenLastName, + isNameChangedBefore, + previousFirstName, + previousMiddleName, + previousLastName, +) { + const newEmployeePersonal = await EmployeePersonal.create({ + uid, + title, + empFirstName, + empLastName, + bloodGroup, + dob, + birthPlace, + motherTongue, + gender, + religion, + numOfChildren, + originalCastCategory, + caste, + subCaste, + spouseMailAddress, + spouseMobileNo, + emrgContactNo, + emrgContactPersonName, + empMobileNo, + panNumber, + aadharCardNo, + creditCardNumber, + drivingLicenceNo, + drivingLicenceExpiry, + passportNumber, + licId, + identificationMark, + addressTypePermanant, + permanantPlotNo, + permanantStreet, + permanantAddress, + permanantAddress2, + permanantCity, + permanantTahshil, + permanantDistrict, + permanantState, + permanantCountry, + permanantPincode, + addressTypeCorrespondance, + correspondancePlotNo, + correspondanceStreet, + correspondanceAddress, + correspondanceAddress2, + correspondanceCity, + correspondanceTahshil, + correspondanceDistrict, + correspondanceState, + correspondanceCountry, + correspondancePincode, + maritalStatus, + maidenFirstName, + maidenMiddleName, + maidenLastName, + isNameChangedBefore, + previousFirstName, + previousMiddleName, + previousLastName, + }); + if (newEmployeePersonal.uid === uid) { + return newEmployeePersonal; + } + throw new databaseError.DataEntryError("Add EmployeePersonal"); +} + +export async function getEmployeePersonal(filter, limit, page) { + const employeePersonal = await EmployeePersonal.read(filter, limit, page); + if (employeePersonal) { + return employeePersonal; + } + throw new databaseError.DataNotFoundError("EmployeePersonal"); +} + +export async function deleteEmployeePersonalById(employeePersonalId) { + const deleted = await EmployeePersonal.remove({ _id: employeePersonalId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("EmployeePersonal"); +} + +export async function updateEmployeePersonalById(id, data) { + const updated = await EmployeePersonal.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("EmployeePersonal"); +} diff --git a/services/exam.js b/services/exam.js new file mode 100644 index 00000000..c917d28a --- /dev/null +++ b/services/exam.js @@ -0,0 +1,45 @@ +import Exam from "#models/exam"; +import databaseError from "#error/database"; + +export async function createExam( + date, + startTime, + duration, + supervisor, + infrastructure, + course, +) { + const newExam = await Exam.create({ + date, + startTime, + duration, + supervisor, + infrastructure, + course, + }); + if (Date(newExam.date) === Date(date)) { + return newExam; + } + throw new databaseError.DataEntryError("exam"); +} + +export async function updateExamById(id, data) { + const updated = await Exam.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("exam"); +} + +export async function examList(filter, limit, page) { + const exams = await Exam.read(filter, limit, page); + return exams; +} + +export async function deleteExamById(examId) { + const deleted = await Exam.remove({ _id: examId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("exam"); +} diff --git a/services/faculty.js b/services/faculty.js index 881346a8..c8e2b1d0 100644 --- a/services/faculty.js +++ b/services/faculty.js @@ -41,8 +41,8 @@ export async function createFaculty( throw new databaseError.DataEntryError("Faculty"); } -export async function facultyList(filter) { - const facList = await Faculty.read(filter); +export async function facultyList(filter, limit, page) { + const facList = await Faculty.read(filter, limit, page); if (facList) { return facList; } @@ -66,5 +66,8 @@ export async function updateFacultyById(id, data) { } export default { - createFaculty, facultyList, deleteFacultyById, updateFacultyById, + createFaculty, + facultyList, + deleteFacultyById, + updateFacultyById, }; diff --git a/services/group.js b/services/group.js index d02ff62e..18e5575f 100644 --- a/services/group.js +++ b/services/group.js @@ -3,7 +3,8 @@ import databaseError from "#error/database"; export async function createGroup(title, student) { const newGroup = await Group.create({ - title, student, + title, + student, }); if (newGroup.title === title) { return newGroup; @@ -19,8 +20,8 @@ export async function updateGroupById(id, data) { throw new databaseError.DataEntryError("group"); } -export async function groupList(filter) { - const groups = await Group.read(filter, 0); +export async function groupList(filter, limit, page) { + const groups = await Group.read(filter, limit, page); return groups; } diff --git a/services/infrastructure.js b/services/infrastructure.js index 073c4e21..57c60fc8 100644 --- a/services/infrastructure.js +++ b/services/infrastructure.js @@ -3,7 +3,11 @@ import databaseError from "#error/database"; export async function createInfrastructure(name, type, wing, floor, capacity) { const newInfrastructure = await Infrastructure.create({ - name, type, wing, floor, capacity, + name, + type, + wing, + floor, + capacity, }); if (newInfrastructure.name === name) { return newInfrastructure; @@ -19,8 +23,8 @@ export async function updateInfrastructureById(id, data) { throw new databaseError.DataEntryError("Infrastructure"); } -export async function infrastructureList(filter) { - const infralist = await Infrastructure.read(filter, 0); +export async function infrastructureList(filter, limit, page) { + const infralist = await Infrastructure.read(filter, limit, page); return infralist; } diff --git a/services/module.js b/services/module.js index b51874b7..389987ed 100644 --- a/services/module.js +++ b/services/module.js @@ -1,17 +1,29 @@ import Module from "#models/module"; import databaseError from "#error/database"; -export async function getModule(filter) { - const modules = await Module.read(filter); +export async function getModule(filter, limit, page) { + const modules = await Module.read(filter, limit, page); if (modules) { return modules; } throw new databaseError.DataNotFoundError("Module"); } -export async function addNewModule(no, name, outcome, contents, hrsPerModule, cognitiveLevels) { +export async function addNewModule( + no, + name, + outcome, + contents, + hrsPerModule, + cognitiveLevels, +) { const newModule = await Module.create({ - no, name, outcome, contents, hrsPerModule, cognitiveLevels, + no, + name, + outcome, + contents, + hrsPerModule, + cognitiveLevels, }); if (newModule.name === name) { return newModule; @@ -19,8 +31,8 @@ export async function addNewModule(no, name, outcome, contents, hrsPerModule, co throw new databaseError.DataEntryError("Add Module"); } -export async function updateModuleById(id,data) { - const updated = await Module.update({_id: id}, data); +export async function updateModuleById(id, data) { + const updated = await Module.update({ _id: id }, data); if (updated) { return updated; } @@ -33,4 +45,4 @@ export async function deleteModuleById(ModuleId) { return deleted; } throw new databaseError.DataDeleteError("Module"); -} \ No newline at end of file +} diff --git a/services/notification.js b/services/notification.js new file mode 100644 index 00000000..a61b5abe --- /dev/null +++ b/services/notification.js @@ -0,0 +1,55 @@ +// Import the Notification model +import Notification from "#models/notification"; +import databaseError from "#error/database"; + +// Service function to create a new Notification entity +export async function createNotification({ data, title, type, from, filter }) { + try { + const newNotification = await Notification.create({ + data, + title, + type, + from, + filter, + }); + return newNotification; + } catch (error) { + throw new databaseError.DataEntryError("notification"); + } +} + +// Service function to update a Notification entity by ID +export async function updateNotificationById(id, data) { + try { + const updated = await Notification.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("notification"); + } catch (error) { + throw new databaseError.DataEntryError("notification"); + } +} + +// Service function to retrieve a list of Notification entities based on filters +export async function listNotifications(filter, limit, page) { + try { + const notificationList = await Notification.read(filter, limit, page); + return notificationList; + } catch (error) { + throw new databaseError.DataEntryError("notification"); + } +} + +// Service function to delete a Notification entity by ID +export async function deleteNotificationById(notificationId) { + try { + const deleted = await Notification.deleteOne({ _id: notificationId }); + if (deleted.deletedCount > 0) { + return deleted; + } + throw new databaseError.DataDeleteError("notification"); + } catch (error) { + throw new databaseError.DataDeleteError("notification"); + } +} diff --git a/services/organization.js b/services/organization.js index aa881b2d..03eedbdd 100644 --- a/services/organization.js +++ b/services/organization.js @@ -1,9 +1,17 @@ import Organization from "#models/organization"; import databaseError from "#error/database"; -export async function addNewOrganization(parent, startDate, name, accreditation) { +export async function addNewOrganization( + parent, + startDate, + name, + accreditation, +) { const newOrganization = await Organization.create({ - parent, startDate, name, accreditation, + parent, + startDate, + name, + accreditation, }); if (newOrganization.name === name) { return newOrganization; @@ -11,8 +19,8 @@ export async function addNewOrganization(parent, startDate, name, accreditation) throw new databaseError.DataEntryError("Add Organization"); } -export async function getOrganizations(filter) { - const organization = await Organization.read(filter); +export async function getOrganizations(filter, limit, page) { + const organization = await Organization.read(filter, limit, page); if (organization) { return organization; } @@ -36,5 +44,8 @@ export async function updateOrganizationById(id, data) { } export default { - deleteOrganizationById, addNewOrganization, updateOrganizationById, getOrganizations, + deleteOrganizationById, + addNewOrganization, + updateOrganizationById, + getOrganizations, }; diff --git a/services/paper.js b/services/paper.js index 64301a18..17c14d70 100644 --- a/services/paper.js +++ b/services/paper.js @@ -29,8 +29,8 @@ export async function updatePaperById(id, data) { throw new databaseError.DataEntryError("paper"); } -export async function listPaper(filter) { - const paper = await Paper.read(filter, 0); +export async function listPaper(filter, limit, page) { + const paper = await Paper.read(filter, limit, page); return paper; } diff --git a/services/practical.js b/services/practical.js index fafb86d8..8660574f 100644 --- a/services/practical.js +++ b/services/practical.js @@ -4,11 +4,19 @@ import databaseError from "#error/database"; // Service function to create a new Practical entity export async function createPractical({ - no, title, type, hours, cognitiveLevels, + no, + title, + type, + hours, + cognitiveLevels, }) { try { const newPractical = await Practical.create({ - no, title, type, hours, cognitiveLevels, + no, + title, + type, + hours, + cognitiveLevels, }); return newPractical; } catch (error) { @@ -30,9 +38,9 @@ export async function updatePracticalById(id, data) { } // Service function to retrieve a list of Practical entities based on filters -export async function listPractical(filter) { +export async function listPractical(filter, limit, page) { try { - const practicalList = await Practical.read(filter); + const practicalList = await Practical.read(filter, limit, page); return practicalList; } catch (error) { throw new databaseError.DataEntryError("practical"); diff --git a/services/semester.js b/services/semester.js index 6cc7c1c7..e762695b 100644 --- a/services/semester.js +++ b/services/semester.js @@ -1,9 +1,19 @@ import Semester from "#models/semester"; import databaseError from "#error/database"; -export async function createSemester(number, academicYear, type, startDate, endDate) { +export async function createSemester( + number, + academicYear, + type, + startDate, + endDate, +) { const newSemester = await Semester.create({ - number, academicYear, type, startDate, endDate, + number, + academicYear, + type, + startDate, + endDate, }); if (newSemester.number === number) { return newSemester; @@ -20,8 +30,8 @@ export async function updateSemesterById(id, data) { throw new databaseError.DataEntryError("semester"); } -export async function semesterList(filter) { - const semlist = await Semester.read(filter, 0); +export async function semesterList(filter, limit, page) { + const semlist = await Semester.read(filter, limit, page); return semlist; } diff --git a/services/student.js b/services/student.js index a20d49c7..235706b5 100644 --- a/services/student.js +++ b/services/student.js @@ -11,7 +11,13 @@ export async function createStudent( coursesOpted, ) { const newStudent = await Student.create({ - ERPID, name, joiningYear, branch, division, rollNo, coursesOpted, + ERPID, + name, + joiningYear, + branch, + division, + rollNo, + coursesOpted, }); if (newStudent.name === name) { return newStudent; @@ -27,8 +33,8 @@ export async function updateStudentById(id, data) { throw new databaseError.DataEntryError("student"); } -export async function studentList(filter) { - const studlist = await Student.read(filter, 0); +export async function studentList(filter, limit, page) { + const studlist = await Student.read(filter, limit, page); return studlist; } diff --git a/services/student/stdBank.js b/services/student/stdBank.js new file mode 100644 index 00000000..45da5153 --- /dev/null +++ b/services/student/stdBank.js @@ -0,0 +1,45 @@ +import StudentBank from "#models/student/stdBank"; +import databaseError from "#error/database"; + +export async function createStudentBank( + uid, + bankName, + bankAccount, + bankBranch, + bankIfsc, + bankMicr, +) { + const newStudentBank = await StudentBank.create({ + uid, + bankName, + bankAccount, + bankBranch, + bankIfsc, + bankMicr, + }); + if (newStudentBank.uid === uid) { + return newStudentBank; + } + throw new databaseError.DataEntryError("student bank"); +} + +export async function updateStudentBankById(id, data) { + const updated = await StudentBank.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("student bank"); +} + +export async function studentBankList(filter, limit, page) { + const studentBank = await StudentBank.read(filter, limit, page); + return studentBank; +} + +export async function deleteStudentBankById(studentBankId) { + const deleted = await StudentBank.remove({ _id: studentBankId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("student bank"); +} diff --git a/services/student/stdCollege.js b/services/student/stdCollege.js new file mode 100644 index 00000000..463fe0f1 --- /dev/null +++ b/services/student/stdCollege.js @@ -0,0 +1,61 @@ +import StudentCollege from "#models/student/stdCollege"; +import databaseError from "#error/database"; + +export async function createStudentCollege( + uid, + admissionYear, + studentCode, + rollNo, + admissionStatus, + admissionPattern, + admissionCategory, + seatDesc, + quotaType, + isBoarderStudent, + seatType, + seatSubType, + eligibilityNo, + enrollmentNo, +) { + const newStudentCollege = await StudentCollege.create({ + uid, + admissionYear, + studentCode, + rollNo, + admissionStatus, + admissionPattern, + admissionCategory, + seatDesc, + quotaType, + isBoarderStudent, + seatType, + seatSubType, + eligibilityNo, + enrollmentNo, + }); + if (newStudentCollege.uid === uid) { + return newStudentCollege; + } + throw new databaseError.DataEntryError("student college"); +} + +export async function updateStudentCollegeById(id, data) { + const updated = await StudentCollege.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("student college"); +} + +export async function studentCollegeList(filter, limit, page) { + const studentColleges = await StudentCollege.read(filter, limit, page); + return studentColleges; +} + +export async function deleteStudentCollegeById(studentCollegeId) { + const deleted = await StudentCollege.remove({ _id: studentCollegeId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("student college"); +} diff --git a/services/student/stdEduHistory.js b/services/student/stdEduHistory.js new file mode 100644 index 00000000..a63cee4e --- /dev/null +++ b/services/student/stdEduHistory.js @@ -0,0 +1,92 @@ +import StudentEducation from "#models/student/stdEduHistory"; +import databaseError from "#error/database"; + +export async function createStudentEducation( + uid, + tenth, + cetHscDetails, + graduationDetails, +) { + const newStudentEducation = await StudentEducation.create({ + uid, + tenth: { + marks: tenth.marks, + percentage: tenth.percentage, + seatNumber: tenth.seatNumber, + examName: tenth.examName, + examBoard: tenth.examBoard, + msOms: tenth.msOms, + meritNumberInQualifyingExam: tenth.meritNumberInQualifyingExam, + admittedNumber: tenth.admittedNumber, + }, + cetHscDetails: { + cetRollNo: cetHscDetails.cetRollNo, + cetMarks: cetHscDetails.cetMarks, + qualifyingExamForAdmission: cetHscDetails.qualifyingExamForAdmission, + stdType: cetHscDetails.stdType, + streamOpted: cetHscDetails.streamOpted, + mediumOfInstruction: cetHscDetails.mediumOfInstruction, + aggTotalMarks: cetHscDetails.aggTotalMarks, + totalMarksOutOf: cetHscDetails.totalMarksOutOf, + percentOfMarks: cetHscDetails.percentOfMarks, + attemptNo: cetHscDetails.attemptNo, + passingMonth: cetHscDetails.passingMonth, + passingYear: cetHscDetails.passingYear, + institutionName: cetHscDetails.institutionName, + educBoardName: cetHscDetails.educBoardName, + pcmPercent: cetHscDetails.pcmPercent, + pbmPercent: cetHscDetails.pbmPercent, + stuQualifyingExam: cetHscDetails.stuQualifyingExam, + marksObtained: cetHscDetails.marksObtained, + stateRank: cetHscDetails.stateRank, + prevExamSeatNumber: cetHscDetails.prevExamSeatNumber, + prevTcNumber: cetHscDetails.prevTcNumber, + hscPassedSchoolName: cetHscDetails.hscPassedSchoolName, + boardPattern: cetHscDetails.boardPattern, + scholarshipName: cetHscDetails.scholarshipName, + scholarshipType: cetHscDetails.scholarshipType, + dteSeatType: cetHscDetails.dteSeatType, + dteUserPassword: cetHscDetails.dteUserPassword, + dteUserId: cetHscDetails.dteUserId, + }, + graduationDetails: { + graduationInstitute: graduationDetails.graduationInstitute, + graduationBranch: graduationDetails.graduationBranch, + graduationDegree: graduationDetails.graduationDegree, + graduationMarksPct: graduationDetails.graduationMarksPct, + graduationsPassingYear: graduationDetails.graduationsPassingYear, + urbanRural: graduationDetails.urbanRural, + scholarshipNumber: graduationDetails.scholarshipNumber, + lastSchoolCollegeAttended: graduationDetails.lastSchoolCollegeAttended, + }, + }); + if (newStudentEducation.uid === uid) { + return newStudentEducation; + } + throw new databaseError.DataEntryError("student education"); +} + +export async function updateStudentEducationById(id, data) { + const updated = await StudentEducation.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("student education"); +} + +export async function studentEducationList(filter, limit, page) { + const studentEducationDetails = await StudentEducation.read( + filter, + limit, + page, + ); + return studentEducationDetails; +} + +export async function deleteStudentEducationById(studentEducationId) { + const deleted = await StudentEducation.remove({ _id: studentEducationId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("student education"); +} diff --git a/services/student/stdMedHistory.js b/services/student/stdMedHistory.js new file mode 100644 index 00000000..a96778ca --- /dev/null +++ b/services/student/stdMedHistory.js @@ -0,0 +1,49 @@ +import MedicalHistory from "#models/student/stdMedHistory"; +import databaseError from "#error/database"; + +export async function createMedicalHistory( + uid, + bloodGroup, + pastMedicalHistory, + immunisationHistory, + chronicMedicalConditions, + parentsEmailId, + parentsContact, + relativeContacts, +) { + const newMedicalHistory = await MedicalHistory.create({ + uid, + bloodGroup, + pastMedicalHistory, + immunisationHistory, + chronicMedicalConditions, + parentsEmailId, + parentsContact, + relativeContacts, + }); + if (newMedicalHistory.uid === uid) { + return newMedicalHistory; + } + throw new databaseError.DataEntryError("medicalHistory"); +} + +export async function updateMedicalHistoryById(id, data) { + const updated = await MedicalHistory.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("medicalHistory"); +} + +export async function medicalHistoryList(filter, limit, page) { + const medHistoryList = await MedicalHistory.read(filter, limit, page); + return medHistoryList; +} + +export async function deleteMedicalHistoryById(medicalHistoryId) { + const deleted = await MedicalHistory.remove({ _id: medicalHistoryId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("medicalHistory"); +} diff --git a/services/student/stdPersonal.js b/services/student/stdPersonal.js new file mode 100644 index 00000000..61ea0525 --- /dev/null +++ b/services/student/stdPersonal.js @@ -0,0 +1,189 @@ +import Student from "#models/student/stdPersonal"; +import databaseError from "#error/database"; + +export async function createStudent( + uid, + title, + firstName, + middleName, + motherName, + gender, + dob, + age, + birthPlace, + nationality, + motherTongue, + domicileState, + religion, + castCategory, + maharashtraKarnatakaBorderCandidate, + castDescription, + subCasteDescription, + nonCreamyLayerCertificateAttached, + hobby, + passportNo, + bloodGroup, + physicallyHandicapped, + studentMobNo, + studentMail, + parentMobNo, + parentMail, + perAddrDescr, + perPlotNo, + perStreetName, + perStuAddr1, + perStuAddr2, + city, + percellphone, + perpincode, + perresiphone, + permailaddress, + country, + state, + district, + tahsil, + correspondanceAddrDescr, + correspondancePlotNo, + correspondanceStreetName, + correspondanceStuAddr1, + correspondanceStuAddr2, + correspondanceCity, + correspondanceCellPhone, + correspondancePincode, + correspondanceResiPhone, + correspondanceMailAddress, + correspondanceCountry, + correspondanceState, + correspondanceDistrict, + correspondanceTahsil, + fatherDetails, + fathersOccupation, + parentsFirstName, + parentsMiddleName, + parentsLastName, + guardianMobNo, + guardianMailId, + nameAsPerTc, + casteAsPerTc, + birthStatus, + maritalStatus, + panCardNo, + passportExpiry, + drivingLicNo, + drivingLicValidTo, + aadharCardNo, + electionCardNo, + motherMobNo, + motherEmailId, + parentIncome, + photoUploaded, + signUploaded, + thumbUploaded, + noOfDocumentsUploaded, +) { + const newStudent = await Student.create({ + uid, + title, + firstName, + middleName, + motherName, + gender, + dob, + age, + birthPlace, + nationality, + motherTongue, + domicileState, + religion, + castCategory, + maharashtraKarnatakaBorderCandidate, + castDescription, + subCasteDescription, + nonCreamyLayerCertificateAttached, + hobby, + passportNo, + bloodGroup, + physicallyHandicapped, + studentMobNo, + studentMail, + parentMobNo, + parentMail, + perAddrDescr, + perPlotNo, + perStreetName, + perStuAddr1, + perStuAddr2, + city, + percellphone, + perpincode, + perresiphone, + permailaddress, + country, + state, + district, + tahsil, + correspondanceAddrDescr, + correspondancePlotNo, + correspondanceStreetName, + correspondanceStuAddr1, + correspondanceStuAddr2, + correspondanceCity, + correspondanceCellPhone, + correspondancePincode, + correspondanceResiPhone, + correspondanceMailAddress, + correspondanceCountry, + correspondanceState, + correspondanceDistrict, + correspondanceTahsil, + fatherDetails, + fathersOccupation, + parentsFirstName, + parentsMiddleName, + parentsLastName, + guardianMobNo, + guardianMailId, + nameAsPerTc, + casteAsPerTc, + birthStatus, + maritalStatus, + panCardNo, + passportExpiry, + drivingLicNo, + drivingLicValidTo, + aadharCardNo, + electionCardNo, + motherMobNo, + motherEmailId, + parentIncome, + photoUploaded, + signUploaded, + thumbUploaded, + noOfDocumentsUploaded, + }); + if (newStudent) { + return newStudent; + } + throw new databaseError.DataEntryError("student"); +} + +export async function updateStudentById(id, data) { + const updated = await Student.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("activity"); +} + +export async function studentList(filter, limit, page) { + const studentlist = await Student.read(filter, limit, page); + return studentlist; +} + +export async function deleteStudentById(id) { + const deleted = await Student.remove({ _id: id }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("activity"); +} diff --git a/services/timetable.js b/services/timetable.js index 17608458..5405dec0 100644 --- a/services/timetable.js +++ b/services/timetable.js @@ -37,8 +37,8 @@ export async function updateTimetableById(id, data) { throw new databaseError.DataEntryError("timetable"); } -export async function timetableList(filter) { - const timetable = await Timetable.read(filter, 0); +export async function timetableList(filter, limit, page) { + const timetable = await Timetable.read(filter, limit, page); return timetable; } diff --git a/services/topic.js b/services/topic.js new file mode 100644 index 00000000..289e764f --- /dev/null +++ b/services/topic.js @@ -0,0 +1,36 @@ +import Topic from "#models/topic"; +import databaseError from "#error/database"; + +export async function addNewTopic(title) { + const newTopic = await Topic.create({ + title, + }); + if (newTopic.title === title) { + return newTopic; + } + throw new databaseError.DataEntryError("Add Topic"); +} + +export async function getTopics(filter, limit, page) { + const topics = await Topic.read(filter, limit, page); + if (topics) { + return topics; + } + throw new databaseError.DataNotFoundError("Topic"); +} + +export async function deleteTopicById(topicId) { + const deleted = await Topic.remove({ _id: topicId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("Topic"); +} + +export async function updateTopicById(id, data) { + const updated = await Topic.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("Topic"); +} diff --git a/services/tutorial.js b/services/tutorial.js index dfefefc6..2cbff8f7 100644 --- a/services/tutorial.js +++ b/services/tutorial.js @@ -14,8 +14,8 @@ export async function addNewTutorial(no, title, hours, cognitiveLevel) { throw new databaseError.DataEntryError("Add Tutorial"); } -export async function getTutorials(filter) { - const tutorials = await Tutorial.read(filter); +export async function getTutorials(filter, limit, page) { + const tutorials = await Tutorial.read(filter, limit, page); if (tutorials) { return tutorials; } @@ -39,5 +39,8 @@ export async function updateTutorialById(id, data) { } export default { - deleteTutorialById, addNewTutorial, updateTutorialById, getTutorials, + deleteTutorialById, + addNewTutorial, + updateTutorialById, + getTutorials, }; diff --git a/services/user.js b/services/user.js index 1e6d7374..188b8721 100644 --- a/services/user.js +++ b/services/user.js @@ -4,16 +4,19 @@ import { comparePasswords, hashPassword } from "#util"; export async function authenticateUser(uid, password) { const user = await User.read({ uid }, 1); - const passwordMatched = await comparePasswords(password, user[0]?.password); + const passwordMatched = await comparePasswords( + password, + user.data[0]?.password, + ); if (passwordMatched) { - return user[0]; + return user.data[0]; } throw new databaseError.UserDoesNotExistError(); } export async function userExists(uid, email) { const user = await User.read({ uid, emailId: email }, 1); - if (user[0].uid === uid) return true; + if (user.data[0].uid === uid) return true; return false; } @@ -24,14 +27,18 @@ export async function updatePassword(uid, password) { throw new databaseError.UpdateError("User"); } -export async function allUsers() { - const allUser = await User.read({}, 0); +export async function allUsers(limit, page) { + const allUser = await User.read({}, limit, page); return allUser; } export async function createUser(name, password, emailId, uid, userType) { const newUser = await User.create({ - name, password, emailId, uid, userType, + name, + password, + emailId, + uid, + userType, }); if (newUser.uid === uid) { return newUser; diff --git a/setup.js b/setup.js deleted file mode 100644 index 619d3f0e..00000000 --- a/setup.js +++ /dev/null @@ -1,7 +0,0 @@ -import fs from "fs"; -import path from "path"; - -fs.copyFile(path.join("hooks", "pre-commit"), path.join(".git", "hooks", "pre-commit"), (err) => { - if (err) throw err; - console.log("Hook setup completed"); -}); diff --git a/test/routes/activity.test.js b/test/routes/activity.test.js index ab826969..eac71790 100644 --- a/test/routes/activity.test.js +++ b/test/routes/activity.test.js @@ -8,14 +8,7 @@ const { agent } = global; function cleanUp(callback) { activityModel .remove({ - startTime: "2023-06-18T14:11:30Z", - duration: 2, - course: "64fc3c8bde9fa947ea1f412f", - faculty: "64fc3c8bde9fa947ea1f412f", - type: "LECTURE", - task: ["64fc3c8bde9fa947ea1f412f"], - group: "64fc3c8bde9fa947ea1f412f", - students: ["64fc3c8bde9fa947ea1f412f"] + course: "5f8778b54b553439ac49a03a" }) .then(() => { connector.disconnect((DBerr) => { @@ -55,7 +48,7 @@ describe("Activity API", () => { activityBlueprint: "64fc3c8bde9fa947ea1f412f", startTime: "2023-06-18T14:11:30Z", duration: 2, - course: "64fc3c8bde9fa947ea1f412f", + course: "5f8778b54b553439ac49a03a", faculty: "64fc3c8bde9fa947ea1f412f", type: "LECTURE", task: ["64fc3c8bde9fa947ea1f412f"], @@ -70,7 +63,7 @@ describe("Activity API", () => { activityBlueprint: "64fc3c8bde9fa947ea1f412f", startTime: "2023-06-18T14:11:30Z", duration: 2, - course: "64fc3c8bde9fa947ea1f412f", + course: "5f8778b54b553439ac49a03a", faculty: "64fc3c8bde9fa947ea1f412f", type: "LECTURE", task: ["64fc3c8bde9fa947ea1f412f"], diff --git a/test/routes/attendance.test.js b/test/routes/attendance.test.js new file mode 100644 index 00000000..08bffc83 --- /dev/null +++ b/test/routes/attendance.test.js @@ -0,0 +1,68 @@ +import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies +import attendanceModel from "#models/attendance"; +import connector from "#models/databaseUtil"; + +jest.mock("#util"); +const { agent } = global; + +function cleanUp(callback) { + attendanceModel.remove({ student: "64fc3c8bde9fa947ea1f412f" }).then(() => { + connector.disconnect((DBerr) => { + if (DBerr) console.log("Database dissconnnect error: ", DBerr); + callback(); + }); + }); +} + +afterAll((done) => { + cleanUp(done); +}); + +describe("checking attendance functions", () => { + it("create attendance", async () => { + const response = await agent.post("/attendance/add").send({ + student: "64fc3c8bde9fa947ea1f412f", + course: "64fc3c8bde9fa947ea1f412f", + monthlyAttended: 123, + monthlyOccured: 123, + cumulativeAttended: 123, + cumulativeOccured: 123, + }); + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/added attendance/); + }); + let id; + beforeEach(async () => { + id = await agent.post("/attendance/add").send({ + student: "64fc3c8bde9fa947ea1f412f", + course: "64fc3c8bde9fa947ea1f412f", + monthlyAttended: 123, + monthlyOccured: 123, + cumulativeAttended: 123, + cumulativeOccured: 123, + }); + id = JSON.parse(id.res.text).id; + }); + + afterEach(async () => { + await attendanceModel.remove({ student: "64fc3c8bde9fa947ea1f412f" }); + }); + + it("read attendance", async () => { + const response = await agent + .get("/attendance/list") + .send({ student: "64fc3c8bde9fa947ea1f412f" }); + expect(response.status).toBe(200); + expect(response.body.res).toBeDefined(); + }); + + it("update attendance", async () => { + const response = await agent + .post(`/attendance/update/${id}`) + .send({ student: "64fc3c8bde9fa947ea1f412f" }); + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/attendance updated/); + }); +}); diff --git a/test/routes/auth.test.js b/test/routes/auth.test.js index 963278eb..33800820 100644 --- a/test/routes/auth.test.js +++ b/test/routes/auth.test.js @@ -1,12 +1,14 @@ import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies import util from "#util"; import userModel from "#models/user"; +import otpModel from "#models/otpStore"; import connector from "#models/databaseUtil"; jest.mock("#util"); const { agent } = global; function cleanUp(callback) { + otpModel.remove({ uid: "S1032190220" }); userModel.remove({ uid: "S1032190220" }).then(() => { connector.disconnect((DBerr) => { if (DBerr) console.log("Database dissconnnect error: ", DBerr); @@ -28,7 +30,7 @@ describe("checking user functions", () => { password: "123", emailId: "test@gmail.com", uid: "S1032190220", - userType: "student", + userType: "STUDENT", }); expect(response.headers["content-type"]).toMatch(/json/); expect(response.status).toBe(200); @@ -44,7 +46,7 @@ describe("checking auth functions", () => { password: "123", emailId: "test@gmail.com", uid: "S1032190220", - userType: "student", + userType: "STUDENT", }); }); diff --git a/test/routes/department.test.js b/test/routes/department.test.js index 44cd595c..77235d64 100644 --- a/test/routes/department.test.js +++ b/test/routes/department.test.js @@ -11,7 +11,7 @@ const { agent } = global; function cleanUp(callback) { departmentmodel.remove( { - name: "Computer", + name: "Electronics", acronym: "COMPS", yearOfStarting: "2020-09-01T00:00:00.000Z", accreditations: [mongoose.Types.ObjectId("5f8778b54b553439ac49a03a")], diff --git a/test/routes/exam.test.js b/test/routes/exam.test.js new file mode 100644 index 00000000..582d5d17 --- /dev/null +++ b/test/routes/exam.test.js @@ -0,0 +1,90 @@ +import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies +import request from "supertest"; +import app from "#app"; +import connector from "#models/databaseUtil"; +import examModel from "#models/exam"; + +jest.mock("#util"); + +let server; +let agent; + +beforeAll((done) => { + server = app.listen(null, () => { + agent = request.agent(server); + connector.set("debug", false); + done(); + }); +}); + +function cleanUp(callback) { + examModel + .remove({ + supervisor: "60a0e7e9a09c3f001c834e07", + }) + .then(() => { + connector.disconnect((DBerr) => { + if (DBerr) console.log("Database disconnect error: ", DBerr); + server.close((serverErr) => { + if (serverErr) console.log(serverErr); + callback(); + }); + }); + }); +} + +afterAll((done) => { + cleanUp(done); +}); + +describe("exam API", () => { + it("should create exam", async () => { + const response = await agent.post("/exam/add").send({ + date: "2023-06-18T14:11:30Z", + startTime: "2023-06-18T14:11:30Z", + duration: 5, + supervisor: ["5f8778b54b553439ac49a03a"], + infrastructure: ["5f8778b54b553439ac49a03a"], + course: ["5f8778b54b553439ac49a03a"], + }); + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/added exam/); + }); + + describe("after adding exam", () => { + let id; + beforeEach(async () => { + id = await agent.post("/exam/add").send({ + date: "2023-06-18T14:11:30Z", + startTime: "2023-06-18T14:11:30Z", + duration: 5, + supervisor: "64453a62c8f2146f2f34c73a", + infrastructure: "64453a62c8f2146f2f34c73a", + course: "64453a62c8f2146f2f34c73a", + }); + id = JSON.parse(id.res.text).id; + }); + + afterEach(async () => { + await examModel.remove({ supervisor: "64453a62c8f2146f2f34c73a" }); + }); + + it("should read exam", async () => { + const response = await agent + .get("/exam/list") + .send({ supervisor: "64453a62c8f2146f2f34c73a" }); + expect(response.status).toBe(200); + expect(response.body.res).toBeDefined(); + }); + + it("should update exam", async () => { + const response = await agent + .post(`/exam/update/${id}`) + .send({ duration: 10 }); + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/updated exam/); + }); + }); +}); diff --git a/test/routes/faculty.test.js b/test/routes/faculty.test.js new file mode 100644 index 00000000..5e30440b --- /dev/null +++ b/test/routes/faculty.test.js @@ -0,0 +1,128 @@ +import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies +import connector from "#models/databaseUtil"; +import facultyModel from "#models/faculty"; + +jest.mock("#util"); +const {agent} = global; + +// test case for deletion +function cleanUp(callback) { + facultyModel.remove( + { + ERPID: "test123", + dateOfJoining: "2023-06-18T14:11:30Z", + dateOfLeaving: "2023-07-18T14:11:30Z", + profileLink: "Sanika", + qualifications: ["Ph.D.", "M.Sc."], + totalExperience: 5, + achievements: ["Award 1", "Award 2"], + areaOfSpecialization: ["Specialization 1", "Specialization 2"], + papersPublishedPG: 10, + papersPublishedUG: 5, + department: ["5f7b75a5c69e2d4f0c285e52"], + preferredSubjects: ["5f7b75a5c69e2d4f0c285e53"], + designation: "Assistant Professor", + natureOfAssociation: "Regular", + additionalResponsibilities: "Teaching and Research", + }, + ) + .then(() => { + connector.disconnect((DBerr) => { + if (DBerr) console.log("Database disconnect error: ", DBerr); + callback(); + }); + }); +} + +afterAll((done) => { + cleanUp(done); +}); + +describe("Faculty API", () => { + it("should create faculty", async () => { + const response = await agent.post("/faculty/create").send({ + ERPID: "test123", + dateOfJoining: "2023-06-18T14:11:30Z", + dateOfLeaving: "2023-07-18T14:11:30Z", + profileLink: "xyz", + qualifications: ["Ph.D.", "M.Sc."], + totalExperience: 5, + achievements: ["Award 1", "Award 2"], + areaOfSpecialization: ["Specialization 1", "Specialization 2"], + papersPublishedPG: 10, + papersPublishedUG: 5, + department: ["5f7b75a5c69e2d4f0c285e52"], + preferredSubjects: ["5f7b75a5c69e2d4f0c285e53"], + designation: "Assistant Professor", + natureOfAssociation: "Regular", + additionalResponsibilities: "Teaching and Research", + }); + + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/added faculty/); + }); + + describe("after adding faculty", () => { + let id; + beforeEach(async () => { + id = await agent.post("/faculty/create").send( + { + ERPID: "test123", + dateOfJoining: "2023-06-18T14:11:30Z", + dateOfLeaving: "2023-07-18T14:11:30Z", + profileLink: "xyz", + qualifications: ["Ph.D.", "M.Sc."], + totalExperience: 5, + achievements: ["Award 1", "Award 2"], + areaOfSpecialization: ["Specialization 1", "Specialization 2"], + papersPublishedPG: 10, + papersPublishedUG: 5, + department: ["5f7b75a5c69e2d4f0c285e52"], + preferredSubjects: ["5f7b75a5c69e2d4f0c285e53"], + designation: "Assistant Professor", + natureOfAssociation: "Regular", + additionalResponsibilities: "Teaching and Research", + }); + + id = JSON.parse(id.res.text).id; + }); + + afterEach(async () => { + await facultyModel.remove( + { + ERPID: "test123", + dateOfJoining: "2023-06-18T14:11:30Z", + dateOfLeaving: "2023-07-18T14:11:30Z", + profileLink: "xyz", + qualifications: ["Ph.D.", "M.Sc."], + totalExperience: 5, + achievements: ["Award 1", "Award 2"], + areaOfSpecialization: ["Specialization 1", "Specialization 2"], + papersPublishedPG: 10, + papersPublishedUG: 5, + department: ["5f7b75a5c69e2d4f0c285e52"], + preferredSubjects: ["5f7b75a5c69e2d4f0c285e53"], + designation: "Assistant Professor", + natureOfAssociation: "Regular", + additionalResponsibilities: "Teaching and Research", + }); + }); + + it("should read faculty", async () => { + const response = await agent + .get("/faculty/list") + .send({ERPID: "test123"}); + + expect(response.status).toBe(200); + expect(response.body.res).toBeDefined(); + }); + + it("should update faculty", async () => { + const response = await agent + .post(`/faculty/update/${id}`) + .send({ ERPID: "test123" }, { totalExperience: 10 }); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/updated faculty/); + }); + }); +}); \ No newline at end of file diff --git a/test/routes/group.test.js b/test/routes/group.test.js index 5649cba0..e36d6a0d 100644 --- a/test/routes/group.test.js +++ b/test/routes/group.test.js @@ -8,7 +8,7 @@ const { agent } = global; function cleanUp(callback) { groupModel .remove({ - id: "6500594e2b7b532006c073dd", + title: "Group 1", }) .then(() => { connector.disconnect((DBerr) => { diff --git a/test/routes/notification.test.js b/test/routes/notification.test.js new file mode 100644 index 00000000..eb689a1f --- /dev/null +++ b/test/routes/notification.test.js @@ -0,0 +1,93 @@ +import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies +import notificationModel from "#models/notification"; +import connector from "#models/databaseUtil"; // Import your Express app instance + +jest.mock("#util"); +const { agent } = global; + +function cleanUp(callback) { + notificationModel + .remove({ + data: "Sample Notification", + title: "Test Title", + from: "64fc3c8bde9fa947ea1f412f", + type: "Student", + filter: ["64fc3c8bde9fa947ea1f412f"], + }) + .then(() => { + connector.disconnect((DBerr) => { + if (DBerr) console.log("database disconnect error: ", DBerr); + callback(); + }); + }); +} + +afterAll((done) => { + cleanUp(done); +}); + +describe("Notification API", () => { + it("should create a new notification", async () => { + const response = await agent.post("/notification/add").send({ + data: "Sample Notification", + title: "Test Title", + from: "64fc3c8bde9fa947ea1f412f", // Use a valid Faculty ID + type: "Student", + filter: ["64fc3c8bde9fa947ea1f412f"], // Use a valid User ID + }); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/Added notification/); + const notificationId = JSON.parse(response.res.text).id; + await notificationModel.remove({ _id: notificationId }); + }); + + describe("after adding notification", () => { + let notificationId; + beforeEach(async () => { + const id = await agent.post("/notification/add").send({ + data: "Sample Notification", + title: "Test Title", + from: "64fc3c8bde9fa947ea1f412f", + type: "Student", + filter: ["64fc3c8bde9fa947ea1f412f"], + }); + notificationId = JSON.parse(id.res.text).id; + }); + afterEach(async () => { + await notificationModel.remove({ + data: "Sample Notification", + title: "Test Title", + from: "64fc3c8bde9fa947ea1f412f", + type: "Student", + filter: ["64fc3c8bde9fa947ea1f412f"], + }); + }); + + it("should update a notification entity", async () => { + const response = await agent + .post(`/notification/update/${notificationId}`) + .send({ + data: "Updated Notification Data", + title: "Updated Title", + from: "64fc3c8bde9fa947ea1f412f", + type: "Faculty", + filter: ["64fc3c8bde9fa947ea1f412f"], + }); + + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/Updated notification/); + }); + + it("should list notification entities", async () => { + const response = await agent.get("/notification/list").send({ + data: "Sample Notification", + title: "Test Title", + from: "64fc3c8bde9fa947ea1f412f", + type: "Student", + filter: ["64fc3c8bde9fa947ea1f412f"], + }); + expect(response.status).toBe(200); + expect(response.body.res).toBeDefined(); + }); + }); +}); diff --git a/test/routes/practical.test.js b/test/routes/practical.test.js index 8a01bbc0..ed6ec923 100644 --- a/test/routes/practical.test.js +++ b/test/routes/practical.test.js @@ -6,14 +6,12 @@ jest.mock("#util"); const { agent } = global; function cleanUp(callback) { - PracticalModel - .remove({}) - .then(() => { - connector.disconnect((DBerr) => { - if (DBerr) console.log("Database disconnect error: ", DBerr); - callback(); - }); + PracticalModel.remove({}).then(() => { + connector.disconnect((DBerr) => { + if (DBerr) console.log("Database disconnect error: ", DBerr); + callback(); }); + }); } afterAll((done) => { @@ -53,16 +51,16 @@ describe("Practical API", () => { }); it("should list practical entities", async () => { - const response = await agent.get("/practical/list") - .send({ title: "new practical" }); + const response = await agent.get("/practical/list"); expect(response.status).toBe(200); - expect(response.body.res).toHaveLength(1); }); it("should update a practical entity", async () => { - const response = await agent.post(`/practical/update/${practicalId}`).send({ - hours: 3, - }); + const response = await agent + .post(`/practical/update/${practicalId}`) + .send({ + hours: 3, + }); expect(response.status).toBe(200); expect(response.body.res).toMatch(/Updated Practical/); diff --git a/test/routes/student.test.js b/test/routes/student.test.js new file mode 100644 index 00000000..04414dda --- /dev/null +++ b/test/routes/student.test.js @@ -0,0 +1,92 @@ +import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies +import connector from "#models/databaseUtil"; +import studentModel from "#models/student"; + +jest.mock("#util"); +const { agent } = global; + +function cleanUp(callback) { + studentModel + .remove({ + ERPID: "S1032220999", + name: "Arya", + joiningYear: 2020, + branch: "64fc3c8bde9fa947ea1f412f", + division: "A", + rollNo: 12, + coursesOpted: "64fc3c8bde9fa947ea1f412f", + }) + .then(() => { + connector.disconnect((DBerr) => { + if (DBerr) console.log("Database disconnect error : ", DBerr); + callback(); + }); + }); +} + + +afterAll((done) => { + cleanUp(done); +}); + +describe("Student API", () => { + it("should create student", async () => { + const response = await agent.post("/student/create").send({ + ERPID: "S1032220999", + name: "Arya", + joiningYear: 2020, + branch: "64fc3c8bde9fa947ea1f412f", + division: "A", + rollNo: 12, + coursesOpted: "64fc3c8bde9fa947ea1f412f", + }); + + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/added user/); + }); + + describe("after adding student", () => { + let id; + beforeEach(async () => { + id = await agent.post("/student/create").send({ + ERPID: "S1032220999", + name: "Arya", + joiningYear: 2020, + branch: "64fc3c8bde9fa947ea1f412f", + division: "A", + rollNo: 12, + coursesOpted: "64fc3c8bde9fa947ea1f412f", + }); + id = JSON.parse(id.res.text).id; + }); + + afterEach(async () => { + await studentModel.remove({ + ERPID: "S1032220999", + name: "Arya", + joiningYear: 2020, + branch: "64fc3c8bde9fa947ea1f412f", + division: "A", + rollNo: 12, + coursesOpted: "64fc3c8bde9fa947ea1f412f", + }); + }); + + it("should read student", async () => { + const response = await agent + .get("/student/list") + .send({ name: "Arya" }); + expect(response.status).toBe(200); + expect(response.body.res).toBeDefined(); + }); + + it("should update student", async () => { + const response = await agent + .post(`/student/update/${id}`) + .send({ERPID: "S1032220999"},{ joiningYear: 2021 }); + + expect(response.status).toBe(200); + expect(response.body.res).toMatch(`updated Student with id ${id}`); + }); + }); +}); diff --git a/test/routes/timetable.test.js b/test/routes/timetable.test.js index 92029c65..1a885614 100644 --- a/test/routes/timetable.test.js +++ b/test/routes/timetable.test.js @@ -6,7 +6,7 @@ jest.mock("#util"); const { agent } = global; function cleanUp(callback) { - timetableModel.remove({ startDate: "2023-06-18T14:11:30Z" }).then(() => { + timetableModel.remove({ lunchbreakStartTime: "test:45 PM" }).then(() => { connector.disconnect((DBerr) => { if (DBerr) console.log("Database disconnect error: ", DBerr); callback(); @@ -26,7 +26,7 @@ describe("checking timetable functions", () => { classIncharge: "60a0e7e9a09c3f001c834e06", group: "60a0e7e9a09c3f001c834e07", activityBlueprints: "60a0e7e9a09c3f001c834e08", - lunchbreakStartTime: "01:45 PM", + lunchbreakStartTime: "test:45 PM", lunchbreakDuration: 45, // minutes teabreakStartTime: "11:30 AM", teabreakDuration: 15, // minutes @@ -43,7 +43,7 @@ describe("checking timetable functions", () => { classIncharge: "60a0e7e9a09c3f001c834e06", group: "60a0e7e9a09c3f001c834e07", activityBlueprints: "60a0e7e9a09c3f001c834e08", - lunchbreakStartTime: "01:45 PM", + lunchbreakStartTime: "test:45 PM", lunchbreakDuration: 45, // minutes teabreakStartTime: "11:30 AM", teabreakDuration: 15, // minutes diff --git a/test/routes/topic.test.js b/test/routes/topic.test.js new file mode 100644 index 00000000..68b2213b --- /dev/null +++ b/test/routes/topic.test.js @@ -0,0 +1,59 @@ +import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies +import topicModel from "#models/topic"; +import connector from "#models/databaseUtil"; + +jest.mock("#util"); + +const { agent } = global; + +function cleanUp(callback) { + topicModel.remove({ title: "xyz" }).then(() => { + connector.disconnect((DBerr) => { + if (DBerr) console.log("Database dissconnnect error: ", DBerr); + }); + callback(); + }); +} + +afterAll((done) => { + cleanUp(done); +}); + +describe("checking topic functions", () => { + it("create topic", async () => { + const response = await agent.post("/topic/add").send({ + title: "xyz", + }); + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/added topic/); + }); + let id; + beforeEach(async () => { + id = await agent.post("/topic/add").send({ + title: "xyz", + }); + id = JSON.parse(id.res.text).id; + }); + + afterEach(async () => { + await topicModel.remove({ title: "xyz" }); + }); + + it("read topic", async () => { + const response = await agent + .get("/topic/list") + .send({ title: "xyz" }); + expect(response.status).toBe(200); + expect(response.body.res).toBeDefined(); + }); + + it("update topic", async () => { + const response = await agent + .post(`/topic/update/${id}`) + .send({ title: "xyz" }, { title: "123" }); + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/topic updated/); + }); +});