tango-app-api-trax 3.9.58 → 3.9.59

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.58",
3
+ "version": "3.9.59",
4
4
  "description": "Trax",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -415,24 +415,18 @@ export const flagCardsV1 = async ( req, res ) => {
415
415
  detectionFlag: { count: 0 },
416
416
  };
417
417
 
418
- let requestData = req.body;
418
+ const requestData = req.body;
419
419
 
420
420
  const findQuery = [
421
421
  {
422
422
  $match: {
423
423
  client_id: clientId,
424
424
  date_iso: { $gte: adjustedFromDate, $lte: adjustedToDate },
425
- $or: clientId === '11' ?
426
- [
427
- { store_id: { $in: storeId } },
428
- { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } },
429
- { aiStoreList: { $in: storeId } },
430
- ] :
431
- [
432
- { store_id: { $in: storeId } },
433
- { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } },
434
- { aiStoreList: { $in: storeId } },
435
- ],
425
+ $or: [
426
+ { store_id: { $in: storeId } },
427
+ { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } },
428
+ { aiStoreList: { $in: storeId } },
429
+ ],
436
430
  },
437
431
  },
438
432
  {
@@ -444,51 +438,38 @@ export const flagCardsV1 = async ( req, res ) => {
444
438
  {
445
439
  $group: {
446
440
  _id: null,
447
- totalFlag: { $sum: { $add: [ '$questionFlag', '$timeFlag' ] } },
448
441
  questionFlag: { $sum: '$questionFlag' },
449
442
  delayInSubmission: { $sum: '$timeFlag' },
450
443
  },
451
444
  },
452
445
  ];
453
446
 
454
- const getOverallChecklistData = await processedchecklistService.aggregate( findQuery );
447
+ // These three lookups are independent of one another, so run them concurrently
448
+ // instead of sequentially (Mongo aggregation + config find + detection Lambda).
449
+ const detectionPayload = { fromDate, toDate, storeId, clientId };
450
+ const lambdaURL = 'https://f65azvtljclaxp6l7rnx65cdmm0lcgvp.lambda-url.ap-south-1.on.aws/';
455
451
 
456
- if ( !getOverallChecklistData.length ) {
457
- const resVal = {
458
- 'flagCards': {
459
- 'totalFlag': 0,
460
- 'questionFlag': {
461
- 'count': 0,
462
- },
463
- 'delayInSubmission': {
464
- 'count': 0,
465
- },
466
- 'detectionFlag': {
467
- 'count': 0,
452
+ const [ getOverallChecklistData, publishedAiChecklists, resultData ] = await Promise.all( [
453
+ processedchecklistService.aggregate( findQuery ),
454
+ checklistconfigService.find(
455
+ {
456
+ client_id: clientId,
457
+ publish: true,
458
+ checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'storehygienemonitoring', 'unattendeddetection' ] },
468
459
  },
469
- },
470
- };
471
- return res.sendSuccess( resVal );
460
+ { checkListType: 1 },
461
+ ),
462
+ LamdaServiceCall( lambdaURL, detectionPayload ),
463
+ ] );
464
+
465
+ if ( !getOverallChecklistData.length ) {
466
+ return res.sendSuccess( { flagCards } );
472
467
  }
473
468
 
474
469
  const [ data ] = getOverallChecklistData;
475
- if ( data.totalFlag ) flagCards.totalFlag = data.totalFlag;
476
470
  if ( data.questionFlag ) flagCards.questionFlag.count = data.questionFlag;
477
471
  if ( data.delayInSubmission ) flagCards.delayInSubmission.count = data.delayInSubmission;
478
-
479
- const publishedAiChecklists = await checklistconfigService.find(
480
- {
481
- client_id: clientId,
482
- publish: true,
483
- checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'storehygienemonitoring', 'unattendeddetection', 'employeemonitoring', 'activitymonitoring' ] },
484
- },
485
- { checkListType: 1 },
486
- );
487
-
488
- const detectionPayload = { fromDate, toDate, storeId, clientId };
489
- const lambdaURL = 'https://f65azvtljclaxp6l7rnx65cdmm0lcgvp.lambda-url.ap-south-1.on.aws/';
490
- const resultData = await LamdaServiceCall( lambdaURL, detectionPayload );
491
-
472
+ flagCards.totalFlag = flagCards.questionFlag.count + flagCards.delayInSubmission.count;
492
473
 
493
474
  const published = publishedAiChecklists.map( ( val ) => val?.checkListType );
494
475
 
@@ -941,7 +922,9 @@ export const flagTablesV1 = async ( req, res ) => {
941
922
 
942
923
 
943
924
  // Lamda Service Call //
944
- async function LamdaServiceCall( url, data ) {
925
+ async function LamdaServiceCall( url, data, timeoutMs = 8000 ) {
926
+ const controller = new AbortController();
927
+ const timer = setTimeout( () => controller.abort(), timeoutMs );
945
928
  try {
946
929
  const requestOptions = {
947
930
  method: 'POST',
@@ -949,17 +932,20 @@ async function LamdaServiceCall( url, data ) {
949
932
  'Content-Type': 'application/json',
950
933
  },
951
934
  body: JSON.stringify( data ),
935
+ keepalive: true,
936
+ signal: controller.signal,
952
937
  };
953
938
  const response = await fetch( url, requestOptions );
954
939
  if ( !response.ok ) {
955
940
  throw new Error( `Response status: ${response.status}` );
956
- return false;
957
941
  }
958
942
  const json = await response.json();
959
943
  return json;
960
944
  } catch ( error ) {
961
945
  logger.error( { error: error, message: data, function: 'LamdaServiceCall' } );
962
946
  return false;
947
+ } finally {
948
+ clearTimeout( timer );
963
949
  }
964
950
  }
965
951
 
@@ -2021,20 +2007,22 @@ export const flagComparisonCardsV2 = async ( req, res ) => {
2021
2007
  clientId: requestData.clientId,
2022
2008
  };
2023
2009
 
2024
- const publishedAiChecklists = await checklistconfigService.find(
2025
- {
2026
- client_id: requestData.clientId,
2027
- publish: true,
2028
- checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'storehygienemonitoring', 'unattendeddetection', 'employeemonitoring', 'activitymonitoring' ] },
2029
- },
2030
- { checkListType: 1 },
2031
- );
2010
+ // The config lookup and the detection Lambda are independent — run them together.
2011
+ const LamdaURL = 'https://f65azvtljclaxp6l7rnx65cdmm0lcgvp.lambda-url.ap-south-1.on.aws/';
2012
+ const [ publishedAiChecklists, resultData ] = await Promise.all( [
2013
+ checklistconfigService.find(
2014
+ {
2015
+ client_id: requestData.clientId,
2016
+ publish: true,
2017
+ checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'storehygienemonitoring', 'unattendeddetection', 'employeemonitoring' ] },
2018
+ },
2019
+ { checkListType: 1 },
2020
+ ),
2021
+ LamdaServiceCall( LamdaURL, detectionPayload ),
2022
+ ] );
2032
2023
  // if ( !publishedAiChecklists?.length ) {
2033
2024
  // return 0;
2034
2025
  // }
2035
-
2036
- const LamdaURL = 'https://f65azvtljclaxp6l7rnx65cdmm0lcgvp.lambda-url.ap-south-1.on.aws/';
2037
- const resultData = await LamdaServiceCall( LamdaURL, detectionPayload );
2038
2026
  const published = publishedAiChecklists.map( ( val ) => val?.checkListType );
2039
2027
  if ( resultData?.status_code === '200' ) {
2040
2028
  let result = 0;
@@ -2052,11 +2040,12 @@ export const flagComparisonCardsV2 = async ( req, res ) => {
2052
2040
  return 0;
2053
2041
  };
2054
2042
 
2055
- const [ rangeOneData, rangeTwoData, rangeOneDetectionCount, rangeTwoDetectionCount ] = await Promise.all( [
2043
+ const [ rangeOneData, rangeTwoData, rangeOneDetectionCount, rangeTwoDetectionCount, traxMonthlyComparisonData ] = await Promise.all( [
2056
2044
  processedchecklistService.aggregate( createFindQuery( rangeOneFromDate, rangeOneToDate ) ),
2057
2045
  processedchecklistService.aggregate( createFindQuery( rangeTwoFromDate, rangeTwoToDate ) ),
2058
2046
  getDetectionCount( rangeOneFromDate, rangeOneToDate ),
2059
2047
  getDetectionCount( rangeTwoFromDate, rangeTwoToDate ),
2048
+ clientService.findOne( { clientId: requestData.clientId }, { traxMonthlyComparison: 1 } ),
2060
2049
  ] );
2061
2050
 
2062
2051
  // console.log( 'rangeOneFromDate =>', rangeOneFromDate );
@@ -2085,7 +2074,6 @@ export const flagComparisonCardsV2 = async ( req, res ) => {
2085
2074
  flagComparisonCards.runAIComparisonFlag = calculateComparison( rangeOneDetectionCount.ai, rangeTwoDetectionCount.ai );
2086
2075
  }
2087
2076
  flagComparisonCards.traxMonthlyComparison = false;
2088
- let traxMonthlyComparisonData = await clientService.findOne( { clientId: requestData.clientId }, { traxMonthlyComparison: 1 } );
2089
2077
  if ( traxMonthlyComparisonData && traxMonthlyComparisonData.traxMonthlyComparison ) {
2090
2078
  flagComparisonCards.traxMonthlyComparison = traxMonthlyComparisonData.traxMonthlyComparison;
2091
2079
  }
@@ -2106,6 +2094,8 @@ export const flagTablesV2 = async ( req, res ) => {
2106
2094
  toDate = new Date( toDate.getTime() - userTimezoneOffset );
2107
2095
  toDate.setUTCHours( 23, 59, 59, 59 );
2108
2096
  let result = {};
2097
+ let limit = parseInt( requestData?.limit ) || 10;
2098
+ let skip = limit * ( requestData?.offset ) || 0;
2109
2099
 
2110
2100
  const lamdaUrl = JSON.parse( process.env.LAMBDAURL );
2111
2101
 
@@ -2114,19 +2104,19 @@ export const flagTablesV2 = async ( req, res ) => {
2114
2104
  findAndQuery.push(
2115
2105
  { client_id: requestData.clientId },
2116
2106
  { date_iso: { $gte: fromDate, $lte: toDate } },
2117
- // { $or: [ { store_id: { $in: requestData.storeId } }, { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } }, { aiStoreList: { $in: requestData.storeId } } ] },
2107
+ { $or: [ { store_id: { $in: requestData.storeId } }, { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } }, { aiStoreList: { $in: requestData.storeId } } ] },
2118
2108
  // { $or: [ { store_id: { $in: requestData.storeId } }, { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } } ] },
2119
2109
  );
2120
- if ( requestData.clientId == '11' ) {
2121
- findAndQuery.push(
2122
- // { $or: [ { store_id: { $in: requestData.storeId } }, { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } } ] },
2123
- { $or: [ { store_id: { $in: requestData.storeId } }, { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } }, { aiStoreList: { $in: requestData.storeId } } ] },
2124
- );
2125
- } else {
2126
- findAndQuery.push(
2127
- { $or: [ { store_id: { $in: requestData.storeId } }, { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } }, { aiStoreList: { $in: requestData.storeId } } ] },
2128
- );
2129
- }
2110
+ // if ( requestData.clientId == '11' ) {
2111
+ // findAndQuery.push(
2112
+ // // { $or: [ { store_id: { $in: requestData.storeId } }, { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } } ] },
2113
+ // { $or: [ { store_id: { $in: requestData.storeId } }, { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } }, { aiStoreList: { $in: requestData.storeId } } ] },
2114
+ // );
2115
+ // } else {
2116
+ // findAndQuery.push(
2117
+ // { $or: [ { store_id: { $in: requestData.storeId } }, { store_id: { $eq: '' }, userEmail: { $in: requestData.userEmailes } }, { aiStoreList: { $in: requestData.storeId } } ] },
2118
+ // );
2119
+ // }
2130
2120
 
2131
2121
  if ( requestData?.filter === 'all' ) {
2132
2122
  findAndQuery.push( { $or: [ { checkListType: { $in: [ 'custom', 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'storehygienemonitoring', 'unattendeddetection', 'vehicle_check_in', 'employeemonitoring', 'activitymonitoring' ] } } ] } );
@@ -2137,7 +2127,7 @@ export const flagTablesV2 = async ( req, res ) => {
2137
2127
  findAndQuery.push( { checkListType: 'custom' } );
2138
2128
  findAndQuery.push( { timeFlag: { $gte: 1 } } );
2139
2129
  } else if ( requestData?.filter === 'detection' ) {
2140
- findAndQuery.push( { checkListType: { $in: [ 'customerunattended', 'mobileusagedetection', 'staffleftinthemiddle', 'storeopenandclose', 'uniformdetection', 'cleaning', 'scrum', 'outsidebusinesshoursqueuetracking', 'halfshutter', 'tvcompliance', 'cameratampering', 'queuealert', 'staffgrouping', 'boxalert', 'employeeCount', 'storehygienemonitoring', 'unattendeddetection', 'vehicle_check_in', 'employeemonitoring', 'activitymonitoring' ] } } );
2130
+ findAndQuery.push( { checkListType: { $ne: 'custom' } } );
2141
2131
  } else if ( requestData?.filter === 'runAI' ) {
2142
2132
  if ( req.body.runAIChecklistName ) {
2143
2133
  findAndQuery.push( { checkListName: { $in: req.body.runAIChecklistName } } );
@@ -2280,10 +2270,10 @@ export const flagTablesV2 = async ( req, res ) => {
2280
2270
  },
2281
2271
  } );
2282
2272
 
2283
- let getTotalCount = await processedchecklistService.aggregate( findQuery );
2284
- if ( !getTotalCount.length ) {
2285
- return res.sendError( { error: 'No Data Found' }, 204 );
2286
- }
2273
+ // let getTotalCount = await processedchecklistService.aggregate( findQuery );
2274
+ // if ( !getTotalCount.length ) {
2275
+ // return res.sendError( { error: 'No Data Found' }, 204 );
2276
+ // }
2287
2277
 
2288
2278
  if ( requestData.sortColumnName && requestData.sortColumnName != '' && requestData.sortBy && requestData.sortBy !='' ) {
2289
2279
  findQuery.push( { $sort: { [requestData.sortColumnName]: requestData.sortBy } } );
@@ -2291,28 +2281,48 @@ export const flagTablesV2 = async ( req, res ) => {
2291
2281
  findQuery.push( { $sort: { ['submittedChecklist']: -1 } } );
2292
2282
  }
2293
2283
 
2294
- if ( !requestData.export ) {
2295
- let limit = parseInt( requestData?.limit ) || 10;
2296
- let skip = limit * ( requestData?.offset ) || 0;
2297
- findQuery.push( { $skip: skip }, { $limit: limit } );
2298
- }
2284
+ findQuery.push( {
2285
+ $facet: {
2286
+ total: [
2287
+ { $count: 'count' },
2288
+ ],
2299
2289
 
2290
+ data: [
2291
+ { $skip: skip }, { $limit: limit },
2292
+ ],
2293
+ },
2294
+ } );
2300
2295
 
2301
- let getChecklistPerformanceData = await processedchecklistService.aggregate( findQuery );
2296
+ // The detection Lambda only needs request params (not the aggregation result),
2297
+ // so fire it concurrently with the Mongo aggregation instead of after it.
2298
+ // 'question'/'time' filters are custom-only, so the Lambda is never needed there.
2299
+ const mayNeedLambda = ![ 'question', 'time' ].includes( requestData?.filter );
2300
+ const detectionPayload = {
2301
+ 'fromDate': requestData.fromDate,
2302
+ 'toDate': requestData.toDate,
2303
+ 'storeId': requestData.storeId,
2304
+ 'clientId': requestData.clientId,
2305
+ };
2306
+ // const LamdaURL = 'https://f65azvtljclaxp6l7rnx65cdmm0lcgvp.lambda-url.ap-south-1.on.aws/';
2302
2307
 
2308
+ let LamdaURL = lamdaUrl.flagTablesV2;
2309
+
2310
+ let [ getChecklistPerformanceData, lambdaResultData ] = await Promise.all( [
2311
+ processedchecklistService.aggregate( findQuery ),
2312
+ mayNeedLambda ? LamdaServiceCall( LamdaURL, detectionPayload ) : Promise.resolve( null ),
2313
+ ] );
2314
+
2315
+ if ( !getChecklistPerformanceData?.[0]?.total?.[0]?.count ) {
2316
+ return res.sendError( 'No data found', 204 );
2317
+ }
2318
+
2319
+ let getTotalCount = getChecklistPerformanceData?.[0]?.total?.[0]?.count;
2320
+ getChecklistPerformanceData = getChecklistPerformanceData?.[0]?.data;
2303
2321
  if ( getChecklistPerformanceData.length ) {
2304
2322
  const detectionChecklists = getChecklistPerformanceData?.filter( ( val ) => val?.checkListType !== 'custom' );
2305
2323
 
2306
2324
  if ( detectionChecklists?.length || [ 'runAI', 'all' ].includes( requestData?.filter ) ) {
2307
- const detectionPayload = {
2308
- 'fromDate': requestData.fromDate,
2309
- 'toDate': requestData.toDate,
2310
- 'storeId': requestData.storeId,
2311
- 'clientId': requestData.clientId,
2312
- };
2313
-
2314
- let LamdaURL = lamdaUrl.flagTablesV2;
2315
- let resultData = await LamdaServiceCall( LamdaURL, detectionPayload );
2325
+ let resultData = lambdaResultData;
2316
2326
  if ( resultData ) {
2317
2327
  if ( resultData.status_code == '200' ) {
2318
2328
  for ( let index = 0; index < getChecklistPerformanceData.length; index++ ) {
@@ -2414,7 +2424,7 @@ export const flagTablesV2 = async ( req, res ) => {
2414
2424
  return await download( exportdata, res );
2415
2425
  }
2416
2426
 
2417
- result.totalCount = getTotalCount.length;
2427
+ result.totalCount = getTotalCount;
2418
2428
  result.checklistPerformance = getChecklistPerformanceData;
2419
2429
  return res.sendSuccess( result );
2420
2430
  } catch ( error ) {