tango-app-api-audio-analytics 1.0.32 → 1.0.33

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-audio-analytics",
3
- "version": "1.0.32",
3
+ "version": "1.0.33",
4
4
  "description": "audioAnalytics",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -329,7 +329,6 @@ export async function getChat( req, res ) {
329
329
  export const callExternalStreamAPI = async ( req, res ) => {
330
330
  try {
331
331
  const { prompt, storeId, productModule, country, region, fromDate, toDate, clusters } = req.body;
332
- console.log( 'Received request for external stream API with parameters:', req.body );
333
332
  // Validation for required parameters
334
333
  if ( !prompt ) {
335
334
  logger.warn( 'Stream API call attempted without prompt' );
@@ -1,6 +1,6 @@
1
1
  // import { sampleCohortData } from '../models/cohortAnalysis.model.js';
2
2
  import { logger } from 'tango-app-api-middleware';
3
- import { getCohortAnalysisSummaryCard } from '../services/conversation.service.js';
3
+ import { getCohortAnalysisSummaryCard, getCohortSummaryCardFromLambda } from '../services/conversation.service.js';
4
4
 
5
5
  /**
6
6
  * Get Cohort Analysis Summary Card
@@ -71,6 +71,74 @@ export const getCohortAnalysisCard = async ( req, res ) => {
71
71
  }
72
72
  };
73
73
 
74
+ /**
75
+ * Get Cohort Summary Card
76
+ * POST /cohort-summary-card
77
+ * @param {Object} req - Express request object
78
+ * @param {Object} req.body - Request body
79
+ * @param {string} req.body.startDate - Start date (YYYY-MM-DD)
80
+ * @param {string} req.body.endDate - End date (YYYY-MM-DD)
81
+ * @param {string[]} req.body.storeId - Array of store IDs
82
+ * @param {string[]} req.body.clientId - Array of client IDs
83
+ * @param {string[]} req.body.cohortId - Array of cohort IDs
84
+ * @param {Object} res - Express response object
85
+ * @return {void} Returns JSON response with cohort summary card data
86
+ */
87
+ export const getCohortSummaryCard = async ( req, res ) => {
88
+ try {
89
+ const { startDate, endDate, storeId, clientId, cohortId } = req.body;
90
+
91
+ if ( !startDate || !endDate || !storeId || !clientId || !cohortId ) {
92
+ return res.status( 400 ).json( {
93
+ status: 'error',
94
+ message: 'Missing required parameters: startDate, endDate, storeId, clientId, cohortId',
95
+ code: 'MISSING_PARAMETERS',
96
+ timestamp: new Date().toISOString(),
97
+ } );
98
+ }
99
+
100
+ logger.info( {
101
+ message: 'Fetching cohort summary card',
102
+ startDate,
103
+ endDate,
104
+ storeId,
105
+ clientId,
106
+ cohortId,
107
+ } );
108
+
109
+ const lambdaResponse = await getCohortSummaryCardFromLambda( {
110
+ startDate,
111
+ endDate,
112
+ storeId,
113
+ clientId,
114
+ cohortId,
115
+ } );
116
+
117
+ if ( !lambdaResponse ) {
118
+ return res.status( 204 ).json( {
119
+ status: 'error',
120
+ message: 'No data found for the given parameters',
121
+ code: 'DATA_NOT_FOUND',
122
+ timestamp: new Date().toISOString(),
123
+ } );
124
+ }
125
+
126
+ return res.status( 200 ).json( {
127
+ status: lambdaResponse?.status || 'success',
128
+ data: lambdaResponse?.data ?? lambdaResponse,
129
+ timestamp: new Date().toISOString(),
130
+ } );
131
+ } catch ( error ) {
132
+ logger.error( { error, message: 'Error fetching cohort summary card', body: req.body } );
133
+ return res.status( 500 ).json( {
134
+ status: 'error',
135
+ message: error.message || 'Internal server error',
136
+ code: 'INTERNAL_ERROR',
137
+ timestamp: new Date().toISOString(),
138
+ } );
139
+ }
140
+ };
141
+
74
142
  /**
75
143
  * Get Complete Cohort Analysis
76
144
  * GET /cohort-analysis
@@ -39,6 +39,7 @@ export const getConversationsList = async ( req, res ) => {
39
39
  isAI,
40
40
  analyticsType,
41
41
  searchValue,
42
+ audioSource,
42
43
  limit,
43
44
  offset,
44
45
  isExport,
@@ -81,6 +82,7 @@ export const getConversationsList = async ( req, res ) => {
81
82
  offset,
82
83
  _id,
83
84
  name,
85
+ audioSource,
84
86
  } );
85
87
 
86
88
  // conversations = exportResponse.conversations || [];
@@ -119,6 +121,7 @@ export const getConversationsList = async ( req, res ) => {
119
121
  isAI,
120
122
  analyticsType,
121
123
  searchValue,
124
+ audioSource,
122
125
  limit,
123
126
  offset,
124
127
  _id,
@@ -189,6 +192,7 @@ export const getTranscriptsList = async ( req, res ) => {
189
192
  isAI,
190
193
  analyticsType,
191
194
  searchValue,
195
+ audioSource,
192
196
  limit,
193
197
  offset,
194
198
  isExport,
@@ -228,6 +232,7 @@ export const getTranscriptsList = async ( req, res ) => {
228
232
  isAI,
229
233
  analyticsType,
230
234
  searchValue,
235
+ audioSource,
231
236
  limit,
232
237
  offset,
233
238
  _id,
@@ -510,6 +510,17 @@ export const cohortAnalysisCardValid = joi.object( {
510
510
  clientId: joi.array().items( joi.string() ).required().min( 1 ).description( 'Array of client IDs' ),
511
511
  } ).strict();
512
512
 
513
+ /**
514
+ * Cohort Summary Card Schema
515
+ */
516
+ export const cohortSummaryCardValid = joi.object( {
517
+ startDate: joi.string().required().pattern( /^\d{4}-\d{2}-\d{2}$/ ).description( 'Start date in YYYY-MM-DD format' ),
518
+ endDate: joi.string().required().pattern( /^\d{4}-\d{2}-\d{2}$/ ).description( 'End date in YYYY-MM-DD format' ),
519
+ storeId: joi.array().items( joi.string() ).required().min( 1 ).description( 'Array of store IDs' ),
520
+ clientId: joi.array().items( joi.string() ).required().min( 1 ).description( 'Array of client IDs' ),
521
+ cohortId: joi.array().items( joi.string() ).required().min( 1 ).description( 'Array of cohort IDs' ),
522
+ } ).strict();
523
+
513
524
  /**
514
525
  * Category Analysis Card Schema
515
526
  */
@@ -535,6 +546,7 @@ export const conversationsListValid = joi.object( {
535
546
  isAI: joi.boolean().optional().description( 'Filter for AI-generated conversations' ),
536
547
  analyticsType: joi.string().optional().valid( 'audio', 'text', 'all' ).description( 'Type of analytics' ),
537
548
  searchValue: joi.string().optional().description( 'Search term' ),
549
+ audioSource: joi.string().optional().description( 'Audio source filter' ),
538
550
  isExport: joi.boolean().optional().description( 'Flag to export as CSV' ),
539
551
  limit: joi.number().integer().min( 1 ).max( 1000 ).optional().default( 10 ).description( 'Pagination limit' ),
540
552
  offset: joi.number().integer().min( 0 ).optional().default( 0 ).description( 'Pagination offset' ),
@@ -552,6 +564,7 @@ export const transcriptListValid = joi.object( {
552
564
  isAI: joi.boolean().optional().description( 'Filter for AI-generated conversations' ),
553
565
  analyticsType: joi.string().optional().valid( 'audio', 'text', 'all' ).description( 'Type of analytics' ),
554
566
  searchValue: joi.string().optional().description( 'Search term' ),
567
+ audioSource: joi.string().optional().description( 'Audio source filter' ),
555
568
  isExport: joi.boolean().optional().description( 'Flag to export as CSV' ),
556
569
  limit: joi.number().integer().min( 1 ).max( 1000 ).optional().default( 10 ).description( 'Pagination limit' ),
557
570
  offset: joi.number().integer().min( 0 ).optional().default( 0 ).description( 'Pagination offset' ),
@@ -2,9 +2,9 @@
2
2
  import express from 'express';
3
3
  import { validate } from 'tango-app-api-middleware';
4
4
  import { createCohortValid, createBulkCohortValid, updateCohortValid, getCohortValid, listCohortsByClientValid, deleteCohortValid } from '../dtos/audioAnalytics.dtos.js';
5
- import { cohortAnalysisCardValid, categoryAnalysisCardValid, conversationsListValid, conversationDetailsValid, chatHistoryListValid, getChatValid, getGeminiResponseValid, transcriptListValid } from '../dtos/audioAnalytics.dtos.js';
5
+ import { cohortAnalysisCardValid, cohortSummaryCardValid, categoryAnalysisCardValid, conversationsListValid, conversationDetailsValid, chatHistoryListValid, getChatValid, getGeminiResponseValid, transcriptListValid } from '../dtos/audioAnalytics.dtos.js';
6
6
  import { createCohort, createBulkCohort, updateCohort, deleteCohort, getCohort, listCohortsByClient, chatHistoryList, getChat, getGeminiResponse, aiStreamResponse } from '../controllers/audioAnalytics.controller.js';
7
- import { getCohortAnalysisCard } from '../controllers/cohortAnalytics.controller.js';
7
+ import { getCohortAnalysisCard, getCohortSummaryCard } from '../controllers/cohortAnalytics.controller.js';
8
8
  import { getConversationsList, getTranscriptsList, getConversationDetails, getCategoryAnalysisCard } from '../controllers/conversationAnalytics.controller.js';
9
9
 
10
10
  export const audioAnalyticsrouter = express.Router(); ;
@@ -27,6 +27,7 @@ audioAnalyticsrouter.post( '/chat-history-list', validate( chatHistoryListValid
27
27
  audioAnalyticsrouter.post( '/get-chat', validate( getChatValid ), getChat );
28
28
  // Cohort Analytics Routes
29
29
  audioAnalyticsrouter.post( '/cohort-analysis-card', validate( cohortAnalysisCardValid ), getCohortAnalysisCard );
30
+ audioAnalyticsrouter.post( '/cohort-summary-card', validate( cohortSummaryCardValid ), getCohortSummaryCard );
30
31
  audioAnalyticsrouter.post( '/category-analysis-card', validate( categoryAnalysisCardValid ), getCategoryAnalysisCard );
31
32
 
32
33
  // Conversation Analytics Routes
@@ -77,10 +77,10 @@ export async function getConversationsListFromLambda( params ) {
77
77
  isAI: params.isAI,
78
78
  analyticsType: params.analyticsType,
79
79
  searchValue: params.searchValue,
80
+ audioSource: params.audioSource,
80
81
  limit: params.limit,
81
82
  offset: params.offset,
82
83
  };
83
- console.log( payload );
84
84
  const response = await axios.post( `${LAMBDA_ENDPOINT.cohortConversationList}/conversations/list`, payload, {
85
85
  timeout: 30000,
86
86
  } );
@@ -122,10 +122,10 @@ export async function getTranscriptListFromLambda( params ) {
122
122
  isAI: params.isAI,
123
123
  analyticsType: params.analyticsType,
124
124
  searchValue: params.searchValue,
125
+ audioSource: params.audioSource,
125
126
  limit: params.limit,
126
127
  offset: params.offset,
127
128
  };
128
- console.log( LAMBDA_ENDPOINT.transcriptList, payload );
129
129
  const response = await axios.post( `${LAMBDA_ENDPOINT.transcriptList}`, payload, {
130
130
  timeout: 30000,
131
131
  } );
@@ -338,6 +338,51 @@ export async function getCategoryAnalysisCardFromLambda( params ) {
338
338
  }
339
339
  }
340
340
 
341
+ /**
342
+ * Call Lambda to get cohort summary card
343
+ * @param {Object} params - Request parameters
344
+ * @param {string} params.startDate - Start date (YYYY-MM-DD)
345
+ * @param {string} params.endDate - End date (YYYY-MM-DD)
346
+ * @param {string[]} params.storeId - Array of store IDs
347
+ * @param {string[]} params.clientId - Array of client IDs
348
+ * @param {string[]} params.cohortId - Array of cohort IDs
349
+ * @return {Promise<Object>} Response from Lambda
350
+ */
351
+ export async function getCohortSummaryCardFromLambda( params ) {
352
+ try {
353
+ const LAMBDA_ENDPOINT = JSON.parse( process.env.URL ) || 'http://lambda-api:8000';
354
+
355
+ const payload = {
356
+ startDate: params.startDate,
357
+ endDate: params.endDate,
358
+ storeId: Array.isArray( params.storeId ) ? params.storeId : [ params.storeId ],
359
+ clientId: Array.isArray( params.clientId ) ? params.clientId : [ params.clientId ],
360
+ cohortId: Array.isArray( params.cohortId ) ? params.cohortId : [ params.cohortId ],
361
+ };
362
+
363
+ logger.info( { message: 'Calling Lambda for cohort summary card', url: LAMBDA_ENDPOINT.cohortSummaryCard, payload } );
364
+
365
+ const response = await axios.post( `${LAMBDA_ENDPOINT.cohortSummaryCard}`, payload, {
366
+ headers: {
367
+ 'Content-Type': 'application/json',
368
+ },
369
+ timeout: 30000,
370
+ } );
371
+
372
+ logger.info( { message: 'Lambda response received for cohort summary card', status: response.status } );
373
+ return response.data;
374
+ } catch ( error ) {
375
+ logger.error( {
376
+ error: error.message,
377
+ status: error.response?.status,
378
+ data: error.response?.data,
379
+ message: 'Error calling Lambda for cohort summary card',
380
+ params,
381
+ } );
382
+ throw new Error( `Failed to fetch cohort summary card: ${error.message}` );
383
+ }
384
+ }
385
+
341
386
  /**
342
387
  * Process and filter conversations based on search criteria
343
388
  * @param {Array} conversations - Array of conversation objects