tango-app-api-audit 1.0.5 → 1.0.6
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/index.js +3 -1
- package/package.json +1 -1
- package/src/controllers/audit.controllers.js +72 -3
- package/src/controllers/auditMetrics.controllers.js +1 -0
- package/src/controllers/client.controllers.js +35 -0
- package/src/docs/audit.docs.js +52 -2
- package/src/docs/client.docs.js +33 -0
- package/src/dtos/audit.dtos.js +24 -0
- package/src/dtos/auditMetrics.dtos.js +1 -1
- package/src/dtos/client.dtos.js +13 -0
- package/src/routes/audit.routes.js +8 -6
- package/src/routes/client.routes.js +10 -0
- package/src/service/client.service.js +4 -0
- package/src/validation/audit.validation.js +43 -1
package/index.js
CHANGED
|
@@ -4,8 +4,10 @@ import { auditRouter } from './src/routes/audit.routes.js';
|
|
|
4
4
|
import { auditMetricsRouter } from './src/routes/auditMetrics.routes.js';
|
|
5
5
|
import { auditMetricsDocs } from './src/docs/auditMetrics.docs.js';
|
|
6
6
|
import { auditDocs } from './src/docs/audit.docs.js';
|
|
7
|
+
import clientRouter from './src/routes/client.routes.js';
|
|
8
|
+
import { clientDocs } from './src/docs/client.docs.js';
|
|
7
9
|
|
|
8
10
|
|
|
9
|
-
export { auditRouter, auditMetricsRouter, auditMetricsDocs, auditDocs };
|
|
11
|
+
export { auditRouter, auditMetricsRouter, auditMetricsDocs, auditDocs, clientRouter, clientDocs };
|
|
10
12
|
|
|
11
13
|
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { chunkArray, getJsonFileData, getUTC, listFileByPath, listFileWithoutLimit, signedUrl } from 'tango-app-api-middleware';
|
|
1
|
+
import { chunkArray, getJsonFileData, getOpenSearchData, getUTC, insertOpenSearchData, listFileByPath, listFileWithoutLimit, signedUrl } from 'tango-app-api-middleware';
|
|
2
2
|
import { aggregateUserAudit, createUserAudit, findOneUserAudit, updateOneUserAudit } from '../service/userAudit.service.js';
|
|
3
3
|
import { aggregateAssignAudit, updateOneAssignAudit } from '../service/assignAudit.service.js';
|
|
4
4
|
import { findOneUser } from '../service/user.service.js';
|
|
@@ -745,7 +745,9 @@ export async function getQueueDetailList( req, res ) {
|
|
|
745
745
|
|
|
746
746
|
export async function saveDraft( req, res ) {
|
|
747
747
|
try {
|
|
748
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
748
749
|
const inputData = req.body;
|
|
750
|
+
inputData.userId = req.user._id;
|
|
749
751
|
const getUserAuditData = await findOneUserAudit( { _id: inputData.auditId } );
|
|
750
752
|
if ( !getUserAuditData ) {
|
|
751
753
|
return res.sendError( 'No Data Found', 204 );
|
|
@@ -797,15 +799,82 @@ export async function saveDraft( req, res ) {
|
|
|
797
799
|
auditId: inputData.auditId,
|
|
798
800
|
},
|
|
799
801
|
};
|
|
802
|
+
await insertOpenSearchData( openSearch.activityLog, logData );
|
|
800
803
|
logger.info( { logData: logData } ); // need to insert to os
|
|
801
804
|
}
|
|
802
|
-
|
|
805
|
+
await insertOpenSearchData( openSearch.auditLog, inputData );
|
|
803
806
|
await updateOneUserAudit( userQuery, userRecord );
|
|
804
807
|
await updateOneStoreAudit( storeQuery, storeRecord );
|
|
805
|
-
return res.sendSuccess(
|
|
808
|
+
return res.sendSuccess( { result: 'The file has been drafted successfully' } );
|
|
806
809
|
} catch ( error ) {
|
|
807
810
|
const err = error.message || 'Internal Server Error';
|
|
808
811
|
logger.error( { error: error, message: req.body, function: 'saveDraft' } );
|
|
809
812
|
return res.sendError( err, 500 );
|
|
810
813
|
}
|
|
811
814
|
}
|
|
815
|
+
|
|
816
|
+
export async function getDraftedData( req, res ) {
|
|
817
|
+
try {
|
|
818
|
+
const openSearch = JSON.parse( process.env.OPENSEARCH );
|
|
819
|
+
const inputData = req.query;
|
|
820
|
+
logger.info( { inputData: inputData } );
|
|
821
|
+
const getLog = await getOpenSearchData( openSearch.auditLog,
|
|
822
|
+
{
|
|
823
|
+
'size': 1,
|
|
824
|
+
'query': {
|
|
825
|
+
'bool': {
|
|
826
|
+
'must': [
|
|
827
|
+
{
|
|
828
|
+
'term': {
|
|
829
|
+
'fileDate.keyword': inputData.fileDate,
|
|
830
|
+
},
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
'term': {
|
|
834
|
+
'storeId.keyword': inputData.storeId,
|
|
835
|
+
},
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
'term': {
|
|
839
|
+
'userId.keyword': req.user._id,
|
|
840
|
+
},
|
|
841
|
+
},
|
|
842
|
+
|
|
843
|
+
],
|
|
844
|
+
|
|
845
|
+
},
|
|
846
|
+
},
|
|
847
|
+
|
|
848
|
+
'sort': [
|
|
849
|
+
{
|
|
850
|
+
'timestamp': {
|
|
851
|
+
'order': 'desc',
|
|
852
|
+
},
|
|
853
|
+
},
|
|
854
|
+
],
|
|
855
|
+
|
|
856
|
+
} );
|
|
857
|
+
const result = getLog?.body?.hits?.hits;
|
|
858
|
+
if ( result.length ==0 ) {
|
|
859
|
+
return res.sendError( 'No Data Found', 500 );
|
|
860
|
+
}
|
|
861
|
+
return res.sendSuccess( { result: result } );
|
|
862
|
+
} catch ( error ) {
|
|
863
|
+
const err = error.message || 'Internal Server Error';
|
|
864
|
+
logger.error( { error: error, message: req.query, function: 'getDraftedData' } );
|
|
865
|
+
return res.sendError( err, 500 );
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
export async function save( req, res ) {
|
|
870
|
+
try {
|
|
871
|
+
const inputData = req.body;
|
|
872
|
+
return res.sendSuccess( { result: inputData } );
|
|
873
|
+
} catch ( error ) {
|
|
874
|
+
const err= error.message || 'Internal Server Error';
|
|
875
|
+
logger.error( { error: error, message: req.body, function: 'save' } );
|
|
876
|
+
return res.sendError( err );
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { logger } from 'tango-app-api-middleware';
|
|
2
|
+
import { aggregateClient } from '../service/client.service.js';
|
|
3
|
+
|
|
4
|
+
export async function clients( req, res ) {
|
|
5
|
+
try {
|
|
6
|
+
const inputData = req.query;
|
|
7
|
+
const query =[
|
|
8
|
+
{
|
|
9
|
+
$match: {
|
|
10
|
+
'status': { $in: [ 'active', 'hold' ] },
|
|
11
|
+
'auditConfigs.audit': true,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const count = await aggregateClient( query );
|
|
17
|
+
if ( count.length == 0 ) {
|
|
18
|
+
return res.sendError( 'No Data Found', 204 );
|
|
19
|
+
}
|
|
20
|
+
if ( inputData.limit ) {
|
|
21
|
+
const offset = inputData.offset ? ( inputData.offset - 1 ) * inputData.limit : 0;
|
|
22
|
+
query.push(
|
|
23
|
+
{ $skip: offset },
|
|
24
|
+
{ $limit: limit },
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
const getAuditClients = await aggregateClient( query );
|
|
28
|
+
|
|
29
|
+
return res.sendSuccess( { result: getAuditClients, count: count.length } );
|
|
30
|
+
} catch ( error ) {
|
|
31
|
+
const err = error.message || 'Internal Server Error';
|
|
32
|
+
logger.info( { error: error, messgae: req.query, function: 'clients' } );
|
|
33
|
+
return res.sendError( err, 500 );
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/docs/audit.docs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getFileSchema, saveDraftSchema } from '../dtos/audit.dtos.js';
|
|
1
|
+
import { getDraftedDataSchema, getFileSchema, saveDraftSchema, saveSchema } from '../dtos/audit.dtos.js';
|
|
2
2
|
import j2s from 'joi-to-swagger';
|
|
3
3
|
|
|
4
4
|
export const auditDocs = {
|
|
@@ -28,7 +28,7 @@ export const auditDocs = {
|
|
|
28
28
|
},
|
|
29
29
|
],
|
|
30
30
|
responses: {
|
|
31
|
-
200: { description: '
|
|
31
|
+
200: { description: 'Successful' },
|
|
32
32
|
401: { description: 'Unauthorized User' },
|
|
33
33
|
422: { description: 'Field Error' },
|
|
34
34
|
500: { description: 'Server Error' },
|
|
@@ -58,4 +58,54 @@ export const auditDocs = {
|
|
|
58
58
|
},
|
|
59
59
|
},
|
|
60
60
|
},
|
|
61
|
+
'/v3/audit/get-drafted-data': {
|
|
62
|
+
get: {
|
|
63
|
+
tags: [ 'Audit' ],
|
|
64
|
+
description: 'Get a saved file via DB',
|
|
65
|
+
operationId: 'get-drafted-data',
|
|
66
|
+
parameters: [
|
|
67
|
+
{
|
|
68
|
+
in: 'query',
|
|
69
|
+
name: 'fileDate',
|
|
70
|
+
scema: j2s( getDraftedDataSchema ).swagger,
|
|
71
|
+
require: true,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
in: 'query',
|
|
75
|
+
name: 'storeId',
|
|
76
|
+
scema: j2s( getDraftedDataSchema ).swagger,
|
|
77
|
+
require: false,
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
responses: {
|
|
81
|
+
200: { description: 'Successful' },
|
|
82
|
+
401: { description: 'Unauthorized User' },
|
|
83
|
+
422: { description: 'Field Error' },
|
|
84
|
+
500: { description: 'Server Error' },
|
|
85
|
+
204: { description: 'Not Found' },
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
'/v3/audit/save': {
|
|
90
|
+
post: {
|
|
91
|
+
tags: [ 'Audit' ],
|
|
92
|
+
description: `submit the audit file. which is store in the bucket in the json format`,
|
|
93
|
+
operationId: 'save',
|
|
94
|
+
parameters: {},
|
|
95
|
+
requestBody: {
|
|
96
|
+
content: {
|
|
97
|
+
'application/json': {
|
|
98
|
+
schema: j2s( saveSchema ).swagger,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
responses: {
|
|
103
|
+
200: { description: 'The Audited file has been submited successfully ' },
|
|
104
|
+
401: { description: 'Unauthorized User' },
|
|
105
|
+
422: { description: 'Field Error' },
|
|
106
|
+
500: { description: 'Server Error' },
|
|
107
|
+
204: { description: 'Not Found' },
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
61
111
|
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import j2s from 'joi-to-swagger';
|
|
2
|
+
import { clientSchema } from '../dtos/client.dtos.js';
|
|
3
|
+
|
|
4
|
+
export const clientDocs = {
|
|
5
|
+
'/v3/audit/client/clients': {
|
|
6
|
+
get: {
|
|
7
|
+
tags: [ 'Audit/Client' ],
|
|
8
|
+
description: 'Get client list which is enable for audit',
|
|
9
|
+
operationId: 'clients',
|
|
10
|
+
parameters: [
|
|
11
|
+
{
|
|
12
|
+
in: 'query',
|
|
13
|
+
name: 'limit',
|
|
14
|
+
scema: j2s( clientSchema ).swagger,
|
|
15
|
+
require: false,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
in: 'query',
|
|
19
|
+
name: 'offset',
|
|
20
|
+
scema: j2s( clientSchema ).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
|
+
};
|
package/src/dtos/audit.dtos.js
CHANGED
|
@@ -29,6 +29,7 @@ export const saveDraftSchema = joi.object(
|
|
|
29
29
|
customerCount: joi.number().optional(),
|
|
30
30
|
customer: joi.array().optional(),
|
|
31
31
|
retagCount: joi.number().optional(),
|
|
32
|
+
retagImage: joi.array().optional(),
|
|
32
33
|
},
|
|
33
34
|
);
|
|
34
35
|
|
|
@@ -36,6 +37,29 @@ export const saveDraftValid = {
|
|
|
36
37
|
body: saveDraftSchema,
|
|
37
38
|
};
|
|
38
39
|
|
|
40
|
+
export const getDraftedDataSchema = joi.object(
|
|
41
|
+
{
|
|
42
|
+
storeId: joi.string().required(),
|
|
43
|
+
fileDate: joi.string().required(),
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
export const getDraftedDataValid = {
|
|
48
|
+
query: getDraftedDataSchema,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const saveSchema = joi.object(
|
|
52
|
+
{
|
|
53
|
+
auditId: joi.string().required(),
|
|
54
|
+
storeId: joi.string().required(),
|
|
55
|
+
fileDate: joi.string().required(),
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
export const saveValid = {
|
|
60
|
+
body: saveSchema,
|
|
61
|
+
};
|
|
62
|
+
|
|
39
63
|
export const getQueueDetailListSchema = joi.object(
|
|
40
64
|
{
|
|
41
65
|
searchValue: joi.string().optional(),
|
|
@@ -47,7 +47,7 @@ export const clientMetricsSchema = joi.object(
|
|
|
47
47
|
toDate: joi.string().required(),
|
|
48
48
|
searchValue: joi.string().optional(),
|
|
49
49
|
filterByClient: joi.array().required(),
|
|
50
|
-
|
|
50
|
+
filterByStatus: joi.array().optional(),
|
|
51
51
|
sortColumnName: joi.string().optional(),
|
|
52
52
|
sortBy: joi.number().optional(),
|
|
53
53
|
limit: joi.number().optional(),
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
|
-
import { isExistsQueue } from '../validation/audit.validation.js';
|
|
2
|
+
import { isExistsQueue, validateUserAudit } from '../validation/audit.validation.js';
|
|
3
3
|
import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
|
|
4
|
-
import { getAuditFile, getQueueDetailList, saveDraft } from '../controllers/audit.controllers.js';
|
|
5
|
-
import { getFileValid, getQueueDetailListValid, saveDraftValid } from '../dtos/audit.dtos.js';
|
|
4
|
+
import { getAuditFile, getDraftedData, getQueueDetailList, save, saveDraft } from '../controllers/audit.controllers.js';
|
|
5
|
+
import { getDraftedDataValid, getFileValid, getQueueDetailListValid, saveDraftValid, saveValid } from '../dtos/audit.dtos.js';
|
|
6
6
|
|
|
7
7
|
export const auditRouter = express.Router();
|
|
8
8
|
|
|
9
|
-
auditRouter.get( '/get-file', validate( getFileValid ),
|
|
10
|
-
auditRouter.post( '/save-draft', validate( saveDraftValid ),
|
|
11
|
-
auditRouter.get( '/get-
|
|
9
|
+
auditRouter.get( '/get-file', isAllowedSessionHandler, validate( getFileValid ), isExistsQueue, getAuditFile );
|
|
10
|
+
auditRouter.post( '/save-draft', isAllowedSessionHandler, validate( saveDraftValid ), saveDraft );
|
|
11
|
+
auditRouter.get( '/get-drafted-data', isAllowedSessionHandler, validate( getDraftedDataValid ), getDraftedData );
|
|
12
|
+
auditRouter.post( '/save', isAllowedSessionHandler, validate( saveValid ), validateUserAudit, save );
|
|
13
|
+
auditRouter.get( '/get-queue-detail-list', isAllowedSessionHandler, validate( getQueueDetailListValid ), getQueueDetailList );
|
|
12
14
|
|
|
13
15
|
export default auditRouter;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { isAllowedSessionHandler, validate } from 'tango-app-api-middleware';
|
|
3
|
+
import { clients } from '../controllers/client.controllers.js';
|
|
4
|
+
import { clientValid } from '../dtos/client.dtos.js';
|
|
5
|
+
|
|
6
|
+
export const clientRouter = Router();
|
|
7
|
+
|
|
8
|
+
clientRouter.get( '/clients', isAllowedSessionHandler, validate( clientValid ), clients );
|
|
9
|
+
|
|
10
|
+
export default clientRouter;
|
|
@@ -4,3 +4,7 @@ import clientModel from 'tango-api-schema/schema/client.model.js';
|
|
|
4
4
|
export function aggregateClient( query ) {
|
|
5
5
|
return clientModel.aggregate( query, { collation: { locale: 'en', strength: 2 } } );
|
|
6
6
|
}
|
|
7
|
+
|
|
8
|
+
export function findClient( query, fields, sort={ createdAt: -1 } ) {
|
|
9
|
+
return clientModel.find( query, fields ).sort( sort );
|
|
10
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { getQueueUrl, logger } from 'tango-app-api-middleware';
|
|
1
|
+
import { checkFileExist, getQueueUrl, logger } from 'tango-app-api-middleware';
|
|
2
|
+
import { findOneUserAudit } from '../service/userAudit.service.js';
|
|
2
3
|
|
|
3
4
|
export async function isExistsQueue( req, res, next ) {
|
|
4
5
|
try {
|
|
@@ -14,3 +15,44 @@ export async function isExistsQueue( req, res, next ) {
|
|
|
14
15
|
return res.sendError( error, 500 );
|
|
15
16
|
}
|
|
16
17
|
}
|
|
18
|
+
|
|
19
|
+
export async function validateUserAudit( req, res, next ) {
|
|
20
|
+
try {
|
|
21
|
+
const inputData = req.body;
|
|
22
|
+
const userAuditDetails = findOneUserAudit( { _id: inputData.auditId } );
|
|
23
|
+
if ( !userAuditDetails ) {
|
|
24
|
+
return res.sendError( 'No Data Available' );
|
|
25
|
+
} else if ( userAuditDetails && userAuditDetails.auditStatus == 'skipped' ) {
|
|
26
|
+
return res.sendError( 'The Audit file Assigned to some one else', 203 );
|
|
27
|
+
}
|
|
28
|
+
req.body.userAudit = userAuditDetails;
|
|
29
|
+
next();
|
|
30
|
+
} catch ( error ) {
|
|
31
|
+
const err = error.message || 'Internal Server Error';
|
|
32
|
+
logger.error( { error: error, message: req.query, function: 'validateUserAudit' } );
|
|
33
|
+
return res.sendError( err, 500 );
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function isMasterJsonExists( req, res, next ) {
|
|
38
|
+
try {
|
|
39
|
+
const bucket = JSON.parse( process.env.BUCKET );
|
|
40
|
+
const inputData = req.body;
|
|
41
|
+
params={
|
|
42
|
+
Bucket: bucket.masterJson,
|
|
43
|
+
Key: `${inputData.storeId}/${inputData.fileDate}/${bucket.masterJsonFile}`,
|
|
44
|
+
};
|
|
45
|
+
const isExist = await checkFileExist( params );
|
|
46
|
+
if ( isExist ) {
|
|
47
|
+
next();
|
|
48
|
+
} else {
|
|
49
|
+
return res.sendError( `NO_MASTER_JSON_AVAILABLE : ${inputData.storeId}/${inputData.fileDate}/${bucketName.masterJsonFile}`, 400 );
|
|
50
|
+
}
|
|
51
|
+
} catch ( error ) {
|
|
52
|
+
const err = error.message || 'Internal Server Error';
|
|
53
|
+
logger.error( { error: error, message: req.query, function: 'isMasterJsonExists' } );
|
|
54
|
+
return res.sendError( err, 500 );
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|