tango-app-api-analysis-zone 3.0.0-alpha.18 → 3.0.0-alpha.19

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-analysis-zone",
3
- "version": "3.0.0-alpha.18",
3
+ "version": "3.0.0-alpha.19",
4
4
  "description": "zone Analysis",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -21,7 +21,7 @@
21
21
  "mongodb": "^6.8.0",
22
22
  "nodemon": "^3.1.4",
23
23
  "tango-api-schema": "^2.0.131",
24
- "tango-app-api-middleware": "^3.1.26",
24
+ "tango-app-api-middleware": "^3.1.41",
25
25
  "winston": "^3.13.1",
26
26
  "winston-daily-rotate-file": "^5.0.0"
27
27
  },
@@ -0,0 +1,294 @@
1
+ import { logger, download } from 'tango-app-api-middleware';
2
+
3
+ // Lamda Service Call //
4
+ async function LamdaServiceCall( url, data ) {
5
+ try {
6
+ const requestOptions = {
7
+ method: 'POST',
8
+ headers: {
9
+ 'Content-Type': 'application/json',
10
+ },
11
+ body: JSON.stringify( data ),
12
+ };
13
+ const response = await fetch( url, requestOptions );
14
+ if ( !response.ok ) {
15
+ throw new Error( `Response status: ${response.status}` );
16
+ return false;
17
+ }
18
+ const json = await response.json();
19
+ return json;
20
+ } catch ( error ) {
21
+ console.log( 'error =>', error );
22
+ logger.error( { error: error, message: data, function: 'LamdaServiceCall' } );
23
+ }
24
+ }
25
+
26
+ // ///// V1 API's ///////
27
+ export const zonecardsV2 = async ( req, res ) => {
28
+ try {
29
+ let reqestData = req.body;
30
+ let LamdaURL = 'https://na4j2n4jsv5eg6xcjmq3p7e3te0vfczs.lambda-url.ap-south-1.on.aws/';
31
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
32
+ if ( resultData ) {
33
+ if ( resultData.status_code == '200' ) {
34
+ return res.sendSuccess( resultData );
35
+ } else {
36
+ return res.sendError( 'No Content', 204 );
37
+ }
38
+ } else {
39
+ return res.sendError( 'No Content', 204 );
40
+ }
41
+ } catch ( error ) {
42
+ logger.error( { error: error, message: req.query, function: 'zonecardsV2' } );
43
+ return res.sendError( { error: error }, 500 );
44
+ }
45
+ };
46
+
47
+ export const topPerformingZonesV2 = async ( req, res ) => {
48
+ try {
49
+ let reqestData = req.body;
50
+ let LamdaURL = 'https://svr2di4xeao5haaqonnrr4b27i0omlef.lambda-url.ap-south-1.on.aws/';
51
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
52
+ if ( resultData ) {
53
+ if ( resultData.status_code == '200' ) {
54
+ return res.sendSuccess( resultData );
55
+ } else {
56
+ return res.sendError( 'No Content', 204 );
57
+ }
58
+ } else {
59
+ return res.sendError( 'No Content', 204 );
60
+ }
61
+ } catch ( error ) {
62
+ logger.error( { error: error, message: req.query, function: 'topPerformingZonesV2' } );
63
+ return res.sendError( { error: error }, 500 );
64
+ }
65
+ };
66
+
67
+ export const topPerformingStoresV2 = async ( req, res ) => {
68
+ try {
69
+ let reqestData = req.body;
70
+ let LamdaURL = 'https://uhjr3jjkmro2uuqfjkjssm53p40nagoe.lambda-url.ap-south-1.on.aws/';
71
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
72
+ if ( resultData ) {
73
+ if ( resultData.status_code == '200' ) {
74
+ return res.sendSuccess( resultData );
75
+ } else {
76
+ return res.sendError( 'No Content', 204 );
77
+ }
78
+ } else {
79
+ return res.sendError( 'No Content', 204 );
80
+ }
81
+ } catch ( error ) {
82
+ logger.error( { error: error, message: req.query, function: 'topPerformingStoresV2' } );
83
+ return res.sendError( { error: error }, 500 );
84
+ }
85
+ };
86
+
87
+ export const zoneSummaryTableV2 = async ( req, res ) => {
88
+ try {
89
+ let reqestData = req.body;
90
+ if ( reqestData.export ) {
91
+ reqestData.limit = 1000;
92
+ }
93
+ let LamdaURL = 'https://hxpnn5weq3lm4nqouk4pjm3chy0jmqdb.lambda-url.ap-south-1.on.aws/';
94
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
95
+ if ( resultData ) {
96
+ if ( resultData.status_code == '200' ) {
97
+ if ( reqestData.export ) {
98
+ if ( resultData.zoneSummaryData.length>0 ) {
99
+ const exportdata = [];
100
+ resultData.zoneSummaryData.forEach( ( element ) => {
101
+ exportdata.push( {
102
+ 'Date': element.date,
103
+ 'Zone Name': element.zoneName,
104
+ 'Store Name': element.storeName,
105
+ 'StoreId': element.storeId,
106
+ 'Zone Conc.Rate': element.concentrationRate,
107
+ 'Avg Dwell Time': element.avgDwellTime,
108
+ 'Zone FF': element.footfallCount,
109
+ 'Zone Bounced': element.bouncedCount,
110
+ 'Zone Engagers': element.engagersCount,
111
+ 'Age Below 12': element.below12,
112
+ 'Age 13-19': element['13-19'],
113
+ 'Age 20-30': element['20-30'],
114
+ 'Age 31-45': element['31-45'],
115
+ 'Age 46-59': element['46-59'],
116
+ 'Age 60+': element['60 above'],
117
+ 'Male': element.maleCount,
118
+ 'Female': element.femaleCount,
119
+ } );
120
+ } );
121
+ return await download( exportdata, res );
122
+ } else {
123
+ return res.sendError( 'No Content', 204 );
124
+ }
125
+ } else {
126
+ return res.sendSuccess( resultData );
127
+ }
128
+ } else {
129
+ return res.sendError( 'No Content', 204 );
130
+ }
131
+ } else {
132
+ return res.sendError( 'No Content', 204 );
133
+ }
134
+ } catch ( error ) {
135
+ logger.error( { error: error, message: req.query, function: 'zoneSummaryTableV2' } );
136
+ return res.sendError( { error: error }, 500 );
137
+ }
138
+ };
139
+
140
+ export const availableZoneNamesV2 = async ( req, res ) => {
141
+ try {
142
+ let reqestData = req.body;
143
+ let LamdaURL = 'https://akjkfykldtyajtdh7ygnefava40xmcfq.lambda-url.ap-south-1.on.aws/';
144
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
145
+ if ( resultData ) {
146
+ if ( resultData.status_code == '200' ) {
147
+ return res.sendSuccess( resultData );
148
+ } else {
149
+ return res.sendError( 'No Content', 204 );
150
+ }
151
+ } else {
152
+ return res.sendError( 'No Content', 204 );
153
+ }
154
+ } catch ( error ) {
155
+ logger.error( { error: error, message: req.query, function: 'availableZoneNamesV2' } );
156
+ return res.sendError( { error: error }, 500 );
157
+ }
158
+ };
159
+
160
+ export const zoneConcentrationSummaryV2 = async ( req, res ) => {
161
+ try {
162
+ let reqestData = req.body;
163
+ let LamdaURL = 'https://clfde6msiv3rungwmxtgmkp3ka0joyyc.lambda-url.ap-south-1.on.aws/';
164
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
165
+ if ( resultData ) {
166
+ if ( resultData.status_code == '200' ) {
167
+ return res.sendSuccess( resultData );
168
+ } else {
169
+ return res.sendError( 'No Content', 204 );
170
+ }
171
+ } else {
172
+ return res.sendError( 'No Content', 204 );
173
+ }
174
+ } catch ( error ) {
175
+ logger.error( { error: error, message: req.query, function: 'zoneConcentrationSummaryV2' } );
176
+ return res.sendError( { error: error }, 500 );
177
+ }
178
+ };
179
+
180
+ export const overallStoreConcentrationDatesV2 = async ( req, res ) => {
181
+ try {
182
+ let reqestData = req.body;
183
+ let LamdaURL = 'https://nmjcclomhgdecmoyned3sp6y6q0pemhg.lambda-url.ap-south-1.on.aws/';
184
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
185
+ if ( resultData ) {
186
+ if ( resultData.status_code == '200' ) {
187
+ return res.sendSuccess( resultData );
188
+ } else {
189
+ return res.sendError( 'No Content', 204 );
190
+ }
191
+ } else {
192
+ return res.sendError( 'No Content', 204 );
193
+ }
194
+ } catch ( error ) {
195
+ logger.error( { error: error, message: req.query, function: 'overallStoreConcentrationDatesV2' } );
196
+ return res.sendError( { error: error }, 500 );
197
+ }
198
+ };
199
+
200
+ export const overallStoreConcentrationHeatmapV2 = async ( req, res ) => {
201
+ try {
202
+ let reqestData = req.body;
203
+ let LamdaURL = 'https://dp7t3kzmu7xg3x3typm75yulge0vxcvp.lambda-url.ap-south-1.on.aws/';
204
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
205
+ if ( resultData ) {
206
+ if ( resultData.status_code == '200' ) {
207
+ return res.sendSuccess( resultData );
208
+ } else {
209
+ return res.sendError( 'No Content', 204 );
210
+ }
211
+ } else {
212
+ return res.sendError( 'No Content', 204 );
213
+ }
214
+ } catch ( error ) {
215
+ logger.error( { error: error, message: req.query, function: 'overallStoreConcentrationHeatmapV2' } );
216
+ return res.sendError( { error: error }, 500 );
217
+ }
218
+ };
219
+ export const trajectoryAnalysisV2 = async ( req, res ) => {
220
+ try {
221
+ let reqestData = req.body;
222
+ let LamdaURL = '';
223
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
224
+ if ( resultData ) {
225
+ if ( resultData.status_code == '200' ) {
226
+ return res.sendSuccess( resultData );
227
+ } else {
228
+ return res.sendError( 'No Content', 204 );
229
+ }
230
+ } else {
231
+ return res.sendError( 'No Content', 204 );
232
+ }
233
+ } catch ( error ) {
234
+ logger.error( { error: error, message: req.query, function: 'trajectoryAnalysisV2' } );
235
+ return res.sendError( { error: error }, 500 );
236
+ }
237
+ };
238
+ export const customerJourneyV2 = async ( req, res ) => {
239
+ try {
240
+ let reqestData = req.body;
241
+ let LamdaURL = '';
242
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
243
+ if ( resultData ) {
244
+ if ( resultData.status_code == '200' ) {
245
+ return res.sendSuccess( resultData );
246
+ } else {
247
+ return res.sendError( 'No Content', 204 );
248
+ }
249
+ } else {
250
+ return res.sendError( 'No Content', 204 );
251
+ }
252
+ } catch ( error ) {
253
+ logger.error( { error: error, message: req.query, function: 'customerJourneyV2' } );
254
+ return res.sendError( { error: error }, 500 );
255
+ }
256
+ };
257
+
258
+ export async function isAllowedClient( req, res, next ) {
259
+ try {
260
+ let reqestData = req.body;
261
+ let getUserEmail = req.user.email;
262
+ let getUserType = req.user.userType;
263
+ let getClientId = req.user.clientId;
264
+ let getRole = req.user.role;
265
+ if ( getUserType == 'tango' ) {
266
+ if ( getRole == 'superadmin' ) {
267
+ next();
268
+ } else {
269
+ const assignedQuery = {
270
+ userEmail: getUserEmail,
271
+ assignedType: 'client',
272
+ assignedValue: reqestData.clientId,
273
+ };
274
+ const getAssignedType = await findOneUserAssignedStore( assignedQuery );
275
+ if ( getAssignedType ) {
276
+ next();
277
+ } else {
278
+ return res.sendError( 'Client Not Assigned', 400 );
279
+ }
280
+ }
281
+ } else if ( getUserType == 'client' ) {
282
+ if ( getClientId == reqestData.clientId ) {
283
+ next();
284
+ } else {
285
+ return res.sendError( 'Client Not Assigned', 400 );
286
+ }
287
+ } else {
288
+ return res.sendError( 'Client Not Assigned', 400 );
289
+ }
290
+ } catch ( error ) {
291
+ logger.error( { error: error, function: 'isAllowedClient' } );
292
+ return res.sendError( error, 500 );
293
+ }
294
+ }
@@ -0,0 +1,183 @@
1
+ import { logger } from 'tango-app-api-middleware';
2
+
3
+ // Lamda Service Call //
4
+ async function LamdaServiceCall( url, data ) {
5
+ try {
6
+ const requestOptions = {
7
+ method: 'POST',
8
+ headers: {
9
+ 'Content-Type': 'application/json',
10
+ },
11
+ body: JSON.stringify( data ),
12
+ };
13
+ const response = await fetch( url, requestOptions );
14
+ if ( !response.ok ) {
15
+ throw new Error( `Response status: ${response.status}` );
16
+ return false;
17
+ }
18
+ const json = await response.json();
19
+ return json;
20
+ } catch ( error ) {
21
+ console.log( 'error =>', error );
22
+ logger.error( { error: error, message: data, function: 'LamdaServiceCall' } );
23
+ }
24
+ }
25
+
26
+ // ///// V1 API's ///////
27
+ export const zonecardsV2 = async ( req, res ) => {
28
+ try {
29
+ let reqestData = req.body;
30
+ let LamdaURL = 'https://na4j2n4jsv5eg6xcjmq3p7e3te0vfczs.lambda-url.ap-south-1.on.aws/';
31
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
32
+ if ( resultData ) {
33
+ if ( resultData.status_code == '200' ) {
34
+ return res.sendSuccess( resultData );
35
+ } else {
36
+ return res.sendError( 'No Content', 204 );
37
+ }
38
+ } else {
39
+ return res.sendError( 'No Content', 204 );
40
+ }
41
+ } catch ( error ) {
42
+ logger.error( { error: error, message: req.query, function: 'zonecardsV2' } );
43
+ return res.sendError( { error: error }, 500 );
44
+ }
45
+ };
46
+
47
+ export const topPerformingZonesV2 = async ( req, res ) => {
48
+ try {
49
+ let reqestData = req.body;
50
+ let LamdaURL = 'https://svr2di4xeao5haaqonnrr4b27i0omlef.lambda-url.ap-south-1.on.aws/';
51
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
52
+ if ( resultData ) {
53
+ if ( resultData.status_code == '200' ) {
54
+ return res.sendSuccess( resultData );
55
+ } else {
56
+ return res.sendError( 'No Content', 204 );
57
+ }
58
+ } else {
59
+ return res.sendError( 'No Content', 204 );
60
+ }
61
+ } catch ( error ) {
62
+ logger.error( { error: error, message: req.query, function: 'topPerformingZonesV2' } );
63
+ return res.sendError( { error: error }, 500 );
64
+ }
65
+ };
66
+
67
+ export const topPerformingStoresV2 = async ( req, res ) => {
68
+ try {
69
+ let reqestData = req.body;
70
+ let LamdaURL = 'https://uhjr3jjkmro2uuqfjkjssm53p40nagoe.lambda-url.ap-south-1.on.aws/';
71
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
72
+ if ( resultData ) {
73
+ if ( resultData.status_code == '200' ) {
74
+ return res.sendSuccess( resultData );
75
+ } else {
76
+ return res.sendError( 'No Content', 204 );
77
+ }
78
+ } else {
79
+ return res.sendError( 'No Content', 204 );
80
+ }
81
+ } catch ( error ) {
82
+ logger.error( { error: error, message: req.query, function: 'topPerformingStoresV2' } );
83
+ return res.sendError( { error: error }, 500 );
84
+ }
85
+ };
86
+
87
+ export const zoneConcentrationSummaryV2 = async ( req, res ) => {
88
+ try {
89
+ let reqestData = req.body;
90
+ let LamdaURL = 'https://clfde6msiv3rungwmxtgmkp3ka0joyyc.lambda-url.ap-south-1.on.aws/';
91
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
92
+ if ( resultData ) {
93
+ if ( resultData.status_code == '200' ) {
94
+ return res.sendSuccess( resultData );
95
+ } else {
96
+ return res.sendError( 'No Content', 204 );
97
+ }
98
+ } else {
99
+ return res.sendError( 'No Content', 204 );
100
+ }
101
+ } catch ( error ) {
102
+ logger.error( { error: error, message: req.query, function: 'zoneConcentrationSummaryV2' } );
103
+ return res.sendError( { error: error }, 500 );
104
+ }
105
+ };
106
+
107
+ export const overallStoreConcentrationDatesV2 = async ( req, res ) => {
108
+ try {
109
+ let reqestData = req.body;
110
+ let LamdaURL = 'https://nmjcclomhgdecmoyned3sp6y6q0pemhg.lambda-url.ap-south-1.on.aws/';
111
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
112
+ if ( resultData ) {
113
+ if ( resultData.status_code == '200' ) {
114
+ return res.sendSuccess( resultData );
115
+ } else {
116
+ return res.sendError( 'No Content', 204 );
117
+ }
118
+ } else {
119
+ return res.sendError( 'No Content', 204 );
120
+ }
121
+ } catch ( error ) {
122
+ logger.error( { error: error, message: req.query, function: 'overallStoreConcentrationDatesV2' } );
123
+ return res.sendError( { error: error }, 500 );
124
+ }
125
+ };
126
+
127
+ export const overallStoreConcentrationHeatmapV2 = async ( req, res ) => {
128
+ try {
129
+ let reqestData = req.body;
130
+ let LamdaURL = 'https://dp7t3kzmu7xg3x3typm75yulge0vxcvp.lambda-url.ap-south-1.on.aws/';
131
+ let resultData = await LamdaServiceCall( LamdaURL, reqestData );
132
+ if ( resultData ) {
133
+ if ( resultData.status_code == '200' ) {
134
+ return res.sendSuccess( resultData );
135
+ } else {
136
+ return res.sendError( 'No Content', 204 );
137
+ }
138
+ } else {
139
+ return res.sendError( 'No Content', 204 );
140
+ }
141
+ } catch ( error ) {
142
+ logger.error( { error: error, message: req.query, function: 'overallStoreConcentrationHeatmapV2' } );
143
+ return res.sendError( { error: error }, 500 );
144
+ }
145
+ };
146
+
147
+ export async function isAllowedClient( req, res, next ) {
148
+ try {
149
+ let reqestData = req.body;
150
+ let getUserEmail = req.user.email;
151
+ let getUserType = req.user.userType;
152
+ let getClientId = req.user.clientId;
153
+ let getRole = req.user.role;
154
+ if ( getUserType == 'tango' ) {
155
+ if ( getRole == 'superadmin' ) {
156
+ next();
157
+ } else {
158
+ const assignedQuery = {
159
+ userEmail: getUserEmail,
160
+ assignedType: 'client',
161
+ assignedValue: reqestData.clientId,
162
+ };
163
+ const getAssignedType = await findOneUserAssignedStore( assignedQuery );
164
+ if ( getAssignedType ) {
165
+ next();
166
+ } else {
167
+ return res.sendError( 'Client Not Assigned', 400 );
168
+ }
169
+ }
170
+ } else if ( getUserType == 'client' ) {
171
+ if ( getClientId == reqestData.clientId ) {
172
+ next();
173
+ } else {
174
+ return res.sendError( 'Client Not Assigned', 400 );
175
+ }
176
+ } else {
177
+ return res.sendError( 'Client Not Assigned', 400 );
178
+ }
179
+ } catch ( error ) {
180
+ logger.error( { error: error, function: 'isAllowedClient' } );
181
+ return res.sendError( error, 500 );
182
+ }
183
+ }
@@ -0,0 +1,71 @@
1
+ import joi from 'joi';
2
+
3
+ // Base schema
4
+ const baseSchema = {
5
+ clientId: joi.string().required(),
6
+ storeId: joi.array().required().empty(),
7
+ fromDate: joi.string().required(),
8
+ toDate: joi.string().required(),
9
+ };
10
+
11
+ export const validateZoneCardsV2Schema = joi.object( {
12
+ ...baseSchema,
13
+ } );
14
+
15
+ export const validateZoneCardsV2Params = {
16
+ body: validateZoneCardsV2Schema,
17
+ };
18
+
19
+ export const validateTopPerformingZonesV2Schema = joi.object( {
20
+ ...baseSchema,
21
+ sortType: joi.string().required(),
22
+ sortBy: joi.number().optional().allow( '' ),
23
+ sort: joi.string().optional().allow( '' ),
24
+ } );
25
+
26
+ export const validateTopPerformingZonesV2Params = {
27
+ body: validateTopPerformingZonesV2Schema,
28
+ };
29
+
30
+ export const validateTopPerformingStoresV2Schema = joi.object( {
31
+ ...baseSchema,
32
+ sortType: joi.string().required(),
33
+ sortBy: joi.number().optional().allow( '' ),
34
+ sort: joi.string().optional().allow( '' ),
35
+ } );
36
+
37
+ export const validateTopPerformingStoresV2Params = {
38
+ body: validateTopPerformingStoresV2Schema,
39
+ };
40
+
41
+ export const validateZoneConcentrationSummaryV2Schema = joi.object( {
42
+ ...baseSchema,
43
+ zoneName: joi.string().required(),
44
+ } );
45
+
46
+ export const validateZoneConcentrationSummaryV2Params = {
47
+ body: validateZoneConcentrationSummaryV2Schema,
48
+ };
49
+
50
+ export const validateOverallStoreConcentrationDatesV2Schema = joi.object( {
51
+ ...baseSchema,
52
+ zoneName: joi.string().required(),
53
+ dateType: joi.string().required(),
54
+ } );
55
+
56
+ export const validateOverallStoreConcentrationDatesV2Params = {
57
+ body: validateOverallStoreConcentrationDatesV2Schema,
58
+ };
59
+
60
+ export const validateOverallStoreConcentrationHeatmapV2Schema = joi.object( {
61
+ ...baseSchema,
62
+ zoneName: joi.string().required(),
63
+ dateType: joi.string().required(),
64
+ zoneDate: joi.string().required(),
65
+ } );
66
+
67
+ export const validateOverallStoreConcentrationHeatmapV2Params = {
68
+ body: validateOverallStoreConcentrationHeatmapV2Schema,
69
+ };
70
+
71
+
@@ -83,3 +83,103 @@ export const validateZoneHeatmapDatasSchema = joi.object( {
83
83
  export const validateZoneHeatmapDatasParams = {
84
84
  body: validateZoneHeatmapDatasSchema,
85
85
  };
86
+
87
+ export const validateZoneCardsV2Schema = joi.object( {
88
+ ...baseSchema,
89
+ } );
90
+
91
+ export const validateZoneCardsV2Params = {
92
+ body: validateZoneCardsV2Schema,
93
+ };
94
+
95
+ export const validateTopPerformingZonesV2Schema = joi.object( {
96
+ ...baseSchema,
97
+ sortType: joi.string().required(),
98
+ sortBy: joi.number().optional().allow( '' ),
99
+ sort: joi.string().optional().allow( '' ),
100
+ } );
101
+
102
+ export const validateTopPerformingZonesV2Params = {
103
+ body: validateTopPerformingZonesV2Schema,
104
+ };
105
+
106
+ export const validateTopPerformingStoresV2Schema = joi.object( {
107
+ ...baseSchema,
108
+ sortType: joi.string().required(),
109
+ sortBy: joi.number().optional().allow( '' ),
110
+ sort: joi.string().optional().allow( '' ),
111
+ } );
112
+
113
+ export const validateTopPerformingStoresV2Params = {
114
+ body: validateTopPerformingStoresV2Schema,
115
+ };
116
+
117
+ export const validateZoneSummaryTableV2Schema = joi.object( {
118
+ ...baseSchema,
119
+ search: joi.string().optional().allow( '' ),
120
+ sortBy: joi.number().optional().allow( '' ),
121
+ sort: joi.string().optional().allow( '' ),
122
+ limit: joi.number().required(),
123
+ offset: joi.number().required(),
124
+ export: joi.boolean().required(),
125
+ } );
126
+
127
+ export const validateZoneSummaryTableV2Params = {
128
+ body: validateZoneSummaryTableV2Schema,
129
+ };
130
+
131
+ export const validateAvailableZoneNamesV2Schema = joi.object( {
132
+ ...baseSchema,
133
+ } );
134
+
135
+ export const validateAvailableZoneNamesV2Params = {
136
+ body: validateAvailableZoneNamesV2Schema,
137
+ };
138
+
139
+ export const validateZoneConcentrationSummaryV2Schema = joi.object( {
140
+ ...baseSchema,
141
+ zoneName: joi.string().required(),
142
+ } );
143
+
144
+ export const validateZoneConcentrationSummaryV2Params = {
145
+ body: validateZoneConcentrationSummaryV2Schema,
146
+ };
147
+
148
+ export const validateOverallStoreConcentrationDatesV2Schema = joi.object( {
149
+ ...baseSchema,
150
+ zoneName: joi.string().required(),
151
+ dateType: joi.string().required(),
152
+ } );
153
+
154
+ export const validateOverallStoreConcentrationDatesV2Params = {
155
+ body: validateOverallStoreConcentrationDatesV2Schema,
156
+ };
157
+
158
+ export const validateOverallStoreConcentrationHeatmapV2Schema = joi.object( {
159
+ ...baseSchema,
160
+ zoneName: joi.string().required(),
161
+ dateType: joi.string().required(),
162
+ zoneDate: joi.string().required(),
163
+ } );
164
+
165
+ export const validateOverallStoreConcentrationHeatmapV2Params = {
166
+ body: validateOverallStoreConcentrationHeatmapV2Schema,
167
+ };
168
+
169
+ export const validateTrajectoryAnalysisV2Schema = joi.object( {
170
+ ...baseSchema,
171
+ } );
172
+
173
+ export const validateTrajectoryAnalysisV2Params = {
174
+ body: validateTrajectoryAnalysisV2Schema,
175
+ };
176
+
177
+ export const validateCustomerJourneyV2Schema = joi.object( {
178
+ ...baseSchema,
179
+ } );
180
+
181
+ export const validateCustomerJourneyV2Params = {
182
+ body: validateCustomerJourneyV2Schema,
183
+ };
184
+
185
+
@@ -1,6 +1,6 @@
1
1
  import express from 'express';
2
- // import { validate, isAllowedSessionHandler, authorize } from 'tango-app-api-middleware';
3
- // import * as validationDtos from '../dtos/validation.dtos.js';
2
+ import { validate, isAllowedSessionHandler, authorize, isAllowedClient } from 'tango-app-api-middleware';
3
+ import * as validationDtos from '../dtos/validation.dtos.js';
4
4
 
5
5
  export const analysisZoneV2Router = express.Router();
6
6
  import {
@@ -14,9 +14,20 @@ import {
14
14
  overallStoreConcentrationHeatmap,
15
15
  trajectoryAnalysis,
16
16
  customerJourney,
17
- customerJourneyTable,
18
17
  } from '../controllers/analysisZoneSampleDataV2.controllers.js';
19
18
 
19
+ import {
20
+ zonecardsV2,
21
+ topPerformingZonesV2,
22
+ topPerformingStoresV2,
23
+ zoneSummaryTableV2,
24
+ availableZoneNamesV2,
25
+ zoneConcentrationSummaryV2,
26
+ overallStoreConcentrationDatesV2,
27
+ overallStoreConcentrationHeatmapV2,
28
+ trajectoryAnalysisV2,
29
+ } from '../controllers/analysisZoneV2.controllers.js';
30
+
20
31
  analysisZoneV2Router
21
32
  .post( '/zonecards', zonecards )
22
33
  .post( '/topPerformingZones', topPerformingZones )
@@ -28,5 +39,54 @@ analysisZoneV2Router
28
39
  .post( '/overallStoreConcentrationHeatmap', overallStoreConcentrationHeatmap )
29
40
  .post( '/trajectoryAnalysis', trajectoryAnalysis )
30
41
  .post( '/customerJourney', customerJourney )
31
- .post( '/customerJourneyTable', customerJourneyTable );
42
+ .post( '/zonecards_V2', isAllowedSessionHandler, isAllowedClient, authorize( {
43
+ userType: [ 'tango', 'client' ], access: [
44
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
45
+ ],
46
+ } ), validate( validationDtos.validateZoneCardsV2Params ), zonecardsV2 )
47
+ .post( '/topPerformingZones_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
48
+ userType: [ 'tango', 'client' ], access: [
49
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
50
+ ],
51
+ } ), validate( validationDtos.validateTopPerformingZonesV2Params ), topPerformingZonesV2 )
52
+ .post( '/topPerformingStores_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
53
+ userType: [ 'tango', 'client' ], access: [
54
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
55
+ ],
56
+ } ), validate( validationDtos.validateTopPerformingStoresV2Params ), topPerformingStoresV2 )
57
+ .post( '/zoneSummaryTable_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
58
+ userType: [ 'tango', 'client' ], access: [
59
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
60
+ ],
61
+ } ), validate( validationDtos.validateZoneSummaryTableV2Params ), zoneSummaryTableV2 )
62
+ .post( '/availableZoneNames_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
63
+ userType: [ 'tango', 'client' ], access: [
64
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
65
+ ],
66
+ } ), validate( validationDtos.validateAvailableZoneNamesV2Params ), availableZoneNamesV2 )
67
+ .post( '/zoneConcentrationSummary_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
68
+ userType: [ 'tango', 'client' ], access: [
69
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
70
+ ],
71
+ } ), validate( validationDtos.validateZoneConcentrationSummaryV2Params ), zoneConcentrationSummaryV2 )
72
+ .post( '/overallStoreConcentrationDates_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
73
+ userType: [ 'tango', 'client' ], access: [
74
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
75
+ ],
76
+ } ), validate( validationDtos.validateOverallStoreConcentrationDatesV2Params ), overallStoreConcentrationDatesV2 )
77
+ .post( '/overallStoreConcentrationHeatmap_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
78
+ userType: [ 'tango', 'client' ], access: [
79
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
80
+ ],
81
+ } ), validate( validationDtos.validateOverallStoreConcentrationHeatmapV2Params ), overallStoreConcentrationHeatmapV2 )
82
+ .post( '/trajectoryAnalysis_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
83
+ userType: [ 'tango', 'client' ], access: [
84
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
85
+ ],
86
+ } ), validate( validationDtos.validateTrajectoryAnalysisV2Params ), trajectoryAnalysisV2 )
87
+ .post( '/customerJourney_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
88
+ userType: [ 'tango', 'client' ], access: [
89
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
90
+ ],
91
+ } ), validate( validationDtos.validateCustomerJourneyV2Params ), customerJourney );
32
92
  export default analysisZoneV2Router;
@@ -1,6 +1,6 @@
1
1
  import express from 'express';
2
- // import { validate, isAllowedSessionHandler, authorize } from 'tango-app-api-middleware';
3
- // import * as validationDtos from '../dtos/validation.dtos.js';
2
+ import { validate, isAllowedSessionHandler, authorize, isAllowedClient } from 'tango-app-api-middleware';
3
+ import * as validationDtos from '../dtos/mobileValidation.dtos.js';
4
4
 
5
5
  export const mobileAnalysisZoneV2Router = express.Router();
6
6
  import {
@@ -12,11 +12,52 @@ import {
12
12
  overallStoreConcentrationHeatmap,
13
13
  } from '../controllers/mobileAnalysisZoneSampleDataV2.controllers.js';
14
14
 
15
+ import {
16
+ zonecardsV2,
17
+ topPerformingZonesV2,
18
+ topPerformingStoresV2,
19
+ zoneConcentrationSummaryV2,
20
+ overallStoreConcentrationDatesV2,
21
+ overallStoreConcentrationHeatmapV2,
22
+ } from '../controllers/mobileAnalysisZoneV2.controllers.js';
23
+
24
+
15
25
  mobileAnalysisZoneV2Router
16
26
  .post( '/zonecards', zonecards )
17
27
  .post( '/topPerformingZones', topPerformingZones )
18
28
  .post( '/topPerformingStores', topPerformingStores )
19
29
  .post( '/zoneConcentrationSummary', zoneConcentrationSummary )
20
30
  .post( '/overallStoreConcentrationDates', overallStoreConcentrationDates )
21
- .post( '/overallStoreConcentrationHeatmap', overallStoreConcentrationHeatmap );
31
+ .post( '/overallStoreConcentrationHeatmap', overallStoreConcentrationHeatmap )
32
+ .post( '/zonecards_V2', isAllowedSessionHandler, isAllowedClient, authorize( {
33
+ userType: [ 'tango', 'client' ], access: [
34
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
35
+ ],
36
+ } ), validate( validationDtos.validateZoneCardsV2Params ), zonecardsV2 )
37
+ .post( '/topPerformingZones_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
38
+ userType: [ 'tango', 'client' ], access: [
39
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
40
+ ],
41
+ } ), validate( validationDtos.validateTopPerformingZonesV2Params ), topPerformingZonesV2 )
42
+ .post( '/topPerformingStores_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
43
+ userType: [ 'tango', 'client' ], access: [
44
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
45
+ ],
46
+ } ), validate( validationDtos.validateTopPerformingStoresV2Params ), topPerformingStoresV2 )
47
+ .post( '/zoneConcentrationSummary_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
48
+ userType: [ 'tango', 'client' ], access: [
49
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
50
+ ],
51
+ } ), validate( validationDtos.validateZoneConcentrationSummaryV2Params ), zoneConcentrationSummaryV2 )
52
+ .post( '/overallStoreConcentrationDates_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
53
+ userType: [ 'tango', 'client' ], access: [
54
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
55
+ ],
56
+ } ), validate( validationDtos.validateOverallStoreConcentrationDatesV2Params ), overallStoreConcentrationDatesV2 )
57
+ .post( '/overallStoreConcentrationHeatmap_v2', isAllowedSessionHandler, isAllowedClient, authorize( {
58
+ userType: [ 'tango', 'client' ], access: [
59
+ { featureName: 'analytics', name: 'tangoZone', permissions: [ 'isView' ] },
60
+ ],
61
+ } ), validate( validationDtos.validateOverallStoreConcentrationHeatmapV2Params ), overallStoreConcentrationHeatmapV2 );
62
+
22
63
  export default mobileAnalysisZoneV2Router;