From 65ddc24aeccb4fca574dbd968b4195f8931f67c6 Mon Sep 17 00:00:00 2001 From: princegupta1131 <114015020+princegupta1131@users.noreply.github.com> Date: Wed, 17 Sep 2025 21:16:59 +0530 Subject: [PATCH 1/5] upsmf-update-department based on new role & regType --- .gitignore | 3 +- src/publicApi_v8/upsmfUser.ts | 225 +++++++++++++++++++++++++++------- src/utils/upsmfUtils.ts | 68 ++++++++++ 3 files changed, 248 insertions(+), 48 deletions(-) create mode 100644 src/utils/upsmfUtils.ts diff --git a/.gitignore b/.gitignore index 4f7a19b9..9c9fc693 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,5 @@ coverage # System Files .DS_Store Thumbs.db -/nodemon/nodemon-aastar-dev.json \ No newline at end of file +/nodemon/nodemon-aastar-dev.json +/src/keys \ No newline at end of file diff --git a/src/publicApi_v8/upsmfUser.ts b/src/publicApi_v8/upsmfUser.ts index 78053921..17addc81 100644 --- a/src/publicApi_v8/upsmfUser.ts +++ b/src/publicApi_v8/upsmfUser.ts @@ -7,6 +7,7 @@ import { v4 as uuidv4 } from 'uuid' import { CONSTANTS } from '../utils/env' import { logError } from '../utils/logger' import { logInfo } from '../utils/logger' +import { getDetailsAsPerRole, validRootOrgs } from '../utils/upsmfUtils' export const upsmfUserCreation = express.Router() const { types } = cassandra @@ -22,8 +23,18 @@ interface UserDetails { lastName: string phone: number upsmfRegistrationNumber?: string + serviceType?: string + facilityName?: { + code?: string, + name: string, + } + privateFacilityType?: string + publicFacilityType?: string + nin?: string + block?: string + ehrmsNumber?: string // tslint:disable-next-line: all - role: 'Student' | 'Faculty', + role: 'Student' | 'Faculty' | 'ANM-UP', } const client = new cassandra.Client({ @@ -48,6 +59,10 @@ const serviceSchemaJoi = Joi.object({ // tslint:disable-next-line: all 'any.required': 'District is required', }), + dob: Joi.date().required().messages({ + 'any.required': 'Date of Birth is required', + 'date.base': 'Date of Birth must be a valid date', + }), email: Joi.string().allow('', null).email().optional(), facultyType: Joi.string() .when('role', { @@ -107,14 +122,50 @@ const serviceSchemaJoi = Joi.object({ 'number.positive': 'Phone number must be a positive integer', }), role: Joi.string() - .valid('Student', 'Faculty') + .valid('Student', 'Faculty', 'ANM-UP') .required() .messages({ // tslint:disable-next-line: all - 'any.only': 'Role must be either Student, Faculty', + 'any.only': 'Role must be either Student, Faculty, or ANM-UP', 'any.required': 'Role is required', }), upsmfRegistrationNumber: Joi.string().allow('', null).optional(), + // ✅ Newly Added Fields + + nursingRegistrationNumber: Joi.string().optional().messages({ + 'any.required': 'Nursing Registration Number is required', + }), + + employmentType: Joi.string().allow('', null).optional(), + + serviceType: Joi.string() + .valid('Regular', 'Contractual', 'Private') + .required() + .messages({ + 'any.only': 'Service type must be Regular, Contractual, or Private', + 'any.required': 'Service type is required', + }), + + ehrmsNumber: Joi.string() + .pattern(/^\d{5,8}$/) + .required() + .messages({ + 'any.required': 'EHRMS Number is required', + 'string.pattern.base': 'EHRMS Number must be 5–8 digits', + }), + + block: Joi.string().optional().messages({ + 'any.required': 'Block is required', + }), + + facilityType: Joi.string().optional().messages({ + 'any.required': 'Facility type is required', + }), + + facilityName: Joi.object().optional().messages({ + 'any.required': 'Facility name is required', + }), + }) const API_END_POINTS = { assignRole: `${CONSTANTS.HTTPS_HOST}/api/user/private/v1/assign/role`, @@ -134,39 +185,7 @@ const getUserDesignationFromRole = { Student: 'ANM-Student-UP', } -const getDetailsAsPerRole = (userDetails: UserDetails) => { - let designation: string - let orgId: string - let orgName: string - - switch (userDetails.role) { - case 'Student': - // tslint:disable-next-line: all - designation = 'ANM-Student-UP' - orgId = '0138708679576535041037' - // tslint:disable-next-line: all - orgName = 'Department of Medical Education Education and Training' - break - case 'Faculty': - designation = 'ANM-Faculty-UP' - orgId = '0138708679576535041037' - orgName = 'Department of Medical Education Education and Training' - break - default: - designation = 'NA' - orgId = 'NA' - orgName = 'NA' - break - } - return { - designation, - orgId, - orgName, - } -} - const standardDob = '01/01/1970' -const upsmfOrgName = 'Department of Medical Education Education and Training' const accessDeniedMessage = 'Access denied! Please contact admin at help.ekshamata@gmail.com for support.' // tslint:disable-next-line: all const userSuccessRegistrationMessage = `Registration Successful! Kindly download e-Kshamata app - https://bit.ly/E-kshamataApp and login using your given mobile number using OTP.`; @@ -184,6 +203,7 @@ const msg91Headers = { upsmfUserCreation.post('/createUser', async (req: Request, res: Response) => { const userJourneyStatus = { createAccount: 'failed', + isUserMigrated: false, profileUpdate: 'failed', registrationSuccessMessage: 'failed', roleAssign: 'failed', @@ -212,8 +232,25 @@ upsmfUserCreation.post('/createUser', async (req: Request, res: Response) => { if (isUserExists.message === 'success' && isUserExists.userDetails) { userJourneyStatus.userAlreadyExists = true // tslint:disable-next-line: all - if (isUserExists.userDetails.rootOrgName == 'Department of Medical Education Education and Training') { - userJourneyStatus.userExistingOrganisation = 'Bihar Nursing Registration Council || Health (Bihar) || Private (Bihar)' + // if (isUserExists.userDetails.rootOrgName == 'Department of Medical Education Education and Training') { + // userJourneyStatus.userExistingOrganisation = 'Bihar Nursing Registration Council || Health (Bihar) || Private (Bihar)' + // await updateUserStatusInDatabase(userFormDetails, userJourneyStatus) + // return res.status(200).json({ + // message: userSuccessRegistrationMessage, + // status: 'SUCCESS', + // }) + // } + if (validRootOrgs.includes(isUserExists.userDetails.rootOrgName)) { + userJourneyStatus.userExistingOrganisation = isUserExists.userDetails.rootOrgName + const newUserOrg = getDetailsAsPerRole(userFormDetails).orgName + if (isUserExists.userDetails.rootOrgName !== newUserOrg) { + await migrateUserToUpsmf(isUserExists.userDetails, userFormDetails) + const roleAssignResponse = await assignRoleToUser(isUserExists.userDetails.id, userFormDetails) + userJourneyStatus.roleAssign = roleAssignResponse ? 'success' : 'failed' + userJourneyStatus.isUserMigrated = true + } + const profileUpdateResponse = await userProfileUpdate(userFormDetails, isUserExists.userDetails.id) + userJourneyStatus.profileUpdate = profileUpdateResponse ? 'success' : 'failed' await updateUserStatusInDatabase(userFormDetails, userJourneyStatus) return res.status(200).json({ message: userSuccessRegistrationMessage, @@ -529,18 +566,28 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { }, professionalDetails: [ { + block: user?.block || '', completePostalAddress: '', designation: 'ANM-Student-UP', doj: '', + ehrmsCode: user?.ehrmsNumber || '', + facilityCode: user?.facilityName?.code || '', + facilityName: user?.facilityName?.name || '', facultyType: '', hrmsId: '', - name: upsmfOrgName, + instituteName: '', + instituteType: '', + name: getDetailsAsPerRole(user).orgName, nameOther: '', + nin: user.nin || '', orgType: 'Government', + privateFacilityType: user?.privateFacilityType || '', profession: 'Nurse', professionOtherSpecify: '', + publicFacilityType: '', qualification: '', - upsmfRegistrationNumber: '', + serviceType: user?.serviceType || '', + upsmfRegistrationNumber: user?.upsmfRegistrationNumber, }, ], userId, @@ -580,19 +627,30 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { }, professionalDetails: [ { + block: user?.block || '', completePostalAddress: '', designation: 'ANM-Student-UP', doj: '', + ehrmsCode: user?.ehrmsNumber || '', + facilityCode: user?.facilityName?.code || '', + facilityName: user?.facilityName?.name || '', facultyType: '', hrmsId: user.hrmsId, - name: upsmfOrgName, + instituteName: user?.instituteName || '', + instituteType: user?.instituteType || '', + name: getDetailsAsPerRole(user).orgName, nameOther: '', + nin: user.nin || '', orgType: 'Government', + privateFacilityType: user?.privateFacilityType || '', profession: 'Student', professionOtherSpecify: '', - qualification: user.courseSelection, - upsmfRegistrationNumber: user.upsmfRegistrationNumber, + publicFacilityType: '', + qualification: user?.courseSelection, + serviceType: user?.serviceType || '', + upsmfRegistrationNumber: user?.upsmfRegistrationNumber, }, + ], userId, }, @@ -633,18 +691,28 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { }, professionalDetails: [ { + block: user?.block || '', completePostalAddress: '', designation: 'ANM-Faculty-UP', doj: '', - facultyType: user.facultyType, + ehrmsCode: user?.ehrmsNumber || '', + facilityCode: user?.facilityName?.code || '', + facilityName: user?.facilityName?.name || '', + facultyType: user?.facultyType, hrmsId: user.hrmsId, - name: user.instituteName, + instituteName: user?.instituteName || '', + instituteType: user?.instituteType || '', + name: getDetailsAsPerRole(user).orgName, nameOther: '', - orgType: user.instituteType, + nin: user.nin || '', + orgType: 'Government', + privateFacilityType: '', profession: 'Faculty', professionOtherSpecify: '', + publicFacilityType: '', qualification: user.courseSelection, - upsmfRegistrationNumber: user.upsmfRegistrationNumber, + serviceType: user?.serviceType || '', + upsmfRegistrationNumber: user?.upsmfRegistrationNumber, }, ], userId: `${userId}`, @@ -654,6 +722,69 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { }, } } + if (user.role == 'ANM-UP') { + userProfileUpdateData = { + request: { + profileDetails: { + preferences: { + language: 'hi', + }, + profileReq: { + academics: [ + { + nameOfInstitute: user.instituteName, + nameOfQualification: user.courseSelection, + type: user.instituteType, + yearOfPassing: '', + }, + ], + id: userId, + personalDetails: { + dob: standardDob, + email: user.email, + firstname: user.firstName, + gender: '', + knownLanguages: [], + mobile: JSON.stringify(user.phone), + postalAddress: `India, Uttar Pradesh, ${user.district}`, + regNurseRegMidwifeNumber: 'NA', + registrationSource, + surname: user.lastName || user.firstName, + }, + professionalDetails: [ + { + block: user?.block || '', + completePostalAddress: '', + designation: getDetailsAsPerRole(user).designation, + doj: '', + ehrmsCode: user?.ehrmsNumber || '', + facilityCode: user?.facilityName?.code || '', + facilityName: user?.facilityName?.name || '', + facultyType: user?.facultyType || '', + hrmsId: user?.hrmsId, + instituteName: '', + instituteType: '', + name: getDetailsAsPerRole(user).orgName, + nameOther: '', + nin: user?.nin || '', + orgType: 'Government', + privateFacilityType: user?.privateFacilityType || '', + profession: 'ANM-UP', + professionOtherSpecify: '', + publicFacilityType: user?.publicFacilityType || '', + qualification: '', + serviceType: user?.serviceType || '', + upsmfRegistrationNumber: user?.upsmfRegistrationNumber, + }, + + ], + userId, + }, + }, + userId, + }, + } + } await axios({ data: userProfileUpdateData, headers: { @@ -741,7 +872,7 @@ const migrateUserToUpsmf = async (userDetails, userFormDetails) => { try { const migrateUserData = { request: { - channel: upsmfOrgName, + channel: getDetailsAsPerRole(userFormDetails).orgName, forceMigration: true, notifyMigration: false, softDeleteOldOrg: true, diff --git a/src/utils/upsmfUtils.ts b/src/utils/upsmfUtils.ts new file mode 100644 index 00000000..0c186de9 --- /dev/null +++ b/src/utils/upsmfUtils.ts @@ -0,0 +1,68 @@ + +interface UserDetails { + role: string + serviceType?: string +} + +export const getDetailsAsPerRole = (userDetails: UserDetails) => { + const DOMEET = 'Department of Medical Education Education and Training' + const DOMEET_ORG_ID = '0138708679576535041037' + switch (userDetails?.role) { + case 'Student': + return { + designation: 'ANM-Student-UP', + orgId: DOMEET_ORG_ID, + orgName: DOMEET, + } + + case 'Faculty': + return { + designation: 'ANM-Faculty-UP', + orgId: DOMEET_ORG_ID, + orgName: DOMEET, + } + + case 'ANM-UP': + // tslint:disable-next-line: all + switch (userDetails?.serviceType) { + case 'Regular': + return { + designation: 'ANM-UP', + orgId: '01400948801286144024329', + orgName: 'Department of Medical Health & Family Welfare (Uttar Pradesh)', + } + case 'Contractual': + return { + designation: 'ANM-UP', + orgId: '0144024313254133763751', + orgName: 'National Health Mission (Uttar Pradesh)', + } + case 'Private': + return { + designation: 'ANM-UP', + orgId: '0144024277797191683752', + orgName: 'Private (Uttar Pradesh)', + } + default: + return { + designation: 'ANM-UP', + orgId: 'NA', + orgName: 'Unknown Service Type', + } + } + default: + return { + designation: 'NA', + orgId: 'NA', + orgName: 'NA', + } + } +} + +export const validRootOrgs = [ + 'National Health Mission (UP)', + 'Department of Medical Education Education and Training', + 'Directorate of Medical Health (UP)', + 'UP State Ministry of Health and Family Welfare', + 'State Institute of Health and Family Welfare, Department of Health & Family Welfare, UP', +] From 0f3ac5b1cf6d60a612c4ebb95ea1107772a5268b Mon Sep 17 00:00:00 2001 From: princegupta1131 <114015020+princegupta1131@users.noreply.github.com> Date: Thu, 18 Sep 2025 10:26:21 +0530 Subject: [PATCH 2/5] added the req mapping for upsmf api --- src/publicApi_v8/upsmfUser.ts | 60 ++++++++++++++++------------------- src/utils/upsmfUtils.ts | 5 +++ 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/publicApi_v8/upsmfUser.ts b/src/publicApi_v8/upsmfUser.ts index 17addc81..0d2b2b83 100644 --- a/src/publicApi_v8/upsmfUser.ts +++ b/src/publicApi_v8/upsmfUser.ts @@ -28,13 +28,14 @@ interface UserDetails { code?: string, name: string, } - privateFacilityType?: string - publicFacilityType?: string - nin?: string block?: string ehrmsNumber?: string // tslint:disable-next-line: all role: 'Student' | 'Faculty' | 'ANM-UP', + regNurseRegMidwifeNumber?: string + employmentType?: string + dob?: string + facilityType?: string } const client = new cassandra.Client({ @@ -80,7 +81,6 @@ const serviceSchemaJoi = Joi.object({ // tslint:disable-next-line: all 'any.required': 'First name is required', }), - hrmsId: Joi.string().allow('', null).optional(), instituteName: Joi.string() .when('role', { @@ -146,7 +146,7 @@ const serviceSchemaJoi = Joi.object({ 'any.required': 'Service type is required', }), - ehrmsNumber: Joi.string() + hrmsId: Joi.string() .pattern(/^\d{5,8}$/) .required() .messages({ @@ -165,6 +165,12 @@ const serviceSchemaJoi = Joi.object({ facilityName: Joi.object().optional().messages({ 'any.required': 'Facility name is required', }), + regNurseRegMidwifeNumber: Joi.string().optional().messages({ + 'any.required': 'RNRM Number is required', + }), + roleForInService: Joi.string().optional().messages({ + 'any.required': 'Role for In-Service is required', + }), }) const API_END_POINTS = { @@ -570,24 +576,21 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { completePostalAddress: '', designation: 'ANM-Student-UP', doj: '', - ehrmsCode: user?.ehrmsNumber || '', - facilityCode: user?.facilityName?.code || '', - facilityName: user?.facilityName?.name || '', + facilityCode: '', + facilityName: '', + facilityType: '', facultyType: '', hrmsId: '', instituteName: '', instituteType: '', name: getDetailsAsPerRole(user).orgName, nameOther: '', - nin: user.nin || '', orgType: 'Government', - privateFacilityType: user?.privateFacilityType || '', profession: 'Nurse', professionOtherSpecify: '', - publicFacilityType: '', qualification: '', serviceType: user?.serviceType || '', - upsmfRegistrationNumber: user?.upsmfRegistrationNumber, + upsmfRegistrationNumber: '', }, ], userId, @@ -614,14 +617,14 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { ], id: userId, personalDetails: { - dob: standardDob, + dob: user?.dob, email: user.email, firstname: user.firstName, gender: '', knownLanguages: [], mobile: JSON.stringify(user.phone), postalAddress: `India, Uttar Pradesh, ${user.district}`, - regNurseRegMidwifeNumber: 'NA', + regNurseRegMidwifeNumber: user?.regNurseRegMidwifeNumber || 'NA', registrationSource, surname: user.lastName || user.firstName, }, @@ -631,21 +634,18 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { completePostalAddress: '', designation: 'ANM-Student-UP', doj: '', - ehrmsCode: user?.ehrmsNumber || '', facilityCode: user?.facilityName?.code || '', facilityName: user?.facilityName?.name || '', + facilityType: user?.facilityType || '', facultyType: '', - hrmsId: user.hrmsId, + hrmsId: user?.hrmsId, instituteName: user?.instituteName || '', instituteType: user?.instituteType || '', name: getDetailsAsPerRole(user).orgName, nameOther: '', - nin: user.nin || '', orgType: 'Government', - privateFacilityType: user?.privateFacilityType || '', profession: 'Student', professionOtherSpecify: '', - publicFacilityType: '', qualification: user?.courseSelection, serviceType: user?.serviceType || '', upsmfRegistrationNumber: user?.upsmfRegistrationNumber, @@ -677,14 +677,14 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { ], id: `${userId}`, personalDetails: { - dob: standardDob, + dob: user?.dob, email: user.email, firstname: user.firstName, gender: '', knownLanguages: [], mobile: JSON.stringify(user.phone), postalAddress: `India, Uttar Pradesh, ${user.district}`, - regNurseRegMidwifeNumber: 'NA', + regNurseRegMidwifeNumber: user?.regNurseRegMidwifeNumber || 'NA', registrationSource, surname: user.lastName || user.firstName, @@ -695,21 +695,18 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { completePostalAddress: '', designation: 'ANM-Faculty-UP', doj: '', - ehrmsCode: user?.ehrmsNumber || '', facilityCode: user?.facilityName?.code || '', facilityName: user?.facilityName?.name || '', + facilityType: user?.facilityType || '', facultyType: user?.facultyType, - hrmsId: user.hrmsId, + hrmsId: user?.hrmsId || '', instituteName: user?.instituteName || '', instituteType: user?.instituteType || '', name: getDetailsAsPerRole(user).orgName, nameOther: '', - nin: user.nin || '', orgType: 'Government', - privateFacilityType: '', profession: 'Faculty', professionOtherSpecify: '', - publicFacilityType: '', qualification: user.courseSelection, serviceType: user?.serviceType || '', upsmfRegistrationNumber: user?.upsmfRegistrationNumber, @@ -740,14 +737,14 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { ], id: userId, personalDetails: { - dob: standardDob, + dob: user?.dob, email: user.email, firstname: user.firstName, gender: '', knownLanguages: [], mobile: JSON.stringify(user.phone), postalAddress: `India, Uttar Pradesh, ${user.district}`, - regNurseRegMidwifeNumber: 'NA', + regNurseRegMidwifeNumber: user?.regNurseRegMidwifeNumber || 'NA', registrationSource, surname: user.lastName || user.firstName, }, @@ -757,21 +754,18 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { completePostalAddress: '', designation: getDetailsAsPerRole(user).designation, doj: '', - ehrmsCode: user?.ehrmsNumber || '', facilityCode: user?.facilityName?.code || '', facilityName: user?.facilityName?.name || '', + facilityType: user?.facilityType || '', facultyType: user?.facultyType || '', - hrmsId: user?.hrmsId, + hrmsId: user?.hrmsId || '', instituteName: '', instituteType: '', name: getDetailsAsPerRole(user).orgName, nameOther: '', - nin: user?.nin || '', orgType: 'Government', - privateFacilityType: user?.privateFacilityType || '', profession: 'ANM-UP', professionOtherSpecify: '', - publicFacilityType: user?.publicFacilityType || '', qualification: '', serviceType: user?.serviceType || '', upsmfRegistrationNumber: user?.upsmfRegistrationNumber, diff --git a/src/utils/upsmfUtils.ts b/src/utils/upsmfUtils.ts index 0c186de9..8f072366 100644 --- a/src/utils/upsmfUtils.ts +++ b/src/utils/upsmfUtils.ts @@ -4,6 +4,11 @@ interface UserDetails { serviceType?: string } +/** + * This function takes a UserDetails object and returns an object containing the designation, orgId, and orgName based on the role and serviceType of the user. + * @param {UserDetails} userDetails - The UserDetails object containing the role and serviceType of the user. + * @returns {Object} - An object containing the designation, orgId, and orgName based on the role and serviceType of the user. + */ export const getDetailsAsPerRole = (userDetails: UserDetails) => { const DOMEET = 'Department of Medical Education Education and Training' const DOMEET_ORG_ID = '0138708679576535041037' From 9669eadb3976fde1bc24d5fc69a2f5af29d682ba Mon Sep 17 00:00:00 2001 From: princegupta1131 <114015020+princegupta1131@users.noreply.github.com> Date: Thu, 18 Sep 2025 14:54:41 +0530 Subject: [PATCH 3/5] new column added in db & logic change for inservice --- package.json | 1 + src/publicApi_v8/upsmfUser.ts | 97 ++++++++++++++++++++++++----------- src/utils/upsmfUtils.ts | 59 ++++++++++++--------- 3 files changed, 104 insertions(+), 53 deletions(-) diff --git a/package.json b/package.json index ee5b1a74..e483b37d 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "csv-parse": "^5.2.0", "date-fns": "^2.0.1", "dateformat": "^4.5.1", + "dayjs": "^1.11.18", "elasticsearch": "^16.7.2", "express": "^4.21.2", "express-fileupload": "^1.1.4", diff --git a/src/publicApi_v8/upsmfUser.ts b/src/publicApi_v8/upsmfUser.ts index 0d2b2b83..910b53e9 100644 --- a/src/publicApi_v8/upsmfUser.ts +++ b/src/publicApi_v8/upsmfUser.ts @@ -9,6 +9,7 @@ import { logError } from '../utils/logger' import { logInfo } from '../utils/logger' import { getDetailsAsPerRole, validRootOrgs } from '../utils/upsmfUtils' export const upsmfUserCreation = express.Router() +const dayjs = require('dayjs') const { types } = cassandra interface UserDetails { @@ -23,11 +24,8 @@ interface UserDetails { lastName: string phone: number upsmfRegistrationNumber?: string - serviceType?: string - facilityName?: { - code?: string, - name: string, - } + facilityName?: string + facilityCode?: string block?: string ehrmsNumber?: string // tslint:disable-next-line: all @@ -36,6 +34,8 @@ interface UserDetails { employmentType?: string dob?: string facilityType?: string + roleForInService?: 'Government' | 'Private' + serviceType?: 'Regular' | 'Contractual' | 'Private' } const client = new cassandra.Client({ @@ -43,6 +43,7 @@ const client = new cassandra.Client({ keyspace: 'sunbird', localDataCenter: 'datacenter1', }) +const ERHMS_CODE_KEY = 'ERHMS-code' const serviceSchemaJoi = Joi.object({ courseSelection: Joi.string() .when('role', { @@ -60,10 +61,15 @@ const serviceSchemaJoi = Joi.object({ // tslint:disable-next-line: all 'any.required': 'District is required', }), - dob: Joi.date().required().messages({ - 'any.required': 'Date of Birth is required', - 'date.base': 'Date of Birth must be a valid date', - }), + dob: Joi.string() + .when('role', { + is: Joi.valid('ANM-UP'), + otherwise: Joi.string().allow('', null).optional(), + then: Joi.string().required().messages({ + 'any.required': 'Date of Birth is required for ANM-UP role', + 'string.base': 'Date of Birth must be a string', + }), + }), email: Joi.string().allow('', null).email().optional(), facultyType: Joi.string() .when('role', { @@ -157,12 +163,15 @@ const serviceSchemaJoi = Joi.object({ block: Joi.string().optional().messages({ 'any.required': 'Block is required', }), + facilityCode: Joi.string().optional().messages({ + 'any.required': 'Facility code is required', + }), facilityType: Joi.string().optional().messages({ 'any.required': 'Facility type is required', }), - facilityName: Joi.object().optional().messages({ + facilityName: Joi.string().optional().messages({ 'any.required': 'Facility name is required', }), regNurseRegMidwifeNumber: Joi.string().optional().messages({ @@ -572,15 +581,15 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { }, professionalDetails: [ { + [ERHMS_CODE_KEY]: '', block: user?.block || '', completePostalAddress: '', designation: 'ANM-Student-UP', doj: '', - facilityCode: '', + facilityCode: '', facilityName: '', - facilityType: '', + facilityType: '', facultyType: '', - hrmsId: '', instituteName: '', instituteType: '', name: getDetailsAsPerRole(user).orgName, @@ -589,9 +598,11 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { profession: 'Nurse', professionOtherSpecify: '', qualification: '', + roleForInService: '', serviceType: user?.serviceType || '', - upsmfRegistrationNumber: '', + upsmfRegistrationNumber: '', }, + ], userId, }, @@ -630,15 +641,15 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { }, professionalDetails: [ { + [ERHMS_CODE_KEY]: user?.hrmsId || '', block: user?.block || '', completePostalAddress: '', designation: 'ANM-Student-UP', doj: '', - facilityCode: user?.facilityName?.code || '', - facilityName: user?.facilityName?.name || '', + facilityCode: user?.facilityCode || '', + facilityName: user?.facilityName || '', facilityType: user?.facilityType || '', facultyType: '', - hrmsId: user?.hrmsId, instituteName: user?.instituteName || '', instituteType: user?.instituteType || '', name: getDetailsAsPerRole(user).orgName, @@ -647,6 +658,7 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { profession: 'Student', professionOtherSpecify: '', qualification: user?.courseSelection, + roleForInService: user?.roleForInService || '', serviceType: user?.serviceType || '', upsmfRegistrationNumber: user?.upsmfRegistrationNumber, }, @@ -691,15 +703,15 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { }, professionalDetails: [ { + [ERHMS_CODE_KEY]: user?.hrmsId || '', block: user?.block || '', completePostalAddress: '', designation: 'ANM-Faculty-UP', doj: '', - facilityCode: user?.facilityName?.code || '', - facilityName: user?.facilityName?.name || '', + facilityCode: user?.facilityCode || '', + facilityName: user?.facilityName || '', facilityType: user?.facilityType || '', facultyType: user?.facultyType, - hrmsId: user?.hrmsId || '', instituteName: user?.instituteName || '', instituteType: user?.instituteType || '', name: getDetailsAsPerRole(user).orgName, @@ -708,9 +720,11 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { profession: 'Faculty', professionOtherSpecify: '', qualification: user.courseSelection, + roleForInService: user?.roleForInService || '', serviceType: user?.serviceType || '', upsmfRegistrationNumber: user?.upsmfRegistrationNumber, }, + ], userId: `${userId}`, }, @@ -750,15 +764,15 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { }, professionalDetails: [ { + [ERHMS_CODE_KEY]: user?.hrmsId || '', block: user?.block || '', completePostalAddress: '', designation: getDetailsAsPerRole(user).designation, doj: '', - facilityCode: user?.facilityName?.code || '', - facilityName: user?.facilityName?.name || '', + facilityCode: user?.facilityCode || '', + facilityName: user?.facilityName || '', facilityType: user?.facilityType || '', facultyType: user?.facultyType || '', - hrmsId: user?.hrmsId || '', instituteName: '', instituteType: '', name: getDetailsAsPerRole(user).orgName, @@ -767,6 +781,7 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { profession: 'ANM-UP', professionOtherSpecify: '', qualification: '', + roleForInService: user?.roleForInService || '', serviceType: user?.serviceType || '', upsmfRegistrationNumber: user?.upsmfRegistrationNumber, }, @@ -795,33 +810,45 @@ const userProfileUpdate = async (user: UserDetails, userId: string) => { } const updateUserStatusInDatabase = async (userDetails: UserDetails, userJourneyStatus) => { const userDetailedStructure = { + [ERHMS_CODE_KEY]: userDetails.hrmsId || '', + block: userDetails?.block || '', courseSelection: userDetails.courseSelection || '', createdOn: new Date(), + designation: getDetailsAsPerRole(userDetails).designation || '', district: userDetails.district || '', + dob: userDetails?.dob + ? types.LocalDate.fromString(dayjs(userDetails.dob).format('YYYY-MM-DD')) + : null, email: userDetails.email || '', + facilityCode: userDetails?.facilityCode || '', + facilityName: userDetails?.facilityName || '', + facilityType: userDetails.facilityType || '', facultyType: userDetails.facultyType || '', firstName: userDetails.firstName || '', - hrmsId: userDetails.hrmsId || '', instituteName: userDetails.instituteName || '', instituteType: userDetails.instituteType || '', lastName: userDetails.lastName || '', organisationId: getDetailsAsPerRole(userDetails).orgId, organisationName: getDetailsAsPerRole(userDetails).orgName, phone: String(userDetails.phone || ''), + regNurseRegMidwifeNumber: userDetails?.regNurseRegMidwifeNumber || 'NA', registrationSource: 'Self Registration', + role: userDetails.role || '', + roleForInService: userDetails?.roleForInService || '', + serviceType: userDetails?.serviceType || '', upsmfRegistrationNumber: userDetails.upsmfRegistrationNumber || '', ...userJourneyStatus, } - + logError('User detailed structure for cassandra', JSON.stringify(userDetailedStructure)) const query = ` INSERT INTO sunbird.upsmf_registration_data ( - unique_id, course_selection, create_account, created_on, district, email, - faculty_type, first_name, hrms_id, institute_name, institute_type, last_name, - organisation_id, organisation_name, phone, profile_update, registration_source, + unique_id, course_selection, create_account, created_on, designation, district, dob, email, facility_name, facility_code, facility_type, + faculty_type, first_name, erhms_code, institute_name, institute_type, last_name, + organisation_id, organisation_name, phone, regNurseRegMidwifeNumber, role, roleForInService, service_type, block, profile_update, registration_source, registration_success_message, role_assign, upsmf_registration_number, user_already_exists, user_existing_organisation, validation_status, validation_status_failed_reason - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ` const params = [ @@ -831,10 +858,15 @@ const updateUserStatusInDatabase = async (userDetails: UserDetails, userJourneyS String(userDetailedStructure.createAccount || ''), // create_account userDetailedStructure.createdOn, // created_on String(userDetailedStructure.district || ''), // district + String(userDetailedStructure.designation || ''), // designation + String(userDetailedStructure.dob || ''), // dob String(userDetailedStructure.email || ''), // email + String(userDetailedStructure.facilityName || ''), // facility_name + String(userDetailedStructure.facilityCode || ''), // facility_code + String(userDetailedStructure.facilityType || ''), // facility_type String(userDetailedStructure.facultyType || ''), // faculty_type String(userDetailedStructure.firstName || ''), // first_name - String(userDetailedStructure.hrmsId || ''), // hrms_id + String(userDetailedStructure[ERHMS_CODE_KEY] || ''), // ERHMS-code String(userDetailedStructure.instituteName || ''), // institute_name String(userDetailedStructure.instituteType || ''), // institute_type String(userDetailedStructure.lastName || ''), // last_name @@ -842,6 +874,11 @@ const updateUserStatusInDatabase = async (userDetails: UserDetails, userJourneyS userDetailedStructure.organisationName, String(userDetailedStructure.phone || ''), // phone + String(userDetailedStructure.regNurseRegMidwifeNumber || ''), // regNurseRegMidwifeNumber + String(userDetailedStructure.role || ''), // role + String(userDetailedStructure.roleForInService || ''), // roleForInService + String(userDetailedStructure.serviceType || ''), // serviceType + String(userDetailedStructure.block || ''), // block String(userDetailedStructure.profileUpdate || ''), // profile_update String(userDetailedStructure.registrationSource || ''), // registration_source String(userDetailedStructure.registrationSuccessMessage || ''), // registration_success_message diff --git a/src/utils/upsmfUtils.ts b/src/utils/upsmfUtils.ts index 8f072366..fe78eda8 100644 --- a/src/utils/upsmfUtils.ts +++ b/src/utils/upsmfUtils.ts @@ -1,13 +1,14 @@ interface UserDetails { role: string - serviceType?: string + roleForInService?: 'Government' | 'Private' + serviceType?: 'Regular' | 'Contractual' | 'Private' } /** - * This function takes a UserDetails object and returns an object containing the designation, orgId, and orgName based on the role and serviceType of the user. - * @param {UserDetails} userDetails - The UserDetails object containing the role and serviceType of the user. - * @returns {Object} - An object containing the designation, orgId, and orgName based on the role and serviceType of the user. + * This function takes a UserDetails object and returns an object containing the designation, orgId, and orgName based on the role , roleForInService and serviceType of the user. + * @param {UserDetails} userDetails - The UserDetails object containing the role, roleForInService and serviceType of the user. + * @returns {Object} - An object containing the designation, orgId, and orgName based on the role,roleForInService and serviceType of the user. */ export const getDetailsAsPerRole = (userDetails: UserDetails) => { const DOMEET = 'Department of Medical Education Education and Training' @@ -27,34 +28,43 @@ export const getDetailsAsPerRole = (userDetails: UserDetails) => { orgName: DOMEET, } - case 'ANM-UP': - // tslint:disable-next-line: all - switch (userDetails?.serviceType) { - case 'Regular': + case 'ANM-UP': { + const designation = 'ANM-UP' + // Government side: Regular / Contractual + if (userDetails?.roleForInService === 'Government') { + if (userDetails?.serviceType === 'Regular') { return { - designation: 'ANM-UP', + designation, orgId: '01400948801286144024329', orgName: 'Department of Medical Health & Family Welfare (Uttar Pradesh)', } - case 'Contractual': + } + + if (userDetails?.serviceType === 'Contractual') { return { - designation: 'ANM-UP', + designation, orgId: '0144024313254133763751', orgName: 'National Health Mission (Uttar Pradesh)', } - case 'Private': - return { - designation: 'ANM-UP', - orgId: '0144024277797191683752', - orgName: 'Private (Uttar Pradesh)', - } - default: - return { - designation: 'ANM-UP', - orgId: 'NA', - orgName: 'Unknown Service Type', - } + } + } + + // Private side + if (userDetails?.roleForInService === 'Private' || userDetails?.serviceType === 'Private') { + return { + designation, + orgId: '0144024277797191683752', + orgName: 'Private (Uttar Pradesh)', + } + } + // Fallback if no condition matches + return { + designation, + orgId: 'NA', + orgName: 'NA', } + } + default: return { designation: 'NA', @@ -70,4 +80,7 @@ export const validRootOrgs = [ 'Directorate of Medical Health (UP)', 'UP State Ministry of Health and Family Welfare', 'State Institute of Health and Family Welfare, Department of Health & Family Welfare, UP', + 'Department of Medical Health & Family Welfare (Uttar Pradesh)', + 'National Health Mission (Uttar Pradesh)', + 'Private (Uttar Pradesh)', ] From a41211388418b74d5de4a60f438bd3bb3d2f9289 Mon Sep 17 00:00:00 2001 From: princegupta1131 <114015020+princegupta1131@users.noreply.github.com> Date: Thu, 18 Sep 2025 17:07:17 +0530 Subject: [PATCH 4/5] validation fix and col for is migrated --- src/publicApi_v8/upsmfUser.ts | 54 +++++++++++++++++++++++++++-------- src/utils/upsmfUtils.ts | 5 ++-- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/publicApi_v8/upsmfUser.ts b/src/publicApi_v8/upsmfUser.ts index 910b53e9..4599e24d 100644 --- a/src/publicApi_v8/upsmfUser.ts +++ b/src/publicApi_v8/upsmfUser.ts @@ -44,6 +44,7 @@ const client = new cassandra.Client({ localDataCenter: 'datacenter1', }) const ERHMS_CODE_KEY = 'ERHMS-code' +const GOV_KEY = 'Government' const serviceSchemaJoi = Joi.object({ courseSelection: Joi.string() .when('role', { @@ -153,6 +154,11 @@ const serviceSchemaJoi = Joi.object({ }), hrmsId: Joi.string() + .when('roleForInService', { + is: GOV_KEY, + otherwise: Joi.string().allow('', null).optional(), + then: Joi.string().required(), + }) .pattern(/^\d{5,8}$/) .required() .messages({ @@ -160,20 +166,40 @@ const serviceSchemaJoi = Joi.object({ 'string.pattern.base': 'EHRMS Number must be 5–8 digits', }), - block: Joi.string().optional().messages({ - 'any.required': 'Block is required', - }), - facilityCode: Joi.string().optional().messages({ - 'any.required': 'Facility code is required', - }), - - facilityType: Joi.string().optional().messages({ - 'any.required': 'Facility type is required', - }), + block: Joi.string() + .when('roleForInService', { + is: GOV_KEY, + otherwise: Joi.string().allow('', null).optional(), + then: Joi.string().required(), + }) + .messages({ + // tslint:disable-next-line: all + 'any.required': 'block is required', + }), + facilityCode: Joi.string() + .when('roleForInService', { + is: GOV_KEY, + otherwise: Joi.string().allow('', null).optional(), + then: Joi.string().required(), + }) + .messages({ + // tslint:disable-next-line: all + 'any.required': 'Facility Code is required', + }), facilityName: Joi.string().optional().messages({ 'any.required': 'Facility name is required', }), + facilityType: Joi.string() + .when('roleForInService', { + is: GOV_KEY, + otherwise: Joi.string().allow('', null).optional(), + then: Joi.string().required(), + }) + .messages({ + // tslint:disable-next-line: all + 'any.required': 'Facility Type is required', + }), regNurseRegMidwifeNumber: Joi.string().optional().messages({ 'any.required': 'RNRM Number is required', }), @@ -274,6 +300,9 @@ upsmfUserCreation.post('/createUser', async (req: Request, res: Response) => { } else if (isUserExists.userDetails.rootOrgName == 'aastrika' || isUserExists.userDetails.rootOrgName == 'SPhere Team 1') { const userMigrationStatus = await migrateUserToUpsmf(isUserExists.userDetails, userFormDetails) const assignRoleResponseForAastrikaOrg = await assignRoleToUser(isUserExists.userDetails.id, userFormDetails) + const profileUpdateResponse = await userProfileUpdate(userFormDetails, isUserExists.userDetails.id) + userJourneyStatus.profileUpdate = profileUpdateResponse ? 'success' : 'failed' + userJourneyStatus.isUserMigrated = true if (!userMigrationStatus || !assignRoleResponseForAastrikaOrg) { userJourneyStatus.userExistingOrganisation = 'aastrika || SPhere Team 1' await updateUserStatusInDatabase(userFormDetails, userJourneyStatus) @@ -843,12 +872,12 @@ const updateUserStatusInDatabase = async (userDetails: UserDetails, userJourneyS const query = ` INSERT INTO sunbird.upsmf_registration_data ( unique_id, course_selection, create_account, created_on, designation, district, dob, email, facility_name, facility_code, facility_type, - faculty_type, first_name, erhms_code, institute_name, institute_type, last_name, + faculty_type, first_name, erhms_code, institute_name, institute_type, is_user_migrated, last_name, organisation_id, organisation_name, phone, regNurseRegMidwifeNumber, role, roleForInService, service_type, block, profile_update, registration_source, registration_success_message, role_assign, upsmf_registration_number, user_already_exists, user_existing_organisation, validation_status, validation_status_failed_reason - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ` const params = [ @@ -869,6 +898,7 @@ const updateUserStatusInDatabase = async (userDetails: UserDetails, userJourneyS String(userDetailedStructure[ERHMS_CODE_KEY] || ''), // ERHMS-code String(userDetailedStructure.instituteName || ''), // institute_name String(userDetailedStructure.instituteType || ''), // institute_type + Boolean(userDetailedStructure.isUserMigrated || false), // migrate_user String(userDetailedStructure.lastName || ''), // last_name userDetailedStructure.organisationId, userDetailedStructure.organisationName, diff --git a/src/utils/upsmfUtils.ts b/src/utils/upsmfUtils.ts index fe78eda8..d6ea76c8 100644 --- a/src/utils/upsmfUtils.ts +++ b/src/utils/upsmfUtils.ts @@ -43,8 +43,8 @@ export const getDetailsAsPerRole = (userDetails: UserDetails) => { if (userDetails?.serviceType === 'Contractual') { return { designation, - orgId: '0144024313254133763751', - orgName: 'National Health Mission (Uttar Pradesh)', + orgId: '014017257506177024441', + orgName: 'National Health Mission (UP)', } } } @@ -81,6 +81,5 @@ export const validRootOrgs = [ 'UP State Ministry of Health and Family Welfare', 'State Institute of Health and Family Welfare, Department of Health & Family Welfare, UP', 'Department of Medical Health & Family Welfare (Uttar Pradesh)', - 'National Health Mission (Uttar Pradesh)', 'Private (Uttar Pradesh)', ] From d2a38716f982560cf68bcf41e5596e79ad6974ed Mon Sep 17 00:00:00 2001 From: princegupta1131 <114015020+princegupta1131@users.noreply.github.com> Date: Thu, 18 Sep 2025 17:49:50 +0530 Subject: [PATCH 5/5] db column fix --- src/publicApi_v8/upsmfUser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/publicApi_v8/upsmfUser.ts b/src/publicApi_v8/upsmfUser.ts index 4599e24d..1a9fb7a1 100644 --- a/src/publicApi_v8/upsmfUser.ts +++ b/src/publicApi_v8/upsmfUser.ts @@ -886,8 +886,8 @@ const updateUserStatusInDatabase = async (userDetails: UserDetails, userJourneyS String(userDetailedStructure.courseSelection || ''), // course_selection String(userDetailedStructure.createAccount || ''), // create_account userDetailedStructure.createdOn, // created_on - String(userDetailedStructure.district || ''), // district String(userDetailedStructure.designation || ''), // designation + String(userDetailedStructure.district || ''), // district String(userDetailedStructure.dob || ''), // dob String(userDetailedStructure.email || ''), // email String(userDetailedStructure.facilityName || ''), // facility_name