tango-app-api-audit 3.4.68-beta.1 → 3.4.68-beta.11

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-audit",
3
- "version": "3.4.68-beta.1",
3
+ "version": "3.4.68-beta.11",
4
4
  "description": "audit & audit metrics apis",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -26,8 +26,8 @@
26
26
  "mongodb": "^6.7.0",
27
27
  "nodemon": "^3.1.3",
28
28
  "swagger-ui-express": "^5.0.1",
29
- "tango-api-schema": "^2.2.95",
30
- "tango-app-api-middleware": "^3.1.71",
29
+ "tango-api-schema": "^2.2.98",
30
+ "tango-app-api-middleware": "^3.1.73",
31
31
  "winston": "^3.13.0",
32
32
  "winston-daily-rotate-file": "^5.0.0"
33
33
  },
@@ -1,4 +1,4 @@
1
- import { getOpenSearchData, getOpenSearchById, logger, insertOpenSearchData, updateOpenSearchData } from 'tango-app-api-middleware';
1
+ import { getOpenSearchData, getOpenSearchById, logger, insertOpenSearchData, updateOpenSearchData, download, chunkArray } from 'tango-app-api-middleware';
2
2
  import { findOneUser } from '../service/user.service.js';
3
3
  import mongoose from 'mongoose';
4
4
  import dayjs from 'dayjs';
@@ -16,7 +16,8 @@ export async function getList( req, res ) {
16
16
  const limit = inputData.limit || 10;
17
17
  const offset = inputData.offset ? ( inputData.offset - 1 ) * limit : 0;
18
18
 
19
-
19
+ const sortBy = inputData?.sortBy ? inputData.sortBy === 'coveredStepsAI' ? inputData.sortBy :`${inputData.sortBy}.keyword` : 'storeName.keyword';
20
+ const order = inputData?.sortOrder || -1;
20
21
  let filter= [
21
22
  {
22
23
  'range': {
@@ -28,21 +29,24 @@ export async function getList( req, res ) {
28
29
  },
29
30
 
30
31
  ];
31
- let search ={
32
- 'must': filter,
33
- };
34
32
 
35
- if ( inputData.visitorsType && inputData.visitorsType.lenght > 0 ) {
36
- filter.push( {
37
33
 
38
- 'terms': {
39
- 'visitorsType.keyword': inputData.visitorsType,
34
+ // if ( inputData.demographics && inputData.demographics.length > 0 ) {
35
+ // filter.push( {
36
+ // 'terms': {
37
+ // 'visitorsType.keyword': inputData.demographics,
38
+ // },
39
+ // } );
40
+ // }
41
+ if ( inputData.type && inputData.type!='' ) {
42
+ filter.push( {
43
+ 'term': {
44
+ 'type.keyword': inputData.type,
40
45
  },
41
46
 
42
47
  } );
43
48
  }
44
-
45
- if ( inputData.storeId && inputData.storeId.lenght > 0 ) {
49
+ if ( inputData.storeId && inputData.storeId.length > 0 ) {
46
50
  filter.push( {
47
51
 
48
52
  'terms': {
@@ -51,6 +55,9 @@ export async function getList( req, res ) {
51
55
 
52
56
  } );
53
57
  }
58
+ let search ={
59
+ 'must': filter,
60
+ };
54
61
 
55
62
  if ( inputData.searchValue && inputData.searchValue !== '' ) {
56
63
  search ={
@@ -109,14 +116,41 @@ export async function getList( req, res ) {
109
116
  'minimum_should_match': 1,
110
117
  };
111
118
  }
112
-
113
119
  let searchQuery={
114
120
  'from': offset,
115
121
  'size': limit,
116
122
  'query': {
117
123
  'bool': search,
118
124
  },
125
+ 'sort': [
126
+ { date: { order: 'desc' } },
127
+ ],
119
128
  };
129
+ if ( sortBy && sortBy !== '' ) {
130
+ searchQuery={
131
+ 'from': offset,
132
+ 'size': limit,
133
+ 'query': {
134
+ 'bool': search,
135
+ },
136
+ 'sort': [
137
+ { [sortBy]: { order: order === -1 ?'desc':'asc' } },
138
+ ],
139
+ };
140
+ }
141
+
142
+ if ( inputData.isExport==true ) {
143
+ searchQuery={
144
+ 'from': 0,
145
+ 'size': 10000,
146
+ 'query': {
147
+ 'bool': search,
148
+ },
149
+ 'sort': [
150
+ { 'storeName.keyword': { order: 'desc' } },
151
+ ],
152
+ };
153
+ }
120
154
  const result = await getOpenSearchData( openSearch.EyeTestInput, searchQuery );
121
155
  const count = result?.body?.hits?.total?.value;
122
156
  if ( !count || count == 0 ) {
@@ -126,6 +160,71 @@ export async function getList( req, res ) {
126
160
  if ( !searchValue || searchValue?.length == 0 ) {
127
161
  return res.sendError( 'No data found', 204 );
128
162
  }
163
+ if ( inputData.isExport == true ) {
164
+ const chunkedMappingData = await chunkArray( searchValue, 10 );
165
+ const promises = chunkedMappingData.map( async ( chunk ) => {
166
+ const exportData = [];
167
+ for ( const element of chunk ) {
168
+ const testDuration = element?._source?.testDuration;
169
+ const minutes = Math.floor( testDuration / 60 );
170
+ const seconds = testDuration % 60;
171
+ const minutes1 =minutes> 1? `${minutes} mins` : `${minutes} min`;
172
+ const seconds1 = seconds > 1? `${minutes} secs`: seconds == 1? `${minutes} sec` : '';
173
+ const duration =`${minutes1} ${seconds1}`;
174
+ const userName = await findOneUser( { _id: element?._source?.userId }, { _id: 0, userName: 1 } );
175
+ if ( element?._source?.type == 'physical' ) {
176
+ exportData.push( {
177
+ 'Date': dayjs( element?._source?.date ).format( 'D MMM, YYYY' ),
178
+ 'Store Name': element?._source?.storeName,
179
+ 'Store ID': element?._source?.storeId || 'Un Assigned',
180
+ 'Store Name': element?._source?.storeName ||'Un Assigned',
181
+ 'Optum ID': element?._source?.optumId,
182
+ 'Queue ID': element?._source?.queueId,
183
+ 'Compliance Score': element?._source?.totalSteps>0 ? Math.round( ( element?._source?.coveredStepsAI/ element?._source?.totalSteps )*100 ): 0,
184
+ 'Steps Covered By AI': element?._source?.coveredStepsAI || 0,
185
+ 'Visitor Type': element?._source?.visitorsType,
186
+ 'Test Duration': duration || '',
187
+ 'Audit Status': element?._source?.auditStatus || '',
188
+ 'Audited By': userName?.userName || '',
189
+
190
+ } );
191
+ } else {
192
+ exportData.push( {
193
+ 'Date': dayjs( element?._source?.date ).format( 'D MMM, YYYY' ),
194
+ 'Store Name': element?._source?.storeName,
195
+ 'Store ID': element?._source?.storeId || 'Un Assigned',
196
+ 'Store Name': element?._source?.storeName ||'Un Assigned',
197
+ 'Engagement ID': element?._source?.engagementId,
198
+ 'Compliance Score': element?._source?.complianceScore || 0,
199
+ 'Steps Covered By AI': element?._source?.coveredStepsAI || 0,
200
+ 'Visitor Type': element?._source?.visitorsType,
201
+ 'Test Duration': duration || '',
202
+ 'Audit Status': element?._source?.auditStatus || '',
203
+ 'Audited By': userName?.userName || '',
204
+
205
+ } );
206
+ }
207
+ }
208
+ return exportData;
209
+ } );
210
+ const mappedArrays = await Promise.all( promises );
211
+ const result = mappedArrays.flat();
212
+ await download( result, res );
213
+ return;
214
+ } else {
215
+ for ( const [ i, item ] of searchValue.entries() ) {
216
+ const userName = await findOneUser( { _id: item?._source?.userId }, { _id: 0, userName: 1 } );
217
+ const testDuration = searchValue[i]?._source?.testDuration;
218
+ const minutes = Math.floor( testDuration / 60 );
219
+ const seconds = testDuration % 60;
220
+ searchValue[i]._source.complianceScore = searchValue[i]?._source?.totalSteps>0 ? Math.round( ( searchValue[i]?._source?.coveredStepsAI/ searchValue[i]?._source?.totalSteps )*100 ): 0;
221
+ searchValue[i]._source.min = minutes;
222
+ searchValue[i]._source.sec = seconds;
223
+ searchValue[i]._source.auditedBy = userName?.userName || '';
224
+ searchValue[i]._source.date = dayjs( searchValue[i]?._source?.date ).format( 'D MMM, YYYY' );
225
+ }
226
+ }
227
+
129
228
  return res.sendSuccess( { result: searchValue, count: count } );
130
229
  } catch ( error ) {
131
230
  const err = error.message || 'Internal Server Error';
@@ -150,13 +249,13 @@ export async function viewFile( req, res ) {
150
249
 
151
250
  let searchFilter =[
152
251
  {
153
- 'terms': {
252
+ 'term': {
154
253
  'queueId.keyword': getData?.queueId,
155
254
  },
156
255
 
157
256
  },
158
257
  {
159
- 'terms': {
258
+ 'term': {
160
259
  'type.keyword': getData?.type,
161
260
  },
162
261
 
@@ -165,13 +264,13 @@ export async function viewFile( req, res ) {
165
264
  if ( getData?.type == 'remote' ) {
166
265
  searchFilter =[
167
266
  {
168
- 'terms': {
267
+ 'term': {
169
268
  'engagementId.keyword': getData?.engagementId,
170
269
  },
171
270
 
172
271
  },
173
272
  {
174
- 'terms': {
273
+ 'term': {
175
274
  'type.keyword': getData?.type,
176
275
  },
177
276
 
@@ -190,21 +289,25 @@ export async function viewFile( req, res ) {
190
289
  { createdAt: { order: 'desc' } },
191
290
  ],
192
291
  };
292
+
193
293
  const searchRes= await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
194
- const temp = searchRes?.body?.hits?.hits?.lenght > 0? searchRes?.body?.hits?.hits[0] : [];
195
- const getUserName = await findOneUser( { _id: new mongoose.Types.ObjectId( temp?.userId ) }, { userName: 1 } );
294
+ const temp = searchRes?.body?.hits?.hits?.length > 0? searchRes?.body?.hits?.hits[0] : [];
295
+
296
+ const getUserName = await findOneUser( { _id: new mongoose.Types.ObjectId( temp?._source?.userId ) }, { userName: 1 } );
196
297
 
197
298
  const searchData = temp?
198
299
  getData['lastAuditedDetails']= {
199
300
  'auditedBy': getUserName?.userName || '',
200
- 'completionTime': temp?.startTime? new Date( temp?.startTime ).toLocaleTimeString( 'en-IN', { hour12: false } ): '',
301
+ 'completionTime': temp?._source?.startTime? dayjs.utc( temp?._source?.startTime ).tz( 'Asia/Kolkata' ).format( 'HH:ss:mm' ): '',
201
302
  'timeZone': temp?.timeZone || '',
202
303
  } : null;
203
304
  getData['complianceScore'] = getData.complianceScore || getData?.totalSteps>0 ? Math.round( ( getData?.coveredStepsAI/ getData?.totalSteps )*100 ): 0;
204
305
  getData['trustScore'] = getData?.trustScore || 0;
205
306
  getData['testDuration'] = Math.round( getData?.testDuration/60 ) || 0;
206
307
  getData['filePath'] = `${url[getData?.type]}${getData?.filePath}`;
308
+ getData['auditType'] = getData.auditType || 'Audit';
207
309
  const response = getData;
310
+
208
311
  switch ( getData?.auditStatus ) {
209
312
  case 'Yet-to-Audit':
210
313
  isEnable=true;
@@ -216,17 +319,19 @@ export async function viewFile( req, res ) {
216
319
  if ( searchData.userId !== req.user._id ) {
217
320
  isEnable=false;
218
321
  }
219
- return res.sendSuccess( { result: result } );
220
322
  break;
221
323
  case 'Audited':
324
+ response['steps']= temp._source?.steps;
325
+ isEnable=true;
222
326
  case 'Re-Audited':
327
+ response['steps']= temp._source?.steps;
223
328
  isEnable=true;
224
329
  }
225
330
 
226
331
  return res.sendSuccess( { result: response, isEnable: isEnable } );
227
332
  } catch ( error ) {
228
333
  const err = error.message || 'Internal Server Error';
229
- logger.error( { message: error, data: req.body, function: 'eyetestAudit-controller-viewFile' } );
334
+ logger.error( { message: error, data: req.params, function: 'eyetestAudit-controller-viewFile' } );
230
335
  return res.sendError( err, 500 );
231
336
  }
232
337
  }
@@ -321,6 +426,7 @@ export async function getFile( req, res ) {
321
426
  'startTime': dayjs().tz( 'Asia/Kolkata' ),
322
427
  'createdAt': dayjs().tz( 'Asia/Kolkata' ),
323
428
  'updatedAt': dayjs().tz( 'Asia/Kolkata' ),
429
+ 'auditType': 'Audit',
324
430
 
325
431
  };
326
432
  record?.steps?.map( ( item, i ) => {
@@ -329,7 +435,7 @@ export async function getFile( req, res ) {
329
435
  if ( !searchData ) {
330
436
  const data1 = await insertOpenSearchData( openSearch.EyeTestOutput, record );
331
437
  logger.info( { data1: data1 } );
332
- await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: { auditStatus: 'In-Progress', userId: req?.user?._id } } );
438
+ await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: { auditStatus: 'In-Progress', auditType: 'Audit', userId: req?.user?._id } } );
333
439
  }
334
440
 
335
441
  break;
@@ -370,13 +476,14 @@ export async function getFile( req, res ) {
370
476
  'totalSteps': getData?.totalSteps,
371
477
  'filePath': `${url[getData?.type]}${getData?.filePath}`,
372
478
  'steps': getData?.steps,
479
+ 'auditType': 'Re-Audit',
373
480
  'startTime': dayjs().tz( 'Asia/Kolkata' ),
374
481
  'createdAt': dayjs().tz( 'Asia/Kolkata' ),
375
482
  'updatedAt': dayjs().tz( 'Asia/Kolkata' ),
376
483
 
377
484
  };
378
485
  await insertOpenSearchData( openSearch.EyeTestOutput, newRecord );
379
- await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: { auditStatus: 'In-Progress' } } );
486
+ await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: { auditStatus: 'In-Progress', auditType: 'Re-Audit' } } );
380
487
 
381
488
  break;
382
489
  default:
@@ -390,6 +497,189 @@ export async function getFile( req, res ) {
390
497
  return res.sendError( err, 500 );
391
498
  }
392
499
  }
500
+ export async function save( req, res ) {
501
+ try {
502
+ const inputData = req.body;
503
+ const openSearch = JSON.parse( process.env.OPENSEARCH );
504
+
505
+ let searchFilter =[
506
+ {
507
+ 'term': {
508
+ 'queueId.keyword': inputData?.fileId,
509
+ },
510
+
511
+ },
512
+ {
513
+ 'term': {
514
+ 'type.keyword': inputData?.type,
515
+ },
516
+
517
+ },
518
+
519
+ {
520
+ 'term': {
521
+ 'auditStatus.keyword': 'In-Progress',
522
+ },
523
+ },
524
+ ];
525
+ if ( inputData?.type == 'remote' ) {
526
+ searchFilter =[
527
+ {
528
+ 'term': {
529
+ 'engagementId.keyword': inputData?.fileId,
530
+ },
531
+
532
+ },
533
+ {
534
+ 'term': {
535
+ 'type.keyword': inputData?.type,
536
+ },
537
+
538
+ },
539
+ {
540
+ 'term': {
541
+ 'userId.keyword': req?.user?._id,
542
+ },
543
+ },
544
+ {
545
+ 'term': {
546
+ 'auditStatus.keyword': 'In-Progress',
547
+ },
548
+ },
549
+ ];
550
+ }
551
+
552
+ let searchQuery={
553
+ 'size': 1,
554
+ 'query': {
555
+ 'bool': {
556
+ 'must': searchFilter,
557
+ },
558
+ },
559
+ };
560
+ const getOutput = await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
561
+ logger.info( { getOutput: getOutput } );
562
+ const output = getOutput?.body?.hits?.hits?.length > 0 ? getOutput?.body?.hits?.hits[0] : null;
563
+ if ( !output ) {
564
+ return res.sendError( 'No saved records found', 400 );
565
+ }
566
+ const record ={
567
+ steps: inputData?.steps,
568
+ auditStatus: inputData?.auditStatus,
569
+ auditedSteps: inputData?.auditedSteps,
570
+ overRides: inputData?.overRides,
571
+ trustScore: Math.round( 100-( ( inputData?.overRides / inputData?.steps?.length ) * 100 ) ),
572
+ spokenLanguage: inputData?.spokenLanguage,
573
+ endTime: dayjs().tz( 'Asia/Kolkata' ),
574
+
575
+ };
576
+ const inputrecord ={
577
+
578
+ auditStatus: inputData?.auditStatus,
579
+ auditedSteps: inputData?.auditedSteps,
580
+ overRides: inputData?.overRides,
581
+ trustScore: Math.round( 100-( ( inputData?.overRides / inputData?.steps?.length ) * 100 ) ),
582
+ spokenLanguage: inputData?.spokenLanguage,
583
+ endTime: dayjs().tz( 'Asia/Kolkata' ),
584
+
585
+ };
586
+ await updateOpenSearchData( openSearch.EyeTestOutput, output?._id, { doc: record } );
587
+ await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: inputrecord } );
588
+ return res.sendSuccess( 'The file has been submited successfully' );
589
+ } catch ( error ) {
590
+ const err = error.message || 'Internal Server Error';
591
+ logger.error( { message: error, data: req.params, function: 'eyetestAudit-controller-save' } );
592
+ return res.sendError( err, 500 );
593
+ }
594
+ }
595
+
596
+ export async function cancel( req, res ) {
597
+ try {
598
+ const inputData = req.body;
599
+ const openSearch = JSON.parse( process.env.OPENSEARCH );
600
+
601
+ let searchFilter =[
602
+ {
603
+ 'term': {
604
+ 'queueId.keyword': inputData?.fileId,
605
+ },
606
+
607
+ },
608
+ {
609
+ 'term': {
610
+ 'type.keyword': inputData?.type,
611
+ },
612
+
613
+ },
614
+
615
+ {
616
+ 'term': {
617
+ 'auditStatus.keyword': 'In-Progress',
618
+ },
619
+ },
620
+ ];
621
+ if ( inputData?.type == 'remote' ) {
622
+ searchFilter =[
623
+ {
624
+ 'term': {
625
+ 'engagementId.keyword': inputData?.fileId,
626
+ },
627
+
628
+ },
629
+ {
630
+ 'term': {
631
+ 'type.keyword': inputData?.type,
632
+ },
633
+
634
+ },
635
+ {
636
+ 'term': {
637
+ 'userId.keyword': req?.user?._id,
638
+ },
639
+ },
640
+ {
641
+ 'term': {
642
+ 'auditStatus.keyword': 'In-Progress',
643
+ },
644
+ },
645
+ ];
646
+ }
647
+
648
+ let searchQuery={
649
+ 'size': 1,
650
+ 'query': {
651
+ 'bool': {
652
+ 'must': searchFilter,
653
+ },
654
+ },
655
+ };
656
+ const getOutput = await getOpenSearchData( openSearch.EyeTestOutput, searchQuery );
657
+ logger.info( { getOutput: getOutput } );
658
+ const output = getOutput?.body?.hits?.hits?.length > 0 ? getOutput?.body?.hits?.hits[0] : null;
659
+ if ( !output ) {
660
+ return res.sendError( 'No saved records found', 400 );
661
+ }
662
+ const record1 ={
663
+
664
+ auditStatus: 'Skipped',
665
+ endTime: dayjs().tz( 'Asia/Kolkata' ),
666
+
667
+ };
668
+ const record2 ={
669
+
670
+ auditStatus: 'Yet-to-Audit',
671
+ endTime: dayjs().tz( 'Asia/Kolkata' ),
672
+
673
+ };
674
+ await updateOpenSearchData( openSearch.EyeTestOutput, output?._id, { doc: record1 } );
675
+ await updateOpenSearchData( openSearch.EyeTestInput, inputData.id, { doc: record2 } );
676
+ return res.sendSuccess( 'The file has canceled ' );
677
+ } catch ( error ) {
678
+ const err = error.message || 'Internal Server Error';
679
+ logger.error( { message: error, data: req.params, function: 'eyetestAudit-controller-cancel' } );
680
+ return res.sendError( err, 500 );
681
+ }
682
+ }
393
683
 
394
684
  export async function getFileHistory( req, res ) {
395
685
  try {
@@ -407,7 +697,11 @@ export async function getFileHistory( req, res ) {
407
697
  'queueId.keyword': inputData.id,
408
698
  },
409
699
  },
410
-
700
+ {
701
+ 'terms': {
702
+ 'auditStatus.keyword': [ 'Audited', 'Re-Audited' ],
703
+ },
704
+ },
411
705
  ],
412
706
  },
413
707
  },
@@ -423,7 +717,11 @@ export async function getFileHistory( req, res ) {
423
717
  'engagementId.keyword': inputData.id,
424
718
  },
425
719
  },
426
-
720
+ {
721
+ 'terms': {
722
+ 'auditStatus.keyword': [ 'Audited', 'Re-Audited' ],
723
+ },
724
+ },
427
725
  ],
428
726
  },
429
727
  },
@@ -435,13 +733,14 @@ export async function getFileHistory( req, res ) {
435
733
  let sourcesArray = resposnse.body.hits.hits.map( ( hit ) => hit );
436
734
  let outputData=[];
437
735
  for ( let data of sourcesArray ) {
736
+ // console.log( data._source.endTime );
438
737
  let findUser= await findOneUser( { _id: new mongoose.Types.ObjectId( data._source.userId ) } );
439
738
  outputData.push( {
440
739
  _id: data._id,
441
740
  userId: data._source.userId,
442
741
  userName: findUser.userName,
443
742
  Date: dayjs( data._source.endTime ).format( 'DD/MM/YYYY' ),
444
- Time: dayjs( data._source.endTime ).format( 'HH:MM:ss' ),
743
+ Time: dayjs.utc( data._source.endTime ).tz( 'Asia/Kolkata' ).format( 'HH:ss:mm' ),
445
744
  } );
446
745
  }
447
746
 
@@ -460,7 +759,9 @@ export async function userAuditedData( req, res ) {
460
759
  try {
461
760
  const parsedOpenSearch = JSON.parse( process.env.OPENSEARCH );
462
761
  const inputData = req.params;
762
+
463
763
  const resposnse = await getOpenSearchById( parsedOpenSearch.EyeTestOutput, inputData.id );
764
+
464
765
  if ( resposnse.body&&resposnse.body._source ) {
465
766
  return res.sendSuccess( { result: resposnse.body._source.steps } );
466
767
  } else {
@@ -1,5 +1,5 @@
1
1
  import j2s from 'joi-to-swagger';
2
- import { getListSchema, getFileSchema, getFileHistorySchema, userAuditedDataSchema, viewFileSchema } from '../dtos/eyeTestAudit.dtos.js';
2
+ import { getListSchema, getFileSchema, getFileHistorySchema, userAuditedDataSchema, viewFileSchema, saveSchema, cancelSchema } from '../dtos/eyeTestAudit.dtos.js';
3
3
 
4
4
  export const eyeTestAuditDocs = {
5
5
 
@@ -71,6 +71,50 @@ export const eyeTestAuditDocs = {
71
71
  },
72
72
  },
73
73
 
74
+ '/v3/eye-test-audit/save': {
75
+ post: {
76
+ tags: [ 'Eye Test Audit' ],
77
+ description: 'submit eytest audit',
78
+ operationId: 'save',
79
+ requestBody: {
80
+ content: {
81
+ 'application/json': {
82
+ schema: j2s( saveSchema ).swagger,
83
+ },
84
+ },
85
+ },
86
+ responses: {
87
+ 200: { description: 'Successful' },
88
+ 401: { description: 'Unauthorized User' },
89
+ 422: { description: 'Field Error' },
90
+ 500: { description: 'Server Error' },
91
+ 204: { description: 'Not Found' },
92
+ },
93
+ },
94
+ },
95
+
96
+ '/v3/eye-test-audit/cancel': {
97
+ post: {
98
+ tags: [ 'Eye Test Audit' ],
99
+ description: 'cancel eytest audit',
100
+ operationId: 'cancel',
101
+ requestBody: {
102
+ content: {
103
+ 'application/json': {
104
+ schema: j2s( cancelSchema ).swagger,
105
+ },
106
+ },
107
+ },
108
+ responses: {
109
+ 200: { description: 'Successful' },
110
+ 401: { description: 'Unauthorized User' },
111
+ 422: { description: 'Field Error' },
112
+ 500: { description: 'Server Error' },
113
+ 204: { description: 'Not Found' },
114
+ },
115
+ },
116
+ },
117
+
74
118
  '/v3/eye-test-audit/get-file-history/{id}': {
75
119
  get: {
76
120
  tags: [ 'Eye Test Audit' ],
@@ -11,6 +11,8 @@ export const getListSchema = joi.object(
11
11
  offset: joi.number().optional(),
12
12
  searchValue: joi.string().optional().allow( '' ),
13
13
  isExport: joi.boolean().optional(),
14
+ sortBy: joi.string().optional(),
15
+ sortOrder: joi.number().optional(),
14
16
  },
15
17
  );
16
18
 
@@ -35,6 +37,33 @@ export const getFileValid = {
35
37
  params: getFileSchema,
36
38
  };
37
39
 
40
+ export const saveSchema = joi.object( {
41
+ type: joi.string().required(),
42
+ fileId: joi.string().required(),
43
+ id: joi.string().required(),
44
+ steps: joi.array().required(),
45
+ auditedSteps: joi.number().required(),
46
+ auditStatus: joi.string().required(),
47
+ overRides: joi.number().required(),
48
+ spokenLanguage: joi.string().optional(),
49
+ } );
50
+
51
+ export const saveValid = {
52
+ body: saveSchema,
53
+ };
54
+
55
+
56
+ export const cancelSchema = joi.object( {
57
+ type: joi.string().required(),
58
+ fileId: joi.string().required(),
59
+ id: joi.string().required(),
60
+ } );
61
+
62
+ export const cancelValid = {
63
+ body: cancelSchema,
64
+ };
65
+
66
+
38
67
  export const getFileHistorySchema = joi.object( {
39
68
  id: joi.string().required(),
40
69
  type: joi.string().required(),
@@ -1,15 +1,16 @@
1
1
  import { Router } from 'express';
2
2
  import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
3
3
  import { accessVerification } from 'tango-app-api-middleware';
4
- import { getFileHistoryValid, getFileValid, getListValid, userAuditedDataValid, viewFileValid } from '../dtos/eyeTestAudit.dtos.js';
5
- import { getFile, getFileHistory, getList, userAuditedData, viewFile } from '../controllers/eyeTestAudit.controllers.js';
4
+ import { cancelValid, getFileHistoryValid, getFileValid, getListValid, saveValid, userAuditedDataValid, viewFileValid } from '../dtos/eyeTestAudit.dtos.js';
5
+ import { cancel, getFile, getFileHistory, getList, save, userAuditedData, viewFile } from '../controllers/eyeTestAudit.controllers.js';
6
6
 
7
7
  export const eyeTestAuditRouter = Router();
8
8
 
9
9
  eyeTestAuditRouter.post( '/get-list', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( getListValid ), getList );
10
10
  eyeTestAuditRouter.get( '/view-file/:id', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( viewFileValid ), viewFile );
11
11
  eyeTestAuditRouter.get( '/get-file/:id', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( getFileValid ), getFile );
12
- eyeTestAuditRouter.post( '/save', isAllowedSessionHandler );
12
+ eyeTestAuditRouter.post( '/save', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( saveValid ), save );
13
+ eyeTestAuditRouter.post( '/cancel', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( cancelValid ), cancel );
13
14
  eyeTestAuditRouter.get( '/get-file-history/:id/:type', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( getFileHistoryValid ), getFileHistory );
14
15
  eyeTestAuditRouter.get( '/user-audited-data/:id', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( userAuditedDataValid ), userAuditedData );
15
16