diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 88c1e4b4..713c09ee 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -4,7 +4,7 @@ module.exports = { es2021: true, jest: true }, - extends: "airbnb-base", + extends: ["airbnb-base", "prettier"], overrides: [], parserOptions: { ecmaVersion: "latest", diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..0657725c --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +**/node_modules +**/apidoc +**/.git +**/_apidoc.js +**/*.json +**/*.css +Dockerfile diff --git a/.prettierrc b/.prettierrc index ed156f05..a6728006 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,5 @@ { - "singleQuote": true, - "tabWidth": 2 + "singleQuote": false, + "tabWidth": 2, + "semi": true } diff --git a/Contribution.md b/CONTRIBUTING.md similarity index 100% rename from Contribution.md rename to CONTRIBUTING.md diff --git a/_apidoc.js b/_apidoc.js index af957ea9..a21f1643 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. @@ -695,6 +701,317 @@ * } */ +/** + * @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 +//----------------------------------------------------------------------------- + +/** + * @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 + * @apiSuccess {String} organization.name name of the organization + * @apiSuccess {ObjectId} organization.accreditations accreditation Id of the organization + */ + +/** + * @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 + */ + +/** + * @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. + * + * @apiError (Error 500) DatabaseError Error message if there was an error during the deletion. + */ + +// ------------------------------------------------------------------------------------------ +// Paper. +// ------------------------------------------------------------------------------------------ +// +/** + * @api {post} /paper/add Add Paper + * @apiName AddPaper + * @apiDescription Adds a new Paper. + * @apiGroup Paper + * + * @apiBody {String} [answersheetID] The id of the Answersheet. + * @apiBody {connector.Schema.Types.ObjectId} Exam The Exam which is associated. + * @apiBody {connector.Schema.Types.ObjectId} Student The Student which is associated. + * @apiBody {connector.Schema.Types.ObjectId} Faculty The Faculty which is associated. + * @apiBody {Number} [marks] marks in the paper. + * + * @apiSuccess {String} res added Paper successfully. + * + * @apiError (Error 500) DatabaseError Error while inserting in the DB. + * + */ + +/** + * @api {get} /paper/list Listdown Paper + * @apiName GetPaper + * @apiDescription Listdown the Paper. + * @apiGroup Paper + * + * @apiQuery {String} [answersheetID] The id of the Answersheet. + * @apiQuery {connector.Schema.Types.ObjectId} Exam The Exam which is associated. + * @apiQuery {connector.Schema.Types.ObjectId} Student The Student which is associated. + * @apiQuery {connector.Schema.Types.ObjectId} Faculty The Faculty which is associated. + * @apiQuery {Number} [marks] marks in the paper. + * + * @apiSuccess {Paper[]} res Array of Filtered Paper Doc. + * @apiSuccess {String} paper._id ID of paper given by database. + * @apiSuccess {String} paper.answersheetID ID of answersheet. + * @apiSuccess {connector.Schema.Types.ObjectId} paper.exam associated Exam. + * @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. + * @apiError (Error 500) err Error while fetching the data. + */ + +/** + * @api {delete} /paper/delete/:id Delete Paper + * @apiName DeletePaper + * @apiDescription Remove the existing Paper. + * @apiGroup Paper + * + * @apiParam {String} id The ID of the Paper document to delete. + * + * @apiSuccess {String} res Paper deleted successfully. + * + * @apiError (Error 500) err Error while deleting from DB. + * +* */ + +// ------------------------------------------------------------------------------------------ +// Assignment. +// ------------------------------------------------------------------------------------------ +/** + * @api {post} /assignment/add Add assignment + * @apiName Addassignment + * @apiGroup Assignment + * @apiDescription Add a new assignment. + * + * @apiBody {String} no Assignment number. + * @apiBody {String} title assignment title. + * @apiBody {String} type type of assignment. + * @apiBody {Number} marks marks in assignment. + * + * @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 assignment Example Assignment" + * } + * + * @apiErrorExample Error-Response: + * HTTP/1.1 500 Internal Server Error + * { + * "err": "Error while inserting in DB" + * } + */ +// ------------------------------------------------------------------------------------------ +// Practical. +// ------------------------------------------------------------------------------------------ + +/** + * @api {post} /practical/create Create Practical + * @apiName CreatePractical + * @apiGroup Practical + * + * @apiBody {Number} no Practical number. + * @apiBody {String} title Title of the practical. + * @apiBody {String} type Type of the practical. + * @apiBody {Number} hours Number of hours required. + * @apiBody {String[]} cognitiveLevels Array of cognitive levels (L1-L6). + * + * @apiSuccess {Object} res The created Practical entity. + * @apiSuccess {String} res._id ID of the created entity. + * @apiSuccess {Number} res.no Practical number. + * @apiSuccess {String} res.title Title of the practical. + * @apiSuccess {String} res.type Type of the practical. + * @apiSuccess {Number} res.hours Number of hours required. + * @apiSuccess {String[]} res.cognitiveLevels Array of cognitive levels (L1-L6). + */ + +/** + * @api {get} /practical/list List Practical + * @apiName ListPractical + * @apiGroup Practical + * + * @apiQuery {Number} [no] Filter by Practical number. + * @apiQuery {String} [title] Filter by title. + * @apiQuery {String} [type] Filter by type. + * @apiQuery {Number} [hours] Filter by hours. + * @apiQuery {String[]} [cognitiveLevels] Filter by cognitive levels (L1-L6). + * + * @apiSuccess {Object[]} res List of Practical entities. + * @apiSuccess {String} res._id ID of the Practical entity. + * @apiSuccess {Number} res.no Practical number. + * @apiSuccess {String} res.title Title of the Practical. + * @apiSuccess {String} res.type Type of the Practical. + * @apiSuccess {Number} res.hours Number of hours required. + * @apiSuccess {String[]} res.cognitiveLevels Array of cognitive levels (L1-L6). + */ + +/** + * @api {post} /practical/update/:id Update Practical + * @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. + * @apiBody {String} [type] New type. + * @apiBody {Number} [hours] New hours. + * @apiBody {String[]} [cognitiveLevels] New cognitive levels (L1-L6). + * + * @apiSuccess {Object} res The updated Practical entity. + * @apiSuccess {String} res._id ID of the updated entity. + * @apiSuccess {Number} res.no Updated Practical number. + * @apiSuccess {String} res.title Updated title. + * @apiSuccess {String} res.type Updated type. + * @apiSuccess {Number} res.hours Updated hours. + * @apiSuccess {String[]} res.cognitiveLevels Updated cognitive levels (L1-L6). + */ + +/** + * @api {delete} /practical/delete/:id Delete Practical + * @apiName DeletePractical + * @apiGroup Practical + * + * @apiParam {String} id ID of the Practical entity to delete. + * + * @apiSuccess {String} res Success message indicating the entity is deleted. + */ + +/** + * @api {error} 500 Internal Server Error + * @apiName InternalServerError + * @apiGroup Errors + * + * @apiError (Error 500) {String} err Error message for internal server errors. + */ + +/** + * @api {error} 404 Not Found + * @apiName NotFoundError + * @apiGroup Errors + * + * @apiError (Error 404) {String} err Error message for resource not found. + */ + +/** + * @api {error} 400 Bad Request + * @apiName BadRequestError + * @apiGroup Errors + * + * @apiError (Error 400) {String} err Error message for bad requests. + */ + +// ------------------------------------------------------------------------------------------ +// Group. +// ------------------------------------------------------------------------------------------ + +/** + * @api {post} /group/add Add Group + * @apiName AddGroup + * @apiGroup Group + * @apiDescription Add a new group. + * + * @apiBody {String} title Group title. + * @apiBody {ObjectId[]} students Array of student ObjectIDs. + * + * @apiSuccess {String} res Response message. + * @apiError (Error 500) GroupAddError Error while adding the group + * + * @apiSuccessExample Success-Response: + * HTTP/1.1 200 OK + * { + * "res": "added group Example Group" + * } + * + * @apiErrorExample Error-Response: + * HTTP/1.1 500 Internal Server Error + * { + * "err": "Error while inserting in DB" + * } + */ + /** * @api {delete} /exam/delete/:id Delete Exam * @apiName DeleteExam @@ -707,6 +1024,57 @@ * */ +/** + * @api {delete} /assignment/delete/:assignmentId To delete Assignment + * @apiName DeleteAssignment + * @apiGroup Assignment + * + * @apiParam {String} assignmentId The ID of the assignment 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} /paper/update/:id Update Paper + * @apiName UpdatePaper + * @apiGroup Paper + * @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 + * @apiSuccess {connector.Schema.Types.ObjectId} paper.exam associated Exam. + * @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/: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. + * + * @apiSuccess {String} res Assignment updated. + * @apiError (Error 500) err Error in updating database + * + */ + /** * @api {post} /exam/update/:id Update Exam Details * @apiName UpdateExam @@ -722,6 +1090,157 @@ * */ +/** + * @api {get} assignment/list Get Assignment List + * @apiName GetAssignment + * @apiGroup Assignment + * + * @apiBody {String} [no] Number of assignment. + * @apiBody {String} [title] Title of assignment. + * @apiBody {String} [type] type of 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. + */ + +// ------------------------------------------------------------------------------------------ +// Semester +// ------------------------------------------------------------------------------------------ +/** + * @api {post} /semester/add Request to add Semester information + * @apiName Addsemester + * @apiGroup Semester + * + * @apiQuery {Number} [number] Number of semester + * @apiQuery {String} [academicYear] To show the current academic year + * @apiQuery {String} [type] Stores the enum ODD or EVEN for semester + * @apiQuery {Date} [startDate] Start date of the semester + * @apiQuery {Date} [endDate] End date of the semester + * + * @apiSuccess {String} res Response message . + * @apiError (Error 500) DatabaseError Err message if there is an error inserting into the database. + * + */ + +/** + * @api {get} /semester/list Request to list Semester information + * @apiName semesterlist + * @apiGroup Semester + * + * @apiQuery {Number} [number] Number of semester + * @apiQuery {String} [academicYear] To show the current academic year + * @apiQuery {String} [type] Stores the enum ODD or EVEN for semester + * @apiQuery {Date} [startDate] Start date of the semester + * @apiQuery {Date} [endDate] End date of the semester + * + * @apiSuccess {semester[]} res Array of Filtered semester Doc. + * @apiSuccess {Number} semester.number Number of semester + * @apiSuccess {String} semester.academicYear To show the current academic year of the semester + * @apiSuccess {String} semester.type Stores the enum ODD or EVEN for semester + * @apiSuccess {Date} semester.startDate Start date of the semester + * @apiSuccess {Date} semester.endDate End date of the semester + * + */ + +/** + * @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. + * @apiError (Error 500) DatabaseError Error in updating the database. + * + */ + +/** +* @api {delete} /semester/delete/:id Request to list Semester information +* @apiName Deletesemester +* @apiGroup Semester +* +* @apiParam {String} id The ID of the Semester 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. +*/ + + +// ------------------------------------------------------------------------------------------ +// Activity. +// ------------------------------------------------------------------------------------------ + +/** + * @api {post} /activity/add Add Activty. + * @apiName AddActivity + * @apiGroup Activity + * + * @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). + * @apiBody {ObjectId} faculty The faculty alloted for the activity(ObjectId). + * @apiBody {String} type The type of activity.One of possible LECTURE, PRACTICAL, TUTORIAL. + * @apiBody {ObjectId} task The task of the activity (ObjectId).One of possible Topic,Practical,Tutorial. + * @apiBody {ObjectId} group The group of the activity (ObjectId). + * @apiBody {ObjectId} students the students who gonna attend the activity(ObjectId). + * + * @apiSuccess {String} res Response message. + * + * @apiError (Error 500) DatabaseError Error while inserting in the database. + * + * @apiDescription Adds a new Activity to the system. + * + * @apiSuccessExample Success-Response: + * HTTP/1.1 200 OK + * { + * "res": "Added activity" + * } + * + * @apiErrorExample Error-Response: + * HTTP/1.1 500 Internal Server Error + * { + * "err": "Error while inserting in DB" + * } + */ + +/** + * @api {delete} /group/delete/:id Delete Group + * @apiName DeleteGroup + * @apiGroup Group + * + * @apiParam {ObjectId} id The ObjectID of the group to delete. + * + * @apiSuccess {String} res Success message indicating the deletion. + * @apiError (Error 500) GroupDeleteError Error while deleting the group + * + */ + +/** + * @api {post} /group/update/:id Update Group Details + * @apiName UpdateGroup + * @apiGroup Group + * @apiDescription Update existing group details. + * + * @apiParam {ObjectId} id The ObjectID of the group to update. + * @apiBody {String} [title] Group title. + * @apiBody {ObjectId[]} [students] Array of student ObjectIDs. + * + * @apiSuccess {String} res Group updated. + * @apiError (Error 500) GroupUpdateError Error in updating database + * + */ + /** * @api {get} /exam/list Get Exam List * @apiName GetExamList @@ -734,3 +1253,413 @@ * @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 + * @apiGroup Group + * + * @apiQuery {String} [title] Title of the group. + * + * @apiSuccess {Group[]} res Array of filtered group documents. + * @apiSuccess {ObjectId} group._id ObjectID of the group document in the database. + * @apiSuccess {String} group.title Title of the group. + * @apiSuccess {ObjectId[]} group.students Array of student ObjectIDs in the group. + */ +/** + * @api {delete} /timetable/delete/:timetableId Delete Timetable + * @apiName DeleteTimetable + * @apiGroup Timetable + * + * @apiParam {String} timetableId The ID of the timetable 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} /organization/update/:organizationId Update Organisation + * @apiName UpdateOrganization + * @apiGroup Organization + * + * @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 + */ + +/** + * @api {delete} /activity/delete/:activity Delete Activity. + * @apiName DeleteActivity + * @apiGroup Activity + * + * @apiParam {String} activity The activity 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} /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). + * @apiBody {ObjectId} faculty The faculty alloted for the activity(ObjectId). + * @apiBody {String} type The type of activity.One of possible LECTURE, PRACTICAL, TUTORIAL. + * @apiBody {ObjectId} task The task of the activity (ObjectId).One of possible Topic,Practical,Tutorial. + * @apiBody {ObjectId} group The group of the activity (ObjectId). + * @apiBody {ObjectId} students the students who gonna attend the activity(ObjectId). + * + * @apiSuccess {String} res Timetable updated. + */ + +/** + * @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). + * @apiBody {ObjectId} faculty The faculty alloted for the activity(ObjectId). + * @apiBody {String} type The type of activity.One of possible LECTURE, PRACTICAL, TUTORIAL. + * @apiBody {ObjectId} task The task of the activity (ObjectId).One of possible Topic,Practical,Tutorial. + * @apiBody {ObjectId} group The group of the activity (ObjectId). + * @apiBody {ObjectId} students the students who gonna attend the activity(ObjectId). + * + * @apiSuccess {String} res Activity updated. + * @apiError (Error 500) DatabaseError Error in updating the database. + */ + +/** + * @api {get} /timetable/list Get Timetable List + * @apiName GetTimetableList + * @apiGroup Timetable + * + * @apiQuery {Date} startTime The startTime of the activity. + * @apiQuery {Number} duration The duration of the activity (in minutes). + * @apiQUERY {ObjectId} course The course of the activity (ObjectId). + * @apiQuery {ObjectId} faculty The faculty alloted for the activity(ObjectId). + * @apiQuery {String} type The type of activity.One of possible LECTURE, PRACTICAL, TUTORIAL. + * @apiQuery {ObjectId} task The task of the activity (ObjectId).One of possible Topic,Practical,Tutorial. + * @apiQuery {ObjectId} group The group of the activity (ObjectId). + * @apiQuery {ObjectId} students the students who gonna attend the activity(ObjectId). + * + * @apiSuccess {Date} startTime The startTime of the activity. + * @apiSuccess {Number} duration The duration of the activity (in minutes). + * @apiSuccess {ObjectId} course The course of the activity (ObjectId). + * @apiSuccess {ObjectId} faculty The faculty alloted for the activity(ObjectId). + * @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). + * @apiSuccess {ObjectId} students the students who gonna attend the activity(ObjectId). + */ + +/** + * @api {get} /activity/list Get Activity List + * @apiName GetActivityList + * @apiGroup Activity + * + * @apiQuery {Date} startTime The startTime of the activity. + * @apiQuery {Number} duration The duration of the activity (in minutes). + * @apiQUERY {ObjectId} course The course of the activity (ObjectId). + * @apiQuery {ObjectId} faculty The faculty alloted for the activity(ObjectId). + * @apiQuery {String} type The type of activity.One of possible LECTURE, PRACTICAL, TUTORIAL. + * @apiQuery {ObjectId} task The task of the activity (ObjectId).One of possible Topic,Practical,Tutorial. + * @apiQuery {ObjectId} group The group of the activity (ObjectId). + * @apiQuery {ObjectId} students the students who gonna attend the activity(ObjectId). + * + * @apiSuccess {Date} startTime The startTime of the activity. + * @apiSuccess {Number} duration The duration of the activity (in minutes). + * @apiSuccess {ObjectId} course The course of the activity (ObjectId). + * @apiSuccess {ObjectId} faculty The faculty alloted for the activity(ObjectId). + * @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). + * @apiSuccess {ObjectId} students the students who gonna attend the activity(ObjectId). + */ + +// ------------------------------------------------------------------------------------------ +// Student. +// ------------------------------------------------------------------------------------------ + +/** + * @api {post} /student/add Add student + * @apiName AddStudent + * @apiGroup Student + * @apiDescription Add a new Student. + * + * @apiBody {String} ERP ID of the student. + * @apiBody {String} name of the student. + * @apiBody {Number} joining year of the student. + * @apiBody {ObjectId} branch of the student (ObjectId). + * @apiBody {String} division of the student. + * @apiBody {Number} roll no of the student. + * @apiBody {ObjectId} coursesOpted by the student(ObjectId). + * + * @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 student" + * } + * + * @apiErrorExample Error-Response: + * HTTP/1.1 500 Internal Server Error + * { + * "err": "Error while inserting in DB" + * } + */ + +/** + * @api {delete} /student/delete/:studentId Delete Student + * @apiName DeleteStudent + * @apiGroup Student + * + * @apiParam {String} studentId The ID of the Student 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} /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. + * @apiBody {ObjectId} branch of the student (ObjectId). + * @apiBody {String} division of the student. + * @apiBody {Number} roll no of the student. + * @apiBody {ObjectId} coursesOpted by the student(ObjectId). + * + * @apiSuccess {String} res Student updated. + * @apiError (Error 500) DatabaseError Error in updating the database. + */ + +/** + * @api {get} /student/list Get Student List + * @apiName GetStudentList + * @apiGroup Student + * + * @apiQuery {String} ERP ID of the student. + * @apiQuery {String} name of the student. + * @apiQuery {Number} joining year of the student. + * @apiQuery {ObjectId} branch of the student (ObjectId). + * @apiQuery {String} division of the student. + * @apiQuery {Number} roll no of the student. + * @apiQuery {ObjectId} coursesOpted by the student(ObjectId). + * + * @apiSuccess {Student[]} res Array of filtered student documents. + * @apiSuccess {String} student._id ID of the student document given by the database. + * @apiSuccess {String} student.ERP ID of the student. + * @apiSuccess {String} student.name of the student. + * @apiSuccess {Number} student.joining year of the student. + * @apiSuccess {ObjectId} student.branch of the student (ObjectId). + * @apiSuccess {String} student.division of the student. + * @apiSuccess {Number} student.roll no of the student. + * @apiSuccess {ObjectId} student.coursesOpted by the student(ObjectId). + */ + +// ------------------------------------------------------------------------------------------ +// 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. + **/ diff --git a/app.js b/app.js index f542145e..55162b85 100644 --- a/app.js +++ b/app.js @@ -8,6 +8,7 @@ import { logger } from "#util"; import indexRouter from "#routes/index"; import usersRouter from "#routes/users"; import authRouter from "#routes/auth"; +import semesterRouter from "#routes/semester"; import accreditationRouter from "#routes/accreditation"; import infrastructureRouter from "#routes/infrastructure"; import practicalRouter from "#routes/practical"; @@ -17,10 +18,15 @@ import tutorialRouter from "#routes/tutorial"; import assignmentRouter from "#routes/assignment"; import timetableRouter from "#routes/timetable"; import courseworkRouter from "#routes/coursework"; +import activityRouter from "#routes/activity"; import moduleRouter from "#routes/module"; +import facultyRouter from "#routes/faculty"; import { identifyUser } from "#middleware/identifyUser"; import departmentRouter from "#routes/department"; import examRouter from "#routes/exam"; +import paperRouter from "#routes/paper"; +import groupRouter from "#routes/group"; +import performarouter from "#routes/performance"; const app = express(); const currDirName = dirname(fileURLToPath(import.meta.url)); @@ -47,6 +53,7 @@ app.use("/department", departmentRouter); app.use("/practical", practicalRouter); app.use("/organization", organizationRouter); app.use("/student", studentRouter); +app.use("/activity", activityRouter); app.use("/tutorial", tutorialRouter); app.use("/assignment", assignmentRouter); app.use("/timetable", timetableRouter); @@ -54,5 +61,10 @@ app.use("/department", departmentRouter); app.use("/coursework", courseworkRouter); app.use("/module", moduleRouter); app.use("/exam", examRouter); +app.use("/paper", paperRouter); +app.use("/group", groupRouter); +app.use("/semester", semesterRouter); +app.use("/faculty", facultyRouter); +app.use("/performance", performarouter); 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/activity.js b/controller/activity.js new file mode 100644 index 00000000..2e1ceb35 --- /dev/null +++ b/controller/activity.js @@ -0,0 +1,64 @@ +import { + 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 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 getActivity(req,res){ + const filter = req.query; + const activitylist =await activityList(filter); + res.json({res:activitylist}); +} + + +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"}); + } +} + +export default { + addActivity, deleteActivity ,getActivity ,updateActivity, +}; \ No newline at end of file diff --git a/controller/assignment.js b/controller/assignment.js index 80868ff2..221d4487 100644 --- a/controller/assignment.js +++ b/controller/assignment.js @@ -9,7 +9,7 @@ async function addAssignment(req, res) { } = req.body; try { const newAssignment = await createAssignment(no, title, type, marks); - res.json({ res: `added user ${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); @@ -24,7 +24,7 @@ async function updateAssignment(req, res) { } = req.body; try { await updateAssignmentById(id, data); - res.json({ res: `updated assignment with id ${id}` }); + res.json({ res: `updated assignment ${id}` }); } catch (error) { logger.error("Error while updating", error); res.status(500); diff --git a/controller/faculty.js b/controller/faculty.js new file mode 100644 index 00000000..47e17775 --- /dev/null +++ b/controller/faculty.js @@ -0,0 +1,84 @@ +import { + createFaculty, facultyList, deleteFacultyById, updateFacultyById, +} from "#services/faculty"; +import { logger } from "#util"; + +async function addFaculty(req, res) { + const { + ERPID, + dateOfJoining, + dateOfLeaving, + profileLink, + qualifications, + totalExperience, + achievements, + areaOfSpecialization, + papersPublishedPG, + papersPublishedUG, + department, + preferredSubjects, + designation, + natureOfAssociation, + additionalResponsibilities, + } = req.body; + try { + const newFaculty = await createFaculty( + ERPID, + dateOfJoining, + dateOfLeaving, + profileLink, + qualifications, + totalExperience, + achievements, + areaOfSpecialization, + papersPublishedPG, + papersPublishedUG, + department, + preferredSubjects, + designation, + natureOfAssociation, + additionalResponsibilities, + ); + res.json({ res: `added faculty ${newFaculty.ERPID}` }); + } catch (error) { + logger.error("Error while inserting", error); + res.status(500); + res.json({ err: "Error while inserting in DB" }); + } +} + +async function getFaculty(req, res) { + const filter = req.query; + const facultylist = await facultyList(filter); + res.json({ res: facultylist }); +} + +async function deleteFaculty(req, res) { + const { facultyId } = req.params; + try { + await deleteFacultyById(facultyId); + res.json({ res: "Faculty deleted successfully" }); + } catch (error) { + logger.error("Error while deleting", error); + res.status(500); + res.json({ err: "Error while deleting from DB" }); + } +} + +async function updateFaculty(req, res) { + const { + id, ...data + } = req.body; + try { + await updateFacultyById(id, data); + res.json({ res: `updated faculty with id ${id}` }); + } catch (error) { + logger.error("Error while updating", error); + res.status(500); + res.json({ err: "Error while updating in DB" }); + } +} + +export default { + addFaculty, getFaculty, deleteFaculty, updateFaculty, +}; diff --git a/controller/group.js b/controller/group.js new file mode 100644 index 00000000..a0284fc3 --- /dev/null +++ b/controller/group.js @@ -0,0 +1,54 @@ +import { + createGroup, deleteGroupById, groupList, updateGroupById, +} from "#services/group"; +import { logger } from "#util"; + +async function addGroup(req, res) { + const { + title, student, + } = req.body; + try { + const group = await createGroup(title, student); + res.json({ res: `added group ${group.id}`, id: group.id }); + } catch (error) { + logger.error("Error while inserting", error); + res.status(500); + res.json({ err: "Error while inserting in DB" }); + } +} + +async function updateGroup(req, res) { + const { id } = req.params; + const { + ...data + } = req.body; + try { + await updateGroupById(id, data); + res.json({ res: `updated group with id ${id}` }); + } catch (error) { + logger.error("Error while updating", error); + res.status(500); + res.json({ err: "Error while updaing in DB" }); + } +} + +async function getGroup(req, res) { + const filter = req.query; + const group = await groupList(filter); + res.json({ res: group }); +} + +async function deleteGroup(req, res) { + const { id } = req.params; + try { + await deleteGroupById(id); + res.json({ res: `Deleted group with ID ${id}` }); + } catch (error) { + logger.error("Error while deleting", error); + res.status(500).json({ error: "Error while deleting from DB" }); + } +} + +export default { + addGroup, deleteGroup, getGroup, updateGroup, +}; diff --git a/controller/module.js b/controller/module.js index 7ef54fbd..d455bf84 100644 --- a/controller/module.js +++ b/controller/module.js @@ -1,4 +1,4 @@ -import { getModule, addNewModule } from "#services/module"; +import { getModule, addNewModule, updateModuleById, deleteModuleById } from "#services/module"; import { logger } from "#util"; async function showModule(req, res) { @@ -33,6 +33,33 @@ async function addModule(req, res) { } } +async function updateModule(req, res) { + const { id } = req.params; + const { + ...data + } = req.body; + try { + await updateModuleById(id, data); + res.json({ res: `updated Module with id ${id}` }); + } catch (error) { + logger.error("Error while updating", error); + res.status(500); + res.json({ err: "Error while updaing in DB" }); + } +} + +async function deleteModule(req, res) { + const { id } = req.params; + try { + await deleteModuleById(id); + + res.json({ res: `Deleted Module with id ${id}` }); + } catch (error) { + logger.error("Error while deleting", error); + res.status(500).json({ error: "Error while deleting from DB" }); + } +} + export default { - showModule, addModule, + showModule, addModule, updateModule, deleteModule, }; diff --git a/controller/paper.js b/controller/paper.js new file mode 100644 index 00000000..6a6e6888 --- /dev/null +++ b/controller/paper.js @@ -0,0 +1,64 @@ +import { + createPaper, updatePaperById, listPaper, deletePaperById, +} from "#services/paper"; +import { logger } from "#util"; + +async function addPaper(req, res) { + const { + answerSheetID, + exam, + student, + checkedBy, + mark, + } = req.body; + try { + const newPaper = await createPaper( + answerSheetID, + exam, + student, + checkedBy, + mark, + ); + res.json({ res: `added paper for: ${newPaper.answerSheetID}`, id: newPaper.id }); + } catch (error) { + logger.error("Error while inserting", error); + res.status(500); + res.json({ err: "Error while inserting in DB" }); + } +} + +async function updatePaper(req, res) { + const { id } = req.params; + const { + ...data + } = req.body; + try { + await updatePaperById(id, data); + res.json({ res: "Paper updated" }); + } catch (error) { + logger.error("Error while updating", error); + res.status(500); + res.json({ err: "Error while updating in DB" }); + } +} + +async function showPaper(req, res) { + const filter = req.query; + const paper = await listPaper(filter); + res.json({ res: paper }); +} + +async function deletePaper(req, res) { + const { id } = req.params; + try { + await deletePaperById(id); + res.json({ res: `Deleted paper with ID ${id}` }); + } catch (error) { + logger.error("Error while deleting", error); + res.status(500).json({ error: "Error while deleting from DB" }); + } +} + +export default { + 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/semester.js b/controller/semester.js new file mode 100644 index 00000000..79be1fd3 --- /dev/null +++ b/controller/semester.js @@ -0,0 +1,54 @@ +import { + createSemester, updateSemesterById, semesterList, deleteSemesterById, +} from "#services/semester"; +import { logger } from "#util"; + +async function addSemester(req, res) { + const { + number, academicYear, type, startDate, endDate, + } = req.body; + + try { + 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); + res.status(500); + res.json({ err: "Error while inserting in DB" }); + } +} + +async function updateSemester(req, res) { + const { id } = req.params; + const { + ...data + } = req.body; + try { + await updateSemesterById(id, data); + res.json({ res: `Updated Semester with id ${id}` }); + } catch (error) { + logger.error("Error while updating", error); + res.status(500); + res.json({ err: "Error while updating in DB" }); + } +} + +async function getSemester(req, res) { + const filter = req.query; + const semlist = await semesterList(filter); + res.json({ res: semlist }); +} + +async function deleteSemester(req, res) { + const { id } = req.params; + try { + await deleteSemesterById(id); + res.json({ res: `Deleted Semster with id ${id}` }); + } catch (error) { + logger.error("Error while deleting", error); + res.status(500).json({ error: "Error while deleting from DB" }); + } +} +export default { + addSemester, deleteSemester, getSemester, updateSemester, +}; diff --git a/hooks/pre-commit b/hooks/pre-commit index f782d0ea..d3dc8072 100644 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -9,6 +9,9 @@ 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 @@ -20,4 +23,4 @@ done if [ $flag -eq 1 ]; then exit 1 -fi \ No newline at end of file +fi diff --git a/jest.config.js b/jest.config.js index a6f409cf..a52c300e 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,6 +1,11 @@ const config = { transform: { }, + testTimeout: 15000, + setupFiles: [ + "./test/config/setup.js", + "./test/config/teardown.js", + ], }; export default config; diff --git a/models/activity.js b/models/activity.js index 4ea27423..f55c464a 100644 --- a/models/activity.js +++ b/models/activity.js @@ -22,37 +22,41 @@ const activitySchema = { const Activity = connector.model("Activity", activitySchema); -// crud +/// crud operation/// -async function create(activityData) { +// add a activity to the database +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; } -async function read(filter, limit = 1) { - const activityDoc = await Activity.find(filter).limit(limit); - 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 update(filter, updateObject, options = { multi: true }) { - const updateResult = await Activity.updateMany(filter, { $set: updateObject }, options); - return updateResult.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; } -async function remove(filter) { - const deleteResult = await Activity.deleteMany(filter); - return deleteResult.acknowledged; +// Delete activity based on a given filter +async function remove(filter){ + const deleteActivity= await Activity.deleteMany(filter).exec(); + return deleteActivity.acknowledged; } -export default { - create, - read, - update, - remove, +// export crud functions + +export default{ + create,read,update,remove, }; + diff --git a/models/employee/empBank.js b/models/employee/empBank.js new file mode 100644 index 00000000..2bb9140a --- /dev/null +++ b/models/employee/empBank.js @@ -0,0 +1,95 @@ +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 = 1) { + const empBankDoc = employeeBankSchema.find(filter).limit(limit); + return empBankDoc; +} + +async function update(filter, updateObject, options = { multi: true }) { + const updateResult = await employeeBankSchema.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateResult.acknowledged; +} + +async function remove(empBankId) { + const deleteResult = await employeeBankSchema.deleteMany(empBankId); + return deleteResult.acknowledged; +} + +export default { + create, + read, + update, + remove, +}; \ No newline at end of file diff --git a/models/employee/emp_cur_detail.js b/models/employee/empCurrentDetail.js similarity index 100% rename from models/employee/emp_cur_detail.js rename to models/employee/empCurrentDetail.js diff --git a/models/employee/empEduHistory.js b/models/employee/empEduHistory.js new file mode 100644 index 00000000..3812f145 --- /dev/null +++ b/models/employee/empEduHistory.js @@ -0,0 +1,121 @@ +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=1) { + const empEduHistoryDoc = employeeEducationHistorySchema.find(filter).limit(limit); + return empEduHistoryDoc; +} + + +async function update(filter, updateObject, options={ multi: true }) { + const updateResult = await employeeEducationHistorySchema.updateMany( + filter, + {$set: updateObject}, + options, + ); + return updateResult.acknowledged; +} + +async function remove(filter) { + const deleteResult= await employeeEducationHistorySchema.deleteMany(filter).exec(); + return deleteResult.acknowledged; +} + +export default{ + create, read, update, remove, +}; \ No newline at end of file diff --git a/models/employee/emp_personal.js b/models/employee/empPersonal.js similarity index 74% rename from models/employee/emp_personal.js rename to models/employee/empPersonal.js index 6f23d9fe..180db495 100644 --- a/models/employee/emp_personal.js +++ b/models/employee/empPersonal.js @@ -55,11 +55,45 @@ 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 = 1) { + const employeePersonalDoc = await EmployeePersonal.find(filter).limit(limit); + return 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_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/faculty.js b/models/faculty.js index 97632131..74bae6e6 100644 --- a/models/faculty.js +++ b/models/faculty.js @@ -18,15 +18,6 @@ const facultySchema = { additionalResponsibilities: { type: String, required: true }, }; -facultySchema.virtual("tcetexperience").get(() => { - const currentDate = new Date(); - const joiningYear = this.dateOfJoining.getFullYear(); - const leavingYear = this.dateOfLeaving - ? this.dateOfLeaving.getFullYear - : currentDate.getFullYear; - return leavingYear - joiningYear; -}); - const Faculty = connector.model("Faculty", facultySchema); // CRUD Operations diff --git a/models/group.js b/models/group.js index 2f9f9f42..57cfed1a 100644 --- a/models/group.js +++ b/models/group.js @@ -19,7 +19,7 @@ async function read(filter, limit = 1) { } async function update(filter, updateObject, options = { multi: true }) { - const updateResult = await Group.updateManyupdateMany(filter, { $set: updateObject }, options); + const updateResult = await Group.updateMany(filter, { $set: updateObject }, options); return updateResult.acknowledged; } async function remove(groupId) { diff --git a/models/paper.js b/models/paper.js index 5076960c..1bb2d467 100644 --- a/models/paper.js +++ b/models/paper.js @@ -8,7 +8,6 @@ const paperSchema = { mark: { type: Number, required: true }, }; -// eslint-disable-next-line no-unused-vars const Paper = connector.model("Paper", paperSchema); // CRUD OPERATIONS diff --git a/models/semester.js b/models/semester.js index d4eee14b..fb43dd72 100644 --- a/models/semester.js +++ b/models/semester.js @@ -10,7 +10,7 @@ const semesterSchema = { message: (props) => `${props.value} is not a valid year format starting with "2"!`, }, }, - type: { enum: ["ODD", "EVEN"], required: true }, + type: { type: String, enum: ["ODD", "EVEN"], required: true }, startDate: { type: Date, required: true }, endDate: { type: Date, required: true }, diff --git a/models/student/stdBank.js b/models/student/stdBank.js new file mode 100644 index 00000000..f4b5fa07 --- /dev/null +++ b/models/student/stdBank.js @@ -0,0 +1,86 @@ +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 = 1) { + const stdBankDoc = studentBankSchema.find(filter).limit(limit); + return stdBankDoc; +} + +async function update(filter, updateObject, options = { multi: true }) { + const updateResult = await studentBankSchema.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateResult.acknowledged; +} + +async function remove(stdBankId) { + const deleteResult = await studentBankSchema.deleteMany(stdBankId); + return deleteResult.acknowledged; +} + +export default { + create, + read, + update, + remove, +}; \ No newline at end of file diff --git a/models/student/stdCollege.js b/models/student/stdCollege.js new file mode 100644 index 00000000..64f9f918 --- /dev/null +++ b/models/student/stdCollege.js @@ -0,0 +1,124 @@ +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 = 1) { + const stdCollegeDoc = studentCollegeSchema.find(filter).limit(limit); + return stdCollegeDoc; +} + +async function update(filter, updateObject, options = { multi: true }) { + const updateResult = await studentCollegeSchema.updateMany( + filter, + { $set: updateObject }, + options, + ); + return updateResult.acknowledged; +} + +async function remove(stdCollegeId) { + const deleteResult = await studentCollegeSchema.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..821bc24a --- /dev/null +++ b/models/student/stdEduHistory.js @@ -0,0 +1,197 @@ +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 = 1) { + const stdEducationDoc = studentEducationSchema.find(filter).limit(limit); + return 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..3a039069 --- /dev/null +++ b/models/student/stdMedHistory.js @@ -0,0 +1,67 @@ +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 = 1) { + const medicalHistoryDoc = await MedicalHistory.find(filter).limit(limit); + return 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..0c6e8613 --- /dev/null +++ b/models/student/stdPersonal.js @@ -0,0 +1,280 @@ +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 = 1) { + const studentDoc = await StdPersonal.find(filter).limit(limit); + return 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/package-lock.json b/package-lock.json index faec7202..89d50b51 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", @@ -27,10 +28,13 @@ "devDependencies": { "eslint": "^8.38.0", "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^9.0.0", "eslint-import-resolver-alias": "^1.1.2", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", - "nodemon": "^3.0.1" + "nodemon": "^3.0.1", + "prettier": "^3.0.3" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -2360,6 +2364,26 @@ "node": ">= 8" } }, + "node_modules/@pkgr/utils": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", + "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "fast-glob": "^3.3.0", + "is-glob": "^4.0.3", + "open": "^9.1.0", + "picocolors": "^1.0.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -3732,6 +3756,15 @@ "node": ">= 10.0.0" } }, + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -3796,6 +3829,18 @@ "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==", "optional": true }, + "node_modules/bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", + "dev": true, + "dependencies": { + "big-integer": "^1.6.44" + }, + "engines": { + "node": ">= 5.10.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3900,6 +3945,21 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "node_modules/bundle-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", + "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", + "dev": true, + "dependencies": { + "run-applescript": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -4326,6 +4386,162 @@ "node": ">=0.10.0" } }, + "node_modules/default-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", + "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", + "dev": true, + "dependencies": { + "bundle-name": "^3.0.0", + "default-browser-id": "^3.0.0", + "execa": "^7.1.1", + "titleize": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", + "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", + "dev": true, + "dependencies": { + "bplist-parser": "^0.2.0", + "untildify": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser/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/default-browser/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/default-browser/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/default-browser/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/default-browser/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/default-browser/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/default-browser/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/default-browser/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/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-properties": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", @@ -4791,6 +5007,18 @@ "semver": "bin/semver.js" } }, + "node_modules/eslint-config-prettier": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", + "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, "node_modules/eslint-import-resolver-alias": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/eslint-import-resolver-alias/-/eslint-import-resolver-alias-1.1.2.tgz", @@ -4929,6 +5157,35 @@ "semver": "bin/semver.js" } }, + "node_modules/eslint-plugin-prettier": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz", + "integrity": "sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.5" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -5196,6 +5453,40 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -6078,6 +6369,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -6114,6 +6420,24 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -6265,6 +6589,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-wsl/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", @@ -7295,6 +7646,15 @@ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -7584,6 +7944,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", @@ -7906,6 +8277,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/open": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", + "dev": true, + "dependencies": { + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -8126,6 +8515,33 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/pretty-format": { "version": "29.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", @@ -8433,6 +8849,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -9044,6 +9475,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/synckit": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", + "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", + "dev": true, + "dependencies": { + "@pkgr/utils": "^2.3.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -9189,6 +9636,18 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/titleize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", + "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -9304,7 +9763,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "optional": true + "devOptional": true }, "node_modules/type-check": { "version": "0.4.0", @@ -9469,6 +9928,15 @@ "node": ">= 0.8" } }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", @@ -9523,7 +9991,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" } diff --git a/package.json b/package.json index b0e008eb..0c6a050d 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,9 @@ "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" }, "dependencies": { "apidoc": "^1.1.0", @@ -39,6 +41,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", @@ -47,9 +50,12 @@ "devDependencies": { "eslint": "^8.38.0", "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^9.0.0", "eslint-import-resolver-alias": "^1.1.2", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", - "nodemon": "^3.0.1" + "nodemon": "^3.0.1", + "prettier": "^3.0.3" } } diff --git a/routes/activity.js b/routes/activity.js new file mode 100644 index 00000000..f5c40a24 --- /dev/null +++ b/routes/activity.js @@ -0,0 +1,10 @@ +import express from "express"; +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); + +export default router; \ No newline at end of file diff --git a/routes/faculty.js b/routes/faculty.js new file mode 100644 index 00000000..aacc1669 --- /dev/null +++ b/routes/faculty.js @@ -0,0 +1,10 @@ +import express from "express"; +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); + +export default router; diff --git a/routes/group.js b/routes/group.js new file mode 100644 index 00000000..e9f20a51 --- /dev/null +++ b/routes/group.js @@ -0,0 +1,10 @@ +import express from "express"; +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); + +export default router; diff --git a/routes/module.js b/routes/module.js index 006e3309..fb373668 100644 --- a/routes/module.js +++ b/routes/module.js @@ -5,5 +5,7 @@ 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); export default router; diff --git a/routes/paper.js b/routes/paper.js new file mode 100644 index 00000000..f754ea35 --- /dev/null +++ b/routes/paper.js @@ -0,0 +1,11 @@ +import express from "express"; +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); + +export default router; diff --git a/routes/performance.js b/routes/performance.js new file mode 100644 index 00000000..66acd231 --- /dev/null +++ b/routes/performance.js @@ -0,0 +1,8 @@ +import express from "express"; +import performacontroller from "#controller/performance"; + +const router = express.Router(); + +router.get("/test", performacontroller); + +export default router; \ No newline at end of file diff --git a/routes/semester.js b/routes/semester.js new file mode 100644 index 00000000..5d23936a --- /dev/null +++ b/routes/semester.js @@ -0,0 +1,10 @@ +import express from "express"; +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); + +export default router; diff --git a/services/activity.js b/services/activity.js new file mode 100644 index 00000000..0c3a3a18 --- /dev/null +++ b/services/activity.js @@ -0,0 +1,33 @@ +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 updateActivityById(id,data){ +const updated= await Activity.update({_id:id},data); +if (updated){ + return updated; +} +throw new databaseError.DataEntryError("activity"); +} + +export async function activityList(filter){ + const activitylist = await Activity.read(filter,0); + 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 diff --git a/services/employee/empBank.js b/services/employee/empBank.js new file mode 100644 index 00000000..67f09b3a --- /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) { + const employeeBank = await EmployeeBank.read(filter, 0); + return employeeBank; +} + +export async function deleteEmployeeBankById(employeeBankId) { + const deleted = await EmployeeBank.remove({ _id: employeeBankId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("employee bank"); +} \ No newline at end of file diff --git a/services/employee/empEduHistory.js b/services/employee/empEduHistory.js new file mode 100644 index 00000000..5273ca9a --- /dev/null +++ b/services/employee/empEduHistory.js @@ -0,0 +1,83 @@ +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) { + const empEduHistory = await EmployeeEducationHistory.read(filter,0); + 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"); + } \ No newline at end of file diff --git a/services/employee/empPersonal.js b/services/employee/empPersonal.js new file mode 100644 index 00000000..af0f003d --- /dev/null +++ b/services/employee/empPersonal.js @@ -0,0 +1,92 @@ +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) { + const employeePersonal = await EmployeePersonal.read(filter); + 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"); +} \ No newline at end of file diff --git a/services/faculty.js b/services/faculty.js new file mode 100644 index 00000000..881346a8 --- /dev/null +++ b/services/faculty.js @@ -0,0 +1,70 @@ +import Faculty from "#models/faculty"; +import databaseError from "#error/database"; + +export async function createFaculty( + ERPID, + dateOfJoining, + dateOfLeaving, + profileLink, + qualifications, + totalExperience, + achievements, + areaOfSpecialization, + papersPublishedPG, + papersPublishedUG, + department, + preferredSubjects, + designation, + natureOfAssociation, + additionalResponsibilities, +) { + const newFaculty = await Faculty.create({ + ERPID, + dateOfJoining, + dateOfLeaving, + profileLink, + qualifications, + totalExperience, + achievements, + areaOfSpecialization, + papersPublishedPG, + papersPublishedUG, + department, + preferredSubjects, + designation, + natureOfAssociation, + additionalResponsibilities, + }); + if (newFaculty.ERPID === ERPID) { + return newFaculty; + } + throw new databaseError.DataEntryError("Faculty"); +} + +export async function facultyList(filter) { + const facList = await Faculty.read(filter); + if (facList) { + return facList; + } + throw new databaseError.DataNotFoundError("Faculty"); +} + +export async function deleteFacultyById(facultyId) { + const deleted = await Faculty.remove({ _id: facultyId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("Faculty"); +} + +export async function updateFacultyById(id, data) { + const updated = await Faculty.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("Faculty"); +} + +export default { + createFaculty, facultyList, deleteFacultyById, updateFacultyById, +}; diff --git a/services/group.js b/services/group.js new file mode 100644 index 00000000..d02ff62e --- /dev/null +++ b/services/group.js @@ -0,0 +1,33 @@ +import Group from "#models/group"; +import databaseError from "#error/database"; + +export async function createGroup(title, student) { + const newGroup = await Group.create({ + title, student, + }); + if (newGroup.title === title) { + return newGroup; + } + throw new databaseError.DataEntryError("group"); +} + +export async function updateGroupById(id, data) { + const updated = await Group.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("group"); +} + +export async function groupList(filter) { + const groups = await Group.read(filter, 0); + return groups; +} + +export async function deleteGroupById(groupId) { + const deleted = await Group.remove({ _id: groupId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("group"); +} diff --git a/services/module.js b/services/module.js index 9cbe6765..b51874b7 100644 --- a/services/module.js +++ b/services/module.js @@ -18,3 +18,19 @@ 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); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("Module"); +} + +export async function deleteModuleById(ModuleId) { + const deleted = await Module.remove({ _id: ModuleId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("Module"); +} \ No newline at end of file diff --git a/services/paper.js b/services/paper.js new file mode 100644 index 00000000..64301a18 --- /dev/null +++ b/services/paper.js @@ -0,0 +1,43 @@ +import Paper from "#models/paper"; +import databaseError from "#error/database"; + +export async function createPaper( + answerSheetID, + exam, + student, + checkedBy, + mark, +) { + const newPaper = await Paper.create({ + answerSheetID, + exam, + student, + checkedBy, + mark, + }); + if (newPaper) { + return newPaper; + } + throw new databaseError.DataEntryError("paper"); +} + +export async function updatePaperById(id, data) { + const updated = await Paper.update({ _id: id }, data); + if (updated) { + return updated; + } + throw new databaseError.DataEntryError("paper"); +} + +export async function listPaper(filter) { + const paper = await Paper.read(filter, 0); + return paper; +} + +export async function deletePaperById(paperId) { + const deleted = await Paper.remove({ _id: paperId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("paper"); +} diff --git a/services/semester.js b/services/semester.js new file mode 100644 index 00000000..6cc7c1c7 --- /dev/null +++ b/services/semester.js @@ -0,0 +1,34 @@ +import Semester from "#models/semester"; +import databaseError from "#error/database"; + +export async function createSemester(number, academicYear, type, startDate, endDate) { + const newSemester = await Semester.create({ + number, academicYear, type, startDate, endDate, + }); + if (newSemester.number === number) { + return newSemester; + } + throw new databaseError.DataDeleteError("semster"); +} + +export async function updateSemesterById(id, data) { + const update = await Semester.update({ _id: id }, data); + + if (update) { + return update; + } + throw new databaseError.DataEntryError("semester"); +} + +export async function semesterList(filter) { + const semlist = await Semester.read(filter, 0); + return semlist; +} + +export async function deleteSemesterById(semesterId) { + const deleted = await Semester.remove({ _id: semesterId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("semester"); +} diff --git a/services/student/stdBank.js b/services/student/stdBank.js new file mode 100644 index 00000000..9a7e24f1 --- /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) { + const studentBank = await StudentBank.read(filter, 0); + return studentBank; +} + +export async function deleteStudentBankById(studentBankId) { + const deleted = await StudentBank.remove({ _id: studentBankId }); + if (deleted) { + return deleted; + } + throw new databaseError.DataDeleteError("student bank"); +} \ No newline at end of file diff --git a/services/student/stdCollege.js b/services/student/stdCollege.js new file mode 100644 index 00000000..b4ab0024 --- /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) { + const studentColleges = await StudentCollege.read(filter, 0); + 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..16259df2 --- /dev/null +++ b/services/student/stdEduHistory.js @@ -0,0 +1,88 @@ +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) { + const studentEducationDetails = await StudentEducation.read(filter, 0); + 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..4e19497d --- /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) { + const medHistoryList = await MedicalHistory.read(filter, 0); + 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..20df3ba1 --- /dev/null +++ b/services/student/stdPersonal.js @@ -0,0 +1,187 @@ +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){ + const studentlist = await Student.read(filter,0); + return studentlist; +} + +export async function deleteStudentById(id){ + const deleted = await Student.remove({_id:id}); + if(deleted){ + return deleted; + } + throw new databaseError.DataDeleteError("activity"); +} \ No newline at end of file diff --git a/test/config/setup.js b/test/config/setup.js new file mode 100644 index 00000000..e5b1d8dd --- /dev/null +++ b/test/config/setup.js @@ -0,0 +1,14 @@ +import request from "supertest"; +import app from "#app"; // Update this import based on your app"s structure +import connector from "#models/databaseUtil"; // Update this import + +const server = app.listen(null, () => { + connector.set("debug", false); +}); +const agent = request.agent(server); +global.server = server; +global.agent = agent; +export default async () => { + global.server = server; + global.agent = agent; +}; \ No newline at end of file diff --git a/test/config/teardown.js b/test/config/teardown.js new file mode 100644 index 00000000..49aa0f64 --- /dev/null +++ b/test/config/teardown.js @@ -0,0 +1,4 @@ +global.server.close(); +global.agent.app.close(); +export default async () => { +}; \ No newline at end of file diff --git a/test/routes/accreditation.test.js b/test/routes/accreditation.test.js index e26b1def..64933cb3 100644 --- a/test/routes/accreditation.test.js +++ b/test/routes/accreditation.test.js @@ -1,30 +1,17 @@ -import request from "supertest"; import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies -import app from "#app"; import accreditationModel from "#models/accreditation"; import connector from "#models/databaseUtil"; jest.mock("#util"); -let server; -let agent; -beforeAll((done) => { - server = app.listen(null, () => { - agent = request.agent(server); - connector.set("debug", false); - done(); - }); -}); +const { agent } = global; function cleanUp(callback) { accreditationModel.remove({ name: "xyz" }).then(() => { connector.disconnect((DBerr) => { if (DBerr) console.log("Database dissconnnect error: ", DBerr); - server.close((serverErr) => { - if (serverErr) console.log(serverErr); - callback(); - }); }); + callback(); }); } diff --git a/test/routes/activity.test.js b/test/routes/activity.test.js new file mode 100644 index 00000000..eac71790 --- /dev/null +++ b/test/routes/activity.test.js @@ -0,0 +1,94 @@ +import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies +import connector from "#models/databaseUtil"; // Update this import +import activityModel from "#models/activity"; // Update this import + +jest.mock("#util"); +const { agent } = global; + +function cleanUp(callback) { + activityModel + .remove({ + course: "5f8778b54b553439ac49a03a" + }) + .then(() => { + connector.disconnect((DBerr) => { + if (DBerr) console.log("Database disconnect error : ", DBerr); + callback(); + }); + }); +} + + +afterAll((done) => { + cleanUp(done); +}); + +describe("Activity API", () => { + it("should create activity", async () => { + const response = await agent.post("/activity/add").send({ + activityBlueprint: "5f8778b54b553439ac49a03a", + startTime: "2023-06-18T14:11:30Z", + duration: 2, + course: "5f8778b54b553439ac49a03a", + faculty: "5f8778b54b553439ac49a03a", + type: "LECTURE", + task: ["5f8778b54b553439ac49a03a"], + group: "5f8778b54b553439ac49a03a", + students: ["5f8778b54b553439ac49a03a"] + }); + + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/added activity/); + }); + + describe("after adding activity", () => { + let id; + beforeEach(async () => { + id = await agent.post("/activity/add").send({ + activityBlueprint: "64fc3c8bde9fa947ea1f412f", + startTime: "2023-06-18T14:11:30Z", + duration: 2, + course: "5f8778b54b553439ac49a03a", + faculty: "64fc3c8bde9fa947ea1f412f", + type: "LECTURE", + task: ["64fc3c8bde9fa947ea1f412f"], + group: "64fc3c8bde9fa947ea1f412f", + students: ["64fc3c8bde9fa947ea1f412f"] + }); + id = JSON.parse(id.res.text).id; + }); + + afterEach(async () => { + await activityModel.remove({ + activityBlueprint: "64fc3c8bde9fa947ea1f412f", + startTime: "2023-06-18T14:11:30Z", + duration: 2, + course: "5f8778b54b553439ac49a03a", + faculty: "64fc3c8bde9fa947ea1f412f", + type: "LECTURE", + task: ["64fc3c8bde9fa947ea1f412f"], + group: "64fc3c8bde9fa947ea1f412f", + students: ["64fc3c8bde9fa947ea1f412f"] + }); + }); + + it("should read activity", async () => { + const response = await agent + .get("/activity/list") + .send({ startTime: "2023-06-18T14:11:30Z" }); + expect(response.status).toBe(200); + expect(response.body.res).toBeDefined(); + }); + + it("should update activity", async () => { + const response = await agent + .post(`/activity/update/${id}`) + .send({ + duration: 5, + }); + + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/updated activity/); + }); + }); +}); diff --git a/test/routes/assignment.test.js b/test/routes/assignment.test.js new file mode 100644 index 00000000..9c8560c5 --- /dev/null +++ b/test/routes/assignment.test.js @@ -0,0 +1,64 @@ +import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies +import assignmentModel from "#models/assignment"; +import connector from "#models/databaseUtil"; + +jest.mock("#util"); +const { agent } = global; + +function cleanUp(callback) { + assignmentModel.remove({ no: "123" }).then(() => { + connector.disconnect((DBerr) => { + if (DBerr) console.log("Database dissconnnect error: ", DBerr); + callback(); + }); + }); +} + +afterAll((done) => { + cleanUp(done); +}); + +describe("checking assignment functions", () => { + it("create assignment", async () => { + const response = await agent.post("/assignment/add").send({ + no: 123, + title: "xyz", + type: "FA", + marks: 100, + }); + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/added assignment/); + }); + let id; + beforeEach(async () => { + id = await agent.post("/assignment/add").send({ + no: "123", + title: "xyz", + type: "FA", + marks: 100, + }); + id = JSON.parse(id.res.text).id; + }); + + afterEach(async () => { + await assignmentModel.remove({ no: "123" }); + }); + + it("read assignment", async () => { + const response = await agent + .get("/assignment/list") + .send({ no: "123" }); + expect(response.status).toBe(200); + expect(response.body.res).toBeDefined(); + }); + + it("update assignment", async () => { + const response = await agent + .post(`/assignment/update/${id}`) + .send({ no: "123" }, { no: "345" }); + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/updated assignment/); + }); +}); diff --git a/test/routes/auth.test.js b/test/routes/auth.test.js index fe28f6eb..862876a5 100644 --- a/test/routes/auth.test.js +++ b/test/routes/auth.test.js @@ -1,30 +1,18 @@ -import request from "supertest"; import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies import util from "#util"; -import app from "#app"; import userModel from "#models/user"; +import otpModel from "#models/otpStore"; import connector from "#models/databaseUtil"; jest.mock("#util"); - -let server; -let agent; -beforeAll((done) => { - server = app.listen(null, () => { - agent = request.agent(server); - connector.set("debug", false); - done(); - }); -}); +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); - server.close((serverErr) => { - if (serverErr) console.log(serverErr); - callback(); - }); + callback(); }); }); } diff --git a/test/routes/coursework.test.js b/test/routes/coursework.test.js index 892f55d7..2d91d1ff 100644 --- a/test/routes/coursework.test.js +++ b/test/routes/coursework.test.js @@ -1,21 +1,9 @@ import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies -import request from "supertest"; -import app from "#app"; // Update this import based on your app"s structure import connector from "#models/databaseUtil"; // Update this import import courseworkModel from "#models/coursework"; // Update this import jest.mock("#util"); - -let server; -let agent; - -beforeAll((done) => { - server = app.listen(null, () => { - agent = request.agent(server); - connector.set("debug", false); - done(); - }); -}); +const { agent } = global; function cleanUp(callback) { courseworkModel @@ -31,11 +19,8 @@ function cleanUp(callback) { .then(() => { connector.disconnect((DBerr) => { if (DBerr) console.log("Database disconnect error: ", DBerr); - server.close((serverErr) => { - if (serverErr) console.log(serverErr); - callback(); - }); }); + callback(); }); } diff --git a/test/routes/department.test.js b/test/routes/department.test.js index 1da3eb4a..77235d64 100644 --- a/test/routes/department.test.js +++ b/test/routes/department.test.js @@ -1,30 +1,17 @@ -import request from "supertest"; import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies import mongoose from "mongoose"; -import app from "#app"; import departmentmodel from "#models/department"; import connector from "#models/databaseUtil"; jest.mock("#util"); - -let server; - -let agent; - -beforeAll((done) => { - server = app.listen(null, () => { - agent = request.agent(server); - connector.set("debug", false); - done(); - }); -}); +const { agent } = global; // test case for deletion function cleanUp(callback) { departmentmodel.remove( { - name: "Computer", + name: "Electronics", acronym: "COMPS", yearOfStarting: "2020-09-01T00:00:00.000Z", accreditations: [mongoose.Types.ObjectId("5f8778b54b553439ac49a03a")], @@ -34,10 +21,7 @@ function cleanUp(callback) { .then(() => { connector.disconnect((DBerr) => { if (DBerr) console.log("Database disconnect error: ", DBerr); - server.close((serverErr) => { - if (serverErr) console.log(serverErr); - callback(); - }); + callback(); }); }); } 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 new file mode 100644 index 00000000..e36d6a0d --- /dev/null +++ b/test/routes/group.test.js @@ -0,0 +1,69 @@ +import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies +import connector from "#models/databaseUtil"; +import groupModel from "#models/group"; + +jest.mock("#util"); +const { agent } = global; + +function cleanUp(callback) { + groupModel + .remove({ + title: "Group 1", + }) + .then(() => { + connector.disconnect((DBerr) => { + if (DBerr) console.log("Database disconnect error: ", DBerr); + callback(); + }); + }); +} + +afterAll((done) => { + cleanUp(done); +}); + +describe("group API", () => { + it("should create group", async () => { + const response = await agent.post("/group/add").send({ + title: "Group 1", + student: "64fdc67feca8a69f01b33614", + }); + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/added group/); + }); + + describe("after adding group", () => { + let id; + beforeEach(async () => { + id = await agent.post("/group/add").send({ + title: "Group 1", + student: "64fdc67feca8a69f01b33614", + }); + id = JSON.parse(id.res.text).id; + }); + + afterEach(async () => { + await groupModel.remove({ + id: "6500594e2b7b532006c073dd", + }); + }); + + it("should read group", async () => { + const response = await agent + .get("/group/list") + .send({ name: "Building A" }); + expect(response.status).toBe(200); + expect(response.body.res).toBeDefined(); + }); + + it("should update group", async () => { + const response = await agent + .post(`/group/update/${id}`) + .send({ title: "Group 1" }, { title: "Group 2" }); + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/updated group/); + }); + }); +}); diff --git a/test/routes/infrastructure.test.js b/test/routes/infrastructure.test.js index 71b74225..64f326d3 100644 --- a/test/routes/infrastructure.test.js +++ b/test/routes/infrastructure.test.js @@ -1,21 +1,9 @@ import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies -import request from "supertest"; -import app from "#app"; // Update this import based on your app"s structure import connector from "#models/databaseUtil"; // Update this import import infrastructureModel from "#models/infrastructure"; // Update this import jest.mock("#util"); - -let server; -let agent; - -beforeAll((done) => { - server = app.listen(null, () => { - agent = request.agent(server); - connector.set("debug", false); - done(); - }); -}); +const { agent } = global; function cleanUp(callback) { infrastructureModel @@ -29,10 +17,7 @@ function cleanUp(callback) { .then(() => { connector.disconnect((DBerr) => { if (DBerr) console.log("Database disconnect error: ", DBerr); - server.close((serverErr) => { - if (serverErr) console.log(serverErr); - callback(); - }); + callback(); }); }); } diff --git a/test/routes/module.test.js b/test/routes/module.test.js index 1ae640f3..886142f6 100644 --- a/test/routes/module.test.js +++ b/test/routes/module.test.js @@ -1,21 +1,9 @@ -import request from "supertest"; import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies -import app from "#app"; import moduleModel from "#models/module"; import connector from "#models/databaseUtil"; jest.mock("#util"); - -let server; -let agent; - -beforeAll((done) => { - server = app.listen(null, () => { - agent = request.agent(server); - connector.set("debug", false); - done(); - }); -}); +const { agent } = global; function cleanUp(callback) { moduleModel.remove({ startDate: "2023-06-18T14:11:30Z" }).then(() => { @@ -23,10 +11,7 @@ function cleanUp(callback) { if (DBerr) { console.log("Database disconnnect error: ", DBerr); } - server.close((serverErr) => { - if (serverErr) console.log(serverErr); - callback(); - }); + callback(); }); }); } @@ -52,7 +37,7 @@ describe("checking module functions", () => { }); beforeEach(async () => { - agent.post("/module/add").send({ + await agent.post("/module/add").send({ no: 1, name: "Module 1", outcome: "I am good at debugging", diff --git a/test/routes/organization.test.js b/test/routes/organization.test.js new file mode 100644 index 00000000..e6f39230 --- /dev/null +++ b/test/routes/organization.test.js @@ -0,0 +1,74 @@ +import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies +import organizationModel from "#models/organization"; +import connector from "#models/databaseUtil"; + +jest.mock("#util"); +const { agent } = global; + +function cleanUp(callback) { + organizationModel.remove({ startDate: "2023-06-18T14:11:30Z" }).then(() => { + connector.disconnect((DBerr) => { + if (DBerr) { + console.log("Database disconnnect error: ", DBerr); + } + callback(); + }); + }); +} + +afterAll((done) => { + cleanUp(done); +}); + +describe("Organization API", () => { + it("should create organization", async () => { + const response = await agent.post("/organization/add").send({ + parent: "60a0e7e9a09c3f001c834e06", + startDate:"2023-06-18T14:11:30Z", + name:"my org", + accreditations: "60a0e7e9a09c3f001c834e06", + }); + + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/added organization/); + }); + + describe("after adding organization", () => { + let id; + beforeEach(async () => { + id = await agent.post("/organization/add").send({ + parent: "60a0e7e9a09c3f001c834e06", + startDate:"2023-06-18T14:11:30Z", + name:"my org", + accreditations: "60a0e7e9a09c3f001c834e06", + }); + id = JSON.parse(id.res.text).id; + }); + + afterEach(async () => { + await organizationModel.remove({ + parent: "60a0e7e9a09c3f001c834e06", + startDate:"2023-06-18T14:11:30Z", + name:"my org", + accreditations: "60a0e7e9a09c3f001c834e06", + }); + }); + + it("should read organization", async () => { + const response = await agent + .get("/organization/list") + .send({ name:"my org" }); + expect(response.status).toBe(200); + expect(response.body.res).toBeDefined(); + }); + + it("should update organization", async () => { + const response = await agent + .post(`/organization/update/${id}`) + .send({ name: "your org" }); + + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/organization updated/); + }); + }); + }); \ No newline at end of file diff --git a/test/routes/paper.test.js b/test/routes/paper.test.js new file mode 100644 index 00000000..7b755c9c --- /dev/null +++ b/test/routes/paper.test.js @@ -0,0 +1,102 @@ +import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies +import paperModel from "#models/paper"; +import connector from "#models/databaseUtil"; + +jest.mock("#util"); +const { agent } = global; + +function cleanUp(callback) { + paperModel.remove( + { + answerSheetID: "asd123", + exam: "64fc3c8bde9fa947ea1f412f", + student: "64fc3c8bde9fa947ea1f412f", + checkedBy: "64fc3c8bde9fa947ea1f412f", + mark: 100, + }, + ) + .then(() => { + connector.disconnect((DBerr) => { + if (DBerr) console.log("Database disconnect error: ", DBerr); + callback(); + }); + }); +} + +afterAll((done) => { + cleanUp(done); +}); + +describe("Paper CRUD", () => { + it("should create paper with associated exam, student and faculty", async () => { + const response = await agent.post("/paper/add").send( + { + answerSheetID: "asd123", + exam: "64fc3c8bde9fa947ea1f412f", + student: "64fc3c8bde9fa947ea1f412f", + checkedBy: "64fc3c8bde9fa947ea1f412f", + mark: 100, + }, + ); + + expect(response.status).toBe(200); + expect(response.headers["content-type"]).toMatch(/json/); + }); + + let id; + beforeEach(async () => { + id = await agent.post("/paper/add").send( + { + answerSheetID: "asd123", + exam: "64fc3c8bde9fa947ea1f412f", + student: "64fc3c8bde9fa947ea1f412f", + checkedBy: "64fc3c8bde9fa947ea1f412f", + mark: 100, + }, + ); + id = JSON.parse(id.res.text).id; + }); + + afterEach(async () => { + await paperModel.remove( + { + answerSheetID: "asd123", + exam: "64fc3c8bde9fa947ea1f412f", + student: "64fc3c8bde9fa947ea1f412f", + checkedBy: "64fc3c8bde9fa947ea1f412f", + mark: 100, + }, + ); + }); + + it("should read paper", async () => { + const response = await agent + .get("/paper/list") + .send( + { + answerSheetID: "asd123", + exam: "64fc3c8bde9fa947ea1f412f", + student: "64fc3c8bde9fa947ea1f412f", + checkedBy: "64fc3c8bde9fa947ea1f412f", + mark: 100, + }, + ); + expect(response.body.res).not.toBeNull(); + }); + + it("should update paper", async () => { + const response = await agent + .post(`/paper/update/${id}`) + .send( + { + answerSheetID: "asd123", + exam: "64fc3c8bde9fa947ea1f412f", + student: "64fc3c8bde9fa947ea1f412f", + checkedBy: "64fc3c8bde9fa947ea1f412f", + mark: 100, + }, + ); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/Paper updated/); + }); + }); \ No newline at end of file diff --git a/test/routes/practical.test.js b/test/routes/practical.test.js index 0fd6124f..8a01bbc0 100644 --- a/test/routes/practical.test.js +++ b/test/routes/practical.test.js @@ -1,21 +1,9 @@ import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies -import request from "supertest"; -import app from "#app"; // Update this import based on your app's structure import connector from "#models/databaseUtil"; // Update this import import PracticalModel from "#models/practical"; // Update this import jest.mock("#util"); - -let server; -let agent; - -beforeAll((done) => { - server = app.listen(null, () => { - agent = request.agent(server); - connector.set("debug", false); - done(); - }); -}); +const { agent } = global; function cleanUp(callback) { PracticalModel @@ -23,10 +11,7 @@ function cleanUp(callback) { .then(() => { connector.disconnect((DBerr) => { if (DBerr) console.log("Database disconnect error: ", DBerr); - server.close((serverErr) => { - if (serverErr) console.log(serverErr); - callback(); - }); + callback(); }); }); } diff --git a/test/routes/semester.test.js b/test/routes/semester.test.js new file mode 100644 index 00000000..65a7fbf2 --- /dev/null +++ b/test/routes/semester.test.js @@ -0,0 +1,83 @@ +import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies +import connector from "#models/databaseUtil"; +import semesterModel from "#models/semester"; + +jest.mock("#util"); +const { agent } = global; + +function cleanUp(callback) { + semesterModel + .remove({ + number: 3, + academicYear: "2023", + type: "ODD", + startDate: "2023-06-18T14:11:30Z", + endDate: "2023-06-18T14:11:30Z", + }) + .then(() => { + connector.disconnect((DBerr) => { + if (DBerr) console.log("Database disconnect error: ", DBerr); + callback(); + }); + }); +} + +afterAll((done) => { + cleanUp(done); +}); + +describe("Semester API", () => { + it("Should create semester", async () => { + const response = await agent.post("/semester/add").send({ + number: 3, + academicYear: "2023", + type: "ODD", + startDate: "2023-06-18T14:11:30Z", + endDate: "2023-06-18T14:11:30Z", + }); + + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/added semester/); + }); + + describe("after adding semester", () => { + let id; + beforeEach(async () => { + id = await agent.post("/semester/add").send({ + number: 3, + academicYear: "2023", + type: "ODD", + startDate: "2023-06-18T14:11:30Z", + endDate: "2023-06-18T14:11:30Z", + }); + id = JSON.parse(id.res.text).id; + }); + + afterEach(async () => { + await semesterModel.remove({ + number: 3, + academicYear: "2023", + type: "ODD", + startDate: "2023-06-18T14:11:30Z", + endDate: "2023-06-18T14:11:30Z", + }); + }); + + it("should read semester", async () => { + const response = await agent + .get("/semester/list") + .send({ number: 3 }); + expect(response.status).toBe(200); + expect(response.body.res).toBeDefined(); + }); + + it("should update semester", async () => { + const response = await agent + .post(`/semester/update/${id}`) + .send({ number: 3 }, { academicYear: 2024 }); + + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/Updated Semester/); + }); + }); +}); 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 0f52b1b7..1a885614 100644 --- a/test/routes/timetable.test.js +++ b/test/routes/timetable.test.js @@ -1,30 +1,15 @@ -import request from "supertest"; import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies -import app from "#app"; import timetableModel from "#models/timetable"; import connector from "#models/databaseUtil"; jest.mock("#util"); - -let server; -let agent; - -beforeAll((done) => { - server = app.listen(null, () => { - agent = request.agent(server); - connector.set("debug", false); - done(); - }); -}); +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); - server.close((serverErr) => { - if (serverErr) console.log(serverErr); - callback(); - }); + callback(); }); }); } @@ -41,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 @@ -58,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/tutorial.test.js b/test/routes/tutorial.test.js new file mode 100644 index 00000000..894b1a11 --- /dev/null +++ b/test/routes/tutorial.test.js @@ -0,0 +1,67 @@ +import { jest } from "@jest/globals"; // eslint-disable-line import/no-extraneous-dependencies +import tutorialModel from "#models/tutorial"; +import connector from "#models/databaseUtil"; + +jest.mock("#util"); +const { agent } = global; + +function cleanUp(callback) { + tutorialModel.remove({ no: "123" }).then(() => { + connector.disconnect((DBerr) => { + if (DBerr) console.log("Database dissconnnect error: ", DBerr); + callback(); + }); + }); +} + +afterAll((done) => { + cleanUp(done); +}); + +describe("checking tutorial functions", () => { + it("create tutorial", async () => { + const response = await agent.post("/tutorial/add").send({ + no: "123", + title: "abc", + hours: "3", + cognitiveLevel: ["L1"], + }); + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/added tutorial/); + }); + + describe("after creating a practical", () => { + let tutorialId; + beforeEach(async () => { + const id = await agent.post("/tutorial/add").send({ + no: "456", + title: "dfg", + hours: "3", + cognitiveLevel: ["L1", "L2"], + }); + tutorialId = JSON.parse(id.res.text).id; + }); + + afterEach(async () => { + await tutorialModel.remove(); + }); + + it("read tutorial", async () => { + const response = await agent + .get("/tutorial/list") + .send({ name: "dfg" }); + expect(response.status).toBe(200); + expect(response.body.res).toBeDefined(); + }); + + it("update tutorial", async () => { + const response = await agent + .post(`/tutorial/update/${tutorialId}`) + .send({ no: "456" }); + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toBe(200); + expect(response.body.res).toMatch(/tutorial updated/); + }); + }); +});