tango-app-api-audio-analytics 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -3,4 +3,3 @@
3
3
  import { audioAnalyticsrouter } from './src/routes/audioAnalytics.routes.js';
4
4
 
5
5
  export { audioAnalyticsrouter };
6
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tango-app-api-audio-analytics",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "audioAnalytics",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -13,6 +13,7 @@
13
13
  "author": "praveenraj",
14
14
  "license": "ISC",
15
15
  "dependencies": {
16
+ "@aws-sdk/client-secrets-manager": "^3.1003.0",
16
17
  "aws-sdk": "^2.1693.0",
17
18
  "body-parser": "^2.2.2",
18
19
  "cors": "^2.8.6",
@@ -22,6 +22,7 @@ export async function createCohort( req, res ) {
22
22
  const cohortData = {
23
23
  clientId: inputData.clientId,
24
24
  cohortId,
25
+ source: inputData.source || [],
25
26
  cohortName: inputData.cohortName,
26
27
  cohortDescription: inputData.cohortDescription,
27
28
  metrics,
@@ -46,9 +46,18 @@ export const getCohortAnalysisCard = async ( req, res ) => {
46
46
  clientId,
47
47
  } );
48
48
 
49
+ if ( !summaryCard ) {
50
+ logger.warn( 'No data returned for cohort analysis summary card', { startDate, endDate, storeId, cohortType, clientId } );
51
+ return res.status( 204 ).json( {
52
+ status: 'error',
53
+ message: 'No data found for the given parameters',
54
+ code: 'DATA_NOT_FOUND',
55
+ timestamp: new Date().toISOString(),
56
+ } );
57
+ }
49
58
  return res.status( 200 ).json( {
50
- status: 'success',
51
- data: summaryCard,
59
+ status: summaryCard?.status || 'success',
60
+ data: summaryCard?.data || [],
52
61
  timestamp: new Date().toISOString(),
53
62
  } );
54
63
  } catch ( error ) {
@@ -5,8 +5,8 @@ import {
5
5
  exportConversationsFromLambda,
6
6
  getConversationDetailsFromLambda,
7
7
  exportConversationsToCSV,
8
- filterConversationsBySearch,
9
- sortConversations,
8
+ // filterConversationsBySearch,
9
+ // sortConversations,
10
10
  } from '../services/conversation.service.js';
11
11
 
12
12
  /**
@@ -34,6 +34,7 @@ export const getConversationsList = async ( req, res ) => {
34
34
  endDate,
35
35
  storeId,
36
36
  clientId,
37
+ cohortId,
37
38
  isAI,
38
39
  analyticsType,
39
40
  searchValue,
@@ -71,13 +72,14 @@ export const getConversationsList = async ( req, res ) => {
71
72
  endDate,
72
73
  storeId,
73
74
  clientId,
74
- isAI,
75
- analyticsType,
76
- searchValue,
75
+ cohortId,
76
+ isExport,
77
+ limit,
78
+ offset,
77
79
  } );
78
80
 
79
- conversations = exportResponse.conversations || [];
80
- totalCount = exportResponse.totalCount || conversations.length;
81
+ // conversations = exportResponse.conversations || [];
82
+ // totalCount = exportResponse.totalCount || conversations.length;
81
83
 
82
84
  logger.info( {
83
85
  message: 'Export Lambda response received',
@@ -85,15 +87,15 @@ export const getConversationsList = async ( req, res ) => {
85
87
  } );
86
88
 
87
89
  // Apply search filter if provided
88
- if ( searchValue ) {
89
- conversations = filterConversationsBySearch( conversations, searchValue );
90
- }
90
+ // if ( searchValue ) {
91
+ // conversations = filterConversationsBySearch( conversations, searchValue );
92
+ // }
91
93
 
92
- // Apply sorting
93
- conversations = sortConversations( conversations, 'date', 'desc' );
94
+ // // Apply sorting
95
+ // conversations = sortConversations( conversations, 'date', 'desc' );
94
96
 
95
97
  // Convert to CSV
96
- const csv = await exportConversationsToCSV( conversations );
98
+ const csv = await exportConversationsToCSV( exportResponse.data );
97
99
  res.setHeader( 'Content-Type', 'text/csv' );
98
100
  res.setHeader( 'Content-Disposition', 'attachment; filename=conversations.csv' );
99
101
  return res.send( csv );
@@ -116,23 +118,22 @@ export const getConversationsList = async ( req, res ) => {
116
118
  offset,
117
119
  } );
118
120
 
119
- conversations = lambdaResponse.conversations || [];
120
- totalCount = lambdaResponse.totalCount || conversations.length;
121
+ // conversations = lambdaResponse.conversations || [];
122
+ // totalCount = lambdaResponse.totalCount || conversations.length;
121
123
 
122
- // Apply search filter if provided
123
- if ( searchValue ) {
124
- conversations = filterConversationsBySearch( conversations, searchValue );
125
- }
124
+ // // Apply search filter if provided
125
+ // if ( searchValue ) {
126
+ // conversations = filterConversationsBySearch( conversations, searchValue );
127
+ // }
126
128
 
127
- // Apply sorting
128
- conversations = sortConversations( conversations, 'date', 'desc' );
129
+ // // Apply sorting
130
+ // conversations = sortConversations( conversations, 'date', 'desc' );
129
131
 
130
132
  // Return paginated JSON response
131
133
  return res.status( 200 ).json( {
132
134
  status: 'success',
133
135
  data: {
134
- totalConversations: totalCount,
135
- conversations,
136
+ lambdaResponse,
136
137
  pagination: {
137
138
  limit,
138
139
  offset,
@@ -167,12 +168,16 @@ export const getConversationsList = async ( req, res ) => {
167
168
  export const getConversationDetails = async ( req, res ) => {
168
169
  try {
169
170
  const { conversationId } = req.params;
170
- const { storeId } = req.body;
171
-
172
- if ( !conversationId || !storeId ) {
171
+ const { cohortId } = req.body;
172
+ logger.info( {
173
+ message: 'Received request for conversation details',
174
+ conversationId,
175
+ cohortId,
176
+ } );
177
+ if ( !conversationId || !cohortId ) {
173
178
  return res.status( 400 ).json( {
174
179
  status: 'error',
175
- message: 'Missing required parameters: conversationId, storeId',
180
+ message: 'Missing required parameters: conversationId, cohortId',
176
181
  code: 'MISSING_PARAMETERS',
177
182
  timestamp: new Date().toISOString(),
178
183
  } );
@@ -181,13 +186,13 @@ export const getConversationDetails = async ( req, res ) => {
181
186
  logger.info( {
182
187
  message: 'Fetching conversation details',
183
188
  conversationId,
184
- storeId,
189
+ cohortId,
185
190
  } );
186
191
 
187
192
  // Call Lambda to get conversation details
188
193
  const conversationData = await getConversationDetailsFromLambda( {
189
194
  conversationId,
190
- storeId,
195
+ cohortId,
191
196
  } );
192
197
 
193
198
  if ( !conversationData ) {
@@ -518,6 +518,7 @@ export const conversationsListValid = joi.object( {
518
518
  endDate: joi.string().required().pattern( /^\d{4}-\d{2}-\d{2}$/ ).description( 'End date in YYYY-MM-DD format' ),
519
519
  storeId: joi.array().items( joi.string() ).required().min( 1 ).description( 'Array of store IDs' ),
520
520
  clientId: joi.array().items( joi.string() ).optional().description( 'Array of client IDs' ),
521
+ cohortType: joi.array().items( joi.string() ).required().min( 1 ).description( 'Array of cohort types' ),
521
522
  isAI: joi.boolean().optional().description( 'Filter for AI-generated conversations' ),
522
523
  analyticsType: joi.string().optional().valid( 'audio', 'text', 'all' ).description( 'Type of analytics' ),
523
524
  searchValue: joi.string().optional().description( 'Search term' ),
@@ -530,7 +531,10 @@ export const conversationsListValid = joi.object( {
530
531
  * Conversation Details Schema
531
532
  */
532
533
  export const conversationDetailsValid = joi.object( {
533
- storeId: joi.string().required().description( 'Store ID' ),
534
+ cohortId: joi.alternatives().try(
535
+ joi.string(),
536
+ joi.array().items( joi.string() ).min( 1 ),
537
+ ).required().description( 'Cohort ID or array of cohort IDs' ),
534
538
  } ).strict();
535
539
 
536
540
  /**
@@ -2,7 +2,6 @@ import { logger } from 'tango-app-api-middleware';
2
2
  import axios from 'axios';
3
3
  import { Parser } from 'json2csv';
4
4
 
5
- const LAMBDA_ENDPOINT = JSON.parse( process.env.URL ) || 'http://lambda-api:8000';
6
5
 
7
6
  /**
8
7
  * Call the Lambda function to get cohort analysis
@@ -16,22 +15,35 @@ const LAMBDA_ENDPOINT = JSON.parse( process.env.URL ) || 'http://lambda-api:8000
16
15
  */
17
16
  export async function getCohortAnalysisFromLambda( params ) {
18
17
  try {
19
- logger.info( { message: 'Calling Lambda for cohort analysis', params } );
18
+ const LAMBDA_ENDPOINT = JSON.parse( process.env.URL ) || 'http://lambda-api:8000';
20
19
 
21
- const response = await axios.post( `${LAMBDA_ENDPOINT.cohortAnalysisCard}/cohort-analysis`, {
20
+ const payload = {
22
21
  startDate: params.startDate,
23
22
  endDate: params.endDate,
24
- storeId: params.storeId,
25
- cohortType: params.cohortType,
26
- clientId: params.clientId,
27
- }, {
23
+ storeId: Array.isArray( params.storeId ) ? params.storeId : [ params.storeId ],
24
+ cohort_id: Array.isArray( params.cohortType ) ? params.cohortType : [ params.cohortType ],
25
+ clientId: Array.isArray( params.clientId ) ? params.clientId : [ params.clientId ],
26
+ };
27
+
28
+ logger.info( { message: 'Calling Lambda for cohort analysis', url: LAMBDA_ENDPOINT.cohortAnalysisCard, payload } );
29
+
30
+ const response = await axios.post( `${LAMBDA_ENDPOINT.cohortAnalysisCard}`, payload, {
31
+ headers: {
32
+ 'Content-Type': 'application/json',
33
+ },
28
34
  timeout: 30000,
29
35
  } );
30
36
 
31
- logger.info( { message: 'Lambda response received', data: response.data } );
37
+ logger.info( { message: 'Lambda response received', status: response.status, data: response.data } );
32
38
  return response.data;
33
39
  } catch ( error ) {
34
- logger.error( { error, message: 'Error calling Lambda for cohort analysis', params } );
40
+ logger.error( {
41
+ error: error.message,
42
+ status: error.response?.status,
43
+ data: error.response?.data,
44
+ message: 'Error calling Lambda for cohort analysis',
45
+ params,
46
+ } );
35
47
  throw new Error( `Failed to fetch cohort analysis: ${error.message}` );
36
48
  }
37
49
  }
@@ -52,6 +64,7 @@ export async function getCohortAnalysisFromLambda( params ) {
52
64
  */
53
65
  export async function getConversationsListFromLambda( params ) {
54
66
  try {
67
+ const LAMBDA_ENDPOINT = JSON.parse( process.env.URL ) || 'http://lambda-api:8000';
55
68
  logger.info( { message: 'Calling Lambda for conversations list', params } );
56
69
 
57
70
  const response = await axios.post( `${LAMBDA_ENDPOINT.cohortConversationList}/conversations/list`, {
@@ -90,24 +103,38 @@ export async function getConversationsListFromLambda( params ) {
90
103
  */
91
104
  export async function exportConversationsFromLambda( params ) {
92
105
  try {
93
- logger.info( { message: 'Calling Lambda for conversations export', params } );
106
+ const LAMBDA_ENDPOINT = JSON.parse( process.env.URL ) || 'http://lambda-api:8000';
94
107
 
95
- const response = await axios.post( `${LAMBDA_ENDPOINT.cohortConversationExport}/conversations/export`, {
108
+ const payload = {
96
109
  startDate: params.startDate,
97
110
  endDate: params.endDate,
98
- storeId: params.storeId,
99
- clientId: params.clientId,
100
- isAI: params.isAI,
101
- analyticsType: params.analyticsType,
102
- searchValue: params.searchValue,
103
- }, {
111
+ storeId: Array.isArray( params.storeId ) ? params.storeId : [ params.storeId ],
112
+ clientId: Array.isArray( params.clientId ) ? params.clientId : [ params.clientId ],
113
+ cohortId: params.cohortId,
114
+ isExport: params.isExport ?? true,
115
+ limit: params.limit || 10,
116
+ offset: params.offset || 0,
117
+ };
118
+
119
+ logger.info( { message: 'Calling Lambda for conversations export', url: LAMBDA_ENDPOINT.cohortConversationList, payload } );
120
+
121
+ const response = await axios.post( `${LAMBDA_ENDPOINT.cohortConversationList}`, payload, {
122
+ headers: {
123
+ 'Content-Type': 'application/json',
124
+ },
104
125
  timeout: 30000,
105
126
  } );
106
127
 
107
- logger.info( { message: 'Lambda response received for conversations export', recordCount: response.data?.recordCount } );
128
+ logger.info( { message: 'Lambda response received for conversations export', data: response.data } );
108
129
  return response.data;
109
130
  } catch ( error ) {
110
- logger.error( { error, message: 'Error calling Lambda for conversations export', params } );
131
+ logger.error( {
132
+ error: error.message,
133
+ status: error.response?.status,
134
+ data: error.response?.data,
135
+ message: 'Error calling Lambda for conversations export',
136
+ params,
137
+ } );
111
138
  throw new Error( `Failed to export conversations: ${error.message}` );
112
139
  }
113
140
  }
@@ -121,18 +148,32 @@ export async function exportConversationsFromLambda( params ) {
121
148
  */
122
149
  export async function getConversationDetailsFromLambda( params ) {
123
150
  try {
124
- logger.info( { message: 'Calling Lambda for conversation details', params } );
151
+ const LAMBDA_ENDPOINT = JSON.parse( process.env.URL ) || 'http://lambda-api:8000';
125
152
 
126
- const response = await axios.post( `${LAMBDA_ENDPOINT.cohortConversationDetail}/conversations/${params.conversationId}`, {
127
- storeId: params.storeId,
128
- }, {
153
+ const payload = {
154
+ audio_id: params.conversationId,
155
+ cohort_id: Array.isArray( params.cohortId ) ? params.cohortId : [ params.cohortId ],
156
+ };
157
+
158
+ logger.info( { message: 'Calling Lambda for conversation details', url: LAMBDA_ENDPOINT.cohortConversationDetail, payload } );
159
+
160
+ const response = await axios.post( `${LAMBDA_ENDPOINT.cohortConversationDetail}`, payload, {
161
+ headers: {
162
+ 'Content-Type': 'application/json',
163
+ },
129
164
  timeout: 30000,
130
165
  } );
131
166
 
132
167
  logger.info( { message: 'Lambda response received for conversation details', conversationId: params.conversationId } );
133
168
  return response.data;
134
169
  } catch ( error ) {
135
- logger.error( { error, message: 'Error calling Lambda for conversation details', params } );
170
+ logger.error( {
171
+ error: error.message,
172
+ status: error.response?.status,
173
+ data: error.response?.data,
174
+ message: 'Error calling Lambda for conversation details',
175
+ params,
176
+ } );
136
177
  throw new Error( `Failed to fetch conversation details: ${error.message}` );
137
178
  }
138
179
  }
@@ -171,20 +212,27 @@ export async function exportConversationsToCSV( conversations, columns = null )
171
212
  */
172
213
  export async function getCohortAnalysisSummaryCard( params ) {
173
214
  try {
174
- const lambdaResponse = await getCohortAnalysisFromLambda( params );
215
+ const paramavalue = {
216
+ startDate: params.startDate,
217
+ endDate: params.endDate,
218
+ storeId: params.storeId,
219
+ cohortType: params.cohortType,
220
+ clientId: params.clientId,
221
+ };
222
+ const lambdaResponse = await getCohortAnalysisFromLambda( paramavalue );
175
223
 
176
224
  // Process response to create summary card
177
- const summaryCard = {
178
- totalConversations: lambdaResponse.totalConversations || 0,
179
- totalDuration: lambdaResponse.totalDuration || 0,
180
- averageRating: lambdaResponse.averageRating || 0,
181
- topCohorts: lambdaResponse.topCohorts || [],
182
- trendData: lambdaResponse.trendData || [],
183
- keyInsights: lambdaResponse.keyInsights || [],
184
- timestamp: new Date().toISOString(),
185
- };
225
+ // const summaryCard = {
226
+ // totalConversations: lambdaResponse.totalConversations || 0,
227
+ // totalDuration: lambdaResponse.totalDuration || 0,
228
+ // averageRating: lambdaResponse.averageRating || 0,
229
+ // topCohorts: lambdaResponse.topCohorts || [],
230
+ // trendData: lambdaResponse.trendData || [],
231
+ // keyInsights: lambdaResponse.keyInsights || [],
232
+ // timestamp: new Date().toISOString(),
233
+ // };
186
234
 
187
- return summaryCard;
235
+ return lambdaResponse;
188
236
  } catch ( error ) {
189
237
  logger.error( { error, message: 'Error getting cohort analysis summary card' } );
190
238
  throw error;