tango-app-api-audit 3.5.17 → 3.5.18

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.
@@ -5,6 +5,8 @@ import dayjs from 'dayjs';
5
5
  import utc from 'dayjs/plugin/utc.js';
6
6
  import timezone from 'dayjs/plugin/timezone.js';
7
7
  import 'dayjs/locale/en.js';
8
+ import { findOneEyeTestConfig, updateOneEyeTestConfig } from '../service/eyeTestConfiguration.service.js';
9
+ import { ObjectId } from 'mongodb';
8
10
 
9
11
  dayjs.extend( utc );
10
12
  dayjs.extend( timezone );
@@ -994,3 +996,821 @@ export async function userAuditedData( req, res ) {
994
996
  return res.sendError( err, 500 );
995
997
  }
996
998
  }
999
+
1000
+ export async function summaryList( req, res ) {
1001
+ try {
1002
+ const inputData = req.body;
1003
+ if ( inputData.keyType === 'rm' ) {
1004
+ return res.sendSuccess( { result: [
1005
+ {
1006
+ RMName: '',
1007
+ clusterCount: '',
1008
+ storeCount: '',
1009
+ totalFiles: 0,
1010
+ completedFiles: 0,
1011
+ tangoScore: 0,
1012
+ trustScore: 0,
1013
+ },
1014
+
1015
+ ], count: 1 } );
1016
+ } else if ( inputData.keyType === 'cluster' ) {
1017
+ return res.sendSuccess( { result: [
1018
+ {
1019
+ RMName: '',
1020
+ clusterName: '',
1021
+ storeName: '',
1022
+ totalFiles: 0,
1023
+ completedFiles: 0,
1024
+ tangoScore: 0,
1025
+ trustScore: 0,
1026
+ },
1027
+
1028
+ ], count: 1 } );
1029
+ } else {
1030
+ return res.sendSuccess( { result: [
1031
+ {
1032
+ 'fileDate': '2025-08-19',
1033
+ 'comment': '',
1034
+ 'subComment': '',
1035
+ 'date': '2025-08-19T00:00:00.000+00:00',
1036
+ 'storeName': 'LKST886',
1037
+ 'storeId': '11-995',
1038
+ 'type': 'physical',
1039
+ 'optumId': '184812',
1040
+ 'queueId': '106906147',
1041
+ 'engagementId': '',
1042
+ 'totalSteps': 6,
1043
+ 'coveredStepsAI': 5,
1044
+ 'testDuration': 420,
1045
+ 'auditStatus': 'Yet-to-Audit',
1046
+ 'userId': null,
1047
+ 'visitorsType': 'adult',
1048
+ 'inputBucketName': 'tango-eye-test-output',
1049
+ 'filePath': 'eye-test/2025-08-19/11-995/106906147_184812.mp4',
1050
+ 'startTime': '',
1051
+ 'endTime': '',
1052
+ 'displayName': '',
1053
+ 'testStartTime': '17:13:34',
1054
+ 'testEndTime': '17:20:34',
1055
+ 'createdAt': '2025-08-20T08:05:28.188Z',
1056
+ 'updatedAt': '2025-08-20T08:05:28.188Z',
1057
+ 'steps': [
1058
+ {
1059
+ 'processName': 'Distance-VA-Check',
1060
+ 'AIStatus': true,
1061
+ 'predictedTranscript': '',
1062
+ },
1063
+ {
1064
+ 'processName': 'DuoChrome-Test',
1065
+ 'AIStatus': true,
1066
+ 'predictedTranscript': '',
1067
+ },
1068
+ {
1069
+ 'processName': 'Torchlight',
1070
+ 'AIStatus': true,
1071
+ 'predictedTranscript': '',
1072
+ },
1073
+ {
1074
+ 'processName': 'JCC',
1075
+ 'AIStatus': true,
1076
+ 'predictedTranscript': '',
1077
+ },
1078
+ {
1079
+ 'processName': 'Near-VA-Check',
1080
+ 'AIStatus': true,
1081
+ 'predictedTranscript': '',
1082
+ },
1083
+ {
1084
+ 'processName': 'Prescription-Verification',
1085
+ 'AIStatus': false,
1086
+ 'predictedTranscript': '',
1087
+ },
1088
+ ],
1089
+ },
1090
+ {
1091
+ 'fileDate': '2025-08-18',
1092
+ 'comment': '',
1093
+ 'subComment': '',
1094
+ 'date': '2025-08-18T00:00:00.000+00:00',
1095
+ 'storeName': 'LKST80',
1096
+ 'storeId': '11-10',
1097
+ 'type': 'physical',
1098
+ 'optumId': '164980',
1099
+ 'queueId': '106772967',
1100
+ 'engagementId': '',
1101
+ 'totalSteps': 6,
1102
+ 'coveredStepsAI': 4,
1103
+ 'testDuration': 580,
1104
+ 'auditStatus': 'Yet-to-Audit',
1105
+ 'userId': null,
1106
+ 'visitorsType': 'adult',
1107
+ 'inputBucketName': 'tango-eye-test-output',
1108
+ 'filePath': 'eye-test/2025-08-18/11-10/106772967_164980.mp4',
1109
+ 'startTime': '',
1110
+ 'endTime': '',
1111
+ 'displayName': '',
1112
+ 'testStartTime': '12:25:32',
1113
+ 'testEndTime': '12:35:12',
1114
+ 'createdAt': '2025-08-19T11:56:55.822Z',
1115
+ 'updatedAt': '2025-08-19T11:56:55.822Z',
1116
+ 'steps': [
1117
+ {
1118
+ 'processName': 'Distance-VA-Check',
1119
+ 'AIStatus': true,
1120
+ 'predictedTranscript': '',
1121
+ },
1122
+ {
1123
+ 'processName': 'DuoChrome-Test',
1124
+ 'AIStatus': true,
1125
+ 'predictedTranscript': '',
1126
+ },
1127
+ {
1128
+ 'processName': 'Prescription-Verification',
1129
+ 'AIStatus': true,
1130
+ 'predictedTranscript': '',
1131
+ },
1132
+ {
1133
+ 'processName': 'Near-VA-Check',
1134
+ 'AIStatus': true,
1135
+ 'predictedTranscript': '',
1136
+ },
1137
+ {
1138
+ 'processName': 'Torchlight',
1139
+ 'AIStatus': false,
1140
+ 'predictedTranscript': '',
1141
+ },
1142
+ {
1143
+ 'processName': 'JCC',
1144
+ 'AIStatus': false,
1145
+ 'predictedTranscript': '',
1146
+ },
1147
+ ],
1148
+ },
1149
+ {
1150
+ 'fileDate': '2025-08-19',
1151
+ 'comment': 'Possible Fake Video',
1152
+ 'subComment': 'Customer not inside clinic within 120 seconds.',
1153
+ 'date': '2025-08-19T00:00:00.000+00:00',
1154
+ 'storeName': 'LKST1362',
1155
+ 'storeId': '11-1563',
1156
+ 'type': 'physical',
1157
+ 'optumId': '131354',
1158
+ 'queueId': '106907022',
1159
+ 'engagementId': '',
1160
+ 'totalSteps': 6,
1161
+ 'coveredStepsAI': 0,
1162
+ 'testDuration': 555,
1163
+ 'auditStatus': 'Yet-to-Audit',
1164
+ 'userId': null,
1165
+ 'visitorsType': 'adult',
1166
+ 'inputBucketName': 'tango-eye-test-output',
1167
+ 'filePath': 'eye-test/2025-08-19/11-1563/106907022_131354.mp4',
1168
+ 'startTime': '',
1169
+ 'endTime': '',
1170
+ 'displayName': '',
1171
+ 'testStartTime': '17:31:57',
1172
+ 'testEndTime': '17:41:12',
1173
+ 'createdAt': '2025-08-20T10:24:15.169Z',
1174
+ 'updatedAt': '2025-08-20T10:24:15.169Z',
1175
+ 'steps': [],
1176
+ },
1177
+ {
1178
+ 'fileDate': '2025-08-19',
1179
+ 'comment': 'Possible Fake Video',
1180
+ 'subComment': 'Customer not inside clinic within 120 seconds.',
1181
+ 'date': '2025-08-19T00:00:00.000+00:00',
1182
+ 'storeName': 'LKST1158',
1183
+ 'storeId': '11-1003',
1184
+ 'type': 'physical',
1185
+ 'optumId': '174254',
1186
+ 'queueId': '106907580',
1187
+ 'engagementId': '',
1188
+ 'totalSteps': 6,
1189
+ 'coveredStepsAI': 0,
1190
+ 'testDuration': 834,
1191
+ 'auditStatus': 'Yet-to-Audit',
1192
+ 'userId': null,
1193
+ 'visitorsType': 'adult',
1194
+ 'inputBucketName': 'tango-eye-test-output',
1195
+ 'filePath': 'eye-test/2025-08-19/11-1003/106907580_174254.mp4',
1196
+ 'startTime': '',
1197
+ 'endTime': '',
1198
+ 'displayName': '',
1199
+ 'testStartTime': '17:21:42',
1200
+ 'testEndTime': '17:35:36',
1201
+ 'createdAt': '2025-08-20T09:52:29.116Z',
1202
+ 'updatedAt': '2025-08-20T09:52:29.116Z',
1203
+ 'steps': [],
1204
+ },
1205
+ {
1206
+ 'fileDate': '2025-08-19',
1207
+ 'comment': 'Possible Fake Video',
1208
+ 'subComment': 'Customer not inside clinic within 120 seconds.',
1209
+ 'date': '2025-08-19T00:00:00.000+00:00',
1210
+ 'storeName': 'LKST1158',
1211
+ 'storeId': '11-1003',
1212
+ 'type': 'physical',
1213
+ 'optumId': '174254',
1214
+ 'queueId': '106878780',
1215
+ 'engagementId': '',
1216
+ 'totalSteps': 6,
1217
+ 'coveredStepsAI': 0,
1218
+ 'testDuration': 335,
1219
+ 'auditStatus': 'Yet-to-Audit',
1220
+ 'userId': null,
1221
+ 'visitorsType': 'adult',
1222
+ 'inputBucketName': 'tango-eye-test-output',
1223
+ 'filePath': 'eye-test/2025-08-19/11-1003/106878780_174254.mp4',
1224
+ 'startTime': '',
1225
+ 'endTime': '',
1226
+ 'displayName': '',
1227
+ 'testStartTime': '13:08:43',
1228
+ 'testEndTime': '13:14:18',
1229
+ 'createdAt': '2025-08-20T09:47:06.812Z',
1230
+ 'updatedAt': '2025-08-20T09:47:06.812Z',
1231
+ 'steps': [],
1232
+ },
1233
+
1234
+ ], count: 14 } );
1235
+ }
1236
+ } catch ( error ) {
1237
+ const err = error.message || 'Internal Server Error';
1238
+ logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-summaryList' } );
1239
+ return res.sendError( err, 500 );
1240
+ }
1241
+ }
1242
+
1243
+ export async function summaryCard( req, res ) {
1244
+ try {
1245
+ const inputData = req.body;
1246
+ const openSearch = JSON.parse( process.env.OPENSEARCH );
1247
+ logger.info( { inputData: inputData } );
1248
+ let filter =[
1249
+ {
1250
+ 'range': {
1251
+ 'date': {
1252
+ 'gte': new Date( inputData.fromDate ),
1253
+ 'lte': new Date( inputData.toDate ),
1254
+ },
1255
+ },
1256
+ },
1257
+ {
1258
+ term: {
1259
+ 'type.keyword': inputData?.type,
1260
+ },
1261
+ },
1262
+ {
1263
+ terms: {
1264
+ 'storeId.keyword': inputData?.storeId,
1265
+ },
1266
+ },
1267
+ ];
1268
+ if ( inputData?.demographics && inputData?.demographics?.length > 0 ) {
1269
+ filter.push( {
1270
+ terms: {
1271
+ 'visitorsType.keyword': inputData?.demographics,
1272
+ },
1273
+ } );
1274
+ }
1275
+
1276
+ if ( inputData?.complianceScore && inputData?.complianceScore !== null ) {
1277
+ filter.push(
1278
+ {
1279
+ range: {
1280
+ coveragePercentage: {
1281
+ lt: inputData?.complianceScore, // 🔹 adjust threshold here (e.g. gte: 50 for >= 50%)
1282
+ },
1283
+ },
1284
+ },
1285
+ );
1286
+ }
1287
+ let bool = {
1288
+ 'must': filter,
1289
+ };
1290
+ if ( inputData?.category ) {
1291
+ switch ( inputData?.category ) {
1292
+ case 'fake':
1293
+ filter.push( {
1294
+ term: {
1295
+ 'comment.keyword': 'Possible Fake Video',
1296
+ },
1297
+ } );
1298
+ break;
1299
+ case 'genuine':
1300
+ filter.push( {
1301
+ term: {
1302
+ 'comment.keyword': '',
1303
+ },
1304
+ } );
1305
+ bool.should = [
1306
+ {
1307
+ bool: {
1308
+ must_not: [
1309
+ { exists: { field: 'comment.keyword' } },
1310
+ ],
1311
+ },
1312
+ },
1313
+ {
1314
+ term: {
1315
+ 'comment.keyword': '',
1316
+ },
1317
+ },
1318
+ ];
1319
+ bool.minimum_should_match = 1;
1320
+ break;
1321
+ default: return res.sendError( 'Give valid Category', 400 );
1322
+ }
1323
+ }
1324
+ const getQuery = {
1325
+ size: 0, // since we only care about metrics now
1326
+ // query: {
1327
+ // bool: bool, // your filters
1328
+ // },
1329
+ // sort: [
1330
+ // { date: { order: 'desc' } },
1331
+ // ],
1332
+ script_fields: {
1333
+ // ✅ makes coveragePercentage visible inside hits
1334
+ coveragePercentage: {
1335
+ script: {
1336
+ source: `
1337
+ if (doc['totalSteps'].size() == 0 || doc['totalSteps'].value == 0) {
1338
+ return 0;
1339
+ } else {
1340
+ return (doc['coveredStepsAI'].value / doc['totalSteps'].value) * 100;
1341
+ }
1342
+ `,
1343
+ },
1344
+ },
1345
+ },
1346
+ aggs: {
1347
+ // 1. Wrap everything in a global bucket
1348
+ all_docs: {
1349
+ global: {}, // includes all docs matching query
1350
+ aggs: {
1351
+ wrapper: {
1352
+ filters: {
1353
+ filters: {
1354
+ filtered: {
1355
+
1356
+ bool: {
1357
+ must: filter,
1358
+ },
1359
+
1360
+
1361
+ },
1362
+
1363
+ },
1364
+ },
1365
+
1366
+ aggs: {
1367
+
1368
+
1369
+ totalFiles: { value_count: { field: '_id' } },
1370
+
1371
+ completedFiles: {
1372
+ filter: {
1373
+ terms: { 'auditStatus.keyword': [ 'audited', 'reAudited' ] },
1374
+ },
1375
+ },
1376
+
1377
+ // ratio calc must be inside the same level
1378
+ completedRatio: {
1379
+ bucket_script: {
1380
+ buckets_path: {
1381
+ audited: 'completedFiles._count',
1382
+ total: 'totalFiles',
1383
+ },
1384
+ script: 'params.total > 0 && params.audited > 0 ? (params.audited / params.total) * 100 : 0',
1385
+ },
1386
+ },
1387
+
1388
+ tangoScore: {
1389
+ scripted_metric: {
1390
+ init_script: 'state.sum = 0; state.count = 0;',
1391
+ map_script: `
1392
+ if (doc['totalSteps'].size() != 0 && doc['totalSteps'].value > 0) {
1393
+ state.sum += (doc['coveredStepsAI'].value / doc['totalSteps'].value) * 100;
1394
+ state.count += 1;
1395
+ }
1396
+ `,
1397
+ combine_script: 'return state;',
1398
+ reduce_script: `
1399
+ double totalSum = 0;
1400
+ double totalCount = 0;
1401
+ for (s in states) {
1402
+ totalSum += s.sum;
1403
+ totalCount += s.count;
1404
+ }
1405
+ return totalCount > 0 ? totalSum / totalCount : 0;
1406
+ `,
1407
+ },
1408
+ },
1409
+
1410
+ trustScore: {
1411
+ filter: {
1412
+ terms: { 'auditStatus.keyword': [ 'audited', 'reAudited' ] },
1413
+ },
1414
+ aggs: {
1415
+ avg_val: { avg: { field: 'trustScore' } },
1416
+ },
1417
+ },
1418
+
1419
+ // 5. Past week comparison
1420
+ trend: {
1421
+ date_range: {
1422
+ field: 'date',
1423
+ format: 'yyyy-MM-dd',
1424
+ ranges: [
1425
+ { key: 'previous', from: 'now-14d/d', to: 'now-7d/d' },
1426
+ { key: 'current', from: 'now-7d/d', to: 'now' },
1427
+ ],
1428
+ },
1429
+ aggs: {
1430
+ total_count: { value_count: { field: '_id' } },
1431
+ },
1432
+ },
1433
+ tangoScoreTrend: {
1434
+ bucket_script: {
1435
+ buckets_path: {
1436
+ current: 'trend[\'current\']>total_count',
1437
+ previous: 'trend[\'previous\']>total_count',
1438
+ },
1439
+ script: `
1440
+ params.previous > 0
1441
+ ? ((params.current - params.previous) / params.previous) * 100
1442
+ : 0
1443
+ `,
1444
+ },
1445
+ },
1446
+ },
1447
+ },
1448
+
1449
+
1450
+ } },
1451
+ },
1452
+
1453
+ };
1454
+
1455
+
1456
+ const getOutput = await getOpenSearchData( openSearch?.EyeTestInput, getQuery );
1457
+ logger.info( { getOutput: getOutput } );
1458
+ const initialValue = {
1459
+ totalFiles: 0,
1460
+ completedFiles: 0,
1461
+ completedRatio: 0,
1462
+ tangoScore: 0,
1463
+ tangoScoreTrend: 0,
1464
+ trustScore: 0,
1465
+ };
1466
+ if ( getOutput?.body?.aggregations?.all_docs?.wrapper?.buckets?.filtered ) {
1467
+ const temp= getOutput?.body?.aggregations?.all_docs?.wrapper?.buckets?.filtered;
1468
+ initialValue.totalFiles =temp?.totalFiles?.value;
1469
+ initialValue.completedFiles =temp?.completedFiles?.doc_count;
1470
+ initialValue.completedRatio =temp?.completedRatio?.value || 0;
1471
+ initialValue.tangoScore =temp?.tangoScore?.value || 0;
1472
+ initialValue.tangoScoreTrend =temp?.tangoScoreTrend?.value || 0;
1473
+ initialValue.trustScore =temp?.trustScore?.avg_val?.value == null ? 'NA':temp?.trustScore?.avg_val?.value;
1474
+ }
1475
+ const result = initialValue;
1476
+
1477
+ return res.sendSuccess( { result: result } );
1478
+ } catch ( error ) {
1479
+ const err = error.message || 'Internal Server Error';
1480
+ logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-summaryCard' } );
1481
+ return res.sendError( err, 500 );
1482
+ }
1483
+ }
1484
+
1485
+ export async function emailAlertLog( req, res ) {
1486
+ try {
1487
+ // declare a key for request data
1488
+ const inputData = req.body;
1489
+ inputData.sortBy = inputData.sortBy || 'updatedAt';
1490
+ inputData.sortOrder = inputData.sortOrder || -1;
1491
+ inputData.clientId = req.user.userType == 'tango'? inputData?.clientId : req?.user?.clientId;
1492
+ // get openserach name form the env file
1493
+ const openSearch = JSON.parse( process.env.OPENSEARCH );
1494
+
1495
+ // getting user and cluster information from mongo db
1496
+
1497
+ // const getUserListQuery = {
1498
+ // clientId: inputData.clientId,
1499
+ // configureType: 'user',
1500
+ // };
1501
+
1502
+ // const getUserList = await findOneEyeTestConfig( getUserListQuery, { userList: 1 } );
1503
+ // if ( !getUserList || !getUserList?.userList || getUserList?.userList?.lenght == 0 ) {
1504
+ // return res.sendError( 'No records found', 204 );
1505
+ // }
1506
+ // const userList = getUserList?.map( ( item ) => item.email );
1507
+
1508
+ // gettting cluster respective users
1509
+ // const clusterQuery =[
1510
+ // {
1511
+ // $match: {
1512
+ // $and: [
1513
+ // {
1514
+ // 'Teamlead.email': { $in: userList },
1515
+ // },
1516
+ // ],
1517
+ // },
1518
+ // },
1519
+ // {
1520
+ // $project: {
1521
+ // email: '$Teamlead.email',
1522
+ // clusterName: '$clusterName',
1523
+ // clientId: 1,
1524
+ // },
1525
+ // },
1526
+ // ];
1527
+ // const getCluster = await aggregateClusters();
1528
+ // open search query to get logs
1529
+
1530
+ let filter =[
1531
+ {
1532
+ 'range': {
1533
+ 'date': {
1534
+ 'gte': new Date( inputData.fromDate ),
1535
+ 'lte': new Date( inputData.toDate ),
1536
+ },
1537
+ },
1538
+ },
1539
+ ];
1540
+ let sort =[
1541
+ { [inputData?.sortBy]: { order: inputData.sortOrder === 1 ? 'asc' : 'desc' } },
1542
+ ];
1543
+ if ( inputData.RmList && inputData.RmList?.lenght > 0 ) {
1544
+ filter.push( {
1545
+ 'terms': {
1546
+ 'RMEmail.keyword': inputData?.RmList,
1547
+ },
1548
+ } );
1549
+ }
1550
+
1551
+ if ( inputData.cluster && inputData.cluster?.lenght > 0 ) {
1552
+ filter.push( {
1553
+ 'terms': {
1554
+ 'cluster.keyword': inputData?.cluster,
1555
+ },
1556
+ } );
1557
+ }
1558
+ const getQuery = {
1559
+ 'size': 100,
1560
+ 'query': {
1561
+ 'bool': {
1562
+ 'must': filter,
1563
+ },
1564
+ },
1565
+ 'sort': sort,
1566
+ };
1567
+
1568
+ // get query result from the open saerch
1569
+ const getData= await getOpenSearchData( openSearch.eyeTestEmailAlert, getQuery );
1570
+
1571
+ // throw error if got null or empty array
1572
+ if ( getData && getData?.body?.hits?.hits?.length > 0 ) {
1573
+ return res.sendError( 'No records found', 204 );
1574
+ }
1575
+
1576
+ // declare open search output
1577
+ const result = getData?.body?.hits?.hits?.length;
1578
+
1579
+
1580
+ // throw error if null or undefined or empty array
1581
+
1582
+
1583
+ logger.info( { inputData: inputData, getData: getData } );
1584
+ return res.sendSuccess( { result: result } );
1585
+ } catch ( error ) {
1586
+ const err = error.message || 'Internal Server Error';
1587
+ logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-emailAlertLog' } );
1588
+ return res.sendError( err, 500 );
1589
+ }
1590
+ }
1591
+
1592
+ export async function getUserConfig( req, res ) {
1593
+ try {
1594
+ const inputData =req.query;
1595
+ const clientId = req.user.userType =='tango' ? inputData?.clientId : req?.user?.clientId;
1596
+ const query = {
1597
+ clientId: clientId,
1598
+ configureType: 'user',
1599
+
1600
+ };
1601
+ const getOne = await findOneEyeTestConfig( query, { userList: 1 } );
1602
+ logger.info( { getOne: getOne, message: 'getUserConfig' } );
1603
+ return res.sendSuccess( { result: getOne?.userList || [] } );
1604
+ } catch ( error ) {
1605
+ const err = error.message || 'Internal Server Error';
1606
+ logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-getUserConfig' } );
1607
+ return res.sendError( err, 500 );
1608
+ }
1609
+ }
1610
+
1611
+ export async function addUserConfig( req, res, next ) {
1612
+ try {
1613
+ const inputQuery = req.query;
1614
+ const inputData = req.body;
1615
+ inputData.clientId = req?.user?.userType == 'tango'? inputData.clientId : req.user.clientId;
1616
+ if ( inputQuery?._id ) {
1617
+ next();
1618
+ } else {
1619
+ const query = {
1620
+ clientId: inputData.clientId,
1621
+ configureType: 'user',
1622
+ };
1623
+ const record = {
1624
+ clientId: inputData.clientId,
1625
+ configureType: 'user',
1626
+ userList: inputData.userList,
1627
+ };
1628
+ const updatedOne = await updateOneEyeTestConfig( query, record, { upsert: true } );
1629
+ logger.info( { updatedOne: updatedOne } );
1630
+ if ( updatedOne ) {
1631
+ return res.sendSuccess( 'Email added successfully' );
1632
+ } else {
1633
+ return res.sendError( 'Added Failed' );
1634
+ }
1635
+ }
1636
+ } catch ( error ) {
1637
+ const err = error.message || 'Internal Server Error';
1638
+ logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-emailAlertLog' } );
1639
+ return res.sendError( err, 500 );
1640
+ }
1641
+ }
1642
+
1643
+ export async function updateUserConfig( req, res ) {
1644
+ try {
1645
+ const inputData = req.body;
1646
+ const inputQuery = req.query;
1647
+ const query = {
1648
+ _id: new ObjectId( inputQuery._id ),
1649
+ };
1650
+ const record = {
1651
+ userList: inputData.userList,
1652
+ clientId: inputData.clientId,
1653
+ configureType: 'user',
1654
+ };
1655
+ const updatedOne = await updateOneEyeTestConfig( query, record, { upsert: true } );
1656
+ logger.info( { updatedOne: updatedOne } );
1657
+ if ( updatedOne ) {
1658
+ return res.sendSuccess( 'Config user updated successfully' );
1659
+ } else {
1660
+ return res.sendError( 'updated Failed' );
1661
+ }
1662
+ } catch ( error ) {
1663
+ const err = error.message || 'Internal Server Error';
1664
+ logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-updateUserConfig' } );
1665
+ return res.sendError( err, 500 );
1666
+ }
1667
+ }
1668
+
1669
+ export async function rmList( req, res ) {
1670
+ try {
1671
+ const inputData = req.query;
1672
+ const query = {
1673
+ clientId: req?.user?.userType == 'tango' ? inputData.clientId : req?.user?.clientId,
1674
+ };
1675
+ const getRMList = await findOneEyeTestConfig( query, { userList: 1 } );
1676
+ return res.sendSuccess( { result: getRMList?.userList || [] } );
1677
+ } catch ( error ) {
1678
+ const err = error.message || 'Internal Server Error';
1679
+ logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-rmList' } );
1680
+ return res.sendError( err, 500 );
1681
+ }
1682
+ }
1683
+
1684
+
1685
+ export async function getEmailConfig( req, res ) {
1686
+ try {
1687
+ const inputData =req.query;
1688
+ const clientId = req.user.userType =='tango' ? inputData?.clientId : req?.user?.clientId;
1689
+ const query = {
1690
+ clientId: clientId,
1691
+ configureType: 'email',
1692
+ };
1693
+ const getOne = await findOneEyeTestConfig( query, { complianceThreshold: 1 } );
1694
+ logger.info( { getOne: getOne, message: 'getEmailConfig' } );
1695
+ // if ( !getOne?.complianceThreshold ) {
1696
+ // return res.sendError( 'No data found', 204 );
1697
+ // }
1698
+ return res.sendSuccess( { result: getOne?.complianceThreshold } );
1699
+ } catch ( error ) {
1700
+ const err = error.message || 'Internal Server Error';
1701
+ logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-getEmailConfig' } );
1702
+ return res.sendError( err, 500 );
1703
+ }
1704
+ }
1705
+
1706
+
1707
+ export async function updateEmailConfig( req, res ) {
1708
+ try {
1709
+ const inputData = req.body;
1710
+ const inputQuery = req.query;
1711
+ const query = {
1712
+ _id: new ObjectId( inputQuery._id ),
1713
+ };
1714
+ const record = {
1715
+ complianceThreshold: inputData.complianceThreshold,
1716
+ clientId: inputData.clientId,
1717
+ configureType: 'email',
1718
+ };
1719
+ const updatedOne = await updateOneEyeTestConfig( query, record, { upsert: true } );
1720
+ logger.info( { updatedOne: updatedOne } );
1721
+ if ( updatedOne ) {
1722
+ return res.sendSuccess( 'Updated successfully' );
1723
+ } else {
1724
+ return res.sendError( 'updated Failed' );
1725
+ }
1726
+ } catch ( error ) {
1727
+ const err = error.message || 'Internal Server Error';
1728
+ logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-emailAlertLog' } );
1729
+ return res.sendError( err, 500 );
1730
+ }
1731
+ }
1732
+
1733
+ export async function updateEmailConfig1( req, res ) {
1734
+ try {
1735
+ const storId =[ '11-1925',
1736
+ '11-1918',
1737
+ '11-2306',
1738
+ '11-1902',
1739
+ '11-1996',
1740
+ '11-2183',
1741
+ '11-1992',
1742
+ '11-1405',
1743
+ '11-2172',
1744
+ '11-1107',
1745
+ '11-1170',
1746
+ '11-1058',
1747
+ '11-1901',
1748
+ '11-1838',
1749
+ '11-2159',
1750
+ '11-1795',
1751
+ '11-1456',
1752
+ '11-2307',
1753
+ '11-1863',
1754
+ '11-2021',
1755
+ '11-1074',
1756
+ '11-1118',
1757
+ '11-2011',
1758
+ '11-1926',
1759
+ '11-2184',
1760
+ '11-1115',
1761
+ '11-1199',
1762
+ '11-2338',
1763
+ '11-2242',
1764
+ '11-2000',
1765
+ '11-1452',
1766
+ '11-1787',
1767
+
1768
+ ];
1769
+ let temp = [];
1770
+ for ( const key of storId ) {
1771
+ const speedTest = await getOpenSearchData( 'edgeapp_systemlogs',
1772
+ {
1773
+ 'size': 1,
1774
+ 'query': {
1775
+ 'bool': {
1776
+ 'must': [
1777
+ {
1778
+ 'term': {
1779
+ 'store_date.keyword': '21-08-2025',
1780
+ },
1781
+ },
1782
+ {
1783
+ 'term': {
1784
+ 'storeId.keyword': key,
1785
+ },
1786
+ },
1787
+ {
1788
+ 'term': {
1789
+ 'log_subtype.keyword': 'Speed_Test',
1790
+ },
1791
+ },
1792
+
1793
+ ],
1794
+
1795
+ },
1796
+ },
1797
+
1798
+ 'sort': [
1799
+ {
1800
+ 'timestamp': {
1801
+ 'order': 'desc',
1802
+ },
1803
+ },
1804
+ ],
1805
+
1806
+ } );
1807
+ temp.push( { storeId: key, speedTest: speedTest?.body?.hits?.hits?.[0]?._source?.data?.upload_Speed || 0 } );
1808
+ }
1809
+ return res.sendSuccess( temp );
1810
+ // logger.info( { speedTest: speedTest } );
1811
+ } catch ( error ) {
1812
+ const err = error.message || 'Internal Server Error';
1813
+ logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-emailAlertLog' } );
1814
+ return res.sendError( err, 500 );
1815
+ }
1816
+ }