tango-app-api-trax 3.9.41 → 3.9.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-trax",
3
- "version": "3.9.41",
3
+ "version": "3.9.43",
4
4
  "description": "Trax",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -30,7 +30,7 @@
30
30
  "path": "^0.12.7",
31
31
  "puppeteer": "^24.39.1",
32
32
  "swagger-ui-express": "^5.0.1",
33
- "tango-api-schema": "^2.6.17",
33
+ "tango-api-schema": "^2.6.23",
34
34
  "tango-app-api-middleware": "^3.5.2",
35
35
  "url": "^0.11.4",
36
36
  "winston": "^3.13.1",
@@ -931,7 +931,7 @@ async function insertData( requestData ) {
931
931
  },
932
932
  } );
933
933
  let getSections = await CLquestions.aggregate( sectionQuery );
934
- if ( getSections.length || [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'cleaning', 'scrum', 'suspiciousactivity', 'suspiciousfootfall', 'drinking', 'bagdetection', 'inventorycount', 'carsattended', 'numberplateinfo', 'vehicle_check_in', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'unattendeddetection', 'employeemonitoring' ].includes( getCLconfig.checkListType ) ) {
934
+ if ( getSections.length || [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'cleaning', 'scrum', 'suspiciousactivity', 'suspiciousfootfall', 'drinking', 'bagdetection', 'inventorycount', 'carsattended', 'numberplateinfo', 'vehicle_check_in', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'unattendeddetection', 'employeemonitoring', 'activitymonitoring' ].includes( getCLconfig.checkListType ) ) {
935
935
  if ( getSections.length ) {
936
936
  for ( let element3 of getSections ) {
937
937
  let collectQuestions = {};
@@ -1226,11 +1226,11 @@ async function insertData( requestData ) {
1226
1226
  // }
1227
1227
  }
1228
1228
  } else {
1229
- if ( [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'cleaning', 'scrum', 'suspiciousactivity', 'suspiciousfootfall', 'drinking', 'bagdetection', 'inventorycount', 'carsattended', 'numberplateinfo', 'vehicle_check_in', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'unattendeddetection', 'employeemonitoring' ].includes( getCLconfig.checkListType ) ) {
1229
+ if ( [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'eyetest', 'remoteoptometrist', 'storehygienemonitoring', 'cleaning', 'scrum', 'suspiciousactivity', 'suspiciousfootfall', 'drinking', 'bagdetection', 'inventorycount', 'carsattended', 'numberplateinfo', 'vehicle_check_in', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'unattendeddetection', 'employeemonitoring', 'activitymonitoring' ].includes( getCLconfig.checkListType ) ) {
1230
1230
  let storeNameList = allQuestion.map( ( item ) => item.store_id );
1231
- let storeDetails = await storeService.find( { clientId: getCLconfig.client_id, status: 'active', ...( [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'scrum', 'cleaning', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'unattendeddetection', 'employeemonitoring' ].includes( getCLconfig.checkListType ) ) ? { storeId: { $in: storeNameList } } : {} }, { storeId: 1 } );
1231
+ let storeDetails = await storeService.find( { clientId: getCLconfig.client_id, status: 'active', ...( [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'scrum', 'cleaning', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'unattendeddetection', 'employeemonitoring', 'activitymonitoring' ].includes( getCLconfig.checkListType ) ) ? { storeId: { $in: storeNameList } } : {} }, { storeId: 1 } );
1232
1232
  let storeList = storeDetails.map( ( store ) => store.storeId );
1233
- if ( [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'scrum', 'cleaning', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'unattendeddetection', 'employeemonitoring' ].includes( getCLconfig.checkListType ) ) {
1233
+ if ( [ 'storeopenandclose', 'mobileusagedetection', 'uniformdetection', 'customerunattended', 'staffleftinthemiddle', 'scrum', 'cleaning', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'unattendeddetection', 'employeemonitoring', 'activitymonitoring' ].includes( getCLconfig.checkListType ) ) {
1234
1234
  allQuestion = allQuestion.filter( ( ele ) => storeList.includes( ele?.store_id ) );
1235
1235
  } else {
1236
1236
  allQuestion = storeDetails.map( ( item ) => {
@@ -2790,7 +2790,7 @@ export async function countUpdateRunAI( req, res ) {
2790
2790
  };
2791
2791
 
2792
2792
  // complianceCount is already populated for the other answer types; add the image/video scores on top.
2793
- let userComplianceTotal = getDetails.userComplianceCount || 0;
2793
+ let userComplianceTotal = 0;
2794
2794
 
2795
2795
  // Pull every "Matched/Not Matched" verdict out of a runAIData array, tolerating both shapes we store:
2796
2796
  // 1) [ { answerImage, results: [ { featureName, value } ] } ] (verdict nested under results)
@@ -2809,26 +2809,31 @@ export async function countUpdateRunAI( req, res ) {
2809
2809
 
2810
2810
  getDetails.questionAnswers.forEach( ( section ) => {
2811
2811
  section.questions.forEach( ( question ) => {
2812
- if ( question.compliance && [ 'image', 'image/video' ].includes( question.answerType ) && question?.answers?.[0]?.multiReferenceImage?.some( ( img ) => img.runAI ) ) {
2813
- // For 'image/video' each userAnswer carries its own answerType and runAIData only lives on
2814
- // the image entries; a pure 'image' question keeps runAIData directly on every userAnswer.
2815
- const aiAnswers = question.answerType === 'image/video' ?
2816
- ( question.userAnswer || [] ).filter( ( ua ) => ua?.answerType === 'image' ) :
2817
- ( question.userAnswer || [] );
2818
-
2819
- // Compliance comes from the first configured answer: every "Matched/Not Matched" verdict
2820
- // across the image answers must be True to count as matched, otherwise it's not matched.
2821
- const matchValues = aiAnswers.flatMap( ( ua ) => extractMatchValues( ua?.runAIData ) );
2822
- const allMatched = matchValues.length > 0 && matchValues.every( ( v ) => v === 'True' || v === true );
2823
- const score = allMatched ?
2824
- ( question.answers?.[0]?.matchedCount ?? 0 ) :
2825
- ( question.answers?.[0]?.notMatchedCount ?? 0 );
2826
-
2827
- // Persist the derived score back onto each userAnswer so PDF/dashboard reads stay consistent.
2828
- ( question.userAnswer || [] ).forEach( ( ua ) => {
2829
- ua.complianceScore = score;
2830
- } );
2831
-
2812
+ if ( question.compliance ) {
2813
+ let score = 0;
2814
+ if ( [ 'image', 'image/video' ].includes( question.answerType ) && question?.answers?.[0]?.multiReferenceImage?.some( ( img ) => img.runAI ) ) {
2815
+ // For 'image/video' each userAnswer carries its own answerType and runAIData only lives on
2816
+ // the image entries; a pure 'image' question keeps runAIData directly on every userAnswer.
2817
+ const aiAnswers = question.answerType === 'image/video' ?
2818
+ ( question.userAnswer || [] ).filter( ( ua ) => ua?.answerType === 'image' ) :
2819
+ ( question.userAnswer || [] );
2820
+
2821
+ // Compliance comes from the first configured answer: every "Matched/Not Matched" verdict
2822
+ // across the image answers must be True to count as matched, otherwise it's not matched.
2823
+ const matchValues = aiAnswers.flatMap( ( ua ) => extractMatchValues( ua?.runAIData ) );
2824
+ const allMatched = matchValues.length > 0 && matchValues.every( ( v ) => v === 'True' || v === true );
2825
+ score = allMatched ?
2826
+ ( question.answers?.[0]?.matchedCount ?? 0 ) :
2827
+ ( question.answers?.[0]?.notMatchedCount ?? 0 );
2828
+
2829
+ // Persist the derived score back onto each userAnswer so PDF/dashboard reads stay consistent.
2830
+ ( question.userAnswer || [] ).forEach( ( ua ) => {
2831
+ ua.complianceScore = score;
2832
+ } );
2833
+ } else {
2834
+ const scores = ( question.userAnswer || [] ).map( ( ua ) => ua.complianceScore ?? 0 );
2835
+ score = scores.length ? Math.max( ...scores ) : 0;
2836
+ }
2832
2837
  userComplianceTotal += score;
2833
2838
  }
2834
2839
  } );