tango-app-api-audit 1.0.27 → 1.0.29
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/README.md +28 -28
- package/package.json +40 -39
- package/src/controllers/auditMetrics.controllers.js +27 -3
- package/src/controllers/store.controllers.js +42 -42
- package/src/controllers/user.controllers.js +41 -41
- package/src/docs/auditMetrics.docs.js +41 -1
- package/src/docs/store.docs.js +27 -27
- package/src/docs/user.docs.js +33 -33
- package/src/dtos/auditMetrics.dtos.js +5 -8
- package/src/dtos/store.dtos.js +14 -14
- package/src/dtos/user.dtos.js +14 -14
- package/src/routes/auditMetrics.routes.js +3 -3
- package/src/routes/store.routes.js +10 -10
- package/src/routes/user.routes.js +9 -9
- package/src/validation/audit.validation.js +92 -2
package/README.md
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
# README #
|
|
2
|
-
|
|
3
|
-
This README would normally document whatever steps are necessary to get your application up and running.
|
|
4
|
-
|
|
5
|
-
### What is this repository for? ###
|
|
6
|
-
|
|
7
|
-
* Quick summary
|
|
8
|
-
* Version
|
|
9
|
-
* [Learn Markdown](https://bitbucket.org/tutorials/markdowndemo)
|
|
10
|
-
|
|
11
|
-
### How do I get set up? ###
|
|
12
|
-
|
|
13
|
-
* Summary of set up
|
|
14
|
-
* Configuration
|
|
15
|
-
* Dependencies
|
|
16
|
-
* Database configuration
|
|
17
|
-
* How to run tests
|
|
18
|
-
* Deployment instructions
|
|
19
|
-
|
|
20
|
-
### Contribution guidelines ###
|
|
21
|
-
|
|
22
|
-
* Writing tests
|
|
23
|
-
* Code review
|
|
24
|
-
* Other guidelines
|
|
25
|
-
|
|
26
|
-
### Who do I talk to? ###
|
|
27
|
-
|
|
28
|
-
* Repo owner or admin
|
|
1
|
+
# README #
|
|
2
|
+
|
|
3
|
+
This README would normally document whatever steps are necessary to get your application up and running.
|
|
4
|
+
|
|
5
|
+
### What is this repository for? ###
|
|
6
|
+
|
|
7
|
+
* Quick summary
|
|
8
|
+
* Version
|
|
9
|
+
* [Learn Markdown](https://bitbucket.org/tutorials/markdowndemo)
|
|
10
|
+
|
|
11
|
+
### How do I get set up? ###
|
|
12
|
+
|
|
13
|
+
* Summary of set up
|
|
14
|
+
* Configuration
|
|
15
|
+
* Dependencies
|
|
16
|
+
* Database configuration
|
|
17
|
+
* How to run tests
|
|
18
|
+
* Deployment instructions
|
|
19
|
+
|
|
20
|
+
### Contribution guidelines ###
|
|
21
|
+
|
|
22
|
+
* Writing tests
|
|
23
|
+
* Code review
|
|
24
|
+
* Other guidelines
|
|
25
|
+
|
|
26
|
+
### Who do I talk to? ###
|
|
27
|
+
|
|
28
|
+
* Repo owner or admin
|
|
29
29
|
* Other community or team contact
|
package/package.json
CHANGED
|
@@ -1,39 +1,40 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "tango-app-api-audit",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "audit & audit metrics apis",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"start": "nodemon --exec \"eslint --fix . && node index.js\""
|
|
9
|
-
},
|
|
10
|
-
"engines": {
|
|
11
|
-
"node": ">=18.10.0"
|
|
12
|
-
},
|
|
13
|
-
"author": "praveenraj",
|
|
14
|
-
"license": "ISC",
|
|
15
|
-
"dependencies": {
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"tango-
|
|
28
|
-
"
|
|
29
|
-
"winston
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"eslint
|
|
34
|
-
"eslint-config-
|
|
35
|
-
"eslint-config-
|
|
36
|
-
"eslint-
|
|
37
|
-
"eslint-plugin-
|
|
38
|
-
|
|
39
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "tango-app-api-audit",
|
|
3
|
+
"version": "1.0.29",
|
|
4
|
+
"description": "audit & audit metrics apis",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "nodemon --exec \"eslint --fix . && node index.js\""
|
|
9
|
+
},
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=18.10.0"
|
|
12
|
+
},
|
|
13
|
+
"author": "praveenraj",
|
|
14
|
+
"license": "ISC",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"adm-zip": "^0.5.15",
|
|
17
|
+
"aws-sdk": "^2.1643.0",
|
|
18
|
+
"dayjs": "^1.11.11",
|
|
19
|
+
"dotenv": "^16.4.5",
|
|
20
|
+
"express": "^4.19.2",
|
|
21
|
+
"handlebars": "^4.7.8",
|
|
22
|
+
"joi-to-swagger": "^6.2.0",
|
|
23
|
+
"lodash": "^4.17.21",
|
|
24
|
+
"mongodb": "^6.7.0",
|
|
25
|
+
"nodemon": "^3.1.3",
|
|
26
|
+
"swagger-ui-express": "^5.0.1",
|
|
27
|
+
"tango-api-schema": "^2.0.138",
|
|
28
|
+
"tango-app-api-middleware": "^3.1.26",
|
|
29
|
+
"winston": "^3.13.0",
|
|
30
|
+
"winston-daily-rotate-file": "^5.0.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"eslint": "^8.57.0",
|
|
34
|
+
"eslint-config-google": "^0.14.0",
|
|
35
|
+
"eslint-config-semistandard": "^17.0.0",
|
|
36
|
+
"eslint-config-standard": "^17.1.0",
|
|
37
|
+
"eslint-plugin-import": "^2.29.1",
|
|
38
|
+
"eslint-plugin-promise": "^6.2.0"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -8,6 +8,7 @@ import dayjs from 'dayjs';
|
|
|
8
8
|
import { createAssignAudit } from '../service/assignAudit.service.js';
|
|
9
9
|
import { countDocumentsStore } from '../service/store.service.js';
|
|
10
10
|
import { findOneClient } from '../service/client.service.js';
|
|
11
|
+
import { getAuditImageData, zipDownloadImage } from '../validation/audit.validation.js';
|
|
11
12
|
// import { listQueue } from 'tango-app-api-middleware/src/utils/aws/sqs.js';
|
|
12
13
|
|
|
13
14
|
export async function userAuditHistory( req, res ) {
|
|
@@ -1297,10 +1298,33 @@ export async function reTrigger( req, res ) {
|
|
|
1297
1298
|
}
|
|
1298
1299
|
}
|
|
1299
1300
|
|
|
1300
|
-
export async function
|
|
1301
|
+
export async function auditImages( req, res ) {
|
|
1301
1302
|
try {
|
|
1302
|
-
const inputData = req.
|
|
1303
|
-
|
|
1303
|
+
const inputData = req.query;
|
|
1304
|
+
let auditImageDownload = '';
|
|
1305
|
+
switch ( inputData.auditType ) {
|
|
1306
|
+
case 'BC':
|
|
1307
|
+
const auditImageBC = await getAuditImageData( inputData );
|
|
1308
|
+
|
|
1309
|
+
if ( inputData.export==true ) {
|
|
1310
|
+
auditImageDownload= await zipDownloadImage( auditImageBC );
|
|
1311
|
+
// Set response headers for the zip file
|
|
1312
|
+
res.set( 'Content-Type', 'application/zip' );
|
|
1313
|
+
res.set( 'Content-Disposition', `attachment; filename=${inputData.storeId}_${inputData.fileDate}_${inputData.auditType}.zip` );
|
|
1314
|
+
|
|
1315
|
+
// Send the zip file as the API response
|
|
1316
|
+
return res.send( auditImageDownload );
|
|
1317
|
+
}
|
|
1318
|
+
return res.sendSuccess( { result: auditImageBC } );
|
|
1319
|
+
|
|
1320
|
+
break;
|
|
1321
|
+
|
|
1322
|
+
default:
|
|
1323
|
+
break;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
// return res.sendSuccess( { result: inputData } );
|
|
1304
1328
|
} catch ( error ) {
|
|
1305
1329
|
const err = error.message || 'Internal Server Error';
|
|
1306
1330
|
logger.info( { error: error, message: req.body, function: 'beforeCountImages' } );
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
import { logger } from 'tango-app-api-middleware';
|
|
2
|
-
import { aggregateStore } from '../service/store.service.js';
|
|
3
|
-
|
|
4
|
-
export async function auditStoreList( req, res ) {
|
|
5
|
-
try {
|
|
6
|
-
const inputData = req.body;
|
|
7
|
-
const query =[
|
|
8
|
-
{
|
|
9
|
-
$match: {
|
|
10
|
-
clientId: { $in: inputData.clientId },
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
$project: {
|
|
15
|
-
_id: 0,
|
|
16
|
-
clientId: 1,
|
|
17
|
-
storeId: 1,
|
|
18
|
-
storeName: 1,
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
const count = await aggregateStore( query );
|
|
24
|
-
if ( count.length == 0 ) {
|
|
25
|
-
return res.sendSuccess( { result: [], count: 0 } );
|
|
26
|
-
}
|
|
27
|
-
if ( inputData.limit ) {
|
|
28
|
-
const offset = inputData.offset ? ( inputData.offset - 1 ) * inputData.limit : 0;
|
|
29
|
-
query.push(
|
|
30
|
-
{ $skip: offset },
|
|
31
|
-
{ $limit: limit },
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
const result = await aggregateStore( query );
|
|
35
|
-
|
|
36
|
-
return res.sendSuccess( { result: result, count: count.length } );
|
|
37
|
-
} catch ( error ) {
|
|
38
|
-
const err = error.message || 'Internal Server Error';
|
|
39
|
-
logger.info( { error: error, messgae: req.body, function: 'auditStoreList' } );
|
|
40
|
-
return res.sendError( err, 500 );
|
|
41
|
-
}
|
|
42
|
-
}
|
|
1
|
+
import { logger } from 'tango-app-api-middleware';
|
|
2
|
+
import { aggregateStore } from '../service/store.service.js';
|
|
3
|
+
|
|
4
|
+
export async function auditStoreList( req, res ) {
|
|
5
|
+
try {
|
|
6
|
+
const inputData = req.body;
|
|
7
|
+
const query =[
|
|
8
|
+
{
|
|
9
|
+
$match: {
|
|
10
|
+
clientId: { $in: inputData.clientId },
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
$project: {
|
|
15
|
+
_id: 0,
|
|
16
|
+
clientId: 1,
|
|
17
|
+
storeId: 1,
|
|
18
|
+
storeName: 1,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
const count = await aggregateStore( query );
|
|
24
|
+
if ( count.length == 0 ) {
|
|
25
|
+
return res.sendSuccess( { result: [], count: 0 } );
|
|
26
|
+
}
|
|
27
|
+
if ( inputData.limit ) {
|
|
28
|
+
const offset = inputData.offset ? ( inputData.offset - 1 ) * inputData.limit : 0;
|
|
29
|
+
query.push(
|
|
30
|
+
{ $skip: offset },
|
|
31
|
+
{ $limit: limit },
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
const result = await aggregateStore( query );
|
|
35
|
+
|
|
36
|
+
return res.sendSuccess( { result: result, count: count.length } );
|
|
37
|
+
} catch ( error ) {
|
|
38
|
+
const err = error.message || 'Internal Server Error';
|
|
39
|
+
logger.info( { error: error, messgae: req.body, function: 'auditStoreList' } );
|
|
40
|
+
return res.sendError( err, 500 );
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import { logger } from 'tango-app-api-middleware';
|
|
2
|
-
import { aggregateUser } from '../service/user.service.js';
|
|
3
|
-
|
|
4
|
-
export async function auditUserList( req, res ) {
|
|
5
|
-
try {
|
|
6
|
-
const inputData = req.query;
|
|
7
|
-
const query =[
|
|
8
|
-
{
|
|
9
|
-
$match: {
|
|
10
|
-
userType: { $eq: 'tango' },
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
$project: {
|
|
15
|
-
userName: 1,
|
|
16
|
-
userId: '$_id',
|
|
17
|
-
_id: 0,
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
];
|
|
21
|
-
|
|
22
|
-
const count = await aggregateUser( query );
|
|
23
|
-
if ( count.length == 0 ) {
|
|
24
|
-
return res.sendSuccess( { result: [], count: 0 } );
|
|
25
|
-
}
|
|
26
|
-
if ( inputData.limit ) {
|
|
27
|
-
const offset = inputData.offset ? ( inputData.offset - 1 ) * inputData.limit : 0;
|
|
28
|
-
query.push(
|
|
29
|
-
{ $skip: offset },
|
|
30
|
-
{ $limit: limit },
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
const result = await aggregateUser( query );
|
|
34
|
-
|
|
35
|
-
return res.sendSuccess( { result: result, count: count.length } );
|
|
36
|
-
} catch ( error ) {
|
|
37
|
-
const err = error.message || 'Internal Server Error';
|
|
38
|
-
logger.info( { error: error, messgae: req.query, function: 'auditUserList' } );
|
|
39
|
-
return res.sendError( err, 500 );
|
|
40
|
-
}
|
|
41
|
-
}
|
|
1
|
+
import { logger } from 'tango-app-api-middleware';
|
|
2
|
+
import { aggregateUser } from '../service/user.service.js';
|
|
3
|
+
|
|
4
|
+
export async function auditUserList( req, res ) {
|
|
5
|
+
try {
|
|
6
|
+
const inputData = req.query;
|
|
7
|
+
const query =[
|
|
8
|
+
{
|
|
9
|
+
$match: {
|
|
10
|
+
userType: { $eq: 'tango' },
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
$project: {
|
|
15
|
+
userName: 1,
|
|
16
|
+
userId: '$_id',
|
|
17
|
+
_id: 0,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const count = await aggregateUser( query );
|
|
23
|
+
if ( count.length == 0 ) {
|
|
24
|
+
return res.sendSuccess( { result: [], count: 0 } );
|
|
25
|
+
}
|
|
26
|
+
if ( inputData.limit ) {
|
|
27
|
+
const offset = inputData.offset ? ( inputData.offset - 1 ) * inputData.limit : 0;
|
|
28
|
+
query.push(
|
|
29
|
+
{ $skip: offset },
|
|
30
|
+
{ $limit: limit },
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
const result = await aggregateUser( query );
|
|
34
|
+
|
|
35
|
+
return res.sendSuccess( { result: result, count: count.length } );
|
|
36
|
+
} catch ( error ) {
|
|
37
|
+
const err = error.message || 'Internal Server Error';
|
|
38
|
+
logger.info( { error: error, messgae: req.query, function: 'auditUserList' } );
|
|
39
|
+
return res.sendError( err, 500 );
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import j2s from 'joi-to-swagger';
|
|
2
|
-
import { clientMetricsSchema, getAuditImagesSchema, overAllAuditSummarySchema, overViewCardSchema, overViewTableSchema, reTriggerValidSchema, storeMetricsSchema, summarySplitSchema, userAuditHistorySchema, userMetricsSchema } from '../dtos/auditMetrics.dtos.js';
|
|
2
|
+
import { auditImageValidSchema, clientMetricsSchema, getAuditImagesSchema, overAllAuditSummarySchema, overViewCardSchema, overViewTableSchema, reTriggerValidSchema, storeMetricsSchema, summarySplitSchema, userAuditHistorySchema, userMetricsSchema } from '../dtos/auditMetrics.dtos.js';
|
|
3
3
|
|
|
4
4
|
export const auditMetricsDocs = {
|
|
5
5
|
|
|
@@ -223,4 +223,44 @@ export const auditMetricsDocs = {
|
|
|
223
223
|
},
|
|
224
224
|
},
|
|
225
225
|
},
|
|
226
|
+
'/v3/audit-metrics/audit-images': {
|
|
227
|
+
get: {
|
|
228
|
+
tags: [ 'Audit Metrics' ],
|
|
229
|
+
description: `View and Download audit images`,
|
|
230
|
+
operationId: 'audit-images',
|
|
231
|
+
parameters: [
|
|
232
|
+
{
|
|
233
|
+
in: 'query',
|
|
234
|
+
name: 'fileDate',
|
|
235
|
+
scema: j2s( auditImageValidSchema ).swagger,
|
|
236
|
+
require: true,
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
in: 'query',
|
|
240
|
+
name: 'storeId',
|
|
241
|
+
scema: j2s( auditImageValidSchema ).swagger,
|
|
242
|
+
require: true,
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
in: 'query',
|
|
246
|
+
name: 'auditType',
|
|
247
|
+
scema: j2s( auditImageValidSchema ).swagger,
|
|
248
|
+
require: true,
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
in: 'query',
|
|
252
|
+
name: 'export',
|
|
253
|
+
scema: j2s( auditImageValidSchema ).swagger,
|
|
254
|
+
require: false,
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
|
+
responses: {
|
|
258
|
+
200: { description: 'Successful' },
|
|
259
|
+
401: { description: 'Unauthorized User' },
|
|
260
|
+
422: { description: 'Field Error' },
|
|
261
|
+
500: { description: 'Server Error' },
|
|
262
|
+
204: { description: 'Not Found' },
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
},
|
|
226
266
|
};
|
package/src/docs/store.docs.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import j2s from 'joi-to-swagger';
|
|
2
|
-
import { auditStoreSchema } from '../dtos/store.dtos.js';
|
|
3
|
-
|
|
4
|
-
export const storeDocs = {
|
|
5
|
-
'/v3/audit/store/audit-stores': {
|
|
6
|
-
post: {
|
|
7
|
-
tags: [ 'Audit/Stores' ],
|
|
8
|
-
description: `sGet list of stores`,
|
|
9
|
-
operationId: 'audit-stores',
|
|
10
|
-
parameters: {},
|
|
11
|
-
requestBody: {
|
|
12
|
-
content: {
|
|
13
|
-
'application/json': {
|
|
14
|
-
schema: j2s( auditStoreSchema ).swagger,
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
responses: {
|
|
19
|
-
200: { description: 'Successful' },
|
|
20
|
-
401: { description: 'Unauthorized User' },
|
|
21
|
-
422: { description: 'Field Error' },
|
|
22
|
-
500: { description: 'Server Error' },
|
|
23
|
-
204: { description: 'Not Found' },
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
};
|
|
1
|
+
import j2s from 'joi-to-swagger';
|
|
2
|
+
import { auditStoreSchema } from '../dtos/store.dtos.js';
|
|
3
|
+
|
|
4
|
+
export const storeDocs = {
|
|
5
|
+
'/v3/audit/store/audit-stores': {
|
|
6
|
+
post: {
|
|
7
|
+
tags: [ 'Audit/Stores' ],
|
|
8
|
+
description: `sGet list of stores`,
|
|
9
|
+
operationId: 'audit-stores',
|
|
10
|
+
parameters: {},
|
|
11
|
+
requestBody: {
|
|
12
|
+
content: {
|
|
13
|
+
'application/json': {
|
|
14
|
+
schema: j2s( auditStoreSchema ).swagger,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
responses: {
|
|
19
|
+
200: { description: 'Successful' },
|
|
20
|
+
401: { description: 'Unauthorized User' },
|
|
21
|
+
422: { description: 'Field Error' },
|
|
22
|
+
500: { description: 'Server Error' },
|
|
23
|
+
204: { description: 'Not Found' },
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
};
|
package/src/docs/user.docs.js
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import j2s from 'joi-to-swagger';
|
|
2
|
-
import { userSchema } from '../dtos/user.dtos.js';
|
|
3
|
-
|
|
4
|
-
export const userDocs = {
|
|
5
|
-
'/v3/audit/user/tango-users': {
|
|
6
|
-
get: {
|
|
7
|
-
tags: [ 'Audit/User' ],
|
|
8
|
-
description: 'Get user list',
|
|
9
|
-
operationId: 'tango-users',
|
|
10
|
-
parameters: [
|
|
11
|
-
{
|
|
12
|
-
in: 'query',
|
|
13
|
-
name: 'limit',
|
|
14
|
-
scema: j2s( userSchema ).swagger,
|
|
15
|
-
require: false,
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
in: 'query',
|
|
19
|
-
name: 'offset',
|
|
20
|
-
scema: j2s( userSchema ).swagger,
|
|
21
|
-
require: false,
|
|
22
|
-
},
|
|
23
|
-
],
|
|
24
|
-
responses: {
|
|
25
|
-
200: { description: 'Successful' },
|
|
26
|
-
401: { description: 'Unauthorized User' },
|
|
27
|
-
422: { description: 'Field Error' },
|
|
28
|
-
500: { description: 'Server Error' },
|
|
29
|
-
204: { description: 'Not Found' },
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
};
|
|
1
|
+
import j2s from 'joi-to-swagger';
|
|
2
|
+
import { userSchema } from '../dtos/user.dtos.js';
|
|
3
|
+
|
|
4
|
+
export const userDocs = {
|
|
5
|
+
'/v3/audit/user/tango-users': {
|
|
6
|
+
get: {
|
|
7
|
+
tags: [ 'Audit/User' ],
|
|
8
|
+
description: 'Get user list',
|
|
9
|
+
operationId: 'tango-users',
|
|
10
|
+
parameters: [
|
|
11
|
+
{
|
|
12
|
+
in: 'query',
|
|
13
|
+
name: 'limit',
|
|
14
|
+
scema: j2s( userSchema ).swagger,
|
|
15
|
+
require: false,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
in: 'query',
|
|
19
|
+
name: 'offset',
|
|
20
|
+
scema: j2s( userSchema ).swagger,
|
|
21
|
+
require: false,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
responses: {
|
|
25
|
+
200: { description: 'Successful' },
|
|
26
|
+
401: { description: 'Unauthorized User' },
|
|
27
|
+
422: { description: 'Field Error' },
|
|
28
|
+
500: { description: 'Server Error' },
|
|
29
|
+
204: { description: 'Not Found' },
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
@@ -167,18 +167,15 @@ export const reTriggerValid = {
|
|
|
167
167
|
body: reTriggerValidSchema,
|
|
168
168
|
};
|
|
169
169
|
|
|
170
|
-
export const
|
|
170
|
+
export const auditImageValidSchema = joi.object(
|
|
171
171
|
{
|
|
172
172
|
fileDate: joi.string().required(),
|
|
173
173
|
storeId: joi.string().required(),
|
|
174
|
-
auditType: joi.string().
|
|
175
|
-
|
|
176
|
-
totalCount: joi.number().required(),
|
|
177
|
-
userId: joi.string().optional(),
|
|
178
|
-
auditId: joi.string().required(),
|
|
174
|
+
auditType: joi.string().required(),
|
|
175
|
+
export: joi.boolean().optional(),
|
|
179
176
|
},
|
|
180
177
|
);
|
|
181
178
|
|
|
182
|
-
export const
|
|
183
|
-
|
|
179
|
+
export const auditImageValid = {
|
|
180
|
+
query: auditImageValidSchema,
|
|
184
181
|
};
|
package/src/dtos/store.dtos.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import joi from 'joi';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export const auditStoreSchema = joi.object(
|
|
5
|
-
{
|
|
6
|
-
clientId: joi.array().required(),
|
|
7
|
-
limit: joi.number().optional(),
|
|
8
|
-
offset: joi.number().optional(),
|
|
9
|
-
},
|
|
10
|
-
);
|
|
11
|
-
|
|
12
|
-
export const auditStoreValid = {
|
|
13
|
-
body: auditStoreSchema,
|
|
14
|
-
};
|
|
1
|
+
import joi from 'joi';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export const auditStoreSchema = joi.object(
|
|
5
|
+
{
|
|
6
|
+
clientId: joi.array().required(),
|
|
7
|
+
limit: joi.number().optional(),
|
|
8
|
+
offset: joi.number().optional(),
|
|
9
|
+
},
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export const auditStoreValid = {
|
|
13
|
+
body: auditStoreSchema,
|
|
14
|
+
};
|
package/src/dtos/user.dtos.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import joi from 'joi';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export const userSchema = joi.object(
|
|
5
|
-
{
|
|
6
|
-
|
|
7
|
-
limit: joi.number().optional(),
|
|
8
|
-
offset: joi.number().optional(),
|
|
9
|
-
},
|
|
10
|
-
);
|
|
11
|
-
|
|
12
|
-
export const userValid = {
|
|
13
|
-
query: userSchema,
|
|
14
|
-
};
|
|
1
|
+
import joi from 'joi';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export const userSchema = joi.object(
|
|
5
|
+
{
|
|
6
|
+
|
|
7
|
+
limit: joi.number().optional(),
|
|
8
|
+
offset: joi.number().optional(),
|
|
9
|
+
},
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export const userValid = {
|
|
13
|
+
query: userSchema,
|
|
14
|
+
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
import express from 'express';
|
|
3
3
|
import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { auditImages, clientMetrics, overAllAuditSummary, overViewCard, overViewTable, reTrigger, storeMetrics, summarySplit, userAuditHistory, userMetrics } from '../controllers/auditMetrics.controllers.js';
|
|
5
|
+
import { auditImageValid, clientMetricsValid, overAllAuditSummaryValid, overViewCardValid, overViewTableValid, reTriggerValid, storeMetricsValid, summarySplitValid, userAuditHistoryValid, userMetricsValid } from '../dtos/auditMetrics.dtos.js';
|
|
6
6
|
import { isAuditDocumentExist, isAuditInputFolderExist } from '../validation/audit.validation.js';
|
|
7
7
|
|
|
8
8
|
export const auditMetricsRouter = express.Router();
|
|
@@ -16,6 +16,6 @@ auditMetricsRouter.post( '/summary-split-up', isAllowedSessionHandler, validate(
|
|
|
16
16
|
auditMetricsRouter.post( '/overview-table', isAllowedSessionHandler, validate( overViewTableValid ), overViewTable );
|
|
17
17
|
auditMetricsRouter.post( '/overall-audit-summary', isAllowedSessionHandler, validate( overAllAuditSummaryValid ), overAllAuditSummary );
|
|
18
18
|
auditMetricsRouter.post( '/re-trigger', isAllowedSessionHandler, validate( reTriggerValid ), isAuditDocumentExist, isAuditInputFolderExist, reTrigger );
|
|
19
|
-
auditMetricsRouter.
|
|
19
|
+
auditMetricsRouter.get( '/audit-images', isAllowedSessionHandler, validate( auditImageValid ), isAuditInputFolderExist, auditImages );
|
|
20
20
|
|
|
21
21
|
export default auditMetricsRouter;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Router } from 'express';
|
|
2
|
-
import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
|
|
3
|
-
import { auditStoreList } from '../controllers/store.controllers.js';
|
|
4
|
-
import { auditStoreValid } from '../dtos/store.dtos.js';
|
|
5
|
-
|
|
6
|
-
export const storeRouter = Router();
|
|
7
|
-
|
|
8
|
-
storeRouter.post( '/audit-stores', isAllowedSessionHandler, validate( auditStoreValid ), auditStoreList );
|
|
9
|
-
|
|
10
|
-
export default storeRouter;
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
|
|
3
|
+
import { auditStoreList } from '../controllers/store.controllers.js';
|
|
4
|
+
import { auditStoreValid } from '../dtos/store.dtos.js';
|
|
5
|
+
|
|
6
|
+
export const storeRouter = Router();
|
|
7
|
+
|
|
8
|
+
storeRouter.post( '/audit-stores', isAllowedSessionHandler, validate( auditStoreValid ), auditStoreList );
|
|
9
|
+
|
|
10
|
+
export default storeRouter;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Router } from 'express';
|
|
2
|
-
import { isAllowedSessionHandler } from 'tango-app-api-middleware';
|
|
3
|
-
import { auditUserList } from '../controllers/user.controllers.js';
|
|
4
|
-
|
|
5
|
-
export const userRouter = Router();
|
|
6
|
-
|
|
7
|
-
userRouter.get( '/tango-users', isAllowedSessionHandler, auditUserList );
|
|
8
|
-
|
|
9
|
-
export default userRouter;
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { isAllowedSessionHandler } from 'tango-app-api-middleware';
|
|
3
|
+
import { auditUserList } from '../controllers/user.controllers.js';
|
|
4
|
+
|
|
5
|
+
export const userRouter = Router();
|
|
6
|
+
|
|
7
|
+
userRouter.get( '/tango-users', isAllowedSessionHandler, auditUserList );
|
|
8
|
+
|
|
9
|
+
export default userRouter;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { checkFileExist, chunkArray, getQueueUrl, logger } from 'tango-app-api-middleware';
|
|
1
|
+
import { checkFileExist, chunkArray, getObject, getQueueUrl, listFileWithoutLimit, logger, signedUrl } from 'tango-app-api-middleware';
|
|
2
2
|
import { findOneUserAudit } from '../service/userAudit.service.js';
|
|
3
3
|
import { findOneStoreAudit } from '../service/storeAudit.service.js';
|
|
4
|
+
import AdmZip from 'adm-zip';
|
|
4
5
|
|
|
5
6
|
export async function isExistsQueue( req, res, next ) {
|
|
6
7
|
try {
|
|
@@ -163,7 +164,8 @@ const mapFunction = async ( chunkData, filterData ) => {
|
|
|
163
164
|
export async function isAuditInputFolderExist( req, res, next ) {
|
|
164
165
|
try {
|
|
165
166
|
const bucket = JSON.parse( process.env.BUCKET );
|
|
166
|
-
const inputData = req.body;
|
|
167
|
+
const inputData = req.method === 'POST' ? req.body : req.query;
|
|
168
|
+
console.log( inputData );
|
|
167
169
|
const params={
|
|
168
170
|
Bucket: bucket.auditInput,
|
|
169
171
|
Key: `${inputData.fileDate}/${inputData.storeId}`,
|
|
@@ -202,4 +204,92 @@ export async function isAuditDocumentExist( req, res, next ) {
|
|
|
202
204
|
}
|
|
203
205
|
}
|
|
204
206
|
|
|
207
|
+
export async function getAuditImageData( data ) {
|
|
208
|
+
try {
|
|
209
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
210
|
+
const storeId = data.storeId;
|
|
211
|
+
const fileDate = data.fileDate;
|
|
212
|
+
const files = [];
|
|
213
|
+
const fetchData = {
|
|
214
|
+
Bucket: `${bucket.auditInput}`,
|
|
215
|
+
filePath: `${fileDate}/${storeId}/`,
|
|
216
|
+
};
|
|
217
|
+
const folderPath = await listFileWithoutLimit( fetchData );
|
|
218
|
+
if ( folderPath.statusCode == 404 ) {
|
|
219
|
+
return folderPath;
|
|
220
|
+
}
|
|
221
|
+
const auditImages = folderPath;
|
|
222
|
+
|
|
223
|
+
if ( data.export==false ) {
|
|
224
|
+
if ( auditImages && auditImages?.length > 0 ) {
|
|
225
|
+
for ( let i = 0; i < auditImages.length; i++ ) {
|
|
226
|
+
const img = auditImages[i].Key.split( '/' );
|
|
227
|
+
const image = img[2].split( '.' );
|
|
228
|
+
const indexes = image[0].split( '_' );
|
|
229
|
+
const params = {
|
|
230
|
+
file_path: auditImages[i].Key,
|
|
231
|
+
Bucket: fetchData.Bucket,
|
|
232
|
+
};
|
|
233
|
+
const data = await signedUrl( params );
|
|
234
|
+
files.push( {
|
|
235
|
+
imgPath: data,
|
|
236
|
+
imgName: indexes[1],
|
|
237
|
+
imgId: image[0],
|
|
238
|
+
// imgFile: auditImages[i],
|
|
239
|
+
} );
|
|
240
|
+
}
|
|
241
|
+
return files;
|
|
242
|
+
}
|
|
243
|
+
} else {
|
|
244
|
+
if ( auditImages && auditImages?.length > 0 ) {
|
|
245
|
+
for ( let i = 0; i < auditImages.length; i++ ) {
|
|
246
|
+
const img = auditImages[i].Key.split( '/' );
|
|
247
|
+
const image = img[2].split( '.' );
|
|
248
|
+
const indexes = image[0].split( '_' );
|
|
249
|
+
const params = {
|
|
250
|
+
file_path: auditImages[i].Key,
|
|
251
|
+
Bucket: fetchData.Bucket,
|
|
252
|
+
};
|
|
253
|
+
const data = await signedUrl( params );
|
|
254
|
+
files.push( {
|
|
255
|
+
imgPath: data,
|
|
256
|
+
imgName: indexes[1],
|
|
257
|
+
imgId: image[0],
|
|
258
|
+
imgFile: auditImages[i],
|
|
259
|
+
} );
|
|
260
|
+
}
|
|
261
|
+
return files;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
} catch ( error ) {
|
|
265
|
+
logger.error( { error: error, type: 'getAuditImageData' } );
|
|
266
|
+
return error;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export async function zipDownloadImage( data ) {
|
|
271
|
+
try {
|
|
272
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
273
|
+
const zip = new AdmZip();
|
|
274
|
+
const split = await chunkArray( data, 10 );
|
|
205
275
|
|
|
276
|
+
const promises = await split.map( async ( chunk ) => {
|
|
277
|
+
for ( let i = 0; i< chunk.length; i++ ) {
|
|
278
|
+
const params ={
|
|
279
|
+
Bucket: `${bucket.auditInput}`,
|
|
280
|
+
Key: chunk[i].imgFile.Key,
|
|
281
|
+
};
|
|
282
|
+
const fileBuffer = await getObject( params );
|
|
283
|
+
zip.addFile( chunk[i].imgFile.Key, fileBuffer );
|
|
284
|
+
}
|
|
285
|
+
return zip;
|
|
286
|
+
} );
|
|
287
|
+
await Promise.all( promises );
|
|
288
|
+
const zipBuffer = zip.toBuffer();
|
|
289
|
+
return zipBuffer;
|
|
290
|
+
} catch ( error ) {
|
|
291
|
+
const err = error.message || 'Internal Server Error';
|
|
292
|
+
logger.error( { error: error, message: data, function: 'zipDownloadImage' } );
|
|
293
|
+
return err;
|
|
294
|
+
}
|
|
295
|
+
}
|