@webex/contact-center 3.12.0-next.9 → 3.12.0-task-refactor.2
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/AGENTS.md +438 -0
- package/ai-docs/README.md +131 -0
- package/ai-docs/RULES.md +455 -0
- package/ai-docs/patterns/event-driven-patterns.md +485 -0
- package/ai-docs/patterns/testing-patterns.md +480 -0
- package/ai-docs/patterns/typescript-patterns.md +365 -0
- package/ai-docs/templates/README.md +102 -0
- package/ai-docs/templates/documentation/create-agents-md.md +240 -0
- package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
- package/ai-docs/templates/existing-service/bug-fix.md +254 -0
- package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
- package/ai-docs/templates/new-method/00-master.md +80 -0
- package/ai-docs/templates/new-method/01-requirements.md +232 -0
- package/ai-docs/templates/new-method/02-implementation.md +295 -0
- package/ai-docs/templates/new-method/03-tests.md +201 -0
- package/ai-docs/templates/new-method/04-validation.md +141 -0
- package/ai-docs/templates/new-service/00-master.md +109 -0
- package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
- package/ai-docs/templates/new-service/02-code-generation.md +346 -0
- package/ai-docs/templates/new-service/03-integration.md +178 -0
- package/ai-docs/templates/new-service/04-test-generation.md +205 -0
- package/ai-docs/templates/new-service/05-validation.md +145 -0
- package/dist/cc.js +65 -123
- package/dist/cc.js.map +1 -1
- package/dist/constants.js +13 -2
- package/dist/constants.js.map +1 -1
- package/dist/index.js +13 -5
- package/dist/index.js.map +1 -1
- package/dist/metrics/behavioral-events.js +26 -13
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +7 -6
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/ApiAiAssistant.js +0 -3
- package/dist/services/ApiAiAssistant.js.map +1 -1
- package/dist/services/config/Util.js +2 -3
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/types.js +16 -14
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/constants.js +0 -1
- package/dist/services/constants.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/Utils.js +79 -55
- package/dist/services/core/Utils.js.map +1 -1
- package/dist/services/core/aqm-reqs.js +17 -92
- package/dist/services/core/aqm-reqs.js.map +1 -1
- package/dist/services/core/websocket/WebSocketManager.js +5 -25
- package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
- package/dist/services/core/websocket/types.js.map +1 -1
- package/dist/services/index.js +1 -2
- package/dist/services/index.js.map +1 -1
- package/dist/services/task/Task.js +644 -0
- package/dist/services/task/Task.js.map +1 -0
- package/dist/services/task/TaskFactory.js +45 -0
- package/dist/services/task/TaskFactory.js.map +1 -0
- package/dist/services/task/TaskManager.js +570 -535
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +132 -28
- package/dist/services/task/TaskUtils.js.map +1 -1
- package/dist/services/task/constants.js +7 -6
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/dialer.js +0 -51
- package/dist/services/task/dialer.js.map +1 -1
- package/dist/services/task/digital/Digital.js +77 -0
- package/dist/services/task/digital/Digital.js.map +1 -0
- package/dist/services/task/state-machine/TaskStateMachine.js +634 -0
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
- package/dist/services/task/state-machine/actions.js +372 -0
- package/dist/services/task/state-machine/actions.js.map +1 -0
- package/dist/services/task/state-machine/constants.js +139 -0
- package/dist/services/task/state-machine/constants.js.map +1 -0
- package/dist/services/task/state-machine/guards.js +263 -0
- package/dist/services/task/state-machine/guards.js.map +1 -0
- package/dist/services/task/state-machine/index.js +53 -0
- package/dist/services/task/state-machine/index.js.map +1 -0
- package/dist/services/task/state-machine/types.js +54 -0
- package/dist/services/task/state-machine/types.js.map +1 -0
- package/dist/services/task/state-machine/uiControlsComputer.js +377 -0
- package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
- package/dist/services/task/taskDataNormalizer.js +99 -0
- package/dist/services/task/taskDataNormalizer.js.map +1 -0
- package/dist/services/task/types.js +157 -18
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +1031 -0
- package/dist/services/task/voice/Voice.js.map +1 -0
- package/dist/services/task/voice/WebRTC.js +149 -0
- package/dist/services/task/voice/WebRTC.js.map +1 -0
- package/dist/types/cc.d.ts +4 -33
- package/dist/types/constants.d.ts +13 -2
- package/dist/types/index.d.ts +11 -5
- package/dist/types/metrics/constants.d.ts +5 -3
- package/dist/types/services/ApiAiAssistant.d.ts +1 -1
- package/dist/types/services/config/types.d.ts +97 -25
- package/dist/types/services/core/Err.d.ts +0 -2
- package/dist/types/services/core/Utils.d.ts +25 -23
- package/dist/types/services/core/aqm-reqs.d.ts +0 -49
- package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -1
- package/dist/types/services/core/websocket/connection-service.d.ts +0 -1
- package/dist/types/services/core/websocket/types.d.ts +1 -1
- package/dist/types/services/index.d.ts +1 -1
- package/dist/types/services/task/Task.d.ts +146 -0
- package/dist/types/services/task/TaskFactory.d.ts +12 -0
- package/dist/types/services/task/TaskUtils.d.ts +39 -8
- package/dist/types/services/task/constants.d.ts +5 -4
- package/dist/types/services/task/dialer.d.ts +0 -15
- package/dist/types/services/task/digital/Digital.d.ts +22 -0
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +906 -0
- package/dist/types/services/task/state-machine/actions.d.ts +8 -0
- package/dist/types/services/task/state-machine/constants.d.ts +91 -0
- package/dist/types/services/task/state-machine/guards.d.ts +78 -0
- package/dist/types/services/task/state-machine/index.d.ts +13 -0
- package/dist/types/services/task/state-machine/types.d.ts +256 -0
- package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
- package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
- package/dist/types/services/task/types.d.ts +539 -88
- package/dist/types/services/task/voice/Voice.d.ts +183 -0
- package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
- package/dist/types/types.d.ts +68 -0
- package/dist/types/webex.d.ts +1 -0
- package/dist/types.js +70 -0
- package/dist/types.js.map +1 -1
- package/dist/webex.js +14 -2
- package/dist/webex.js.map +1 -1
- package/package.json +14 -11
- package/src/cc.ts +91 -177
- package/src/constants.ts +13 -2
- package/src/index.ts +14 -5
- package/src/metrics/ai-docs/AGENTS.md +348 -0
- package/src/metrics/ai-docs/ARCHITECTURE.md +336 -0
- package/src/metrics/behavioral-events.ts +28 -14
- package/src/metrics/constants.ts +7 -8
- package/src/services/ApiAiAssistant.ts +2 -4
- package/src/services/agent/ai-docs/AGENTS.md +238 -0
- package/src/services/agent/ai-docs/ARCHITECTURE.md +302 -0
- package/src/services/ai-docs/AGENTS.md +384 -0
- package/src/services/config/Util.ts +2 -3
- package/src/services/config/ai-docs/AGENTS.md +253 -0
- package/src/services/config/ai-docs/ARCHITECTURE.md +424 -0
- package/src/services/config/types.ts +108 -20
- package/src/services/constants.ts +0 -1
- package/src/services/core/Err.ts +0 -1
- package/src/services/core/Utils.ts +90 -67
- package/src/services/core/ai-docs/AGENTS.md +379 -0
- package/src/services/core/ai-docs/ARCHITECTURE.md +696 -0
- package/src/services/core/aqm-reqs.ts +22 -100
- package/src/services/core/websocket/WebSocketManager.ts +4 -23
- package/src/services/core/websocket/types.ts +1 -1
- package/src/services/index.ts +1 -2
- package/src/services/task/Task.ts +785 -0
- package/src/services/task/TaskFactory.ts +55 -0
- package/src/services/task/TaskManager.ts +579 -633
- package/src/services/task/TaskUtils.ts +175 -31
- package/src/services/task/ai-docs/AGENTS.md +448 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +573 -0
- package/src/services/task/constants.ts +5 -4
- package/src/services/task/dialer.ts +1 -56
- package/src/services/task/digital/Digital.ts +95 -0
- package/src/services/task/state-machine/TaskStateMachine.ts +793 -0
- package/src/services/task/state-machine/actions.ts +422 -0
- package/src/services/task/state-machine/ai-docs/AGENTS.md +495 -0
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1135 -0
- package/src/services/task/state-machine/constants.ts +150 -0
- package/src/services/task/state-machine/guards.ts +303 -0
- package/src/services/task/state-machine/index.ts +28 -0
- package/src/services/task/state-machine/types.ts +228 -0
- package/src/services/task/state-machine/uiControlsComputer.ts +542 -0
- package/src/services/task/taskDataNormalizer.ts +137 -0
- package/src/services/task/types.ts +641 -95
- package/src/services/task/voice/Voice.ts +1255 -0
- package/src/services/task/voice/WebRTC.ts +187 -0
- package/src/types.ts +88 -5
- package/src/utils/AGENTS.md +276 -0
- package/src/webex.js +2 -0
- package/test/unit/spec/cc.ts +59 -142
- package/test/unit/spec/logger-proxy.ts +70 -0
- package/test/unit/spec/services/ApiAiAssistant.ts +17 -0
- package/test/unit/spec/services/config/index.ts +26 -55
- package/test/unit/spec/services/core/Utils.ts +103 -52
- package/test/unit/spec/services/core/websocket/WebSocketManager.ts +48 -112
- package/test/unit/spec/services/core/websocket/connection-service.ts +5 -4
- package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
- package/test/unit/spec/services/task/Task.ts +416 -0
- package/test/unit/spec/services/task/TaskFactory.ts +62 -0
- package/test/unit/spec/services/task/TaskManager.ts +781 -1735
- package/test/unit/spec/services/task/TaskUtils.ts +125 -0
- package/test/unit/spec/services/task/dialer.ts +112 -198
- package/test/unit/spec/services/task/digital/Digital.ts +105 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +473 -0
- package/test/unit/spec/services/task/state-machine/guards.ts +288 -0
- package/test/unit/spec/services/task/state-machine/types.ts +18 -0
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +147 -0
- package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
- package/test/unit/spec/services/task/voice/Voice.ts +587 -0
- package/test/unit/spec/services/task/voice/WebRTC.ts +242 -0
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
- package/dist/services/task/index.js +0 -1525
- package/dist/services/task/index.js.map +0 -1
- package/dist/types/services/task/index.d.ts +0 -650
- package/src/services/task/index.ts +0 -1801
- package/test/unit/spec/services/task/index.ts +0 -2184
package/ai-docs/RULES.md
ADDED
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
# Contact Center SDK - Coding Standards & Rules
|
|
2
|
+
|
|
3
|
+
> **Purpose**: Defines the coding standards, conventions, and architectural rules that all code in `@webex/contact-center` must follow.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## TypeScript Standards
|
|
8
|
+
|
|
9
|
+
### Strict Mode
|
|
10
|
+
- TypeScript strict mode is enabled
|
|
11
|
+
- Avoid `any` type unless absolutely necessary (document justification with `// eslint-disable-line`)
|
|
12
|
+
- Prefer `unknown` over `any` for unknown types
|
|
13
|
+
- All public APIs must have explicit return types
|
|
14
|
+
|
|
15
|
+
### Naming Conventions
|
|
16
|
+
|
|
17
|
+
| Element | Convention | Example |
|
|
18
|
+
|---------|------------|---------|
|
|
19
|
+
| Classes | PascalCase | `ContactCenter`, `TaskManager` |
|
|
20
|
+
| Interfaces | PascalCase with `I` prefix for contracts | `IContactCenter`, `ITask`, `IVoice` |
|
|
21
|
+
| Types | PascalCase | `SetStateResponse`, `BuddyAgentsResponse` |
|
|
22
|
+
| Enums/Constants | SCREAMING_SNAKE_CASE | `CC_EVENTS`, `METRIC_EVENT_NAMES` |
|
|
23
|
+
| Methods | camelCase | `stationLogin`, `setAgentState` |
|
|
24
|
+
| Private properties | camelCase with `$` prefix for SDK references | `$webex`, `$config` |
|
|
25
|
+
| Regular private | camelCase | `agentConfig`, `eventEmitter` |
|
|
26
|
+
| Module constants | SCREAMING_SNAKE_CASE | `CC_FILE`, `READY` |
|
|
27
|
+
|
|
28
|
+
### File Naming
|
|
29
|
+
- Component files: `PascalCase.ts` (e.g., `TaskManager.ts`, `WebSocketManager.ts`)
|
|
30
|
+
- Type files: `types.ts` in service folders
|
|
31
|
+
- Constant files: `constants.ts` in service folders
|
|
32
|
+
- Index files: `index.ts` for exports
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## JSDoc Standards
|
|
37
|
+
|
|
38
|
+
### Public APIs (MANDATORY)
|
|
39
|
+
|
|
40
|
+
All public methods and types must have comprehensive JSDoc:
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
/**
|
|
44
|
+
* Brief description of what this does.
|
|
45
|
+
*
|
|
46
|
+
* @description
|
|
47
|
+
* Longer description if needed with:
|
|
48
|
+
* - Bullet points for features
|
|
49
|
+
* - Multiple lines for clarity
|
|
50
|
+
*
|
|
51
|
+
* @param {ParamType} paramName - Description of the parameter
|
|
52
|
+
* @returns {Promise<ReturnType>} Description of return value
|
|
53
|
+
* @throws {Error} Description of when errors are thrown
|
|
54
|
+
*
|
|
55
|
+
* @public
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const result = await cc.methodName({
|
|
60
|
+
* param: 'value',
|
|
61
|
+
* });
|
|
62
|
+
* console.log(result);
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
public async methodName(data: ParamType): Promise<ReturnType> {
|
|
66
|
+
// implementation
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Private/Internal APIs
|
|
71
|
+
|
|
72
|
+
Use `@private` or `@ignore` tag:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
/**
|
|
76
|
+
* Internal utility function.
|
|
77
|
+
* @private
|
|
78
|
+
* @ignore
|
|
79
|
+
*/
|
|
80
|
+
private helperMethod(): void {
|
|
81
|
+
// implementation
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Type Definitions
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
/**
|
|
89
|
+
* Description of what this type represents.
|
|
90
|
+
* @public
|
|
91
|
+
*/
|
|
92
|
+
export type MyType = {
|
|
93
|
+
/** Description of this field */
|
|
94
|
+
fieldName: string;
|
|
95
|
+
/** Optional field description */
|
|
96
|
+
optionalField?: number;
|
|
97
|
+
};
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Logging Standards
|
|
103
|
+
|
|
104
|
+
### Always Use LoggerProxy
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// ✅ REQUIRED pattern
|
|
108
|
+
import LoggerProxy from '../../logger-proxy';
|
|
109
|
+
|
|
110
|
+
LoggerProxy.info('Starting operation', {
|
|
111
|
+
module: 'ModuleName',
|
|
112
|
+
method: 'methodName',
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Log Levels
|
|
117
|
+
|
|
118
|
+
| Level | Use Case | Example |
|
|
119
|
+
|-------|----------|---------|
|
|
120
|
+
| `trace` | Detailed debugging | Entry/exit of complex functions |
|
|
121
|
+
| `log` | General information | Operation completed successfully |
|
|
122
|
+
| `info` | Important milestones | Starting registration, login |
|
|
123
|
+
| `warn` | Potential issues | Deprecated usage, fallback behavior |
|
|
124
|
+
| `error` | Failures | API errors, exceptions |
|
|
125
|
+
|
|
126
|
+
### Logging Context (Required)
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// All log calls MUST include module and method
|
|
130
|
+
{
|
|
131
|
+
module: 'FileName', // Required: Class/file name
|
|
132
|
+
method: 'methodName', // Required: Current method name
|
|
133
|
+
trackingId?: string, // Optional: Request correlation ID
|
|
134
|
+
interactionId?: string, // Optional: Task/call ID
|
|
135
|
+
data?: object, // Optional: Additional context
|
|
136
|
+
error?: Error, // Optional: Error object for error logs
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Error Handling Standards
|
|
143
|
+
|
|
144
|
+
### Standard Error Pattern
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import {getErrorDetails} from './services/core/Utils';
|
|
148
|
+
import {Failure} from './services/core/GlobalTypes';
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
const result = await this.riskyOperation();
|
|
152
|
+
return result;
|
|
153
|
+
} catch (error) {
|
|
154
|
+
const failure = error.details as Failure;
|
|
155
|
+
|
|
156
|
+
// 1. Track failure metrics
|
|
157
|
+
this.metricsManager.trackEvent(
|
|
158
|
+
METRIC_EVENT_NAMES.OPERATION_FAILED,
|
|
159
|
+
MetricsManager.getCommonTrackingFieldForAQMResponseFailed(failure),
|
|
160
|
+
['operational']
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
// 2. Get detailed error (logs automatically)
|
|
164
|
+
const {error: detailedError} = getErrorDetails(
|
|
165
|
+
error,
|
|
166
|
+
'methodName',
|
|
167
|
+
'ModuleName'
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
// 3. Throw augmented error
|
|
171
|
+
throw detailedError;
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Never Swallow Errors
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
// ❌ WRONG - silently swallowing errors
|
|
179
|
+
try {
|
|
180
|
+
await riskyOperation();
|
|
181
|
+
} catch (error) {
|
|
182
|
+
// doing nothing
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ✅ CORRECT - at minimum log the error
|
|
186
|
+
try {
|
|
187
|
+
await riskyOperation();
|
|
188
|
+
} catch (error) {
|
|
189
|
+
LoggerProxy.error(`Operation failed: ${error}`, {
|
|
190
|
+
module: 'ModuleName',
|
|
191
|
+
method: 'methodName',
|
|
192
|
+
});
|
|
193
|
+
throw error;
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Metrics Standards
|
|
200
|
+
|
|
201
|
+
### All Operations Must Track Metrics
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
// Start timing at method entry
|
|
205
|
+
this.metricsManager.timeEvent([
|
|
206
|
+
METRIC_EVENT_NAMES.SUCCESS_EVENT,
|
|
207
|
+
METRIC_EVENT_NAMES.FAILED_EVENT,
|
|
208
|
+
]);
|
|
209
|
+
|
|
210
|
+
// Track on success
|
|
211
|
+
this.metricsManager.trackEvent(
|
|
212
|
+
METRIC_EVENT_NAMES.SUCCESS_EVENT,
|
|
213
|
+
{
|
|
214
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponse(response),
|
|
215
|
+
// Add operation-specific fields
|
|
216
|
+
},
|
|
217
|
+
['behavioral', 'operational']
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
// Track on failure (in catch block)
|
|
221
|
+
this.metricsManager.trackEvent(
|
|
222
|
+
METRIC_EVENT_NAMES.FAILED_EVENT,
|
|
223
|
+
{
|
|
224
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(failure),
|
|
225
|
+
},
|
|
226
|
+
['behavioral', 'operational']
|
|
227
|
+
);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Metric Event Naming
|
|
231
|
+
|
|
232
|
+
Add new events to `src/metrics/constants.ts`:
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
export const METRIC_EVENT_NAMES = {
|
|
236
|
+
// Existing events...
|
|
237
|
+
NEW_OPERATION_SUCCESS: 'new operation success',
|
|
238
|
+
NEW_OPERATION_FAILED: 'new operation failed',
|
|
239
|
+
} as const;
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Service Architecture Standards
|
|
245
|
+
|
|
246
|
+
### Singleton Pattern
|
|
247
|
+
|
|
248
|
+
Services use singleton pattern via `Services` class:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
// Access services through Services singleton
|
|
252
|
+
this.services = Services.getInstance({
|
|
253
|
+
webex: this.$webex,
|
|
254
|
+
connectionConfig: this.getConnectionConfig(),
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// Use services
|
|
258
|
+
await this.services.agent.stationLogin({data});
|
|
259
|
+
await this.services.config.getAgentConfig(orgId, agentId);
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Service Factory Pattern
|
|
263
|
+
|
|
264
|
+
Agent/contact services use factory pattern:
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
// services/agent/index.ts
|
|
268
|
+
export default function routingAgent(routing: AqmReqs) {
|
|
269
|
+
return {
|
|
270
|
+
methodName: routing.req((p: {data: ParamType}) => ({
|
|
271
|
+
url: '/v1/endpoint',
|
|
272
|
+
host: WCC_API_GATEWAY,
|
|
273
|
+
data: p.data,
|
|
274
|
+
err: createErrDetailsObject,
|
|
275
|
+
method: HTTP_METHODS.POST, // Optional, defaults to POST
|
|
276
|
+
notifSuccess: {
|
|
277
|
+
bind: {
|
|
278
|
+
type: CC_EVENTS.SUCCESS_EVENT,
|
|
279
|
+
data: {type: CC_EVENTS.SUCCESS_EVENT},
|
|
280
|
+
},
|
|
281
|
+
msg: {} as SuccessType,
|
|
282
|
+
},
|
|
283
|
+
notifFail: {
|
|
284
|
+
bind: {
|
|
285
|
+
type: CC_EVENTS.FAIL_EVENT,
|
|
286
|
+
data: {type: CC_EVENTS.FAIL_EVENT},
|
|
287
|
+
},
|
|
288
|
+
errId: 'Service.aqm.agent.methodName',
|
|
289
|
+
},
|
|
290
|
+
})),
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Event Standards
|
|
298
|
+
|
|
299
|
+
### Event Constant Objects
|
|
300
|
+
|
|
301
|
+
Define events as const objects with `as const`:
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
export const MY_EVENTS = {
|
|
305
|
+
SUCCESS: 'MySuccess',
|
|
306
|
+
FAILED: 'MyFailed',
|
|
307
|
+
} as const;
|
|
308
|
+
|
|
309
|
+
// Extract union type
|
|
310
|
+
type Enum<T extends Record<string, unknown>> = T[keyof T];
|
|
311
|
+
export type MY_EVENTS = Enum<typeof MY_EVENTS>;
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Event Emission
|
|
315
|
+
|
|
316
|
+
Always use event constants:
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
import {AGENT_EVENTS} from './services/agent/types';
|
|
320
|
+
|
|
321
|
+
// ✅ CORRECT
|
|
322
|
+
this.emit(AGENT_EVENTS.AGENT_STATE_CHANGE, eventData);
|
|
323
|
+
|
|
324
|
+
// ❌ WRONG
|
|
325
|
+
this.emit('stateChange', eventData);
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## Testing Standards
|
|
331
|
+
|
|
332
|
+
For full testing patterns including test file location, MockWebex setup, singleton mocking, LoggerProxy mocking, and test structure, see [`patterns/testing-patterns.md`](patterns/testing-patterns.md).
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Import Standards
|
|
337
|
+
|
|
338
|
+
### Import Order
|
|
339
|
+
|
|
340
|
+
1. External packages (`@webex/*`, `events`, `uuid`)
|
|
341
|
+
2. Internal absolute imports (types, constants)
|
|
342
|
+
3. Relative imports (local files)
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
// 1. External
|
|
346
|
+
import {WebexPlugin} from '@webex/webex-core';
|
|
347
|
+
import EventEmitter from 'events';
|
|
348
|
+
import {v4 as uuidv4} from 'uuid';
|
|
349
|
+
|
|
350
|
+
// 2. Internal types/constants
|
|
351
|
+
import {WebexSDK, CCPluginConfig, AgentLogin} from './types';
|
|
352
|
+
import {READY, CC_FILE, METHODS} from './constants';
|
|
353
|
+
|
|
354
|
+
// 3. Relative imports
|
|
355
|
+
import Services from './services';
|
|
356
|
+
import LoggerProxy from './logger-proxy';
|
|
357
|
+
import {getErrorDetails} from './services/core/Utils';
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Export Standards
|
|
361
|
+
|
|
362
|
+
- Public types: Export from `src/types.ts`
|
|
363
|
+
- Internal types: Export from service-level `types.ts`
|
|
364
|
+
- Services: Use default export for main class, named exports for types
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## Accessibility & Security
|
|
369
|
+
|
|
370
|
+
### No Hardcoded Credentials
|
|
371
|
+
|
|
372
|
+
Never commit:
|
|
373
|
+
- API keys, tokens, secrets
|
|
374
|
+
- Passwords or authentication data
|
|
375
|
+
- Private keys or certificates
|
|
376
|
+
|
|
377
|
+
### Sensitive Data Logging
|
|
378
|
+
|
|
379
|
+
Never log sensitive data:
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
// ❌ WRONG
|
|
383
|
+
LoggerProxy.log(`User token: ${token}`);
|
|
384
|
+
|
|
385
|
+
// ✅ CORRECT
|
|
386
|
+
LoggerProxy.log('Token received', {
|
|
387
|
+
module: 'Auth',
|
|
388
|
+
method: 'login',
|
|
389
|
+
// No sensitive data in logs
|
|
390
|
+
});
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## Performance Standards
|
|
396
|
+
|
|
397
|
+
### Async/Await
|
|
398
|
+
|
|
399
|
+
Always use async/await over raw Promises:
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
// ✅ CORRECT
|
|
403
|
+
public async fetchData(): Promise<Data> {
|
|
404
|
+
const result = await this.service.getData();
|
|
405
|
+
return result;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// ❌ AVOID (when possible)
|
|
409
|
+
public fetchData(): Promise<Data> {
|
|
410
|
+
return this.service.getData().then(result => result);
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Cleanup on Deregistration
|
|
415
|
+
|
|
416
|
+
Always clean up resources:
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
public async deregister(): Promise<void> {
|
|
420
|
+
// Remove event listeners
|
|
421
|
+
this.taskManager.off(TASK_EVENTS.TASK_INCOMING, this.handleIncomingTask);
|
|
422
|
+
this.services.webSocketManager.off('message', this.handleWebsocketMessage);
|
|
423
|
+
|
|
424
|
+
// Close connections
|
|
425
|
+
if (!this.services.webSocketManager.isSocketClosed) {
|
|
426
|
+
this.services.webSocketManager.close(false, 'Reason');
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Clear state
|
|
430
|
+
this.agentConfig = null;
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
## Code Review Checklist
|
|
437
|
+
|
|
438
|
+
Before submitting code:
|
|
439
|
+
|
|
440
|
+
- [ ] All public APIs have JSDoc with `@public`, `@param`, `@returns`, `@example`
|
|
441
|
+
- [ ] LoggerProxy used for all logging with module/method context
|
|
442
|
+
- [ ] MetricsManager tracks success/failure for all operations
|
|
443
|
+
- [ ] Error handling follows `getErrorDetails` pattern
|
|
444
|
+
- [ ] No `console.log` or `console.error`
|
|
445
|
+
- [ ] No hardcoded credentials or sensitive data
|
|
446
|
+
- [ ] Event constants used (not string literals)
|
|
447
|
+
- [ ] Types exported appropriately
|
|
448
|
+
- [ ] Unit tests added/updated
|
|
449
|
+
- [ ] No `any` types without justification
|
|
450
|
+
|
|
451
|
+
## Need More Context?
|
|
452
|
+
|
|
453
|
+
- **TypeScript patterns**: [`patterns/typescript-patterns.md`](patterns/typescript-patterns.md)
|
|
454
|
+
- **Testing patterns**: [`patterns/testing-patterns.md`](patterns/testing-patterns.md)
|
|
455
|
+
- **Event patterns**: [`patterns/event-driven-patterns.md`](patterns/event-driven-patterns.md)
|