tango-app-api-audio-analytics 1.0.0

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.
@@ -0,0 +1,235 @@
1
+ #!/bin/bash
2
+
3
+ # Cohort API Test Examples
4
+ # This file contains curl commands to test all cohort API endpoints
5
+
6
+ BASE_URL="https://testtangoretail-api.tangoeye.ai/v3/audio-analitics"
7
+ COHORT_ID="cohort_photochromatic_001"
8
+ CLIENT_ID="11"
9
+
10
+ # ==================== Helper Function ====================
11
+ print_section() {
12
+ echo ""
13
+ echo "=================================="
14
+ echo "$1"
15
+ echo "=================================="
16
+ }
17
+
18
+ # ==================== 1. CREATE COHORT ====================
19
+ print_section "1. CREATE COHORT"
20
+
21
+ curl -X POST "$BASE_URL/cohorts" \
22
+ -H "Content-Type: application/json" \
23
+ -d '{
24
+ "clientId": "11",
25
+ "cohortId": "cohort_photochromatic_001",
26
+ "cohortName": "Photochromatic",
27
+ "cohortDescription": "A strict evaluation of the photochromatic sales journey, focusing on pitch quality, technical accuracy, and customer sentiment",
28
+ "metrics": [
29
+ {
30
+ "metricId": "pitch_quality_001",
31
+ "metricName": "Standard Pitch Quality",
32
+ "metricDescription": "Identify which specific value propositions were explicitly used by the staff",
33
+ "hasContext": true,
34
+ "isNumneric": false,
35
+ "contexts": [
36
+ {
37
+ "contextName": "ONE_GLASS_ALL_NEEDS",
38
+ "priority": 2,
39
+ "description": "Convenience of one pair for all lighting"
40
+ },
41
+ {
42
+ "contextName": "TRAVEL_CONVENIENCE",
43
+ "priority": 2,
44
+ "description": "Specific benefits for bikers/commuters"
45
+ },
46
+ {
47
+ "contextName": "LIGHT_ADAPTATION",
48
+ "priority": 2,
49
+ "description": "Technical explanation of UV reaction"
50
+ },
51
+ {
52
+ "contextName": "REDUCES_EYE_STRAIN",
53
+ "priority": 2,
54
+ "description": "Glare and fatigue protection"
55
+ }
56
+ ]
57
+ },
58
+ {
59
+ "metricId": "technical_depth_score_001",
60
+ "metricName": "Technical Depth Score",
61
+ "metricDescription": "A numeric evaluation of the staff'\''s product knowledge during the pitch",
62
+ "hasContext": true,
63
+ "isNumneric": true,
64
+ "contexts": [
65
+ {
66
+ "minValue": 0,
67
+ "maxValue": 100
68
+ }
69
+ ]
70
+ },
71
+ {
72
+ "metricId": "customer_sentiment_001",
73
+ "metricName": "Initial Customer Sentiment",
74
+ "metricDescription": "The immediate reaction of the customer when the lens was introduced",
75
+ "hasContext": true,
76
+ "isNumneric": false,
77
+ "contexts": [
78
+ {
79
+ "contextName": "POSITIVE",
80
+ "priority": 2,
81
+ "description": "High interest or curiosity"
82
+ },
83
+ {
84
+ "contextName": "NEUTRAL",
85
+ "priority": 1,
86
+ "description": "Acknowledgment or price-focused only"
87
+ },
88
+ {
89
+ "contextName": "NEGATIVE",
90
+ "priority": 0,
91
+ "description": "Dismissive or disinterested"
92
+ }
93
+ ]
94
+ },
95
+ {
96
+ "metricId": "staff_responsiveness_001",
97
+ "metricName": "Staff Responsiveness",
98
+ "metricDescription": "How effectively were customer doubts addressed?",
99
+ "hasContext": true,
100
+ "isNumneric": false,
101
+ "contexts": [
102
+ {
103
+ "contextName": "FULLY_RESPONSIVE",
104
+ "priority": 2,
105
+ "description": "All doubts cleared with evidence"
106
+ },
107
+ {
108
+ "contextName": "PARTIALLY_RESPONSIVE",
109
+ "priority": 1,
110
+ "description": "Some doubts addressed, others ignored"
111
+ },
112
+ {
113
+ "contextName": "UNRESPONSIVE",
114
+ "priority": 0,
115
+ "description": "Customer doubts were dismissed"
116
+ }
117
+ ]
118
+ },
119
+ {
120
+ "metricId": "sales_outcome_001",
121
+ "metricName": "Final Sales Outcome",
122
+ "metricDescription": "The final commitment level reached at the end of the conversation",
123
+ "hasContext": true,
124
+ "isNumneric": false,
125
+ "contexts": [
126
+ {
127
+ "contextName": "BOUGHT_PHOTOCHROMATIC",
128
+ "priority": 2,
129
+ "description": "Customer agreed to the upgrade"
130
+ },
131
+ {
132
+ "contextName": "BOUGHT_SOMETHING_ELSE",
133
+ "priority": 0,
134
+ "description": "Bought standard lenses/frames only"
135
+ },
136
+ {
137
+ "contextName": "NO_SALE",
138
+ "priority": 0,
139
+ "description": "No purchase commitment"
140
+ }
141
+ ]
142
+ },
143
+ {
144
+ "metricId": "pitch_timing_summary_001",
145
+ "metricName": "Pitch Timing & Context",
146
+ "metricDescription": "Narrative summary of when and how the pitch was introduced",
147
+ "hasContext": false,
148
+ "isNumneric": false
149
+ }
150
+ ]
151
+ }'
152
+
153
+ # ==================== 2. GET COHORT BY ID ====================
154
+ print_section "2. GET COHORT BY ID"
155
+
156
+ curl -X GET "$BASE_URL/cohorts/$COHORT_ID" \
157
+ -H "Content-Type: application/json"
158
+
159
+ # ==================== 3. GET COHORTS BY CLIENT ====================
160
+ print_section "3. GET COHORTS BY CLIENT"
161
+
162
+ curl -X GET "$BASE_URL/cohorts/client/$CLIENT_ID?limit=10&offset=0" \
163
+ -H "Content-Type: application/json"
164
+
165
+ # ==================== 4. SEARCH COHORTS ====================
166
+ print_section "4. SEARCH COHORTS"
167
+
168
+ curl -X POST "$BASE_URL/cohorts/search" \
169
+ -H "Content-Type: application/json" \
170
+ -d '{
171
+ "clientId": "11",
172
+ "cohortName": "Photochrom",
173
+ "limit": 10,
174
+ "offset": 0
175
+ }'
176
+
177
+ # ==================== 5. UPDATE COHORT ====================
178
+ print_section "5. UPDATE COHORT"
179
+
180
+ # Note: Replace DOCUMENT_ID with actual ID returned from create
181
+ DOCUMENT_ID="550e8400-e29b-41d4-a716-446655440000"
182
+
183
+ curl -X PUT "$BASE_URL/cohorts/$DOCUMENT_ID" \
184
+ -H "Content-Type: application/json" \
185
+ -d '{
186
+ "cohortName": "Updated Photochromatic",
187
+ "cohortDescription": "Updated description for photochromatic cohort"
188
+ }'
189
+
190
+ # ==================== 6. GET COHORT ANALYTICS ====================
191
+ print_section "6. GET COHORT ANALYTICS"
192
+
193
+ curl -X GET "$BASE_URL/cohorts/$COHORT_ID/analytics" \
194
+ -H "Content-Type: application/json"
195
+
196
+ # ==================== 7. DELETE COHORT ====================
197
+ print_section "7. DELETE COHORT"
198
+
199
+ # Note: Replace DOCUMENT_ID with actual ID
200
+ curl -X DELETE "$BASE_URL/cohorts/$DOCUMENT_ID" \
201
+ -H "Content-Type: application/json"
202
+
203
+ # ==================== VALIDATION TESTS ====================
204
+ print_section "VALIDATION TESTS"
205
+
206
+ echo "Testing invalid cohort name (too short):"
207
+ curl -X POST "$BASE_URL/cohorts" \
208
+ -H "Content-Type: application/json" \
209
+ -d '{
210
+ "clientId": "11",
211
+ "cohortId": "invalid_test",
212
+ "cohortName": "AB",
213
+ "cohortDescription": "This should fail because name is too short"
214
+ }'
215
+
216
+ echo ""
217
+ echo "Testing missing required field:"
218
+ curl -X POST "$BASE_URL/cohorts" \
219
+ -H "Content-Type: application/json" \
220
+ -d '{
221
+ "clientId": "11",
222
+ "cohortId": "invalid_test",
223
+ "cohortName": "Valid Name"
224
+ }'
225
+
226
+ echo ""
227
+ echo "Testing invalid cohortId (special characters):"
228
+ curl -X POST "$BASE_URL/cohorts" \
229
+ -H "Content-Type: application/json" \
230
+ -d '{
231
+ "clientId": "11",
232
+ "cohortId": "invalid@test",
233
+ "cohortName": "Valid Name",
234
+ "cohortDescription": "This should fail because cohortId has invalid characters"
235
+ }'
@@ -0,0 +1,296 @@
1
+ # Cohort API Implementation Summary
2
+
3
+ ## Overview
4
+ A complete Cohort API has been implemented with full OpenSearch integration using the `tango-app-api-middleware` package. The API supports creating, retrieving, searching, updating, and deleting cohorts with Joi validation.
5
+
6
+ ## Files Created/Modified
7
+
8
+ ### 1. Validation Schema (`src/validations/cohort.validation.js`)
9
+ - **Purpose**: Define Joi validation schemas for cohort operations
10
+ - **Schemas**:
11
+ - `cohortCreationSchema` - Validates new cohort data
12
+ - `cohortUpdateSchema` - Validates cohort updates (partial)
13
+ - `cohortQuerySchema` - Validates search/query parameters
14
+ - **Features**:
15
+ - Recursive validation of nested metrics and contexts
16
+ - Alphanumeric validation for cohort IDs
17
+ - String length validation
18
+ - Numeric range validation
19
+ - `validateCohortData()` helper function
20
+
21
+ ### 2. Cohort Service (`src/services/cohort.service.js`)
22
+ - **Purpose**: Handle all OpenSearch CRUD operations
23
+ - **OpenSearch Index**: `tango-audio-cohort`
24
+ - **Functions**:
25
+ - `createCohort()` - Insert cohort with auto-generated UUID
26
+ - `getCohortById()` - Retrieve by cohort ID
27
+ - `getCohortsByClientId()` - Paginated retrieval by client
28
+ - `searchCohorts()` - Fuzzy search by multiple criteria
29
+ - `updateCohort()` - Update cohort metadata
30
+ - `deleteCohort()` - Remove cohort
31
+ - `getCohortAnalytics()` - Get metrics summary
32
+ - `cohortExists()` - Check existence
33
+ - **Features**:
34
+ - Uses `insert()` with document ID from `tango-app-api-middleware`
35
+ - Automatic timestamp management
36
+ - Comprehensive error handling
37
+ - Logging via `tango-app-api-middleware`
38
+
39
+ ### 3. Cohort Controller (`src/controllers/cohort.controller.js`)
40
+ - **Purpose**: API endpoint handlers
41
+ - **Endpoints**:
42
+ - `createCohort()` - POST /cohorts
43
+ - `getCohort()` - GET /cohorts/:cohortId
44
+ - `getCohortsByClient()` - GET /cohorts/client/:clientId
45
+ - `searchCohortsEndpoint()` - POST /cohorts/search
46
+ - `updateCohort()` - PUT /cohorts/:documentId
47
+ - `deleteCohort()` - DELETE /cohorts/:documentId
48
+ - `getCohortAnalyticsEndpoint()` - GET /cohorts/:cohortId/analytics
49
+ - **Features**:
50
+ - Joi validation integration
51
+ - Duplicate cohort detection
52
+ - Comprehensive error responses
53
+ - Detailed request/response logging
54
+
55
+ ### 4. Validation Middleware (`src/middlewares/validation.middleware.js`)
56
+ **Added Functions**:
57
+ - `validateCohortCreation()` - Validates POST /cohorts requests
58
+ - `validateCohortUpdate()` - Validates PUT requests
59
+ - `validateCohortQuery()` - Validates search/query requests
60
+ - **Features**:
61
+ - Uses Joi schemas
62
+ - Provides detailed error feedback
63
+ - Sets `req.validatedData` for controller use
64
+
65
+ ### 5. Router Updates (`src/routes/audioAnalytics.routes.js`)
66
+ **New Routes Added**:
67
+ ```
68
+ POST /cohorts - Create cohort
69
+ GET /cohorts/:cohortId - Get by ID
70
+ GET /cohorts/client/:clientId - Get by client
71
+ POST /cohorts/search - Search cohorts
72
+ PUT /cohorts/:documentId - Update cohort
73
+ DELETE /cohorts/:documentId - Delete cohort
74
+ GET /cohorts/:cohortId/analytics - Get analytics
75
+ ```
76
+
77
+ ## Data Schema
78
+
79
+ ### Cohort Document Structure
80
+ ```json
81
+ {
82
+ "documentId": "UUID (auto-generated)",
83
+ "clientId": "string (required)",
84
+ "cohortId": "string (required, alphanumeric with - and _)",
85
+ "cohortName": "string (3-100 chars)",
86
+ "cohortDescription": "string (10-500 chars)",
87
+ "metrics": [
88
+ {
89
+ "metricId": "string",
90
+ "metricName": "string",
91
+ "metricDescription": "string",
92
+ "hasContext": "boolean",
93
+ "isNumneric": "boolean",
94
+ "contexts": [
95
+ {
96
+ "contextName": "string",
97
+ "priority": "number (0-2)",
98
+ "description": "string",
99
+ "minValue": "number (optional)",
100
+ "maxValue": "number (optional)"
101
+ }
102
+ ]
103
+ }
104
+ ],
105
+ "isActive": "boolean (default: true)",
106
+ "version": "string (default: 1.0)",
107
+ "createdAt": "ISO-8601 timestamp",
108
+ "updatedAt": "ISO-8601 timestamp"
109
+ }
110
+ ```
111
+
112
+ ## OpenSearch Integration
113
+
114
+ ### Index Configuration
115
+ - **Index Name**: `tango-audio-cohort`
116
+ - **Document ID**: UUID v4 (auto-generated)
117
+ - **Operations**: insert, search, update, delete
118
+
119
+ ### Functions Used
120
+ - `insert(index, documentId, document)` - From `tango-app-api-middleware`
121
+ - `search(index, query)` - From `tango-app-api-middleware`
122
+ - `update(index, documentId, document)` - From `tango-app-api-middleware`
123
+ - `delete(index, documentId)` - From `tango-app-api-middleware`
124
+
125
+ ### Search Queries
126
+ ```javascript
127
+ // Search by exact match
128
+ {
129
+ query: {
130
+ match: {
131
+ cohortId: "cohort_photochromatic_001"
132
+ }
133
+ }
134
+ }
135
+
136
+ // Fuzzy search
137
+ {
138
+ query: {
139
+ match: {
140
+ cohortName: {
141
+ query: "Photochrom",
142
+ fuzziness: "AUTO"
143
+ }
144
+ }
145
+ }
146
+ }
147
+
148
+ // Multiple criteria (bool query)
149
+ {
150
+ query: {
151
+ bool: {
152
+ must: [
153
+ { match: { clientId: "11" } },
154
+ { match: { cohortId: "cohort_photochromatic_001" } }
155
+ ]
156
+ }
157
+ }
158
+ }
159
+ ```
160
+
161
+ ## API Endpoints
162
+
163
+ ### 1. Create Cohort (POST /cohorts)
164
+ - **Status**: 201 Created / 400 Bad Request / 409 Conflict / 500 Error
165
+ - **Validation**: Full cohort schema validation
166
+ - **Returns**: Created cohort with documentId
167
+
168
+ ### 2. Get Cohort (GET /cohorts/:cohortId)
169
+ - **Status**: 200 OK / 404 Not Found / 500 Error
170
+ - **Returns**: Full cohort document with all metrics
171
+
172
+ ### 3. Get by Client (GET /cohorts/client/:clientId)
173
+ - **Status**: 200 OK / 500 Error
174
+ - **Pagination**: limit (default 10), offset (default 0)
175
+ - **Returns**: Array of cohorts with pagination metadata
176
+
177
+ ### 4. Search Cohorts (POST /cohorts/search)
178
+ - **Status**: 200 OK / 400 Bad Request / 500 Error
179
+ - **Criteria**: clientId, cohortId, cohortName, limit, offset
180
+ - **Returns**: Matching cohorts with pagination
181
+
182
+ ### 5. Update Cohort (PUT /cohorts/:documentId)
183
+ - **Status**: 200 OK / 400 Bad Request / 500 Error
184
+ - **Fields**: Partial update (cohortName, cohortDescription, metrics)
185
+ - **Returns**: Updated cohort with new updatedAt timestamp
186
+
187
+ ### 6. Delete Cohort (DELETE /cohorts/:documentId)
188
+ - **Status**: 200 OK / 500 Error
189
+ - **Returns**: Deletion confirmation
190
+
191
+ ### 7. Get Analytics (GET /cohorts/:cohortId/analytics)
192
+ - **Status**: 200 OK / 404 Not Found / 500 Error
193
+ - **Returns**: Analytics summary with metrics breakdown
194
+
195
+ ## Validation Rules
196
+
197
+ ### Cohort Creation
198
+ | Field | Type | Rules | Example |
199
+ |-------|------|-------|---------|
200
+ | clientId | string | Required | "11" |
201
+ | cohortId | string | Required, alphanumeric with - _ | "cohort_photo_001" |
202
+ | cohortName | string | Required, 3-100 chars | "Photochromatic" |
203
+ | cohortDescription | string | Required, 10-500 chars | "A strict evaluation..." |
204
+ | metrics | array | Required, 1-50 items | [...] |
205
+
206
+ ### Metric Fields
207
+ | Field | Type | Rules |
208
+ |-------|------|-------|
209
+ | metricId | string | Required |
210
+ | metricName | string | Required |
211
+ | metricDescription | string | Required |
212
+ | hasContext | boolean | Required |
213
+ | isNumneric | boolean | Required |
214
+ | contexts | array | Required if hasContext=true |
215
+
216
+ ### Context Fields (if hasContext=true)
217
+ | Field | Type | Rules | Example |
218
+ |-------|------|-------|---------|
219
+ | contextName | string | Required | "POSITIVE" |
220
+ | priority | number | Required, 0-2 | 2 |
221
+ | description | string | Required | "High interest..." |
222
+ | minValue | number | Optional (for numeric) | 0 |
223
+ | maxValue | number | Optional (for numeric) | 100 |
224
+
225
+ ## Error Handling
226
+
227
+ ### Error Response Format
228
+ ```json
229
+ {
230
+ "status": "error",
231
+ "message": "Human-readable error message",
232
+ "code": "ERROR_CODE",
233
+ "details": [...],
234
+ "timestamp": "ISO-8601"
235
+ }
236
+ ```
237
+
238
+ ### Common Error Codes
239
+ - `VALIDATION_ERROR` - 400 - Failed schema validation
240
+ - `COHORT_EXISTS` - 409 - Duplicate cohort ID
241
+ - `COHORT_NOT_FOUND` - 404 - Cohort doesn't exist
242
+ - `COHORT_CREATE_ERROR` - 500 - Creation failed
243
+ - `COHORT_SEARCH_ERROR` - 500 - Search/retrieval failed
244
+ - `INTERNAL_ERROR` - 500 - Server error
245
+
246
+ ## Logging
247
+
248
+ All operations are logged via `tango-app-api-middleware` logger:
249
+ - `logger.info()` - Successful operations
250
+ - `logger.warn()` - Validation warnings
251
+ - `logger.error()` - Errors with stack traces
252
+
253
+ ## Usage Examples
254
+
255
+ ### Create a Cohort
256
+ ```bash
257
+ curl -X POST https://api.example.com/v3/audio-analitics/cohorts \
258
+ -H "Content-Type: application/json" \
259
+ -d '{
260
+ "clientId": "11",
261
+ "cohortId": "cohort_photochromatic_001",
262
+ ...
263
+ }'
264
+ ```
265
+
266
+ ### Search Cohorts
267
+ ```bash
268
+ curl -X POST https://api.example.com/v3/audio-analitics/cohorts/search \
269
+ -H "Content-Type: application/json" \
270
+ -d '{
271
+ "clientId": "11",
272
+ "cohortName": "Photochrom",
273
+ "limit": 10
274
+ }'
275
+ ```
276
+
277
+ ## Testing
278
+
279
+ Use `COHORT_API_EXAMPLES.sh` for curl-based testing:
280
+ ```bash
281
+ bash COHORT_API_EXAMPLES.sh
282
+ ```
283
+
284
+ ## Next Steps
285
+
286
+ 1. Install required dependencies: `npm install joi`
287
+ 2. Configure OpenSearch connection in `tango-app-api-middleware`
288
+ 3. Test endpoints using provided curl examples
289
+ 4. Integrate with conversation analyzers to apply cohort metrics
290
+ 5. Build dashboard to visualize cohort analytics
291
+
292
+ ## Documentation Files
293
+
294
+ - `COHORT_API.md` - Complete API documentation
295
+ - `COHORT_API_EXAMPLES.sh` - Curl command examples
296
+ - `COHORT_API_IMPLEMENTATION.md` - This implementation summary