From 54c3d48fa7000d10c54d57934a9b809e1fdf4678 Mon Sep 17 00:00:00 2001 From: ManojNathIC Date: Tue, 3 Dec 2024 10:02:17 +0530 Subject: [PATCH 1/2] Draft unique schemas --- schemas/Examiner.json | 67 ++++++++++++++++++----------------- schemas/Inspector.json | 66 +++++++++++++++++----------------- schemas/Student.json | 6 ++-- schemas/casteCertificate.json | 7 ++-- src/Helper/transformers.ts | 18 ++++++++++ 5 files changed, 93 insertions(+), 71 deletions(-) diff --git a/schemas/Examiner.json b/schemas/Examiner.json index 98ee0b2..accae71 100644 --- a/schemas/Examiner.json +++ b/schemas/Examiner.json @@ -1,34 +1,35 @@ { - "$schema": "http://json-schema.org/draft-07/schema", - "type": "object", - "properties": { "Examiner": { "$ref": "#/definitions/Examiner" } }, - "required": ["Examiner"], - "title": "Examiner", - "definitions": { - "Examiner": { - "$id": "#/properties/Examiner", - "type": "object", - "title": "Examinerschema", - "required": ["name", "email", "phoneNumber", "password"], - "uniqueIndexFields": ["email"], - "properties": { - "name": {"type": "string", "title": "Name"}, - "email": { "type": "string", "title": "Email" }, - "phoneNumber": { "type": "string", "title": "Phone Number" }, - "status": { "type": "string", "title": "Status" }, - "password": { "type": "string", "minLength": 8, "title": "Password" } - } - } - }, - "_osConfig": { - "ownershipAttributes": [ - { - "email": "/email", - "mobile": "/phoneNumber", - "userId": "/email", - "password": "/password" - } - ], - "inviteRoles": ["anonymous"] - } -} \ No newline at end of file + "$schema": "http://json-schema.org/draft-07/schema", + "type": "object", + "properties": { "Examiner": { "$ref": "#/definitions/Examiner" } }, + "required": ["Examiner"], + "title": "Examiner", + "definitions": { + "Examiner": { + "$id": "#/properties/Examiner", + "type": "object", + "title": "Examinerschema", + "required": ["name", "email", "phoneNumber", "password"], + "uniqueIndexFields": ["email"], + "properties": { + "name": { "type": "string", "title": "Name" }, + "email": { "type": "string", "title": "Email" }, + "phoneNumber": { "type": "string", "title": "Phone Number" }, + "status": { "type": "string", "title": "Status" }, + "password": { "type": "string", "minLength": 8, "title": "Password" } + } + } + }, + "_osConfig": { + "ownershipAttributes": [ + { + "email": "/email", + "mobile": "/phoneNumber", + "userId": "/email", + "password": "/password" + } + ], + "inviteRoles": ["anonymous"], + "uniqueIndexFields": ["email"] + } +} diff --git a/schemas/Inspector.json b/schemas/Inspector.json index 8aba9e2..861d127 100644 --- a/schemas/Inspector.json +++ b/schemas/Inspector.json @@ -1,34 +1,34 @@ { - "$schema": "http://json-schema.org/draft-07/schema", - "type": "object", - "properties": { "Inspector": { "$ref": "#/definitions/Inspector" } }, - "required": ["Inspector"], - "title": "Inspector", - "definitions": { - "Inspector": { - "$id": "#/properties/Inspector", - "type": "object", - "title": "Inspectorschema", - "required": ["name", "email", "phoneNumber", "password"], - "uniqueIndexFields": ["email"], - "properties": { - "name": {"type": "string", "title": "Name"}, - "email": { "type": "string", "title": "Email" }, - "phoneNumber": { "type": "string", "title": "Phone Number" }, - "status": { "type": "string", "title": "Status" }, - "password": { "type": "string", "minLength": 8, "title": "Password" } - } - } - }, - "_osConfig": { - "ownershipAttributes": [ - { - "email": "/email", - "mobile": "/phoneNumber", - "userId": "/email", - "password": "/password" - } - ], - "inviteRoles": ["anonymous"] - } -} \ No newline at end of file + "$schema": "http://json-schema.org/draft-07/schema", + "type": "object", + "properties": { "Inspector": { "$ref": "#/definitions/Inspector" } }, + "required": ["Inspector"], + "title": "Inspector", + "definitions": { + "Inspector": { + "$id": "#/properties/Inspector", + "type": "object", + "title": "Inspectorschema", + "required": ["name", "email", "phoneNumber", "password"], + "properties": { + "name": { "type": "string", "title": "Name" }, + "email": { "type": "string", "title": "Email" }, + "phoneNumber": { "type": "string", "title": "Phone Number" }, + "status": { "type": "string", "title": "Status" }, + "password": { "type": "string", "minLength": 8, "title": "Password" } + } + } + }, + "_osConfig": { + "ownershipAttributes": [ + { + "email": "/email", + "mobile": "/phoneNumber", + "userId": "/email", + "password": "/password" + } + ], + "inviteRoles": ["anonymous"], + "uniqueIndexFields": ["email"] + } +} diff --git a/schemas/Student.json b/schemas/Student.json index cbb433b..9e55e46 100644 --- a/schemas/Student.json +++ b/schemas/Student.json @@ -17,8 +17,9 @@ "school", "password" ], - "uniqueIndexFields": ["email", "nin"], + "properties": { + "uniqueId": { "type": "string", "title": "Student unique Id" }, "studentId": { "type": "string", "title": "Student Id" }, "studentJssId": { "type": "string", @@ -50,6 +51,7 @@ "password": "/password" } ], - "inviteRoles": ["anonymous"] + "inviteRoles": ["anonymous"], + "uniqueIndexFields": ["uniqueId"] } } diff --git a/schemas/casteCertificate.json b/schemas/casteCertificate.json index a792528..4d015cd 100644 --- a/schemas/casteCertificate.json +++ b/schemas/casteCertificate.json @@ -22,8 +22,8 @@ "dateOfIssuance", "certificateNumber" ], - "uniqueIndexFields": ["studentId"], "properties": { + "uniqueId": { "type": "string", "title": "Student unique Id" }, "studentId": { "type": "string", "title": "Student Identifier" @@ -39,7 +39,7 @@ "relationWithApplicant": { "type": "string", "title": "Relation with Applicant" - }, + }, "firstName": { "type": "string", "title": "First Name" @@ -136,6 +136,7 @@ } }, "_osConfig": { - "inviteRoles": ["anonymous"] + "inviteRoles": ["anonymous"], + "uniqueIndexFields": ["uniqueId"] } } diff --git a/src/Helper/transformers.ts b/src/Helper/transformers.ts index be91e7e..95345b9 100644 --- a/src/Helper/transformers.ts +++ b/src/Helper/transformers.ts @@ -53,6 +53,9 @@ export const tenMarksheetTransformer = (data) => { export const marksheet = (data) => { return data?.map((record) => { return { + uniqueId: `${record.schoolId?.trim() || ''}-${ + record.studentUniqueId?.trim() || '' + }-${record.class?.trim() || ''}`, studentId: record.studentUniqueId, firstName: record.firstName, middleName: record.middleName, @@ -85,6 +88,9 @@ export const marksheet = (data) => { export const enrollmentCertificate = (data) => { return data.map((record) => { return { + uniqueId: `${record.schoolId?.trim() || ''}-${ + record.studentUniqueId?.trim() || '' + }-${record.class?.trim() || ''}`, studentId: record.studentUniqueId, schoolId: record.schoolId, firstName: record.firstName, @@ -122,6 +128,9 @@ export const enrollmentCertificate = (data) => { export const casteCertificate = (data) => { return data.map((record) => { return { + uniqueId: `${record.schoolId?.trim() || ''}-${ + record.studentUniqueId?.trim() || '' + }`, familyLeaderBhamashahNumber: record.familyLeaderBhamashahNumber, relationWithApplicant: record.relationWithApplicant, studentId: record.studentUniqueId, @@ -173,6 +182,9 @@ export const casteCertificate = (data) => { export const sportsParticipationCertificate = (data) => { return data.map((record) => { return { + uniqueId: `${record.schoolId?.trim() || ''}-${ + record.studentUniqueId?.trim() || '' + }-${record.class?.trim() || ''}`, studentId: record.studentUniqueId, schoolId: record.schoolId, firstName: record.firstName, @@ -223,6 +235,9 @@ export const sportsParticipationCertificate = (data) => { export const janAadharCertificate = (data) => { return data.map((record) => { return { + uniqueId: `${record.schoolId?.trim() || ''}-${ + record.studentUniqueId?.trim() || '' + }`, studentId: record.studentUniqueId, schoolId: record.schoolId, schoolName: record.schoolName, @@ -259,6 +274,9 @@ export const janAadharCertificate = (data) => { export const incomeCertificate = (data) => { return data?.map((record) => { return { + uniqueId: `${record.schoolId?.trim() || ''}-${ + record.studentUniqueId?.trim() || '' + }`, studentId: record.studentUniqueId, schoolId: record.schoolId, schoolName: record.schoolName, From fda2117873c594c218be3e55a7ce0c9187b16aaa Mon Sep 17 00:00:00 2001 From: ManojNathIC Date: Mon, 16 Dec 2024 16:02:23 +0530 Subject: [PATCH 2/2] de-duplication fixes --- schemas/marksheet.json | 22 +++-- src/examiner/examiner.controller.ts | 1 + src/examiner/examiner.service.ts | 103 +--------------------- src/inspector/inspector.controller.ts | 9 +- src/services/registry/registry.service.ts | 82 ++++++++++++----- 5 files changed, 81 insertions(+), 136 deletions(-) diff --git a/schemas/marksheet.json b/schemas/marksheet.json index a5be885..191796a 100644 --- a/schemas/marksheet.json +++ b/schemas/marksheet.json @@ -7,31 +7,34 @@ } }, "required": ["marksheet"], - "title": "Marksheet", + "title": "marksheet", "definitions": { "marksheet": { "$id": "#/properties/marksheet", "type": "object", "title": "marksheetSchema", "required": [ + "uniqueId", "studentId", "firstName", - "schoolUniqueCode", + "schoolId", "schoolName", "examDate", "academicYear", "issuerName" ], - "uniqueIndexFields": ["studentId"], + "properties": { "studentId": { "type": "string", "title": "Student Identifier" }, - "SchoolId": { + "uniqueId": { "type": "string", - "title": "School Identifier" + "title": "Unique ID", + "unique": true }, + "firstName": { "type": "string", "title": "First Name" @@ -44,7 +47,7 @@ "type": "string", "title": "Last Name" }, - "schoolUniqueCode": { + "schoolId": { "type": "string", "title": "School Identifier" }, @@ -96,6 +99,10 @@ "type": "string", "title": "Name of Issuer" }, + "issuanceDate": { + "type": "string", + "title": "Issuance Date" + }, "certificateId": { "type": "string", "title": "Certificate Id" @@ -108,6 +115,7 @@ } }, "_osConfig": { - "inviteRoles": ["anonymous"] + "inviteRoles": ["anonymous"], + "uniqueIndexFields": ["uniqueId"] } } diff --git a/src/examiner/examiner.controller.ts b/src/examiner/examiner.controller.ts index 20e4e16..9686f77 100644 --- a/src/examiner/examiner.controller.ts +++ b/src/examiner/examiner.controller.ts @@ -60,6 +60,7 @@ export class ExaminerController { }) .on('end', async () => { const data = await this.examinerService.uploadResult( + authToken, results, documentType, ); diff --git a/src/examiner/examiner.service.ts b/src/examiner/examiner.service.ts index d8e7dc4..b98e646 100644 --- a/src/examiner/examiner.service.ts +++ b/src/examiner/examiner.service.ts @@ -11,105 +11,6 @@ export class ExaminerService { private readonly registryService: RegistryService, ) {} - async uploadResult1(academicYear, result, examinerId, examinerName) { - const expectedHeaders = [ - 'Student Id', - 'School Type', - 'Student FirstName', - 'Student MiddleName', - 'Student LastName', - 'School Id', - 'School Name', - 'Grade', - 'Term', - 'Exam Date', - 'Subject and Grade', - 'Academic Year', - 'Duration', - 'Degree', - ]; - const csvheader = Object.keys(result[0]); - const areHeadersValid = this.arraysHaveSameElements( - expectedHeaders.map((key) => { - return key.toLowerCase().replace(/_/g, '').replace(/ /g, ''); - }), - csvheader.map((key) => { - return key.toLowerCase().replace(/_/g, '').replace(/ /g, ''); - }), - ); - const updates = []; - if (areHeadersValid) { - for (const log of result) { - if (Object.keys(log).length) { - const getValue = (key: string) => { - const orignalKey = csvheader.filter((header) => { - const iKey = key - .toLowerCase() - .replace(/_/g, '') - .replace(/ /g, ''); - const mKey = header - .toLowerCase() - .replace(/_/g, '') - .replace(/ /g, ''); - return iKey === mKey; - }); - return orignalKey.length ? log[orignalKey[0]] : null; - }; - - updates.push({ - uniqueId: this.generateFixedId( - getValue('Student Id'), - getValue('Grade'), - getValue('Term'), - academicYear, - ), - studentId: getValue('Student Id'), - schoolType: getValue('School Type'), - firstName: getValue('Student FirstName'), - middleName: getValue('Student MiddleName'), - lastName: getValue('Student LastName'), - schoolId: getValue('School Id'), - schoolName: getValue('School Name'), - examDate: getValue('Exam Date'), - subjectAndGrade: getValue('Subject and Grade'), - academicYear: academicYear ?? getValue('Academic Year'), - duration: getValue('Duration'), - degree: getValue('Degree'), - examinerId: examinerId, - examinerName: examinerName, - grade: getValue('Grade'), - term: getValue('Term'), - certificateNo: - academicYear.split('-')[1] + - '/' + - getValue('Grade') + - '/' + - getValue('Term') + - '/' + - getValue('Student Id'), - candidateNo: - getValue('Grade') + - '/' + - getValue('Term') + - '/' + - getValue('Student Id'), - }); - } - } - //return updates - const promises = []; - updates.forEach((item) => { - //promises.push(this.credentialsService.issueCredential(item)) - promises.push(this.registryService.inviteResultsData(item, '')); - }); - return await Promise.allSettled(promises); - } else { - return { - error: 'Invalid CSV headers', - }; - } - } - async bulkDelete(data, authToken) { try { const promises = []; @@ -138,14 +39,14 @@ export class ExaminerService { return hash; } - async uploadResult(result, documentType) { + async uploadResult(authToken, result, documentType) { const credConfig = CredsConfig[documentType]; // Get the correct transformer and credConfig based on document type const transformedData = transformer[credConfig.transformer](result); const promises = transformedData.map((item) => - this.registryService.inviteResultsData(item, credConfig), + this.registryService.inviteResultsData(authToken, item, credConfig), ); const results = await Promise.allSettled(promises); diff --git a/src/inspector/inspector.controller.ts b/src/inspector/inspector.controller.ts index 11887da..2b6c7c3 100644 --- a/src/inspector/inspector.controller.ts +++ b/src/inspector/inspector.controller.ts @@ -181,18 +181,11 @@ export class InspectorController { //const updatedHtml = html.replace(`alt="QR Code"`, `src="${qrCodeBase64}" alt="QR Code"`); - const updatedHtml1 = html.replace( - /]*src=['"]data:image\/png;base64,[^'"]*['"][^>]*>/g, - `Updated Image`, - ); - const updatedHtml = html.replace( - /]*src=['"](https:\/\/suraj-tekdi\.github\.io\/dsn-dpi-backend-service\/template\/assests\/images\/qrcode\.png)['"][^>]*>/g, + /]*src=['"]data:image\/png;base64,[^'"]*['"][^>]*>/g, `Updated Image`, ); - //console.log("updatedHtml", updatedHtml) - const fileType = format.split('/')[1] as 'png' | 'jpeg' | 'pdf' | 'html'; try { diff --git a/src/services/registry/registry.service.ts b/src/services/registry/registry.service.ts index 1ce1308..3066054 100644 --- a/src/services/registry/registry.service.ts +++ b/src/services/registry/registry.service.ts @@ -14,29 +14,77 @@ export class RegistryService { constructor(private readonly httpService: HttpService) {} - async inviteResultsData(data, credConfig): Promise { + async inviteResultsData(authToken, data, credConfig): Promise { console.log('inviteData', data); - const config = { + let getDataConfig = { + maxBodyLength: Infinity, headers: { - 'Content-Type': 'application/json', + Authorization: `${authToken}`, }, - maxBodyLength: Infinity, }; + const payload = { + filters: { + uniqueId: { + eq: data.uniqueId, + }, + }, + }; try { - console.log('calling invite api'); - const response = await lastValueFrom( + const isDataExist = await lastValueFrom( this.httpService.post( - this.baseUrl + `/registry/api/v1/${credConfig.schemaName}/invite`, - JSON.stringify(data), - config, + this.baseUrl + `/registry/api/v1/${credConfig.schemaName}/search`, + payload, + getDataConfig, ), ); - console.log(JSON.stringify(response.data)); - return response.data; + console.log('Response:', isDataExist.data); + if (isDataExist.data.length > 0) { + const updateData = { + ...data, + status: 'pending', + }; + + const config = { + headers: { + 'Content-Type': 'application/json', + Authorization: authToken, + }, + maxBodyLength: Infinity, + }; + + const response = await lastValueFrom( + this.httpService.put( + this.baseUrl + + `/registry/api/v1/${credConfig.schemaName}/${isDataExist?.data[0]?.osid}`, + JSON.stringify(updateData), + config, + ), + ); + console.log(response); + return response.data; + } else { + const config = { + headers: { + 'Content-Type': 'application/json', + }, + maxBodyLength: Infinity, + }; + + console.log('calling invite api'); + const response = await lastValueFrom( + this.httpService.post( + this.baseUrl + `/registry/api/v1/${credConfig.schemaName}/invite`, + JSON.stringify(data), + config, + ), + ); + console.log(JSON.stringify(response.data)); + return response.data; + } } catch (error) { - console.error(error); + console.error(error.response); throw new HttpException('Duplicate data', error.response?.status || 500); } } @@ -100,25 +148,19 @@ export class RegistryService { rejectData.vctype.split('/')[0] || rejectData.vctype.split('/')[1] ]; - const data = { - status: 'rejected', - }; const config = { headers: { 'Content-Type': 'application/json', Authorization: authToken, - Cookie: 'JSESSIONID=8BF89D1A55B41729876DE84786897796', }, - maxBodyLength: Infinity, }; try { const response = await lastValueFrom( - this.httpService.put( + this.httpService.delete( this.baseUrl + `/registry/api/v1/${credConfig.schemaName}/${resultDataId}`, - JSON.stringify(data), config, ), ); @@ -127,7 +169,7 @@ export class RegistryService { } catch (error) { console.error(error); throw new HttpException( - 'Failed to update results data', + 'Failed to delete data', error.response?.status || 500, ); }