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
|
@@ -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()
|
|
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
|
-
|
|
2162
|
-
let sqsQueueCopy;
|
|
2147
|
+
|
|
2163
2148
|
if ( inputData.moduleType === 'track' ) {
|
|
2164
|
-
const
|
|
2165
|
-
sendMessageToFIFOQueue( sqsProduceQueue ),
|
|
2166
|
-
sendMessageToFIFOQueue( sqsProduceQueueCopy ),
|
|
2167
|
-
] );
|
|
2149
|
+
const firstResponse = await sendMessageToFIFOQueue( sqsProduceQueue );
|
|
2168
2150
|
|
|
2169
|
-
|
|
2170
|
-
|
|
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
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
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'
|
|
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
|
-
).
|
|
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
|
-
|
|
5
|
+
const userRole = req?.user?.role;
|
|
6
6
|
req.body.clientId = req?.user?.userType == 'tango'? req?.body?.clientId : req?.user?.clientId;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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 ) {
|