From dd4364653614de46032618d1d5b66bb7171f1e9e Mon Sep 17 00:00:00 2001 From: Suraj Date: Thu, 6 Feb 2025 17:50:52 +0530 Subject: [PATCH 1/3] currenTRole --- .../hasura/altBulkUploadTeacher.adapter.ts | 73 +++++++++++++---- src/adapters/hasura/group.adapter.ts | 81 +++++++++++++++++++ 2 files changed, 138 insertions(+), 16 deletions(-) diff --git a/src/adapters/hasura/altBulkUploadTeacher.adapter.ts b/src/adapters/hasura/altBulkUploadTeacher.adapter.ts index b901a20..5375f06 100644 --- a/src/adapters/hasura/altBulkUploadTeacher.adapter.ts +++ b/src/adapters/hasura/altBulkUploadTeacher.adapter.ts @@ -60,29 +60,70 @@ export class ALTBulkUploadTeacherService { teacher.groups = []; let groupInfo; - for (let teacherClass of teacherClasses) { - console.log("teacherClass 64", teacherClass) + if(teacher.currentRole === 'School_Admin') { const academicYear = teacher.academicYear || new Date().getFullYear().toString(); - const groupRes: any = await this.groupService.getGroupBySchoolClass( + + const getClassesbySchoolUdise = await this.groupService.getClassesbySchoolUdise( request, - teacher.schoolUdise, - teacherClass, - academicYear - ); + teacher.schoolUdise, + academicYear + ) - console.log("groupRes", groupRes) + console.log("getClassesbySchoolUdise", getClassesbySchoolUdise) + const schoolAdminClasses: any = getClassesbySchoolUdise + - if (!groupRes.data[0].groupId) { - errors.push({ - name: teacher.name, - groupRes, - }); - } else { - groupInfo = groupRes; - teacher.groups.push(groupRes.data[0].groupId); + for (let teacherClass of schoolAdminClasses) { + console.log("teacherClass 64", teacherClass) + const className = teacherClass.name + //const academicYear = teacher.academicYear || new Date().getFullYear().toString(); + const groupRes: any = await this.groupService.getGroupBySchoolClass( + request, + teacher.schoolUdise, + className, + academicYear + ); + + console.log("groupRes 73", groupRes) + + if (!groupRes.data[0].groupId) { + errors.push({ + name: teacher.name, + groupRes, + }); + } else { + groupInfo = groupRes; + teacher.groups.push(groupRes.data[0].groupId); + } + } + + } else { + for (let teacherClass of teacherClasses) { + console.log("teacherClass 64", teacherClass) + const academicYear = teacher.academicYear || new Date().getFullYear().toString(); + const groupRes: any = await this.groupService.getGroupBySchoolClass( + request, + teacher.schoolUdise, + teacherClass, + academicYear + ); + + console.log("groupRes 73", groupRes) + + if (!groupRes.data[0].groupId) { + errors.push({ + name: teacher.name, + groupRes, + }); + } else { + groupInfo = groupRes; + teacher.groups.push(groupRes.data[0].groupId); + } } } + + if (!teacher.groups.length) { errors.push({ name: teacher.name, diff --git a/src/adapters/hasura/group.adapter.ts b/src/adapters/hasura/group.adapter.ts index c7532c3..8d2b11c 100644 --- a/src/adapters/hasura/group.adapter.ts +++ b/src/adapters/hasura/group.adapter.ts @@ -689,6 +689,87 @@ export class HasuraGroupService implements IServicelocatorgroup { }); } + // getClassesbySchoolUdise + + public async getClassesbySchoolUdise( + request: any, + schoolUdise: string, + //className: string, + year: string + ) { + + console.log("schoolUdise", schoolUdise) + //console.log("className", className) + console.log("year", year) + const decoded: any = jwt_decode(request.headers.authorization); + const altUserRoles = + decoded["https://hasura.io/jwt/claims"]["x-hasura-allowed-roles"]; + const groupDetails = { + query: `query GetGroupList($board:String,$medium:String,$schoolUdise:String,$year:numeric) { + Group(where: + { + academicYear: {_eq: $year} + status: {_eq: true} + + schoolUdise: {_eq: $schoolUdise} + }) + { + groupId + schoolUdise + medium + grade + name + status + academicYear + board + } + }`, + variables: { + schoolUdise: schoolUdise, + // name: className, + year: year, + }, + }; + + const config = { + method: "post", + url: process.env.ALTHASURA, + headers: { + Authorization: request.headers.authorization, + "x-hasura-role": getUserRole(altUserRoles), + "Content-Type": "application/json", + }, + data: groupDetails, + }; + + const response = await this.axios(config); + if (response?.data?.errors) { + return new ErrorResponse({ + errorCode: response.data.errors[0].extensions, + errorMessage: response.data.errors[0].message, + }); + } + + let result: any[] = response.data.data.Group; + + if (!result.length) { + const msg = `No matching record found for the current combination of school and class.`; + return new SuccessResponse({ + statusCode: 404, + message: msg, + data: result, + }); + } + + return result + + // return new SuccessResponse({ + // statusCode: 200, + // message: "Ok.", + // data: result, + // }); + } + public async StudentMappedResponse(result: any) { const studentResponse = result.map((item: any) => { const studentMapping = { From 052e4795d9398839fc81b70357a99aca5d293e0b Mon Sep 17 00:00:00 2001 From: Suraj Date: Fri, 7 Feb 2025 12:14:11 +0530 Subject: [PATCH 2/3] school_admin onbaording --- .../hasura/altBulkUploadTeacher.adapter.ts | 100 ++++++++++++------ src/adapters/hasura/altTeacher.adapter.ts | 2 + src/adapters/hasura/group.adapter.ts | 6 +- 3 files changed, 71 insertions(+), 37 deletions(-) diff --git a/src/adapters/hasura/altBulkUploadTeacher.adapter.ts b/src/adapters/hasura/altBulkUploadTeacher.adapter.ts index 5375f06..19019fc 100644 --- a/src/adapters/hasura/altBulkUploadTeacher.adapter.ts +++ b/src/adapters/hasura/altBulkUploadTeacher.adapter.ts @@ -61,12 +61,15 @@ export class ALTBulkUploadTeacherService { let groupInfo; if(teacher.currentRole === 'School_Admin') { - const academicYear = teacher.academicYear || new Date().getFullYear().toString(); + const academicYear = new Date().getFullYear().toString(); + const academicYearList: any = [(parseInt(academicYear) - 1).toString(), academicYear] + + console.log("academicYearList", academicYearList) const getClassesbySchoolUdise = await this.groupService.getClassesbySchoolUdise( request, teacher.schoolUdise, - academicYear + academicYearList ) console.log("getClassesbySchoolUdise", getClassesbySchoolUdise) @@ -77,23 +80,49 @@ export class ALTBulkUploadTeacherService { console.log("teacherClass 64", teacherClass) const className = teacherClass.name //const academicYear = teacher.academicYear || new Date().getFullYear().toString(); - const groupRes: any = await this.groupService.getGroupBySchoolClass( - request, - teacher.schoolUdise, - className, - academicYear - ); + // const groupRes: any = await this.groupService.getGroupBySchoolClass( + // request, + // teacher.schoolUdise, + // className, + // academicYear + // ); + + const groupId = teacherClass.groupId - console.log("groupRes 73", groupRes) + console.log("groupId 92", groupId) - if (!groupRes.data[0].groupId) { + if (!groupId) { errors.push({ name: teacher.name, - groupRes, + groupId, }); } else { - groupInfo = groupRes; - teacher.groups.push(groupRes.data[0].groupId); + groupInfo = teacherClass; + teacher.groups.push(groupId); + } + } + + if (!teacher.groups.length) { + errors.push({ + name: teacher.name, + msg: "No Group found", + }); + } else { + teacher.board = groupInfo.board; + teacher.password = getPassword(8); + teacher.status = true; + const teacherRes: any = await this.teacherService.createAndAddToGroup( + request, + teacher, + bulkToken + ); + if (teacherRes?.statusCode === 200) { + responses.push(teacherRes.data); + } else { + errors.push({ + name: teacher.name, + teacherRes, + }); } } @@ -120,33 +149,36 @@ export class ALTBulkUploadTeacherService { teacher.groups.push(groupRes.data[0].groupId); } } - } - - - if (!teacher.groups.length) { - errors.push({ - name: teacher.name, - msg: "No Group found", - }); - } else { - teacher.board = groupInfo.data[0].board; - teacher.password = getPassword(8); - teacher.status = true; - const teacherRes: any = await this.teacherService.createAndAddToGroup( - request, - teacher, - bulkToken - ); - if (teacherRes?.statusCode === 200) { - responses.push(teacherRes.data); - } else { + if (!teacher.groups.length) { errors.push({ name: teacher.name, - teacherRes, + msg: "No Group found", }); + } else { + teacher.board = groupInfo.data[0].board; + teacher.password = getPassword(8); + teacher.status = true; + const teacherRes: any = await this.teacherService.createAndAddToGroup( + request, + teacher, + bulkToken + ); + if (teacherRes?.statusCode === 200) { + responses.push(teacherRes.data); + } else { + errors.push({ + name: teacher.name, + teacherRes, + }); + } } + } + + + + } const result = { diff --git a/src/adapters/hasura/altTeacher.adapter.ts b/src/adapters/hasura/altTeacher.adapter.ts index ae16c80..2242ae5 100644 --- a/src/adapters/hasura/altTeacher.adapter.ts +++ b/src/adapters/hasura/altTeacher.adapter.ts @@ -100,6 +100,8 @@ export class ALTTeacherService { teacherDto: TeacherDto, bulkToken: string ) { + + console.log("teacherDto 104", teacherDto) const decoded: any = jwt_decode(request.headers.authorization); const altUserRoles = decoded["https://hasura.io/jwt/claims"]["x-hasura-allowed-roles"]; diff --git a/src/adapters/hasura/group.adapter.ts b/src/adapters/hasura/group.adapter.ts index 8d2b11c..94b1ada 100644 --- a/src/adapters/hasura/group.adapter.ts +++ b/src/adapters/hasura/group.adapter.ts @@ -695,7 +695,7 @@ export class HasuraGroupService implements IServicelocatorgroup { request: any, schoolUdise: string, //className: string, - year: string + year: any ) { console.log("schoolUdise", schoolUdise) @@ -705,10 +705,10 @@ export class HasuraGroupService implements IServicelocatorgroup { const altUserRoles = decoded["https://hasura.io/jwt/claims"]["x-hasura-allowed-roles"]; const groupDetails = { - query: `query GetGroupList($board:String,$medium:String,$schoolUdise:String,$year:numeric) { + query: `query GetGroupList($board:String,$medium:String,$schoolUdise:String,$year:[numeric]) { Group(where: { - academicYear: {_eq: $year} + academicYear: {_in: $year} status: {_eq: true} schoolUdise: {_eq: $schoolUdise} From 16ec32b7a26ed0751caf47d9e80ace6a84be7ea4 Mon Sep 17 00:00:00 2001 From: Manasi Tayade Date: Fri, 7 Feb 2025 17:16:58 +0530 Subject: [PATCH 3/3] deletion script updated --- src/adapters/hasura/altUser.adapter.ts | 126 +++++++++++++++++-------- 1 file changed, 88 insertions(+), 38 deletions(-) diff --git a/src/adapters/hasura/altUser.adapter.ts b/src/adapters/hasura/altUser.adapter.ts index 56512a6..44f0e70 100644 --- a/src/adapters/hasura/altUser.adapter.ts +++ b/src/adapters/hasura/altUser.adapter.ts @@ -23,7 +23,7 @@ import { ALTUserUpdateDto } from "src/altUser/dto/alt-user-update.dto"; export class ALTHasuraUserService { axios = require("axios"); - constructor(private httpService: HttpService) { } + constructor(private httpService: HttpService) {} public async getUser(userId: string, request: any) { const decoded: any = jwt_decode(request.headers.authorization); @@ -894,8 +894,9 @@ export class ALTHasuraUserService { const [firstName, lastName] = obj.name.split(" "); // Step 1: Extract initials - const initials = `${firstName[0].toLowerCase()}${lastName ? lastName[0].toLowerCase() : "" - }`; + const initials = `${firstName[0].toLowerCase()}${ + lastName ? lastName[0].toLowerCase() : "" + }`; const dob = obj.dateOfBirth .trim() @@ -1150,19 +1151,21 @@ export class ALTHasuraUserService { decoded["https://hasura.io/jwt/claims"]["x-hasura-allowed-roles"]; const username = decoded.preferred_username; - // Fetch Teacher data with currentRole - if (roles[0] === 'teacher') { - console.log("fetchTeacherUserData") + if (roles[0] === "teacher") { + console.log("fetchTeacherUserData"); - const userData = await this.fetchTeacherUserData(username, token, roles); + const userData = await this.fetchTeacherUserData( + username, + token, + roles + ); if (!userData) { return this.sendErrorResponse(res, 404, "User not found or inactive"); } // Send success response return this.sendSuccessResponse(res, 200, "Authenticated", userData); - } // Fetch user details from GraphQL @@ -1256,9 +1259,9 @@ export class ALTHasuraUserService { try { const response = await this.axios(config); - console.log("response.data.data", response.data) - if(response.data.data.Users[0].role === 'teacher') { - return this.fetchTeacherRole(username, token, roles) + console.log("response.data.data", response.data); + if (response.data.data.Users[0].role === "teacher") { + return this.fetchTeacherRole(username, token, roles); } return response.data.data.Users || null; } catch (error) { @@ -1319,8 +1322,8 @@ export class ALTHasuraUserService { try { const response = await this.axios(config); - console.log("response.data.data", response.data) - + console.log("response.data.data", response.data); + console.log("response.data.data", response.data); return response.data.data.Users || null; } catch (error) { @@ -1548,17 +1551,58 @@ export class ALTHasuraUserService { Authorization: `Bearer ${adminToken}`, }, }); - if (!userSearchResponse.data || userSearchResponse.data.length === 0) { - deletedRecords.push({ - ...recordStatus, - error: `User ${username} not found in Keycloak`, - }); - continue; - } + // if (!userSearchResponse.data || userSearchResponse.data.length === 0) { + // deletedRecords.push({ + // ...recordStatus, + // error: `User ${username} not found in Keycloak`, + // }); + // continue; + // } console.log("userSearchResponse->>", userSearchResponse.data); - const keycloakUserId = userSearchResponse.data[0].id; + let keycloakUserId = userSearchResponse?.data[0]?.id; + + // If Keycloak user is not found, check in Hasura + if (!keycloakUserId) { + console.log( + `User ${username} not found in Keycloak, checking Hasura` + ); + const hasuraQuery = { + query: ` + query GetUser($username: String ) { + Users(where: {username: {_eq: $username}}){ + userId + } + }`, + variables: { username }, + }; + const hasuraResponse = await this.axios({ + method: "post", + url: process.env.HASURAURL, + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${userToken}`, + }, + data: hasuraQuery, + }); + if ( + hasuraResponse.data && + hasuraResponse.data.data && + hasuraResponse.data.data.Users.length > 0 + ) { + keycloakUserId = hasuraResponse.data.data.Users[0].userId; + console.log( + `User ${username} found in Hasura with userId: ${keycloakUserId}` + ); + } else { + deletedRecords.push({ + ...recordStatus, + error: `User ${username} not found in Keycloak or Hasura`, + }); + continue; + } + } // Delete from database try { for (const table of tables) { @@ -1595,23 +1639,28 @@ export class ALTHasuraUserService { continue; } - // Delete from Keycloak - try { - await this.axios({ - method: "delete", - url: `${searchUrl}/${keycloakUserId}`, - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${adminToken}`, - }, - }); - recordStatus.kcDeleted = true; - } catch (kcError) { - console.error( - `Keycloak deletion failed for user ${username}:`, - kcError.message + // Delete from Keycloak only if user was found there + if (userSearchResponse?.data.length > 0) { + try { + await this.axios({ + method: "delete", + url: `${searchUrl}/${keycloakUserId}`, + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${adminToken}`, + }, + }); + recordStatus.kcDeleted = true; + } catch (kcError) { + console.error( + `Keycloak deletion failed for user ${username}:`, + kcError.message + ); + } + } else { + console.log( + `Skipping Keycloak deletion for ${username} as user was not found there` ); - continue; } // Delete from telemetry @@ -1621,7 +1670,8 @@ export class ALTHasuraUserService { process.env.TELEMETRY_DB_URL || `postgres://${process.env.TELEMETRY_DB_USER}:${encodeURIComponent( process.env.TELEMETRY_DB_PASSWORD - )}@${process.env.TELEMETRY_DB_HOST}:${process.env.TELEMETRY_DB_PORT + )}@${process.env.TELEMETRY_DB_HOST}:${ + process.env.TELEMETRY_DB_PORT }/${process.env.TELEMETRY_DB_NAME}?sslmode=disable`; // Create a connection pool