tango-app-api-audit 3.6.8 → 3.6.9

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.6.8",
3
+ "version": "3.6.9",
4
4
  "description": "audit & audit metrics apis",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -2131,7 +2131,7 @@ export async function save( req, res ) {
2131
2131
  retry: 1,
2132
2132
  } ),
2133
2133
  MessageGroupId: 'my-group-1', // Required for FIFO queues
2134
- MessageDeduplicationId: Date.now().toString(), // Or a UUID, if content-based deduplication is off
2134
+ MessageDeduplicationId: `${inputData.storeId}_${inputData.fileDate}_${inputData.auditType}_${Date.now().toString()}`, // Or a UUID, if content-based deduplication is off
2135
2135
  }:
2136
2136
  {
2137
2137
  QueueUrl: ( auditConfig?.isCheckMinAfterCount ==1 && inputData.customerCount > auditConfig?.minAfterCount ) ? `${sqs.url}${sqs.feature_new}`: `${sqs.url}${sqs.feature}`,
@@ -2143,46 +2143,54 @@ export async function save( req, res ) {
2143
2143
  process_type: 'audit',
2144
2144
  } ),
2145
2145
  };
2146
- const sqsProduceQueueCopy = {
2147
- QueueUrl: `${sqs.url}track-output-copy.fifo`,
2148
- MessageBody: JSON.stringify( {
2149
- store_id: inputData.storeId,
2150
- zone_id: [ 'traffic_zone' ],
2151
- streams: streams || [],
2152
- store_date: inputData.fileDate,
2153
- bucket_name: 'tango-yolo-v2-output',
2154
- time: '23:00',
2155
- retry: 1,
2156
- } ),
2157
- MessageGroupId: 'my-group-1', // Required for FIFO queues
2158
- MessageDeduplicationId: Date.now().toString(), // Or a UUID, if content-based deduplication is off
2159
- };
2160
2146
 
2161
- let sqsQueue;
2162
- let sqsQueueCopy;
2147
+
2163
2148
  if ( inputData.moduleType === 'track' ) {
2164
- const [ firstResponse, secondResponse ] = await Promise.all( [
2165
- sendMessageToFIFOQueue( sqsProduceQueue ),
2166
- sendMessageToFIFOQueue( sqsProduceQueueCopy ),
2167
- ] );
2149
+ const firstResponse = await sendMessageToFIFOQueue( sqsProduceQueue );
2168
2150
 
2169
- sqsQueue = firstResponse;
2170
- sqsQueueCopy = secondResponse;
2151
+ /* openSearch logs start */
2152
+ id = `${inputData.moduleType}_${inputData.auditId}_${inputData.storeId}_${inputData.moduleType}_${inputData.auditType}_save_Info_${req?.user?.email}_${Date.now()}`;
2153
+ const message = {
2154
+ getBody: getBody,
2155
+ streams: streams,
2156
+ sqsProduceQueue: sqsProduceQueue,
2157
+ sqsQueue: firstResponse,
2158
+ };
2159
+ temp.message =JSON.stringify( message );
2160
+ await openSearchLog( temp, req.user, id );
2161
+ /* openSearch logs end */
2162
+
2163
+ if ( firstResponse.statusCode ) {
2164
+ const results = await Promise.allSettled( [
2165
+ withRetry( () => sendMessageToFIFOQueue( sqsProduceQueue ), 3, 2000 ),
2166
+ ] );
2167
+ const [ firstRetryResponse ] = results;
2168
+ /* openSearch logs start */
2169
+ id = `${inputData.moduleType}_${inputData.auditId}_${inputData.storeId}_${inputData.moduleType}_${inputData.auditType}_save_Info_${req?.user?.email}_${Date.now()}`;
2170
+ const message = {
2171
+ getBody: getBody,
2172
+ streams: streams,
2173
+ sqsProduceQueue: sqsProduceQueue,
2174
+ sqsQueue: firstRetryResponse,
2175
+ };
2176
+ temp.message =JSON.stringify( message );
2177
+ await openSearchLog( temp, req.user, id );
2178
+ /* openSearch logs end */
2179
+ }
2171
2180
  } else {
2172
- sqsQueue = await sendMessageToQueue( sqsProduceQueue.QueueUrl, sqsProduceQueue.MessageBody );
2173
- }
2174
- /* openSearch logs start */
2175
- id = `${inputData.moduleType}_${inputData.auditId}_${inputData.storeId}_${inputData.moduleType}_${inputData.auditType}_save_Info_${req?.user?.email}_${Date.now()}`;
2176
- const message = {
2177
- getBody: getBody,
2178
- streams: streams,
2179
- sqsProduceQueue: sqsProduceQueue,
2180
- sqsQueue: sqsQueue,
2181
- sqsQueueCopy: sqsQueueCopy,
2182
- };
2183
- temp.message =JSON.stringify( message );
2184
- await openSearchLog( temp, req.user, id );
2181
+ const sqsQueue = await sendMessageToQueue( sqsProduceQueue.QueueUrl, sqsProduceQueue.MessageBody );
2182
+ /* openSearch logs start */
2183
+ id = `${inputData.moduleType}_${inputData.auditId}_${inputData.storeId}_${inputData.moduleType}_${inputData.auditType}_save_Info_${req?.user?.email}_${Date.now()}`;
2184
+ const message = {
2185
+ getBody: getBody,
2186
+ streams: streams,
2187
+ sqsProduceQueue: sqsProduceQueue,
2188
+ sqsQueue: sqsQueue,
2189
+ };
2190
+ temp.message =JSON.stringify( message );
2191
+ await openSearchLog( temp, req.user, id );
2185
2192
  /* openSearch logs end */
2193
+ }
2186
2194
  if ( inputData.moduleType === 'track' ) {
2187
2195
  // declare id
2188
2196
  id = `${inputData.moduleType}_${inputData.auditId}_${inputData.storeId}_${inputData.moduleType}_${inputData.auditType}_save_Info_${req?.user?.email}_${Date.now()}`;
@@ -2210,6 +2218,25 @@ export async function save( req, res ) {
2210
2218
  }
2211
2219
  }
2212
2220
 
2221
+ // Retry send SQS message
2222
+ async function withRetry( fn, retries = 3, delay = 1000 ) {
2223
+ let lastError;
2224
+ for ( let attempt = 1; attempt <= retries; attempt++ ) {
2225
+ try {
2226
+ const result = await fn();
2227
+ return result; // success — return immediately
2228
+ } catch ( err ) {
2229
+ lastError = err;
2230
+ logger.error( `Attempt ${attempt} failed: ${err.message}` );
2231
+ if ( attempt < retries ) {
2232
+ await new Promise( ( res ) => setTimeout( res, delay ) ); // wait before retry
2233
+ }
2234
+ }
2235
+ }
2236
+ throw lastError; // all attempts failed
2237
+ }
2238
+
2239
+
2213
2240
  const filteredMap = async ( data ) => {
2214
2241
  const temp = data.map( ( item ) => item.img_name );
2215
2242
  return temp;
@@ -1207,7 +1207,7 @@ export async function summaryList( req, res ) {
1207
1207
  const limit = inputData.limit || 10;
1208
1208
  const offset = inputData.offset ? ( inputData.offset - 1 ) * limit : 0;
1209
1209
 
1210
- const sortBy = inputData?.sortBy ? [ 'coveredStepsAI', 'trustScore', 'date', 'ComplianceScore', 'auditedSteps' ].includes( inputData.sortBy ) ? inputData.sortBy :`${inputData.sortBy}.keyword` : 'storeName.keyword';
1210
+ const sortBy = inputData?.sortBy ? [ 'coveredStepsAI', 'trustScore', 'date', 'ComplianceScore' ].includes( inputData.sortBy ) ? inputData.sortBy :`${inputData.sortBy}.keyword` : 'storeName.keyword';
1211
1211
  const order = inputData?.sortOrder || -1;
1212
1212
 
1213
1213
  let filter= [
@@ -1221,15 +1221,7 @@ export async function summaryList( req, res ) {
1221
1221
  },
1222
1222
 
1223
1223
  ];
1224
-
1225
- if ( inputData?.auditStatus && inputData?.auditStatus?.length > 0 ) {
1226
- filter.push( {
1227
- 'terms': {
1228
- 'auditStatus.keyword': inputData.auditStatus,
1229
- },
1230
- } );
1231
- }
1232
- if ( inputData?.demographics && inputData?.demographics?.length > 0 ) {
1224
+ if ( inputData.demographics && inputData.demographics.length > 0 ) {
1233
1225
  filter.push( {
1234
1226
  'terms': {
1235
1227
  'visitorsType.keyword': inputData.demographics,
@@ -1856,7 +1848,6 @@ export async function summaryList( req, res ) {
1856
1848
  if ( element?._source?.type == 'physical' ) {
1857
1849
  exportData.push( {
1858
1850
  'Date': dayjs( element?._source?.date ).format( 'D MMM, YYYY' ),
1859
- 'Audited Date': [ 'Re-Audited', 'Audited' ].includes( element?._source?.auditStatus )?dayjs( element?._source?.updatedAt ).format( 'D MMM, YYYY' ): 'NA',
1860
1851
  ...( req?.user?.role === 'superadmin' && { 'RM Name': RMName } ),
1861
1852
  ...( req?.user?.role !== 'user' && { 'Cluster Name': clusterName } ),
1862
1853
  'Store Name': element?._source?.storeName,
@@ -1866,7 +1857,6 @@ export async function summaryList( req, res ) {
1866
1857
  'Queue ID': element?._source?.queueId,
1867
1858
  'Tango Score': `${element?._source?.totalSteps>0 ? Math.round( ( element?._source?.coveredStepsAI/ element?._source?.totalSteps )*100 ): 0} %`,
1868
1859
  'Steps Covered By AI': element?._source?.coveredStepsAI || 0,
1869
- 'Steps Covered By User': [ 'Re-Audited', 'Audited' ].includes( element?._source?.auditStatus )?element?._source?.auditedSteps :'NA',
1870
1860
  'Trust Score': element?._source?.trustScore == null || element?._source?.trustScore ==undefined ? 'NA' : `${element?._source?.trustScore} %`,
1871
1861
  'Visitor Type': element?._source?.visitorsType,
1872
1862
  'Test Duration': duration || '',
@@ -1879,7 +1869,6 @@ export async function summaryList( req, res ) {
1879
1869
  } else {
1880
1870
  exportData.push( {
1881
1871
  'Date': dayjs( element?._source?.date ).format( 'D MMM, YYYY' ),
1882
- 'Audited Date': [ 'Re-Audited', 'Audited' ].includes( element?._source?.auditStatus )?dayjs( element?._source?.updatedAt ).format( 'D MMM, YYYY' ): 'NA',
1883
1872
  ...( req?.user?.role === 'superadmin' && { 'RM Name': RMName } ),
1884
1873
  ...( req?.user?.role !== 'user' && { 'Cluster Name': clusterName } ),
1885
1874
  'Store Name': element?._source?.storeName,
@@ -1889,7 +1878,6 @@ export async function summaryList( req, res ) {
1889
1878
  'Engagement ID': element?._source?.engagementId,
1890
1879
  'Tango Score': `${element?._source?.totalSteps>0 ? Math.round( ( element?._source?.coveredStepsAI/ element?._source?.totalSteps )*100 ): 0} %`,
1891
1880
  'Steps Covered By AI': element?._source?.coveredStepsAI || 0,
1892
- 'Steps Covered By User': [ 'Re-Audited', 'Audited' ].includes( element?._source?.auditStatus )?element?._source?.auditedSteps :'NA',
1893
1881
  'Trust Score': element?._source?.trustScore == null || element?._source?.trustScore ==undefined ? 'NA' : `${element?._source?.trustScore} %`,
1894
1882
  'Test Duration': duration || '',
1895
1883
  'Audit Status': element?._source?.auditStatus || '',
@@ -2031,7 +2019,6 @@ export async function summaryList( req, res ) {
2031
2019
  temp[i].sec = seconds;
2032
2020
  temp[i].auditedBy = userName?.userName || '';
2033
2021
  temp[i].date = dayjs( item?._source?.date ).format( 'D MMM, YYYY' );
2034
- temp[i].auditedDate = [ 'Re-Audited', 'Audited' ].includes( item?._source?.auditStatus )?dayjs( item?._source?.updatedAt ).format( 'D MMM, YYYY' ): 'NA';
2035
2022
  temp[i].RMName = RMName;
2036
2023
  temp[i].clusterName =clusterName;
2037
2024
  temp[i].RMEmail =RMEmail;
@@ -150,7 +150,7 @@ export const summaryListSchema = joi.object( {
150
150
  demographics: joi.array().optional(),
151
151
  RMList: joi.array().items(
152
152
  joi.string().required(),
153
- ).required(),
153
+ ).optional(),
154
154
  cluster: joi.array().items(
155
155
  joi.string().optional(),
156
156
  ).optional(),
@@ -164,7 +164,6 @@ export const summaryListSchema = joi.object( {
164
164
  category: joi.string().optional() .valid( 'fake', 'genuine' ),
165
165
  offset: joi.number().optional(),
166
166
  limit: joi.number().optional(),
167
- auditStatus: joi.array().items( joi.string().required().valid( 'Re-Audited', 'Audited', 'In-Progress', 'Yet-to-Audit' ) ).optional(),
168
167
  } );
169
168
 
170
169
  export const summaryListValid = {
@@ -22,7 +22,7 @@ eyeTestAuditRouter.post( '/summary-card', isAllowedSessionHandler, accessVerific
22
22
  eyeTestAuditRouter.post( '/email-alert-log', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), isSuperAdmin, validate( emailAlertLogValid ), emailAlertLog );
23
23
 
24
24
  eyeTestAuditRouter.post( '/cluster-list', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( clusterListValid ), clusterList );
25
- eyeTestAuditRouter.get( '/rm-list', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), validate( rmListValid ), rmList );
25
+ eyeTestAuditRouter.get( '/rm-list', isAllowedSessionHandler, accessVerification( { userType: [ 'tango', 'client' ] } ), isSuperAdmin, validate( rmListValid ), rmList );
26
26
 
27
27
 
28
28
  // setting
@@ -2,20 +2,20 @@ import { logger } from 'tango-app-api-middleware';
2
2
 
3
3
  export async function roleValidation( req, res, next ) {
4
4
  try {
5
- // const userRole = req?.user?.role;
5
+ const userRole = req?.user?.role;
6
6
  req.body.clientId = req?.user?.userType == 'tango'? req?.body?.clientId : req?.user?.clientId;
7
- // switch ( userRole ) {
8
- // case 'user':
9
- // req.body.RMList = [ req?.user?.email ];
10
- // break;
11
- // case 'admin':
12
- // req.body.RMList = [ req?.user?.email ];
13
- // // delete req?.body?.RMList;
14
- // break;
15
- // case 'superadmin':
16
- // break;
17
- // default: return res.sendError( 'forbidden to access: you must be User or Admin or Super Admin', 403 );
18
- // }
7
+ switch ( userRole ) {
8
+ case 'user':
9
+ req.body.RMList = [ req?.user?.email ];
10
+ break;
11
+ case 'admin':
12
+ req.body.RMList = [ req?.user?.email ];
13
+ // delete req?.body?.RMList;
14
+ break;
15
+ case 'superadmin':
16
+ break;
17
+ default: return res.sendError( 'forbidden to access: you must be User or Admin or Super Admin', 403 );
18
+ }
19
19
  next();
20
20
  return;
21
21
  } catch ( error ) {