diff --git a/backend/src/routes/districts.js b/backend/src/routes/districts.js index 145dee675..940011887 100644 --- a/backend/src/routes/districts.js +++ b/backend/src/routes/districts.js @@ -6,14 +6,16 @@ const auth = require('../components/auth'); const isValidBackendToken = auth.isValidBackendToken(); const { validateAccessToken, findDistrictID_params, findDistrictId_body, findDistrictContactId_body, checkEDXUserAccessToRequestedInstitute, findDistrictContactId_params, checkEdxUserPermission } = require('../components/permissionUtils'); const { PERMISSION } = require('../util/Permission'); +const validate = require('../components/validator'); +const { getByDistrictIdSchema, putDistrictSchema, districtContactSchema, putDistrictContactSchema, deleteDistrictContactSchema } = require('../validations/districts'); /* * Get a District entity by districtID */ -router.post('/:districtID/contact', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_DISTRICT_EDIT), findDistrictID_params, checkEDXUserAccessToRequestedInstitute, createDistrictContact); -router.get('/:districtID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_DISTRICT_VIEW), findDistrictID_params, checkEDXUserAccessToRequestedInstitute, getDistrictByDistrictID); -router.post('/:districtID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_DISTRICT_EDIT), findDistrictID_params, checkEDXUserAccessToRequestedInstitute, updateDistrict); -router.put('/update-contact', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_DISTRICT_EDIT), findDistrictId_body, checkEDXUserAccessToRequestedInstitute, findDistrictContactId_body, updateDistrictContact); -router.delete('/:districtID/contact/:contactID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_DISTRICT_EDIT), findDistrictID_params, checkEDXUserAccessToRequestedInstitute, findDistrictContactId_params, removeDistrictContact); +router.post('/:districtID/contact', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_DISTRICT_EDIT), validate(districtContactSchema), findDistrictID_params, checkEDXUserAccessToRequestedInstitute, createDistrictContact); +router.get('/:districtID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_DISTRICT_VIEW), validate(getByDistrictIdSchema), findDistrictID_params, checkEDXUserAccessToRequestedInstitute, getDistrictByDistrictID); +router.post('/:districtID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_DISTRICT_EDIT), validate(putDistrictSchema), findDistrictID_params, checkEDXUserAccessToRequestedInstitute, updateDistrict); +router.put('/update-contact', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_DISTRICT_EDIT), validate(putDistrictContactSchema), findDistrictId_body, checkEDXUserAccessToRequestedInstitute, findDistrictContactId_body, updateDistrictContact); +router.delete('/:districtID/contact/:contactID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_DISTRICT_EDIT), validate(deleteDistrictContactSchema), findDistrictID_params, checkEDXUserAccessToRequestedInstitute, findDistrictContactId_params, removeDistrictContact); module.exports = router; diff --git a/backend/src/routes/edx.js b/backend/src/routes/edx.js index 115f0b95e..3dab96084 100644 --- a/backend/src/routes/edx.js +++ b/backend/src/routes/edx.js @@ -15,6 +15,9 @@ const isValidBackendToken = auth.isValidBackendToken(); const router = express.Router(); const { findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess , conflictActionOnClosedSecureExchange, checkEdxUserPermission, checkPermissionForRequestedInstitute, validateAccessToken, findInstituteInformation_query, findInstituteInformation_body_params, findInstituteType_params, findInstituteIdentifier_params, findSchoolID_body, findSchoolID_body_params, findDistrictID_query, findDistrictID_body, findDistrictID_body_params, checkEDXUserAccessToRequestedInstitute } = require('../components/permissionUtils'); const { PERMISSION } = require('../util/Permission'); +const validate = require('../components/validator'); +const { exchangeSchema, exchangeDocumentSchema, exchangeStudentSchema, exchangeCommentSchema, getExchangeDocumentSchema, getDownloadExchangeDocumentSchema, deleteExchangeDocumentSchema, deleteExchangeStudentSchema, putExchangeMarkAsSchema, getByExchangeIdSchema, getExchangePaginatedSchema, getExchangeCountSchema, + districtUserInviteSchema, schoolUserInviteSchema, getUserActivationSchema, userActivationSchema, primaryUserActivationSchema, instituteSelectionSchema, districtSchoolSchema, userSchoolSchema, getUserSchoolSchema, getUserRoleSchema, getUserSchema, getDistrictUsersSchema, userRelinkSchema, userRemoveSchema } = require('../validations/edx'); router.get('/', (_req, res) => { res.status(200).json({ @@ -29,45 +32,45 @@ router.get('/document-types', passport.authenticate('jwt', {session: false}), is router.get('/file-requirements', passport.authenticate('jwt', {session: false}), isValidBackendToken, validateAccessToken, getCodes('edx:exchangeURL', CACHE_KEYS.EDX_SECURE_EXChANGE_FILE_REQUIREMENTS, '/file-requirements')); -router.post('/exchange/:id/documents', passport.authenticate('jwt', {session: false}), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, conflictActionOnClosedSecureExchange, scanFilePayload, uploadFile); +router.post('/exchange/:id/documents', passport.authenticate('jwt', {session: false}), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), validate(exchangeDocumentSchema), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, conflictActionOnClosedSecureExchange, scanFilePayload, uploadFile); -router.get('/exchange/:id/documents', passport.authenticate('jwt', {session: false}), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, (req, res) => forwardGetReq(req, res, `${config.get('edx:exchangeURL')}/${req.params.id}/documents`)); +router.get('/exchange/:id/documents', passport.authenticate('jwt', {session: false}), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), validate(getByExchangeIdSchema), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, (req, res) => forwardGetReq(req, res, `${config.get('edx:exchangeURL')}/${req.params.id}/documents`)); -router.get('/exchange/:id/documents/:documentId', passport.authenticate('jwt', {session: false}), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, (req, res) => forwardGetReq(req, res, `${config.get('edx:exchangeURL')}/${req.params.id}/documents/${req.params.documentId}`)); +router.get('/exchange/:id/documents/:documentId', passport.authenticate('jwt', {session: false}), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), validate(getExchangeDocumentSchema), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, (req, res) => forwardGetReq(req, res, `${config.get('edx:exchangeURL')}/${req.params.id}/documents/${req.params.documentId}`)); // special case this does not use frontend axios, so need to refresh here to handle expired jwt. -router.get('/exchange/:id/documents/:documentId/download/:fileName', auth.refreshJWT, isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, downloadFile); +router.get('/exchange/:id/documents/:documentId/download/:fileName', auth.refreshJWT, isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), validate(getDownloadExchangeDocumentSchema), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, downloadFile); -router.post('/exchange', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), scanSecureExchangeDocumentPayload, createExchange); -router.get('/exchange', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), getExchanges); -router.get('/exchange/count', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), getExchangesCount); +router.post('/exchange', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), validate(exchangeSchema), scanSecureExchangeDocumentPayload, createExchange); +router.get('/exchange', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), validate(getExchangePaginatedSchema), getExchanges); +router.get('/exchange/count', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), validate(getExchangeCountSchema), getExchangesCount); router.get('/exchange/role-permissions', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, getCodes('edx:edxRolePermissionsURL', CACHE_KEYS.EDX_ROLE_PERMISSIONS)); router.get('/exchange/statuses', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, getCodes('edx:exchangeStatusesURL', CACHE_KEYS.EDX_SECURE_EXCHANGE_STATUS)); -router.delete('/exchange/:id/documents/:documentId', passport.authenticate('jwt', {session: false}), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, conflictActionOnClosedSecureExchange, deleteDocument); -router.delete('/exchange/:id/removeStudent/:studentID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, conflictActionOnClosedSecureExchange, removeSecureExchangeStudent); -router.get('/exchange/:id', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, getExchange); -router.post('/exchange/:id/comments', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, conflictActionOnClosedSecureExchange, createSecureExchangeComment); -router.post('/exchange/:id/students', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, conflictActionOnClosedSecureExchange, createSecureExchangeStudent); -router.put('/exchange/:id/markAs/:readStatus', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, markAs); -router.post('/users/remove', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, findInstituteInformation_body_params, checkPermissionForRequestedInstitute(PERMISSION.EDX_USER_DISTRICT_ADMIN, PERMISSION.EDX_USER_SCHOOL_ADMIN), checkEDXUserAccessToRequestedInstitute, removeUserSchoolOrDistrictAccess); -router.post('/users/relink', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, findInstituteInformation_body_params, checkPermissionForRequestedInstitute(PERMISSION.EDX_USER_DISTRICT_ADMIN, PERMISSION.EDX_USER_SCHOOL_ADMIN), checkEDXUserAccessToRequestedInstitute, relinkUserAccess); +router.delete('/exchange/:id/documents/:documentId', passport.authenticate('jwt', {session: false}), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), validate(deleteExchangeDocumentSchema), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, conflictActionOnClosedSecureExchange, deleteDocument); +router.delete('/exchange/:id/removeStudent/:studentID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), validate(deleteExchangeStudentSchema), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, conflictActionOnClosedSecureExchange, removeSecureExchangeStudent); +router.get('/exchange/:id', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), validate(getByExchangeIdSchema), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, getExchange); +router.post('/exchange/:id/comments', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), validate(exchangeCommentSchema), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, conflictActionOnClosedSecureExchange, createSecureExchangeComment); +router.post('/exchange/:id/students', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), validate(exchangeStudentSchema), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, conflictActionOnClosedSecureExchange, createSecureExchangeStudent); +router.put('/exchange/:id/markAs/:readStatus', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), validate(putExchangeMarkAsSchema), findSecureExchange_id_params, loadSecureExchange, checkSecureExchangeAccess, markAs); +router.post('/users/remove', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, validate(userRemoveSchema), findInstituteInformation_body_params, checkPermissionForRequestedInstitute(PERMISSION.EDX_USER_DISTRICT_ADMIN, PERMISSION.EDX_USER_SCHOOL_ADMIN), checkEDXUserAccessToRequestedInstitute, removeUserSchoolOrDistrictAccess); +router.post('/users/relink', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, validate(userRelinkSchema), findInstituteInformation_body_params, checkPermissionForRequestedInstitute(PERMISSION.EDX_USER_DISTRICT_ADMIN, PERMISSION.EDX_USER_SCHOOL_ADMIN), checkEDXUserAccessToRequestedInstitute, relinkUserAccess); router.get('/users/ministry-teams', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, getCodes('edx:ministryTeamURL', CACHE_KEYS.EDX_MINISTRY_TEAMS)); -router.get('/users/user-schools', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, +router.get('/users/user-schools', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, validate(getUserSchoolSchema), (req, res) => forwardGetReq(req, res,`${config.get('edx:rootURL')}/users/user-schools`) ); -router.get('/users/activation-code/primary/:instituteType/:instituteIdentifier', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, findInstituteType_params, findInstituteIdentifier_params, checkPermissionForRequestedInstitute(PERMISSION.EDX_USER_DISTRICT_ADMIN, PERMISSION.EDX_USER_SCHOOL_ADMIN), checkEDXUserAccessToRequestedInstitute, findPrimaryEdxActivationCode); -router.post('/users/activation-code/primary/:instituteType/:instituteIdentifier', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, findInstituteType_params, findInstituteIdentifier_params, checkPermissionForRequestedInstitute(PERMISSION.EDX_USER_DISTRICT_ADMIN, PERMISSION.EDX_USER_SCHOOL_ADMIN), checkEDXUserAccessToRequestedInstitute, generateOrRegeneratePrimaryEdxActivationCode); +router.get('/users/activation-code/primary/:instituteType/:instituteIdentifier', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, validate(getUserActivationSchema), findInstituteType_params, findInstituteIdentifier_params, checkPermissionForRequestedInstitute(PERMISSION.EDX_USER_DISTRICT_ADMIN, PERMISSION.EDX_USER_SCHOOL_ADMIN), checkEDXUserAccessToRequestedInstitute, findPrimaryEdxActivationCode); +router.post('/users/activation-code/primary/:instituteType/:instituteIdentifier', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, validate(primaryUserActivationSchema), findInstituteType_params, findInstituteIdentifier_params, checkPermissionForRequestedInstitute(PERMISSION.EDX_USER_DISTRICT_ADMIN, PERMISSION.EDX_USER_SCHOOL_ADMIN), checkEDXUserAccessToRequestedInstitute, generateOrRegeneratePrimaryEdxActivationCode); -router.post('/user-activation', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, activateEdxUser); +router.post('/user-activation', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, validate(userActivationSchema), activateEdxUser); router.get('/activate-user-verification', verifyActivateUserLink); -router.get('/users/roles', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, (req, res) => forwardGetReq(req, res,`${config.get('edx:rootURL')}/users/roles`)); -router.post('/users/user-school', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_USER_DISTRICT_ADMIN), findSchoolID_body_params, checkEDXUserAccessToRequestedInstitute, updateEdxUserSchool); -router.post('/users/roles/school', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_USER_SCHOOL_ADMIN), findSchoolID_body_params, checkEDXUserAccessToRequestedInstitute, updateEdxUserSchoolRoles); -router.post('/users/roles/district', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_USER_DISTRICT_ADMIN), findDistrictID_body_params, checkEDXUserAccessToRequestedInstitute, updateEdxUserDistrictRoles); +router.get('/users/roles', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, validate(getUserRoleSchema), (req, res) => forwardGetReq(req, res,`${config.get('edx:rootURL')}/users/roles`)); +router.post('/users/user-school', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_USER_DISTRICT_ADMIN), validate(userSchoolSchema), findSchoolID_body_params, checkEDXUserAccessToRequestedInstitute, updateEdxUserSchool); +router.post('/users/roles/school', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_USER_SCHOOL_ADMIN), validate(userSchoolSchema), findSchoolID_body_params, checkEDXUserAccessToRequestedInstitute, updateEdxUserSchoolRoles); +router.post('/users/roles/district', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_USER_DISTRICT_ADMIN), validate(districtSchoolSchema), findDistrictID_body_params, checkEDXUserAccessToRequestedInstitute, updateEdxUserDistrictRoles); router.get('/users/clearActiveUserSession', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, clearActiveSession) ; -router.post('/institute-selection', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, instituteSelection); -router.get('/users', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, findInstituteInformation_query, checkPermissionForRequestedInstitute(PERMISSION.EDX_USER_DISTRICT_ADMIN, PERMISSION.EDX_USER_SCHOOL_ADMIN), checkEDXUserAccessToRequestedInstitute, getEdxUsers); -router.get('/all-district-school-users', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_USER_DISTRICT_ADMIN), findDistrictID_query, checkEDXUserAccessToRequestedInstitute, getAllDistrictSchoolEdxUsers); -router.post('/school-user-activation-invite', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_USER_SCHOOL_ADMIN), findSchoolID_body, checkEDXUserAccessToRequestedInstitute, schoolUserActivationInvite); -router.post('/district-user-activation-invite', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_USER_DISTRICT_ADMIN), findDistrictID_body, checkEDXUserAccessToRequestedInstitute, districtUserActivationInvite); +router.post('/institute-selection', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validate(instituteSelectionSchema), instituteSelection); +router.get('/users', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, validate(getUserSchema), findInstituteInformation_query, checkPermissionForRequestedInstitute(PERMISSION.EDX_USER_DISTRICT_ADMIN, PERMISSION.EDX_USER_SCHOOL_ADMIN), checkEDXUserAccessToRequestedInstitute, getEdxUsers); +router.get('/all-district-school-users', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_USER_DISTRICT_ADMIN), validate(getDistrictUsersSchema), findDistrictID_query, checkEDXUserAccessToRequestedInstitute, getAllDistrictSchoolEdxUsers); +router.post('/school-user-activation-invite', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_USER_SCHOOL_ADMIN), validate(schoolUserInviteSchema), findSchoolID_body, checkEDXUserAccessToRequestedInstitute, schoolUserActivationInvite); +router.post('/district-user-activation-invite', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_USER_DISTRICT_ADMIN), validate(districtUserInviteSchema), findDistrictID_body, checkEDXUserAccessToRequestedInstitute, districtUserActivationInvite); module.exports = router; diff --git a/backend/src/routes/institute.js b/backend/src/routes/institute.js index ed65941da..96374ade6 100644 --- a/backend/src/routes/institute.js +++ b/backend/src/routes/institute.js @@ -4,25 +4,28 @@ const router = express.Router(); const {getDistricts, getDistrictByDistrictId, getSchools, getCachedInstituteData,getCachedAuthorities,getAuthorityByID} = require('../components/institute-cache'); const auth = require('../components/auth'); const constants = require('../util/constants'); +const validate = require('../components/validator'); +const {getByDistrictIdSchema} = require('../validations/districts'); +const {geAuthoritySchema, getActiveDataSchema} = require('../validations/institute'); -router.get('/districts', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getDistricts); +router.get('/districts', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), validate(getActiveDataSchema), getDistricts); -router.get('/schools', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getSchools); +router.get('/schools', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), validate(getActiveDataSchema), getSchools); -router.get('/districts/:districtID', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getDistrictByDistrictId); +router.get('/districts/:districtID', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), validate(getByDistrictIdSchema), getDistrictByDistrictId); router.get('/province-codes', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getCachedInstituteData(constants.CACHE_KEYS.PROVINCE_CODES, 'institute:provinceCodesURL')); router.get('/country-codes', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getCachedInstituteData(constants.CACHE_KEYS.COUNTRY_CODES, 'institute:countryCodesURL')); -router.get('/facility-types', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getCachedInstituteData(constants.CACHE_KEYS.SCHOOL_FACILITY_TYPES, 'institute:facilityTypeURL')); -router.get('/school-category-types', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getCachedInstituteData(constants.CACHE_KEYS.SCHOOL_CATEGORY_TYPES, 'institute:categoryCodesURL')); -router.get('/school-contact-types', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getCachedInstituteData(constants.CACHE_KEYS.SCHOOL_CONTACT_TYPE_CODES, 'institute:schoolContactTypeCodesURL')); -router.get('/school-organization-types', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getCachedInstituteData(constants.CACHE_KEYS.SCHOOL_ORGANIZATION_TYPES, 'institute:organizationCodeURL')); -router.get('/school-neighborhood-learning-types', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getCachedInstituteData(constants.CACHE_KEYS.SCHOOL_NEIGHBORHOOD_LEARNING_TYPES, 'institute:neighbourhoodLearningURL')); +router.get('/facility-types', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), validate(getActiveDataSchema), getCachedInstituteData(constants.CACHE_KEYS.SCHOOL_FACILITY_TYPES, 'institute:facilityTypeURL')); +router.get('/school-category-types', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), validate(getActiveDataSchema), getCachedInstituteData(constants.CACHE_KEYS.SCHOOL_CATEGORY_TYPES, 'institute:categoryCodesURL')); +router.get('/school-contact-types', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), validate(getActiveDataSchema), getCachedInstituteData(constants.CACHE_KEYS.SCHOOL_CONTACT_TYPE_CODES, 'institute:schoolContactTypeCodesURL')); +router.get('/school-organization-types', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), validate(getActiveDataSchema), getCachedInstituteData(constants.CACHE_KEYS.SCHOOL_ORGANIZATION_TYPES, 'institute:organizationCodeURL')); +router.get('/school-neighborhood-learning-types', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), validate(getActiveDataSchema), getCachedInstituteData(constants.CACHE_KEYS.SCHOOL_NEIGHBORHOOD_LEARNING_TYPES, 'institute:neighbourhoodLearningURL')); router.get('/school-grade-types', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getCachedInstituteData(constants.CACHE_KEYS.SCHOOL_GRADE_TYPES, 'institute:gradeCodeURL')); -router.get('/district-contact-types', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getCachedInstituteData(constants.CACHE_KEYS.DISTRICT_CONTACT_TYPE_CODES, 'institute:districtContactTypeCodesURL')); +router.get('/district-contact-types', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), validate(getActiveDataSchema), getCachedInstituteData(constants.CACHE_KEYS.DISTRICT_CONTACT_TYPE_CODES, 'institute:districtContactTypeCodesURL')); router.get('/reporting-requirement-codes', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getCachedInstituteData(constants.CACHE_KEYS.SCHOOL_REPORTING_REQUIREMENT_CODES,'institute:reportingRequirementCodesURL')); router.get('/authority', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getCachedAuthorities); -router.get('/authority/:id', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getAuthorityByID); +router.get('/authority/:id', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), validate(geAuthoritySchema), getAuthorityByID); module.exports = router; diff --git a/backend/src/routes/penServices.js b/backend/src/routes/penServices.js index 30c96580a..dc4093e5d 100644 --- a/backend/src/routes/penServices.js +++ b/backend/src/routes/penServices.js @@ -13,11 +13,13 @@ const { checkSdcSchoolCollectionAccess } = require('../components/permissionUtils'); const {PERMISSION} = require('../util/Permission'); +const validate = require('../components/validator'); +const { validateStudentSchema } = require('../validations/penServices'); /* * Get results of student demographics validation */ -router.post('/sdcSchoolCollection/:sdcSchoolCollectionID/demog-validation', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, validateStudentDemogData); +router.post('/sdcSchoolCollection/:sdcSchoolCollectionID/demog-validation', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), validate(validateStudentSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, validateStudentDemogData); router.get('/prbValidationTypeCodes', passport.authenticate('jwt', {session: false}, undefined), auth.isValidBackendToken(), getCachedPENServicesData(constants.CACHE_KEYS.PRB_VALIDATION_ISSUE_TYPE_CODES, 'penServices:prbValidationTypeCodesURL')); module.exports = router; diff --git a/backend/src/routes/schools.js b/backend/src/routes/schools.js index 097fb562e..51dafe565 100644 --- a/backend/src/routes/schools.js +++ b/backend/src/routes/schools.js @@ -7,18 +7,18 @@ const isValidBackendToken = auth.isValidBackendToken(); const { validateAccessToken, findSchoolID_query, findSchoolID_params, findSchoolID_body, findDistrictID_querySearchParams, findSchoolContactId_body, checkEDXUserAccessToRequestedInstitute, findSchoolContactId_params, checkEdxUserPermission, verifyQueryParamValueMatchesBodyValue } = require('../components/permissionUtils'); const { PERMISSION } = require('../util/Permission'); const validate = require('../components/validator'); -const {schoolContactSchema, schoolPaginatedSchema, getSchoolSchema, putSchoolSchema} = require('../validations/schools'); +const { getBySchoolIdSchema, getSchoolPaginatedSchema, schoolContactSchema, putSchoolContactSchema, deleteSchoolContactSchema, putSchoolSchema } = require('../validations/schools'); /* * Get a school entity by schoolID */ router.get('/', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_VIEW), findSchoolID_query, checkEDXUserAccessToRequestedInstitute, getSchoolBySchoolID); router.get('/lastUpdated', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_VIEW), findSchoolID_query, checkEDXUserAccessToRequestedInstitute, getSchoolBySchoolID); -router.get('/schoolBelongsToLoggedInDistrict/:schoolID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, checkEdxUserPermission(PERMISSION.EDX_DISTRICT_VIEW), findSchoolID_params, checkSchoolBelongsToDistrict); -router.get('/allSchools', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_VIEW), findDistrictID_querySearchParams, checkEDXUserAccessToRequestedInstitute, validate(schoolPaginatedSchema), getAllSchoolDetails); -router.get('/schoolDetailsById/:schoolID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_VIEW), validateAccessToken, findSchoolID_params, checkEDXUserAccessToRequestedInstitute, validate(getSchoolSchema), getFullSchoolDetails); -router.put('/:schoolID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_EDIT), verifyQueryParamValueMatchesBodyValue('schoolID', 'schoolId'), findSchoolID_params, checkEDXUserAccessToRequestedInstitute, validate(putSchoolSchema), updateSchool); -router.post('/:schoolID/contact', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_EDIT), findSchoolID_params, checkEDXUserAccessToRequestedInstitute, validate(schoolContactSchema), addSchoolContact); -router.delete('/:schoolID/contact/:contactID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_EDIT), findSchoolID_params, checkEDXUserAccessToRequestedInstitute, findSchoolContactId_params, removeSchoolContact); -router.post('/update-contact', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_EDIT), findSchoolID_body, checkEDXUserAccessToRequestedInstitute, findSchoolContactId_body, updateSchoolContact); +router.get('/schoolBelongsToLoggedInDistrict/:schoolID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, checkEdxUserPermission(PERMISSION.EDX_DISTRICT_VIEW), validate(getBySchoolIdSchema), findSchoolID_params, checkSchoolBelongsToDistrict); +router.get('/allSchools', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_VIEW), validate(getSchoolPaginatedSchema), findDistrictID_querySearchParams, checkEDXUserAccessToRequestedInstitute, getAllSchoolDetails); +router.get('/schoolDetailsById/:schoolID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_VIEW), validateAccessToken, validate(getBySchoolIdSchema), findSchoolID_params, checkEDXUserAccessToRequestedInstitute, getFullSchoolDetails); +router.put('/:schoolID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_EDIT), validate(putSchoolSchema), verifyQueryParamValueMatchesBodyValue('schoolID', 'schoolId'), findSchoolID_params, checkEDXUserAccessToRequestedInstitute, updateSchool); +router.post('/:schoolID/contact', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_EDIT), validate(schoolContactSchema), findSchoolID_params, checkEDXUserAccessToRequestedInstitute, addSchoolContact); +router.delete('/:schoolID/contact/:contactID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_EDIT), validate(deleteSchoolContactSchema), findSchoolID_params, checkEDXUserAccessToRequestedInstitute, findSchoolContactId_params, removeSchoolContact); +router.post('/update-contact', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.EDX_SCHOOL_EDIT), validate(putSchoolContactSchema), findSchoolID_body, checkEDXUserAccessToRequestedInstitute, findSchoolContactId_body, updateSchoolContact); module.exports = router; diff --git a/backend/src/routes/sdc.js b/backend/src/routes/sdc.js index 835233126..7d9d7d069 100644 --- a/backend/src/routes/sdc.js +++ b/backend/src/routes/sdc.js @@ -18,16 +18,20 @@ const { validateAccessToken, checkEdxUserPermission, checkPermissionForRequested loadInstituteCollection, checkStudentBelongsInCollection, findSdcSchoolCollectionStudentID_body, checkSdcDuplicateAccess, checkUserAccessToDuplicateSdcSchoolCollections, findSdcSchoolCollectionsInDuplicate} = require('../components/permissionUtils'); const { PERMISSION } = require('../util/Permission'); const {getPenMatch} = require('../components/penMatch'); +const validate = require('../components/validator'); +const { putSdcStudentSchema, putDistrictCollectionSchema, putSchoolCollectionSchema, getActiveDataSchema, getByDistrictIdSchema, getBySchoolIdSchema, getBySdcDistrictCollectionSchema, getBySdcSchoolCollectionSchema, getBySdcSchoolCollectionStudentSchema, + getBySdcDistrictCollectionPaginatedSchema, getBySdcSchoolCollectionPaginatedSchema, getPenMatchSchema, getSchoolHistoricPaginatedSchema, getDistrictHistoricPaginatedSchema, getSchoolReportDownloadSchema, getDistrictReportDownloadSchema, + unsubmitCollectionSchema, zeroEnrollmentSchema, removeStudentFromSchoolCollectionSchema, districtSignoffSchema, districtFileCollectionSchema, schoolFileCollectionSchema, resolveDuplicateSchema, markDiffSchema, startFromPriorCollectionSchema } = require('../validations/sdc'); //cached code table calls -router.get('/band-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, getCachedSDCData(constants.CACHE_KEYS.SDC_BAND_CODES, 'sdc:bandCodesURL')); -router.get('/career-program-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, getCachedSDCData(constants.CACHE_KEYS.SDC_CAREER_PROGRAM_CODES, 'sdc:careerProgramCodesURL')); -router.get('/enrolled-grade-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, getCachedSDCData(constants.CACHE_KEYS.SDC_ENROLLED_GRADE_CODES, 'sdc:enrolledGradeCodesURL')); -router.get('/enrolled-program-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, getCachedSDCData(constants.CACHE_KEYS.SDC_ENROLLED_PROGRAM_CODES, 'sdc:enrolledProgramCodesURL')); -router.get('/gender-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, getCodes('sdc:genderCodesURL', constants.CACHE_KEYS.SDC_GENDER_CODES, null, true)); -router.get('/home-language-spoken-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, getCachedSDCData(constants.CACHE_KEYS.SDC_HOME_LANGUAGE_SPOKEN_CODES, 'sdc:homeLanguageSpokenCodesURL')); -router.get('/school-funding-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, getCachedSDCData(constants.CACHE_KEYS.SDC_SCHOOL_FUNDING_CODES, 'sdc:schoolFundingCodesURL')); -router.get('/specialEducation-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, getCachedSDCData(constants.CACHE_KEYS.SDC_SPECIAL_ED_CODES, 'sdc:specialEdCodesURL')); +router.get('/band-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validate(getActiveDataSchema), getCachedSDCData(constants.CACHE_KEYS.SDC_BAND_CODES, 'sdc:bandCodesURL')); +router.get('/career-program-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validate(getActiveDataSchema), getCachedSDCData(constants.CACHE_KEYS.SDC_CAREER_PROGRAM_CODES, 'sdc:careerProgramCodesURL')); +router.get('/enrolled-grade-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validate(getActiveDataSchema), getCachedSDCData(constants.CACHE_KEYS.SDC_ENROLLED_GRADE_CODES, 'sdc:enrolledGradeCodesURL')); +router.get('/enrolled-program-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validate(getActiveDataSchema), getCachedSDCData(constants.CACHE_KEYS.SDC_ENROLLED_PROGRAM_CODES, 'sdc:enrolledProgramCodesURL')); +router.get('/gender-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, validate(getActiveDataSchema), getCodes('sdc:genderCodesURL', constants.CACHE_KEYS.SDC_GENDER_CODES, null, true)); +router.get('/home-language-spoken-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validate(getActiveDataSchema), getCachedSDCData(constants.CACHE_KEYS.SDC_HOME_LANGUAGE_SPOKEN_CODES, 'sdc:homeLanguageSpokenCodesURL')); +router.get('/school-funding-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validate(getActiveDataSchema), getCachedSDCData(constants.CACHE_KEYS.SDC_SCHOOL_FUNDING_CODES, 'sdc:schoolFundingCodesURL')); +router.get('/specialEducation-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validate(getActiveDataSchema), getCachedSDCData(constants.CACHE_KEYS.SDC_SPECIAL_ED_CODES, 'sdc:specialEdCodesURL')); router.get('/validation-issue-type-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, getCachedSDCData(constants.CACHE_KEYS.SDC_VALIDATION_ISSUE_TYPE_CODES, 'sdc:validationIssueTypeCodesURL')); router.get('/program-eligibility-issue-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, getCodes('sdc:programEligibilityTypeCodesURL', constants.CACHE_KEYS.SDC_PROGRAM_ELIGIBILITY_TYPE_CODES, null, true)); router.get('/zero-fte-reason-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, getCodes('sdc:zeroFteReasonCodesURL', constants.CACHE_KEYS.SDC_ZERO_FTE_REASON_CODES, null, true)); @@ -35,59 +39,59 @@ router.get('/duplicate-resolution-codes', passport.authenticate('jwt', {session: router.get('/school-collection-status-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, getCodes('sdc:schoolCollectionStatusCodesURL', constants.CACHE_KEYS.SDC_SCHOOL_COLLECTION_STATUS_CODES, null, true)); //end cached code table calls -router.get('/getCollectionBySchoolId/:schoolID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSchoolID_params, checkEDXUserAccessToRequestedInstitute, getCollectionBySchoolId); -router.get('/getCollectionByDistrictId/:districtID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), findDistrictID_params, checkEDXUserAccessToRequestedInstitute, getCollectionByDistrictId); -router.get('/sdcSchoolCollection/:sdcSchoolCollectionID/duplicates', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSchoolStudentDuplicates); -router.get('/sdcSchoolCollection/:sdcSchoolCollectionID/sdc-duplicates', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSchoolSdcDuplicates); -router.get('/sdcSchoolCollection/:sdcSchoolCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSchoolCollectionById); -router.post('/:sdcSchoolCollectionID/file', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, scanFilePayload, uploadFile); -router.post('/:sdcSchoolCollectionID/startFromPriorCollection', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, startFromPriorSeptCollection); -router.get('/:sdcSchoolCollectionID/file', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSdcFileProgress); -router.post('/:sdcSchoolCollectionID/reportZeroEnrollment', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, reportZeroEnrollment); -router.put('/:sdcSchoolCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, updateSchoolCollection); -router.post('/:sdcSchoolCollectionID/unsubmit', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_EDIT), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, unsubmitSdcSchoolCollection); -router.get('/sdcSchoolCollection/:sdcSchoolCollectionID/provincial-duplicates', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getProvincialDuplicatesForSchool); -router.get('/sdcSchoolCollection/:sdcSchoolCollectionID/student-validation-issue-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getStudentValidationIssueCodes); -router.get('/sdcSchoolCollection/:sdcSchoolCollectionID/studentDifferences', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getStudentDifferencesByInstituteCollectionId); -router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/sdcSchoolCollectionMonitoring', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getSdcSchoolCollectionMonitoringBySdcDistrictCollectionId); -router.post('/sdcSchoolCollectionStudent/:sdcSchoolCollectionStudentID/penMatch', passport.authenticate('jwt', {session: false}, undefined), validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), findSdcSchoolCollectionStudentID_params, loadSdcSchoolCollectionStudent, findSdcSchoolCollectionID_fromRequestedSdcSchoolCollectionStudent, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getPenMatch); -router.post('/sdcSchoolCollection/:sdcSchoolCollectionID/newStudent/penMatch', passport.authenticate('jwt', {session: false}, undefined), validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getPenMatch); +router.get('/getCollectionBySchoolId/:schoolID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getBySchoolIdSchema), findSchoolID_params, checkEDXUserAccessToRequestedInstitute, getCollectionBySchoolId); +router.get('/getCollectionByDistrictId/:districtID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), validate(getByDistrictIdSchema), findDistrictID_params, checkEDXUserAccessToRequestedInstitute, getCollectionByDistrictId); +router.get('/sdcSchoolCollection/:sdcSchoolCollectionID/duplicates', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getBySdcSchoolCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSchoolStudentDuplicates); +router.get('/sdcSchoolCollection/:sdcSchoolCollectionID/sdc-duplicates', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getBySdcSchoolCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSchoolSdcDuplicates); +router.get('/sdcSchoolCollection/:sdcSchoolCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getBySdcSchoolCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSchoolCollectionById); +router.post('/:sdcSchoolCollectionID/file', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), validate(schoolFileCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, scanFilePayload, uploadFile); +router.post('/:sdcSchoolCollectionID/startFromPriorCollection', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), validate(startFromPriorCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, startFromPriorSeptCollection); +router.get('/:sdcSchoolCollectionID/file', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getBySdcSchoolCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSdcFileProgress); +router.post('/:sdcSchoolCollectionID/reportZeroEnrollment', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), validate(zeroEnrollmentSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, reportZeroEnrollment); +router.put('/:sdcSchoolCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), validate(putSchoolCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, updateSchoolCollection); +router.post('/:sdcSchoolCollectionID/unsubmit', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_EDIT), validate(unsubmitCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, unsubmitSdcSchoolCollection); +router.get('/sdcSchoolCollection/:sdcSchoolCollectionID/provincial-duplicates', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getBySdcSchoolCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getProvincialDuplicatesForSchool); +router.get('/sdcSchoolCollection/:sdcSchoolCollectionID/student-validation-issue-codes', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getBySdcSchoolCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getStudentValidationIssueCodes); +router.get('/sdcSchoolCollection/:sdcSchoolCollectionID/studentDifferences', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getBySdcSchoolCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getStudentDifferencesByInstituteCollectionId); +router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/sdcSchoolCollectionMonitoring', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), validate(getBySdcDistrictCollectionSchema), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getSdcSchoolCollectionMonitoringBySdcDistrictCollectionId); +router.post('/sdcSchoolCollectionStudent/:sdcSchoolCollectionStudentID/penMatch', passport.authenticate('jwt', {session: false}, undefined), validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), validate(getPenMatchSchema), findSdcSchoolCollectionStudentID_params, loadSdcSchoolCollectionStudent, findSdcSchoolCollectionID_fromRequestedSdcSchoolCollectionStudent, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getPenMatch); +router.post('/sdcSchoolCollection/:sdcSchoolCollectionID/newStudent/penMatch', passport.authenticate('jwt', {session: false}, undefined), validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), validate(getPenMatchSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getPenMatch); //student -router.get('/sdcSchoolCollectionStudent/:sdcSchoolCollectionID/paginated', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSDCSchoolCollectionStudentPaginated); -router.get('/sdcSchoolCollectionStudent/stats/error-warning-count/:sdcSchoolCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSDCSchoolCollectionStudentSummaryCounts); -router.get('/sdcSchoolCollectionStudent/:sdcSchoolCollectionStudentID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSdcSchoolCollectionStudentID_params, loadSdcSchoolCollectionStudent, findSdcSchoolCollectionID_fromRequestedSdcSchoolCollectionStudent, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSDCSchoolCollectionStudentDetail); +router.get('/sdcSchoolCollectionStudent/:sdcSchoolCollectionID/paginated', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getBySdcSchoolCollectionPaginatedSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSDCSchoolCollectionStudentPaginated); +router.get('/sdcSchoolCollectionStudent/stats/error-warning-count/:sdcSchoolCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getBySdcSchoolCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSDCSchoolCollectionStudentSummaryCounts); +router.get('/sdcSchoolCollectionStudent/:sdcSchoolCollectionStudentID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getBySdcSchoolCollectionStudentSchema), findSdcSchoolCollectionStudentID_params, loadSdcSchoolCollectionStudent, findSdcSchoolCollectionID_fromRequestedSdcSchoolCollectionStudent, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getSDCSchoolCollectionStudentDetail); //update student router.post('/sdcSchoolCollectionStudent', passport.authenticate('jwt', {session: false}, undefined), - isValidBackendToken, validateAccessToken, findSInstituteTypeCollectionID_body, checkPermissionForRequestedInstitute(PERMISSION.DISTRICT_SDC_EDIT, PERMISSION.SCHOOL_SDC_EDIT), + isValidBackendToken, validateAccessToken, validate(putSdcStudentSchema), findSInstituteTypeCollectionID_body, checkPermissionForRequestedInstitute(PERMISSION.DISTRICT_SDC_EDIT, PERMISSION.SCHOOL_SDC_EDIT), loadInstituteCollection, checkInstituteCollectionAccess, checkIfCreateorUpdateSDCStudentIsAllowed, findSdcSchoolCollectionStudentID_body, loadSdcSchoolCollectionStudent, checkStudentBelongsInCollection, updateAndValidateSdcSchoolCollectionStudent); -router.post('/resolve-duplicates/:sdcDuplicateID/:type', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), checkSdcDuplicateAccess, findSdcSchoolCollectionsInDuplicate, checkUserAccessToDuplicateSdcSchoolCollections, resolveDuplicates); +router.post('/resolve-duplicates/:sdcDuplicateID/:type', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), validate(resolveDuplicateSchema), checkSdcDuplicateAccess, findSdcSchoolCollectionsInDuplicate, checkUserAccessToDuplicateSdcSchoolCollections, resolveDuplicates); -router.post('/sdcSchoolCollectionStudent/:sdcSchoolCollectionID/markDiff', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, markSdcSchoolCollectionStudentAsDifferent); -router.delete('/sdcSchoolCollectionStudent/:sdcSchoolCollectionStudentID', passport.authenticate('jwt', {session: false}, undefined), validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), findSdcSchoolCollectionStudentID_params, loadSdcSchoolCollectionStudent, findSdcSchoolCollectionID_fromRequestedSdcSchoolCollectionStudent, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, deleteSDCSchoolCollectionStudent); -router.post('/sdcSchoolCollectionStudent/:sdcSchoolCollectionID/students/remove', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, removeSDCSchoolCollectionStudents); +router.post('/sdcSchoolCollectionStudent/:sdcSchoolCollectionID/markDiff', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), validate(markDiffSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, markSdcSchoolCollectionStudentAsDifferent); +router.delete('/sdcSchoolCollectionStudent/:sdcSchoolCollectionStudentID', passport.authenticate('jwt', {session: false}, undefined), validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), validate(getBySdcSchoolCollectionStudentSchema), findSdcSchoolCollectionStudentID_params, loadSdcSchoolCollectionStudent, findSdcSchoolCollectionID_fromRequestedSdcSchoolCollectionStudent, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, deleteSDCSchoolCollectionStudent); +router.post('/sdcSchoolCollectionStudent/:sdcSchoolCollectionID/students/remove', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), validate(removeStudentFromSchoolCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, removeSDCSchoolCollectionStudents); -router.get('/sdcSchoolCollectionStudent/getStudentHeadcounts/:sdcSchoolCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getStudentHeadcounts); +router.get('/sdcSchoolCollectionStudent/getStudentHeadcounts/:sdcSchoolCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getBySdcSchoolCollectionSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, getStudentHeadcounts); // special case this does not use frontend axios, so need to refresh here to handle expired jwt. -router.get('/:sdcSchoolCollectionID/report/:reportTypeCode/download', auth.refreshJWT, isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, downloadSdcReport); -router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/report/:reportTypeCode/download', auth.refreshJWT, isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, downloadSdcReport); -router.get('/sdcDistrictCollection/:districtID/historic-paginated', auth.refreshJWT, isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), findDistrictID_params, checkEDXUserAccessToRequestedInstitute, getSdcDistrictCollectionPaginated); -router.get('/sdcSchoolCollection/:schoolID/historic-paginated', auth.refreshJWT, isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), findSchoolID_params, checkEDXUserAccessToRequestedInstitute, getSdcSchoolCollectionPaginated); +router.get('/:sdcSchoolCollectionID/report/:reportTypeCode/download', auth.refreshJWT, isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getSchoolReportDownloadSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, downloadSdcReport); +router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/report/:reportTypeCode/download', auth.refreshJWT, isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), validate(getDistrictReportDownloadSchema), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, downloadSdcReport); +router.get('/sdcDistrictCollection/:districtID/historic-paginated', auth.refreshJWT, isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), validate(getDistrictHistoricPaginatedSchema), findDistrictID_params, checkEDXUserAccessToRequestedInstitute, getSdcDistrictCollectionPaginated); +router.get('/sdcSchoolCollection/:schoolID/historic-paginated', auth.refreshJWT, isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_VIEW), validate(getSchoolHistoricPaginatedSchema), findSchoolID_params, checkEDXUserAccessToRequestedInstitute, getSdcSchoolCollectionPaginated); //district -router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/paginated', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getSDCSchoolCollectionStudentPaginated); -router.get('/sdcDistrictCollection/:sdcDistrictCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getDistrictCollectionById); -router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/studentDifferences', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getStudentDifferencesByInstituteCollectionId); -router.put('/sdcDistrictCollection/:sdcDistrictCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_EDIT), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, updateDistrictCollection); -router.post('/district/:sdcDistrictCollectionID/file', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_EDIT), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, scanFilePayload, uploadFile); -router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/fileProgress', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getDistrictSdcFileProgress); -router.get('/sdcSchoolCollectionStudent/getDistrictHeadcounts/:sdcDistrictCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getDistrictHeadcounts); -router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/in-district-duplicates', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getInDistrictDuplicates); -router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/sdcSchoolCollections', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getSdcSchoolCollections); -router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/provincial-duplicates', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getProvincialDuplicates); +router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/paginated', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), validate(getBySdcDistrictCollectionPaginatedSchema), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getSDCSchoolCollectionStudentPaginated); +router.get('/sdcDistrictCollection/:sdcDistrictCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), validate(getBySdcDistrictCollectionSchema), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getDistrictCollectionById); +router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/studentDifferences', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), validate(getBySdcDistrictCollectionPaginatedSchema), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getStudentDifferencesByInstituteCollectionId); +router.put('/sdcDistrictCollection/:sdcDistrictCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_EDIT), validate(putDistrictCollectionSchema), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, updateDistrictCollection); +router.post('/district/:sdcDistrictCollectionID/file', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_EDIT), validate(districtFileCollectionSchema), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, scanFilePayload, uploadFile); +router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/fileProgress', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), validate(getBySdcDistrictCollectionSchema), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getDistrictSdcFileProgress); +router.get('/sdcSchoolCollectionStudent/getDistrictHeadcounts/:sdcDistrictCollectionID', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), validate(getBySdcDistrictCollectionSchema), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getDistrictHeadcounts); +router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/in-district-duplicates', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), validate(getBySdcDistrictCollectionSchema), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getInDistrictDuplicates); +router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/sdcSchoolCollections', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), validate(getBySdcDistrictCollectionSchema), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getSdcSchoolCollections); +router.get('/sdcDistrictCollection/:sdcDistrictCollectionID/provincial-duplicates', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_VIEW), validate(getBySdcDistrictCollectionSchema), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, getProvincialDuplicates); -router.post('/sdcDistrictCollection/:sdcDistrictCollectionID/sign-off', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_EDIT), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, submitDistrictSignature); +router.post('/sdcDistrictCollection/:sdcDistrictCollectionID/sign-off', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.DISTRICT_SDC_EDIT), validate(districtSignoffSchema), findSdcDistrictCollectionID_params, loadSdcDistrictCollection, checkSdcDistrictCollectionAccess, submitDistrictSignature); module.exports = router; diff --git a/backend/src/routes/student.js b/backend/src/routes/student.js index 3337db888..165cdb7ad 100644 --- a/backend/src/routes/student.js +++ b/backend/src/routes/student.js @@ -10,10 +10,11 @@ const { validateAccessToken, checkEdxUserPermission, checkSdcSchoolCollectionAccess } = require('../components/permissionUtils'); const { PERMISSION } = require('../util/Permission'); - +const validate = require('../components/validator'); +const {newStudentSchema} = require('../validations/student'); /* * Get student details based on PEN Number */ router.get('/', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SECURE_EXCHANGE), getStudentByPEN); -router.post('/sdcSchoolCollection/:sdcSchoolCollectionID/createStudent', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, createNewStudent); +router.post('/sdcSchoolCollection/:sdcSchoolCollectionID/createStudent', passport.authenticate('jwt', {session: false}, undefined), isValidBackendToken, validateAccessToken, checkEdxUserPermission(PERMISSION.SCHOOL_SDC_EDIT), validate(newStudentSchema), findSdcSchoolCollectionID_params, loadSdcSchoolCollection, checkSdcSchoolCollectionAccess, createNewStudent); module.exports = router; diff --git a/backend/src/validations/base.js b/backend/src/validations/base.js new file mode 100644 index 000000000..e3772ced1 --- /dev/null +++ b/backend/src/validations/base.js @@ -0,0 +1,37 @@ +const { object, string, date } = require('yup'); + +const baseRequestSchema = object({ + createDate: date().nullable().optional(), + createUser: string().nullable().max(100).optional(), + updateDate: date().nullable().optional(), + updateUser: string().nullable().max(100).optional(), +}).noUnknown(); + +const baseAddressSchema = object({ + addressLine1: string().max(255), + addressLine2: string().nullable().max(255), + city: string().max(255), + postal: string().max(255), + provinceCode: string().max(10), + countryCode: string().max(10), + addressTypeCode: string(), +}).noUnknown(); + +const baseContactSchema = object({ + firstName: string().nullable().max(255), + lastName: string().max(255), + jobTitle: string().nullable(), + phoneNumber: string().nullable().max(10), + phoneExtension: string().nullable().max(10), + alternatePhoneNumber: string().nullable().max(10), + alternatePhoneExtension: string().nullable().max(10), + email: string().email().nullable().max(255), + effectiveDate: date(), + expiryDate: date().nullable(), +}).noUnknown(); + +module.exports = { + baseAddressSchema, + baseContactSchema, + baseRequestSchema, +}; diff --git a/backend/src/validations/districts.js b/backend/src/validations/districts.js new file mode 100644 index 000000000..0470f96cf --- /dev/null +++ b/backend/src/validations/districts.js @@ -0,0 +1,79 @@ +const { object, string, array } = require('yup'); +const { baseAddressSchema, baseContactSchema, baseRequestSchema } = require('./base'); + +const getByDistrictIdSchema = object({ + body: object().noUnknown(), + params: object({ + districtID: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const districtContactSchema = object({ + districtContactTypeCode: string().max(10), +}).concat(baseContactSchema).concat(baseRequestSchema).noUnknown(); + +const districtAddressSchema = baseAddressSchema.concat(baseRequestSchema).noUnknown(); + +const postDistrictContactSchema = object({ + body: districtContactSchema, + params: object({ + districtID: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const putDistrictContactSchema = object({ + body: districtContactSchema.shape({ + districtContactId: string(), + districtId: string() + }), + params: object({ + districtID: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const deleteDistrictContactSchema = object({ + body: object().noUnknown(), + params: object({ + districtID: string(), + contactID: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const putDistrictSchema = object({ + body: object({ + districtId: string().nullable(), + displayName: string().max(255).nonNullable(), + districtNumber: string().max(3).nonNullable(), + districtRegionCode: string().max(10).nonNullable(), + districtStatusCode: string().max(10).nonNullable(), + phoneNumber: string().max(10).nullable(), + faxNumber: string().nullable().max(10).nullable(), + email: string().nullable().max(255), + website: string().nullable().max(255), + contacts: array().of(districtContactSchema.shape({ + districtContactId: string(), + districtId: string() + })), + addresses: array().of(districtAddressSchema.shape({ + districtAddressId: string(), + districtId: string() + })), + notes: string().nullable(), + }), + params: object({ + districtID: string() + }).noUnknown(), + query: object().noUnknown() +}).concat(baseRequestSchema).noUnknown(); + +module.exports = { + getByDistrictIdSchema, + putDistrictSchema, + districtContactSchema: postDistrictContactSchema, + putDistrictContactSchema, + deleteDistrictContactSchema, +}; diff --git a/backend/src/validations/edx.js b/backend/src/validations/edx.js new file mode 100644 index 000000000..d9d3f4177 --- /dev/null +++ b/backend/src/validations/edx.js @@ -0,0 +1,344 @@ +const { object, string, array, number, date, lazy } = require('yup'); +const { baseRequestSchema } = require('./base'); + +const exchangeDocumentSchema = object({ + documentTypeCode: string().max(10).nonNullable(), + fileName: string().max(255).nonNullable(), + fileExtension: string().max(255).nonNullable(), + documentData: string().nonNullable(), + fileSize: number().positive() +}).noUnknown(); + +const exchangeCommentSchema = object({ + edxUserID: string().nullable().optional(), + commentUserName: string().max(255).nonNullable().optional(), + content: string().nonNullable() +}).noUnknown(); + +const exchangeStudentSchema = object({ + studentID: string().nonNullable(), + pen: string().max(255).nonNullable() +}).noUnknown(); + +const postExchangeSchema = object({ + body: object({ + ministryOwnershipTeamID: string(), + reviewer: string().nullable().max(255), + subject: string().nonNullable().max(4000), + content: string().nonNullable(), + secureExchangeDocuments: array().of(exchangeDocumentSchema), + secureExchangeStudents: array().of(exchangeStudentSchema) + }).concat(baseRequestSchema).noUnknown(), + params: object().noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const postExchangeDocumentSchema = object({ + body: exchangeDocumentSchema, + params: object({ + id: string().nonNullable() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const postExchangeStudentSchema = object({ + body: object({ + studentID: string() + }).noUnknown(), + params: object({ + id: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const postExchangeCommentSchema = object({ + body: exchangeCommentSchema.noUnknown(), + params: object({ + id: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const deleteExchangeDocumentSchema = object({ + body: object().noUnknown(), + params: object({ + id: string().nonNullable(), + documentId: string().nonNullable() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const deleteExchangeStudentSchema = object({ + body: object().noUnknown(), + params: object({ + id: string().nonNullable(), + studentID: string().nonNullable() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const putExchangeMarkAsSchema = object({ + body: object().noUnknown(), + params: object({ + id: string().nonNullable(), + readStatus: string().nonNullable() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const getByExchangeIdSchema = object({ + body: object().noUnknown(), + params: object({ + id: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const getExchangePaginatedSchema = object({ + body: object().noUnknown(), + params: object().noUnknown(), + query: object({ + pageNumber: number().required().moreThan(-1).integer(), + pageSize: number().required().positive().integer(), + sort: object({ + createDate: string().oneOf(['ASC','DESC']), + updateDate: string().oneOf(['ASC','DESC']) + }), + searchParams: object({ + ministryOwnershipTeamID: string().nullable().optional(), + subject: string().nullable().optional(), + createDate: date().nullable().optional(), + secureExchangeStatusCode: array().of(string()).optional(), + sequenceNumber: number().nullable().optional(), + studentPEN: string().nullable().optional() + }), + }).noUnknown() +}).noUnknown(); + +const getExchangeCountSchema = object({ + body: object().noUnknown(), + params: object(), + query: object({ + pageNumber: number().required().moreThan(-1).integer(), + pageSize: number().required().positive().integer(), + sort: lazy((value) => + typeof value === 'object' + ? object().nullable() + : string().nullable() + ).optional(), + searchParams: object().nullable().optional() + }) +}).noUnknown(); + +const getExchangeDocumentSchema = object({ + body: object().noUnknown(), + params: object({ + id: string().nonNullable(), + documentId: string().nonNullable(), + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const getDownloadExchangeDocumentSchema = object({ + body: object().noUnknown(), + params: object({ + id: string().nonNullable(), + documentId: string().nonNullable(), + fileName: string().nonNullable() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + + +const userInviteSchema = object({ + firstName: string().max(255).nonNullable(), + lastName: string().max(255).nonNullable(), + email: string().max(255).nonNullable(), + edxActivationRoleCodes: array().of(string()), + edxUserExpiryDate: string().nullable().optional() +}).noUnknown(); + +const postDistrictUserInviteSchema = object({ + body: userInviteSchema.shape({ + districtName: string().nonNullable(), + districtCode: string().nullable().optional(), + districtID: string().nonNullable() + }).noUnknown(), + params: object().noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const postSchoolUserInviteSchema = object({ + body: userInviteSchema.shape({ + schoolName: string().nonNullable(), + schoolID: string().nonNullable() + }).noUnknown(), + params: object().noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const getUserActivationSchema = object({ + body: object().noUnknown(), + params: object({ + instituteType: string().oneOf(['SCHOOL', 'DISTRICT']), + instituteIdentifier: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const postUserActivationSchema = object({ + body: object({ + mincode: string().nonNullable(), + primaryEdxCode: string().nonNullable(), + personalActivationCode: string().nonNullable + }), + params: object().noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const postPrimaryUserActivationSchema = object({ + body: object({ + schoolID: string().nullable().optional(), + districtID: string().nullable().optional(), + }).concat(baseRequestSchema).noUnknown(), + params: object({ + instituteType: string(), + instituteIdentifier: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const postInstituteSelectionSchema = object({ + body: object({ + params: object(), + }).noUnknown(), + params: object().noUnknown(), + query: object().noUnknown(), +}).noUnknown(); + +const postDistrictSchoolSchema = object({ + body: object({ + params: object({ + districtID: string().nonNullable().optional(), + edxUserID: string().nonNullable().optional(), + expiryDate: string().nullable().optional(), + selectedRoles: array().of(string()) + }).noUnknown(), + }).noUnknown(), + params: object().noUnknown(), + query: object().noUnknown(), +}).noUnknown(); + +const postUserSchoolSchema = object({ + body: object({ + params: object({ + edxUserSchoolID: string().nonNullable().optional(), + edxUserID: string().nonNullable().optional(), + schoolID: string().nonNullable().optional(), + expiryDate: string().nullable().optional(), + selectedRoles: array().of(string()) + }).noUnknown(), + }).noUnknown(), + params: object().noUnknown(), + query: object().noUnknown(), +}).noUnknown(); + +const getUserSchoolSchema = object({ + body: object().noUnknown(), + params: object().noUnknown(), + query: object({ + permissionCode: string().nullable().optional() + }).noUnknown(), +}).noUnknown(); + +const getUserRoleSchema = object({ + body: object().noUnknown(), + params: object().noUnknown(), + query: object({ + instituteType: string().nullable().optional() + }).noUnknown(), +}).noUnknown(); + +const getUserSchema = object({ + body: object().noUnknown(), + params: object().noUnknown(), + query: object({ + digitalId: string().nullable().optional(), + schoolID: string().nullable().optional(), + firstName: string().nullable().optional(), + lastName: string().nullable().optional(), + districtID: string().nullable().optional() + }).noUnknown(), +}).noUnknown(); + +const getDistrictUsersSchema = object({ + body: object().noUnknown(), + params: object().noUnknown(), + query: object({ + districtID: string().nullable().optional() + }).noUnknown(), +}).noUnknown(); + +const userRelinkSchema = object({ + userToRelink: string().nonNullable(), + edxUserExpiryDate: string().nullable().optional(), +}); + +const districtUserIdSchema = object({ + districtID: string().nonNullable().optional(), + edxUserDistrictID: string().nonNullable().optional(), +}); + +const schoolUserIdSchema = object({ + schoolID: string().nonNullable().optional(), + userSchoolID: string().nonNullable().optional(), +}); + +const postUserRelinkSchema = object({ + body: object({ + params: userRelinkSchema.concat(districtUserIdSchema).concat(schoolUserIdSchema).noUnknown(), + }).noUnknown(), + params: object().noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const userRemoveSchema = object({ + userToRemove: string().nonNullable(), +}); + +const postUserRemoveSchema = object({ + body: object({ + params: userRemoveSchema.concat(districtUserIdSchema).concat(schoolUserIdSchema).noUnknown(), + }).noUnknown(), + params: object().noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +module.exports = { + exchangeSchema: postExchangeSchema, + exchangeDocumentSchema: postExchangeDocumentSchema, + exchangeStudentSchema: postExchangeStudentSchema, + exchangeCommentSchema: postExchangeCommentSchema, + deleteExchangeDocumentSchema, + deleteExchangeStudentSchema, + putExchangeMarkAsSchema, + getByExchangeIdSchema, + getExchangePaginatedSchema, + getExchangeCountSchema, + getExchangeDocumentSchema, + getDownloadExchangeDocumentSchema, + districtUserInviteSchema: postDistrictUserInviteSchema, + schoolUserInviteSchema: postSchoolUserInviteSchema, + getUserActivationSchema, + userActivationSchema: postUserActivationSchema, + primaryUserActivationSchema: postPrimaryUserActivationSchema, + instituteSelectionSchema: postInstituteSelectionSchema, + districtSchoolSchema: postDistrictSchoolSchema, + userSchoolSchema: postUserSchoolSchema, + getUserRoleSchema, + getUserSchema, + getDistrictUsersSchema, + getUserSchoolSchema, + userRelinkSchema: postUserRelinkSchema, + userRemoveSchema: postUserRemoveSchema +}; diff --git a/backend/src/validations/institute.js b/backend/src/validations/institute.js new file mode 100644 index 000000000..d196fcd1f --- /dev/null +++ b/backend/src/validations/institute.js @@ -0,0 +1,22 @@ +const { object, string, boolean } = require('yup'); + +const geAuthoritySchema = object({ + body: object(), + params: object({ + id: string(), + }), + query: object() +}).noUnknown(); + +const getActiveDataSchema = object({ + body: object().noUnknown(), + params: object().noUnknown(), + query: object({ + active: boolean().optional() + }).noUnknown() +}).noUnknown(); + +module.exports = { + geAuthoritySchema, + getActiveDataSchema +}; diff --git a/backend/src/validations/penServices.js b/backend/src/validations/penServices.js new file mode 100644 index 000000000..d9fe7535a --- /dev/null +++ b/backend/src/validations/penServices.js @@ -0,0 +1,17 @@ +const { object, string, boolean } = require('yup'); +const { newStudentSchema } = require('./student'); + +const postValidateStudentSchema = object({ + body: object({ + isInteractive: boolean().nullable().optional(), + transactionID: string().nullable().optional(), + }).concat(newStudentSchema), + params: object({ + sdcSchoolCollectionID: string() + }).noUnknown(), + query: object() +}).noUnknown(); + +module.exports = { + validateStudentSchema: postValidateStudentSchema +}; diff --git a/backend/src/validations/schools.js b/backend/src/validations/schools.js index 9a8602df8..f8a172519 100644 --- a/backend/src/validations/schools.js +++ b/backend/src/validations/schools.js @@ -1,6 +1,7 @@ -const { object, string, number, date, array} = require('yup'); +const { object, string, number, date, array, boolean } = require('yup'); +const { baseAddressSchema, baseContactSchema, baseRequestSchema } = require('./base'); -const getSchoolSchema = object({ +const getBySchoolIdSchema = object({ body: object().noUnknown(), params: object({ schoolID: string() @@ -9,31 +10,12 @@ const getSchoolSchema = object({ }).noUnknown(); const schoolContactSchema = object({ - alternatePhoneExtension: string().nullable(), - alternatePhoneNumber: string().nullable(), - createDate: date().nullable(), - createUser: string().nullable(), - effectiveDate: date(), - email: string().email().nullable(), - expiryDate: date().nullable(), - firstName: string().nullable(), - jobTitle: string().nullable(), - lastName: string(), - phoneExtension: string().nullable(), - phoneNumber: string().nullable(), - schoolContactId: string().nullable(), - schoolContactTypeCode: string(), + schoolContactTypeCode: string().max(10), schoolId: string(), - updateDate: date().nullable(), - updateUser: string().nullable(), -}).noUnknown(); + schoolContactId: string().nullable() +}).concat(baseContactSchema).concat(baseRequestSchema).noUnknown(); -const fundingGroupSchema = object({ - schoolFundingGroupCode: string().nullable(), - label: string().nullable(), - description: string().nullable(), - displayOrder: string().nullable() -}).noUnknown(); +const schoolAddressSchema = baseAddressSchema.concat(baseRequestSchema).noUnknown(); const postSchoolContactSchema = object({ body: schoolContactSchema, @@ -43,108 +25,116 @@ const postSchoolContactSchema = object({ query: object().noUnknown() }).noUnknown(); +const putSchoolContactSchema = object({ + body: schoolContactSchema.shape({ + schoolID: string() + }), + query: object().noUnknown(), + params: object().noUnknown() +}).noUnknown(); + +const deleteSchoolContactSchema = object({ + body: object().noUnknown(), + params: object({ + schoolID: string(), + contactID: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + const putSchoolSchema = object({ body: object({ - addresses: array().of(object({ - addressLine1: string(), - addressLine2: string().nullable(), - addressTypeCode: string(), - city: string(), - countryCode: string(), - createDate: date().nullable(), - createUser: string().nullable(), - postal: string(), - provinceCode: string(), - schoolAddressId: string().nullable(), - schoolId: string().nullable(), - updateDate: date().nullable(), - updateUser: string().nullable(), - }).noUnknown()), - canIssueCertificates: string().nullable(), - canIssueTranscripts: string().nullable(), + schoolId: string(), + districtId: string(), + mincode: string(), + independentAuthorityId: string().nullable(), + schoolNumber: number().positive().integer(), + faxNumber: string().max(10).nullable(), + phoneNumber: string().max(10).nullable(), + email: string().email().max(255).nullable(), + website: string().url().nullable().max(255), + schoolReportingRequirementCode: string().max(10).nonNullable(), + displayName: string().max(255).nonNullable(), + displayNameNoSpecialChars: string().max(255).nullable(), + schoolOrganizationCode: string().max(10).nonNullable(), + schoolCategoryCode: string().max(10).nonNullable(), + facilityTypeCode: string().max(10).nonNullable(), + openedDate: date(), closedDate: date().nullable(), + canIssueCertificates: boolean().nullable(), + canIssueTranscripts: boolean().nullable(), contacts: array().of(schoolContactSchema), - createDate: date(), - createUser: string(), - displayName: string(), - displayNameNoSpecialChars: string().nullable(), - districtId: string(), - email: string().email().nullable(), - facilityType: string(), - facilityTypeCode: string(), - faxNumber: string().nullable(), - grades: array().of(object({ - description: string(), - displayOrder: number().positive().integer(), - effectiveDate: date(), - expiryDate: date(), - label: string(), - schoolGradeCode: string(), + addresses: array().of(schoolAddressSchema.shape({ + schoolAddressId: string(), + schoolId: string() + }).noUnknown()), + notes: string().nullable(), + grades: array().of( + object({ + schoolGradeId: String(), + schoolId: string(), + schoolGradeCode: string().max(10).nonNullable(), + label: string(), + description: string(), + displayOrder: number().positive().integer(), + effectiveDate: date(), + expiryDate: date() + }).concat(baseRequestSchema).noUnknown()), + schoolFundingGroups: array().of(object({ + schoolFundingGroupCode: string().nullable(), + label: string().nullable(), + description: string().nullable(), + displayOrder: string().nullable() }).noUnknown()), - independentAuthorityId: string().nullable(), - mincode: string(), neighborhoodLearning: array().of(object({ description: string(), displayOrder: number().positive().integer(), effectiveDate: date(), expiryDate: date(), label: string(), - neighborhoodLearningTypeCode: string(), + neighborhoodLearningTypeCode: string().max(10).nonNullable() }).noUnknown()), - notes: string().nullable(), - openedDate: date(), - phoneNumber: string().nullable(), - schoolCategory: string(), - schoolCategoryCode: string(), - schoolFundingGroups: array().of(fundingGroupSchema), - schoolId: string(), schoolMove: array().of(object({ - createDate: date(), - createUser: string(), - fromSchoolId: string(), - moveDate: date(), + fromSchoolId: string().nonNullable(), + moveDate: date().nonNullable(), schoolMoveId: string(), - toSchoolId: string(), - updateDate: date(), - updateUser: string(), - }).noUnknown()), - schoolNumber: number().positive().integer(), - schoolOrganizationCode: string(), - schoolReportingRequirementCode: string(), - status: string(), - updateDate: date(), - updateUser: string(), - website: string().url().nullable() - }).noUnknown(), + toSchoolId: string().nonNullable() + }).concat(baseRequestSchema).noUnknown()), + facilityType: string(), + schoolCategory: string(), + status: string() + }).concat(baseRequestSchema).noUnknown(), params: object({ schoolID: string() }).noUnknown(), query: object().noUnknown() }).noUnknown(); -const schoolPaginatedSchema = object({ +const getSchoolPaginatedSchema = object({ body: object().noUnknown(), params: object().noUnknown(), query: object({ pageNumber: number().required().moreThan(-1).integer(), pageSize: number().required().positive().integer(), sort: object({ - schoolNumber: string().matches(/(ASC|DESC)/), - updateDate: string().matches(/(ASC|DESC)/) + schoolNumber: string().oneOf(['ASC','DESC']), + updateDate: string().oneOf(['ASC','DESC']) }).noUnknown(), searchParams: object({ status: string(), pubEarlyLearning: string(), schoolID: string(), districtID: string(), - type: string() + type: string(), }).noUnknown() }).noUnknown() }).noUnknown(); module.exports = { - getSchoolSchema, + getBySchoolIdSchema, putSchoolSchema, schoolContactSchema: postSchoolContactSchema, - schoolPaginatedSchema, + putSchoolContactSchema, + deleteSchoolContactSchema, + getSchoolPaginatedSchema, }; diff --git a/backend/src/validations/sdc.js b/backend/src/validations/sdc.js new file mode 100644 index 000000000..d7293be30 --- /dev/null +++ b/backend/src/validations/sdc.js @@ -0,0 +1,426 @@ +const { object, string, boolean, number, array } = require('yup'); +const {baseRequestSchema} = require('./base'); + +const baseQuerySchema = object({ + type: string().optional(), + compare: boolean().optional() +}); + +const baseStudentSchema = object({ + sdcSchoolCollectionStudentID: string().nullable().optional(), + sdcSchoolCollectionID: string().nonNullable(), + sdcDistrictCollectionID:string().nullable().optional(), + localID: string().max(12).nullable().optional(), + studentPen: string().max(9).nullable().optional(), + legalFirstName: string().max(255).nullable().optional(), + legalMiddleName: string().max(255).nullable().optional(), + legalLastName: string().max(255).nonNullable(), + usualFirstName: string().max(255).nullable().optional(), + usualMiddleName: string().max(255).nullable().optional(), + usualLastName: string().max(255).nullable().optional(), + dob: string().max(8).nonNullable(), + gender: string().max(1).nonNullable(), + postalCode: string().max(6).nullable().optional(), + sdcSchoolCollectionStudentStatusCode: string().max(10).nonNullable(), + enrolledGradeCode: string().max(10).nonNullable(), + schoolFundingCode: string().max(10).nullable().optional(), + careerProgramCode: string().max(10).nullable().optional(), + nativeAncestryInd: string().max(1).nonNullable(), + otherCourses: string().max(1).nullable().optional(), + supportBlocks: string().max(1).nullable().optional(), + numberOfCourses: string().nullable().optional() +}); + +const baseSdcSchoolStudent = baseStudentSchema.shape({ + enrolledProgramCodes: string().max(16).nullable().optional(), + numberOfCoursesDec: number().nullable().optional(), + schoolID: string().nullable().optional(), + bandCode:string().max(4).nullable().optional(), + isAdult: string().nullable().optional(), + isSchoolAged: string().nullable().optional(), + fte: number().nullable().optional(), + fteZeroReasonCode: string().max(10).nullable().optional(), + frenchProgramNonEligReasonCode:string().max(10).nullable().optional(), + ellNonEligReasonCode:string().max(10).nullable().optional(), + indigenousSupportProgramNonEligReasonCode:string().max(10).nullable().optional(), + careerProgramNonEligReasonCode:string().max(10).nullable().optional(), + specialEducationNonEligReasonCode: string().max(10).nullable().optional(), + specialEducationCategoryCode: string().max(10).nullable().optional(), + homeLanguageSpokenCode: string().max(10).nullable().optional(), + isGraduated: string().nullable().optional(), + assignedStudentId: string().nullable().optional(), + assignedPen: string().max(10).nullable().optional(), + penMatchResult: string().nullable().optional(), + yearsInEll: string().nullable().optional(), + mappedSpedCode: string().nullable().optional(), + mappedAncestryIndicator: string().nullable().optional(), + mappedFrenchEnrolledProgram: string().nullable().optional(), + mappedEllEnrolledProgram: string().nullable().optional(), + mappedLanguageEnrolledProgram: string().nullable().optional(), + mappedCareerProgram: string().nullable().optional(), + mappedIndigenousEnrolledProgram: string().nullable().optional(), + fundingEligibleRefugee: string().nullable().optional(), + mappedBandCode: string().nullable().optional(), + mappedCareerProgramCode: string().nullable().optional(), + mappedSchoolFunding: string().nullable().optional(), + indProgramEligible: string().nullable().optional(), + frenchProgramEligible: string().nullable().optional(), + ellProgramEligible: string().nullable().optional(), + careerProgramEligible: string().nullable().optional(), + spedProgramEligible: string().nullable().optional(), + mappedNoOfCourses: string().nullable().optional(), + mappedHomelanguageCode: string().nullable().optional(), + sdcSchoolCollectionStudentValidationIssues: array().of(object({ + sdcSchoolCollectionStudentValidationIssueID:string().nullable().optional(), + sdcSchoolCollectionStudentID:string().nullable().optional(), + })).nullable().optional(), + sdcSchoolCollectionStudentEnrolledPrograms: array().of(object({ + sdcSchoolCollectionStudentEnrolledProgramID:string().nullable().optional(), + sdcSchoolCollectionStudentID:string().nullable().optional(), + enrolledProgramCode: string().nullable().optional(), + })).nullable().optional(), + schoolName: string().nullable().optional() +}); + +const baseSubmissionSignatureSchema = object({ + sdcDistrictSubmissionSignatureID: string().nullable().optional(), + sdcDistrictCollectionID: string().nullable().optional(), + districtSignatoryUserID:string().nullable().optional(), + districtSignatoryRole:string().nullable().optional(), + signatureDate:string().nullable().optional(), +}).concat(baseRequestSchema); + +const baseDistrictCollectionSchema = object({ + sdcDistrictCollectionID: string().nullable().optional(), + collectionID: string().nullable().optional(), + districtID:string().nullable().optional(), + collectionTypeCode:string().max(10).nullable().optional(), + sdcDistrictCollectionStatusCode:string().max(10).nullable().optional(), + collectionOpenDate:string().nullable().optional(), + collectionCloseDate:string().nullable().optional(), + submissionDueDate:string().nullable().optional(), + duplicationResolutionDueDate:string().nullable().optional(), + signOffDueDate:string().nullable().optional(), + submissionSignatures: array().of(baseSubmissionSignatureSchema) +}).concat(baseRequestSchema); + +const baseSignature = object({ + districtSignatoryRole: string().nonNullable(), + districtSignatoryUserID: string().nullable().optional(), +}).noUnknown(); + +const putDistrictCollectionSchema = object({ + body: object({ + districtCollection: baseDistrictCollectionSchema, + status:string().nullable().optional(), + }).concat(baseRequestSchema).noUnknown(), + params: object({ + sdcDistrictCollectionID: string().nonNullable() + }).noUnknown(), + query: object().noUnknown(), +}).noUnknown(); + +const putSchoolCollectionSchema = object({ + body: object({ + sdcSchoolCollectionID: string().nonNullable(), + collectionID: string().nonNullable(), + schoolID: string().nonNullable(), + sdcDistrictCollectionID: string().nullable().optional(), + uploadDate: string().nullable().optional(), + uploadFileName: string().max(255).nullable().optional(), + uploadReportDate: string().max(8).nullable().optional(), + collectionTypeCode: string().max(10).nullable().optional(), + sdcSchoolCollectionStatusCode: string().max(10).nonNullable().optional(), + collectionOpenDate: string().nullable().optional(), + collectionCloseDate: string().nullable().optional(), + students: array().of(baseStudentSchema.shape({ + enrolledProgramCodes: array().of(string()), + filteredEnrolledProgramCodes: array().of(string()) + })), + status: string().nullable().optional() + }), + params: object({ + sdcSchoolCollectionID: string() + }).noUnknown(), + query: object().noUnknown(), +}).noUnknown(); + +const postSdcDistrictSignoffSchema = object({ + body: baseSignature.concat(baseRequestSchema).noUnknown(), + params: object({ + sdcDistrictCollectionID: string(), + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const putSdcStudentSchema = object({ + body: baseStudentSchema.shape({ + enrolledProgramCodes: array().of(string()), + filteredEnrolledProgramCodes: array().of(string()) + }), + params: object({ + districtID: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const getActiveDataSchema = object({ + body: object().noUnknown(), + params: object().noUnknown(), + query: object({ + active: boolean() + }).noUnknown(), +}).noUnknown(); + +const getByDistrictIdSchema = object({ + body: object().noUnknown(), + params: object({ + districtID: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const getBySchoolIdSchema = object({ + body: object().noUnknown(), + params: object({ + schoolID: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const getBySdcDistrictCollectionSchema = object({ + body: object().noUnknown(), + params: object({ + sdcDistrictCollectionID: string() + }), + query: baseQuerySchema +}).noUnknown(); + +const getBySdcSchoolCollectionSchema = object({ + body: object().noUnknown(), + params: object({ + sdcSchoolCollectionID: string() + }).noUnknown(), + query: baseQuerySchema +}).noUnknown(); + +const getBySdcSchoolCollectionStudentSchema = object({ + body: object().noUnknown(), + params: object({ + sdcSchoolCollectionStudentID: string(), + }).noUnknown(), + query: baseQuerySchema +}).noUnknown(); + +const getBySdcDistrictCollectionPaginatedSchema = object({ + body: object().noUnknown(), + params: object({ + sdcDistrictCollectionID: string() + }), + query: object({ + tableFormat:boolean().optional(), + pageNumber: number().moreThan(-1).integer().optional(), + pageSize: number().positive().integer().optional(), + sort: object().optional(), + searchParams: object().optional() + }) +}).noUnknown(); + +const getBySdcSchoolCollectionPaginatedSchema = object({ + body: object().noUnknown(), + params: object({ + sdcSchoolCollectionID: string() + }), + query: object({ + tableFormat:boolean().optional(), + pageNumber: number().moreThan(-1).integer().optional(), + pageSize: number().positive().integer().optional(), + sort: object().optional(), + searchParams: object().optional() + }) +}).noUnknown(); + +const getPenMatchSchema = object({ + body: object({ + localID: string().max(12).nullable().optional(), + givenName: string().max(255).nullable().optional(), + middleName: string().max(255).nullable().optional(), + surname: string().max(255).nullable().optional(), + usualGivenName: string().max(255).nullable().optional(), + usualMiddleName: string().max(255).nullable().optional(), + usualSurname: string().max(255).nullable().optional(), + dob: string().max(8).nullable().optional(), + postal: string().max(6).nullable().optional(), + pen:string().max(9).nullable().optional(), + enrolledGradeCode:string().max(10).nullable().optional(), + sex: string().max(1).nullable().optional() + }), + params: object({ + sdcSchoolCollectionID: string() + }), + query: object() +}).noUnknown(); + +const getSchoolHistoricPaginatedSchema = object({ + body: object().noUnknown(), + params: object({ + schoolID: string() + }), + query: object({ + tableFormat:boolean().optional(), + pageNumber: number().required().moreThan(-1).integer(), + pageSize: number().required().positive().integer(), + sort: object(), + searchParams: object() + }) +}).noUnknown(); + +const getDistrictHistoricPaginatedSchema = object({ + body: object().noUnknown(), + params: object({ + districtID: string() + }), + query: object({ + tableFormat:boolean().optional(), + pageNumber: number().required().moreThan(-1).integer(), + pageSize: number().required().positive().integer(), + sort: object(), + searchParams: object() + }) +}).noUnknown(); + +const getSchoolReportDownloadSchema = object({ + body: object().noUnknown(), + params: object({ + sdcSchoolCollectionID: string().nonNullable(), + reportTypeCode: string().nonNullable() + }), + query: object() +}).noUnknown(); + +const getDistrictReportDownloadSchema = object({ + body: object().noUnknown(), + params: object({ + sdcDistrictCollectionID: string().nonNullable(), + reportTypeCode: string().nonNullable() + }), + query: object() +}).noUnknown(); + + + +const unsubmitCollectionSchema = object({ + body: object({ + sdcSchoolCollectionID: string().nonNullable(), + updateUser: string() + }).concat(baseRequestSchema).noUnknown(), + params: object({ + sdcSchoolCollectionID: string(), + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const zeroEnrollmentSchema = object({ + body: object({ + sdcSchoolCollectionID: string().nonNullable(), + updateUser: string() + }).noUnknown(), + params: object({ + sdcSchoolCollectionID: string() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const postRemoveStudentFromSchoolCollectionSchema = object({ + body:array().of(string()).nonNullable(), + params: object({ + sdcSchoolCollectionID: string().nonNullable() + }).noUnknown(), + query: object().noUnknown() +}).noUnknown(); + +const postDistrictFileCollectionSchema = object({ + body:object({ + fileName: string().nonNullable(), + fileContents: string().nonNullable() + }).concat(baseRequestSchema).noUnknown(), + params: object({ + sdcDistrictCollectionID: string().nonNullable() + }).noUnknown(), + query: object().noUnknown(), +}).noUnknown(); + +const postSchoolFileCollectionSchema = object({ + body:object({ + fileName: string().nonNullable(), + fileContents: string().nonNullable() + }).concat(baseRequestSchema).noUnknown(), + params: object({ + sdcSchoolCollectionID: string().nonNullable() + }).noUnknown(), + query: object().noUnknown(), +}).noUnknown(); + +const postResolveDuplicateSchema = object({ + body: object({ + students: array().of(baseSdcSchoolStudent), + duplicate: object() //Marked as object to support dynamic naming + }).concat(baseRequestSchema), + params: object({ + sdcDuplicateID: string().nonNullable(), + type: string().nonNullable() + }), + query: object(), +}).unknown(); + +const postMarKDiffSchema = object({ + body: baseSdcSchoolStudent.shape({ + legalMiddleNames: string().max(25).nullable().optional(), + usualMiddleNames: string().max(25).nullable().optional() + }).concat(baseRequestSchema), + params: object({ + sdcDuplicateID: string().nonNullable(), + type: string().nonNullable() + }), + query: object(), +}).unknown(); + +const postStartFromPriorCollectionSchema = object({ + body: baseSdcSchoolStudent.shape({ + updateUser: string(), + sdcSchoolCollectionID: string().nonNullable(), + }).concat(baseRequestSchema), + params: object({ + sdcSchoolCollectionID: string().nonNullable() + }), + query: object(), +}).unknown(); + + +module.exports = { + putSdcStudentSchema, + putDistrictCollectionSchema, + putSchoolCollectionSchema, + getActiveDataSchema, + getByDistrictIdSchema, + getBySchoolIdSchema, + getBySdcDistrictCollectionSchema, + getBySdcSchoolCollectionSchema, + getBySdcSchoolCollectionStudentSchema, + getBySdcDistrictCollectionPaginatedSchema, + getBySdcSchoolCollectionPaginatedSchema, + getPenMatchSchema, + getSchoolHistoricPaginatedSchema, + getDistrictHistoricPaginatedSchema, + getSchoolReportDownloadSchema, + getDistrictReportDownloadSchema, + unsubmitCollectionSchema, + zeroEnrollmentSchema, + removeStudentFromSchoolCollectionSchema: postRemoveStudentFromSchoolCollectionSchema, + districtSignoffSchema: postSdcDistrictSignoffSchema, + districtFileCollectionSchema: postDistrictFileCollectionSchema, + schoolFileCollectionSchema: postSchoolFileCollectionSchema, + resolveDuplicateSchema: postResolveDuplicateSchema, + markDiffSchema: postMarKDiffSchema, + startFromPriorCollectionSchema: postStartFromPriorCollectionSchema +}; diff --git a/backend/src/validations/student.js b/backend/src/validations/student.js new file mode 100644 index 000000000..e018dcf84 --- /dev/null +++ b/backend/src/validations/student.js @@ -0,0 +1,39 @@ +const { object, string } = require('yup'); +const { baseRequestSchema } = require('./base'); + +const postNewStudentSchema = object({ + body: object({ + pen:string().max(9).nonNullable().optional(), + legalFirstName: string().max(25).nonNullable().optional(), + legalMiddleNames: string().max(25).nullable().optional(), + legalLastName: string().max(25).nonNullable().optional(), + dob: string().nonNullable().optional(), + sexCode: string().nonNullable().optional(), + genderCode: string().nullable().optional(), + usualFirstName: string().max(25).nullable().optional(), + usualMiddleNames: string().max(25).nullable().optional(), + usualLastName: string().max(25).nullable().optional(), + email: string().max(80).nullable().optional(), + emailVerified: string().oneOf(['Y','N']).nullable().optional(), + deceasedDate: string().nullable().optional(), + postalCode: string().max(7).nullable().optional(), + mincode: string().max(8).nullable().optional(), + localID: string().max(12).nullable().optional(), + gradeCode: string().max(2).nullable().optional(), + gradeYear: string().max(4).nullable().optional(), + demogCode: string().max(1).nonNullable().optional(), + statusCode: string().max(1).nonNullable().optional(), + memo: string().max(4000).nullable().optional(), + trueStudentID: string().nullable().optional(), + documentTypeCode: string().nullable().optional(), + dateOfConfirmation: string().nullable().optional() + }).concat(baseRequestSchema), + params: object({ + sdcSchoolCollectionID: string() + }).noUnknown(), + query: object() +}).noUnknown(); + +module.exports = { + newStudentSchema: postNewStudentSchema +};