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 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,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-audit",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "audit & audit metrics apis",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -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
- logger.info( { userRecord: userRecord, storeRecord: storeRecord } );
805
+ await insertOpenSearchData( openSearch.auditLog, inputData );
803
806
  await updateOneUserAudit( userQuery, userRecord );
804
807
  await updateOneStoreAudit( storeQuery, storeRecord );
805
- return res.sendSuccess( inputData );
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
+
@@ -379,6 +379,7 @@ export async function clientMetrics( req, res ) {
379
379
  query.push(
380
380
  {
381
381
  $project: {
382
+ '_id': 0,
382
383
  'File Date': '$fileDate',
383
384
  'Client Name': '$clientName',
384
385
  'Client Id': '$clientId',
@@ -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
+ }
@@ -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: 'Successfully' },
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
+ };
@@ -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
- filterBystatus: joi.array().optional(),
50
+ filterByStatus: joi.array().optional(),
51
51
  sortColumnName: joi.string().optional(),
52
52
  sortBy: joi.number().optional(),
53
53
  limit: joi.number().optional(),
@@ -0,0 +1,13 @@
1
+ import joi from 'joi';
2
+
3
+
4
+ export const clientSchema = joi.object(
5
+ {
6
+ limit: joi.number().optional(),
7
+ offset: joi.number().optional(),
8
+ },
9
+ );
10
+
11
+ export const clientValid = {
12
+ query: clientSchema,
13
+ };
@@ -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 ), isAllowedSessionHandler, isExistsQueue, getAuditFile );
10
- auditRouter.post( '/save-draft', validate( saveDraftValid ), isAllowedSessionHandler, saveDraft );
11
- auditRouter.get( '/get-queue-detail-list', validate( getQueueDetailListValid ), isAllowedSessionHandler, getQueueDetailList );
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
+