@webex/contact-center 3.12.0-next.8 → 3.12.0-next.80
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 +265 -29
- package/dist/cc.js.map +1 -1
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +16 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.js +20 -5
- package/dist/index.js.map +1 -1
- package/dist/metrics/behavioral-events.js +101 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +23 -4
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/ApiAiAssistant.js +74 -3
- package/dist/services/ApiAiAssistant.js.map +1 -1
- package/dist/services/UserPreference.js +427 -0
- package/dist/services/UserPreference.js.map +1 -0
- package/dist/services/config/Util.js +3 -3
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +23 -2
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/types.js +49 -9
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/Utils.js +107 -32
- package/dist/services/core/Utils.js.map +1 -1
- package/dist/services/core/websocket/WebSocketManager.js +2 -1
- 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 -1
- package/dist/services/index.js.map +1 -1
- package/dist/services/task/Task.js +688 -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 +725 -526
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +162 -26
- package/dist/services/task/TaskUtils.js.map +1 -1
- package/dist/services/task/constants.js +9 -2
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/dialer.js +78 -0
- 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 +837 -0
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
- package/dist/services/task/state-machine/actions.js +543 -0
- package/dist/services/task/state-machine/actions.js.map +1 -0
- package/dist/services/task/state-machine/constants.js +161 -0
- package/dist/services/task/state-machine/constants.js.map +1 -0
- package/dist/services/task/state-machine/guards.js +340 -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 +553 -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 +212 -4
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +1042 -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 +94 -1
- package/dist/types/config.d.ts +6 -0
- package/dist/types/constants.d.ts +16 -1
- package/dist/types/index.d.ts +21 -6
- package/dist/types/metrics/constants.d.ts +19 -1
- package/dist/types/services/ApiAiAssistant.d.ts +11 -3
- package/dist/types/services/UserPreference.d.ts +118 -0
- package/dist/types/services/config/constants.d.ts +21 -0
- package/dist/types/services/config/types.d.ts +171 -10
- package/dist/types/services/core/Err.d.ts +4 -0
- package/dist/types/services/core/Utils.d.ts +33 -13
- package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -0
- 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 +157 -0
- package/dist/types/services/task/TaskFactory.d.ts +12 -0
- package/dist/types/services/task/TaskUtils.d.ts +46 -2
- package/dist/types/services/task/constants.d.ts +7 -0
- package/dist/types/services/task/dialer.d.ts +30 -0
- package/dist/types/services/task/digital/Digital.d.ts +22 -0
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1144 -0
- package/dist/types/services/task/state-machine/actions.d.ts +10 -0
- package/dist/types/services/task/state-machine/constants.d.ts +107 -0
- package/dist/types/services/task/state-machine/guards.d.ts +90 -0
- package/dist/types/services/task/state-machine/index.d.ts +13 -0
- package/dist/types/services/task/state-machine/types.d.ts +267 -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 +603 -66
- package/dist/types/services/task/voice/Voice.d.ts +184 -0
- package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
- package/dist/types/types.d.ts +94 -0
- package/dist/types/webex.d.ts +1 -0
- package/dist/types.js +85 -0
- package/dist/types.js.map +1 -1
- package/dist/webex.js +14 -2
- package/dist/webex.js.map +1 -1
- package/package.json +15 -12
- package/src/cc.ts +329 -30
- package/src/config.ts +6 -0
- package/src/constants.ts +16 -1
- package/src/index.ts +23 -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 +106 -0
- package/src/metrics/constants.ts +23 -4
- package/src/services/ApiAiAssistant.ts +104 -3
- package/src/services/UserPreference.ts +509 -0
- 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 +3 -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/constants.ts +25 -1
- package/src/services/config/types.ts +174 -11
- package/src/services/core/Err.ts +2 -0
- package/src/services/core/Utils.ts +123 -37
- package/src/services/core/ai-docs/AGENTS.md +379 -0
- package/src/services/core/ai-docs/ARCHITECTURE.md +696 -0
- package/src/services/core/websocket/WebSocketManager.ts +2 -0
- package/src/services/core/websocket/types.ts +1 -1
- package/src/services/index.ts +1 -1
- package/src/services/task/Task.ts +837 -0
- package/src/services/task/TaskFactory.ts +55 -0
- package/src/services/task/TaskManager.ts +738 -613
- package/src/services/task/TaskUtils.ts +205 -25
- package/src/services/task/ai-docs/AGENTS.md +455 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +585 -0
- package/src/services/task/constants.ts +7 -0
- package/src/services/task/dialer.ts +80 -0
- package/src/services/task/digital/Digital.ts +95 -0
- package/src/services/task/state-machine/TaskStateMachine.ts +1077 -0
- package/src/services/task/state-machine/actions.ts +685 -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 +172 -0
- package/src/services/task/state-machine/guards.ts +406 -0
- package/src/services/task/state-machine/index.ts +28 -0
- package/src/services/task/state-machine/types.ts +241 -0
- package/src/services/task/state-machine/uiControlsComputer.ts +867 -0
- package/src/services/task/taskDataNormalizer.ts +137 -0
- package/src/services/task/types.ts +710 -71
- package/src/services/task/voice/Voice.ts +1267 -0
- package/src/services/task/voice/WebRTC.ts +187 -0
- package/src/types.ts +122 -2
- package/src/utils/AGENTS.md +276 -0
- package/src/webex.js +2 -0
- package/test/unit/spec/cc.ts +343 -23
- package/test/unit/spec/logger-proxy.ts +70 -0
- package/test/unit/spec/services/ApiAiAssistant.ts +122 -17
- package/test/unit/spec/services/UserPreference.ts +401 -0
- package/test/unit/spec/services/WebCallingService.ts +7 -1
- package/test/unit/spec/services/config/index.ts +30 -30
- package/test/unit/spec/services/core/Utils.ts +425 -8
- package/test/unit/spec/services/core/websocket/WebSocketManager.ts +66 -40
- package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
- package/test/unit/spec/services/task/Task.ts +477 -0
- package/test/unit/spec/services/task/TaskFactory.ts +62 -0
- package/test/unit/spec/services/task/TaskManager.ts +832 -1702
- package/test/unit/spec/services/task/TaskUtils.ts +206 -0
- package/test/unit/spec/services/task/dialer.ts +190 -0
- package/test/unit/spec/services/task/digital/Digital.ts +105 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +1825 -0
- package/test/unit/spec/services/task/state-machine/guards.ts +479 -0
- package/test/unit/spec/services/task/state-machine/types.ts +18 -0
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +2020 -0
- package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
- package/test/unit/spec/services/task/voice/Voice.ts +631 -0
- package/test/unit/spec/services/task/voice/WebRTC.ts +235 -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
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# New Service - Test Generation
|
|
2
|
+
|
|
3
|
+
> **Purpose**: Create unit tests for the new service.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Test File Location
|
|
8
|
+
|
|
9
|
+
Create: `test/unit/spec/services/ServiceName.ts`
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Test File Template
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import 'jsdom-global/register';
|
|
17
|
+
import MockWebex from '@webex/test-helper-mock-webex';
|
|
18
|
+
import ServiceName, {
|
|
19
|
+
ServiceListResponse,
|
|
20
|
+
ServiceSearchParams,
|
|
21
|
+
} from '../../../../src/services/ServiceName';
|
|
22
|
+
|
|
23
|
+
jest.mock('../../../../src/logger-proxy', () => ({
|
|
24
|
+
__esModule: true,
|
|
25
|
+
default: {
|
|
26
|
+
log: jest.fn(),
|
|
27
|
+
error: jest.fn(),
|
|
28
|
+
info: jest.fn(),
|
|
29
|
+
warn: jest.fn(),
|
|
30
|
+
trace: jest.fn(),
|
|
31
|
+
initialize: jest.fn(),
|
|
32
|
+
},
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
describe('ServiceName', () => {
|
|
36
|
+
let webex: any;
|
|
37
|
+
let service: ServiceName;
|
|
38
|
+
|
|
39
|
+
// Mock data
|
|
40
|
+
const mockOrgId = 'mock-org-id';
|
|
41
|
+
const mockResponse: ServiceListResponse = {
|
|
42
|
+
data: [
|
|
43
|
+
{ id: 'item-1', name: 'Item 1' },
|
|
44
|
+
{ id: 'item-2', name: 'Item 2' },
|
|
45
|
+
],
|
|
46
|
+
meta: {
|
|
47
|
+
page: 0,
|
|
48
|
+
pageSize: 50,
|
|
49
|
+
totalPages: 1,
|
|
50
|
+
totalRecords: 2,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
webex = MockWebex({
|
|
56
|
+
logger: {
|
|
57
|
+
log: jest.fn(),
|
|
58
|
+
error: jest.fn(),
|
|
59
|
+
info: jest.fn(),
|
|
60
|
+
},
|
|
61
|
+
credentials: {
|
|
62
|
+
getOrgId: jest.fn(() => mockOrgId),
|
|
63
|
+
},
|
|
64
|
+
request: jest.fn(),
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
service = new ServiceName(webex);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
afterEach(() => {
|
|
71
|
+
jest.clearAllMocks();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe('getItems', () => {
|
|
75
|
+
it('should fetch items successfully', async () => {
|
|
76
|
+
// Arrange
|
|
77
|
+
webex.request.mockResolvedValue({ body: mockResponse });
|
|
78
|
+
|
|
79
|
+
// Act
|
|
80
|
+
const result = await service.getItems();
|
|
81
|
+
|
|
82
|
+
// Assert
|
|
83
|
+
expect(result).toEqual(mockResponse);
|
|
84
|
+
expect(webex.request).toHaveBeenCalledWith({
|
|
85
|
+
method: 'GET',
|
|
86
|
+
uri: expect.stringContaining(mockOrgId),
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should apply pagination parameters', async () => {
|
|
91
|
+
// Arrange
|
|
92
|
+
webex.request.mockResolvedValue({ body: mockResponse });
|
|
93
|
+
const params: ServiceSearchParams = { page: 1, pageSize: 25 };
|
|
94
|
+
|
|
95
|
+
// Act
|
|
96
|
+
await service.getItems(params);
|
|
97
|
+
|
|
98
|
+
// Assert
|
|
99
|
+
expect(webex.request).toHaveBeenCalledWith({
|
|
100
|
+
method: 'GET',
|
|
101
|
+
uri: expect.stringContaining('page=1'),
|
|
102
|
+
});
|
|
103
|
+
expect(webex.request).toHaveBeenCalledWith({
|
|
104
|
+
method: 'GET',
|
|
105
|
+
uri: expect.stringContaining('pageSize=25'),
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should apply search parameter', async () => {
|
|
110
|
+
// Arrange
|
|
111
|
+
webex.request.mockResolvedValue({ body: mockResponse });
|
|
112
|
+
const params: ServiceSearchParams = { search: 'test' };
|
|
113
|
+
|
|
114
|
+
// Act
|
|
115
|
+
await service.getItems(params);
|
|
116
|
+
|
|
117
|
+
// Assert
|
|
118
|
+
expect(webex.request).toHaveBeenCalledWith({
|
|
119
|
+
method: 'GET',
|
|
120
|
+
uri: expect.stringContaining('search=test'),
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('should throw error on API failure', async () => {
|
|
125
|
+
// Arrange
|
|
126
|
+
const mockError = new Error('API Error');
|
|
127
|
+
webex.request.mockRejectedValue(mockError);
|
|
128
|
+
|
|
129
|
+
// Act & Assert
|
|
130
|
+
await expect(service.getItems()).rejects.toThrow('API Error');
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe('getItemById', () => {
|
|
135
|
+
it('should fetch single item successfully', async () => {
|
|
136
|
+
// Arrange
|
|
137
|
+
const mockItem = { id: 'item-1', name: 'Item 1' };
|
|
138
|
+
webex.request.mockResolvedValue({ body: mockItem });
|
|
139
|
+
|
|
140
|
+
// Act
|
|
141
|
+
const result = await service.getItemById('item-1');
|
|
142
|
+
|
|
143
|
+
// Assert
|
|
144
|
+
expect(result).toEqual(mockItem);
|
|
145
|
+
expect(webex.request).toHaveBeenCalledWith({
|
|
146
|
+
method: 'GET',
|
|
147
|
+
uri: expect.stringContaining('item-1'),
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should throw error if item not found', async () => {
|
|
152
|
+
// Arrange
|
|
153
|
+
const mockError = new Error('Not Found');
|
|
154
|
+
webex.request.mockRejectedValue(mockError);
|
|
155
|
+
|
|
156
|
+
// Act & Assert
|
|
157
|
+
await expect(service.getItemById('invalid-id')).rejects.toThrow('Not Found');
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Test Integration with cc.ts
|
|
166
|
+
|
|
167
|
+
Add to `test/unit/spec/cc.ts`:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
describe('cc.serviceName', () => {
|
|
171
|
+
it('should initialize service on ready', () => {
|
|
172
|
+
expect(webex.cc.serviceName).toBeDefined();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('should fetch items through service', async () => {
|
|
176
|
+
// Mock the service method
|
|
177
|
+
const mockResponse = { data: [], meta: {} };
|
|
178
|
+
jest.spyOn(webex.cc.serviceName, 'getItems').mockResolvedValue(mockResponse);
|
|
179
|
+
|
|
180
|
+
// Act
|
|
181
|
+
const result = await webex.cc.serviceName.getItems();
|
|
182
|
+
|
|
183
|
+
// Assert
|
|
184
|
+
expect(result).toEqual(mockResponse);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Running Tests
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# Run specific test file
|
|
195
|
+
yarn workspace @webex/contact-center test -- --testPathPattern=ServiceName
|
|
196
|
+
|
|
197
|
+
# Run with coverage
|
|
198
|
+
yarn workspace @webex/contact-center test -- --coverage --testPathPattern=ServiceName
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Next Step
|
|
204
|
+
|
|
205
|
+
Proceed to: [`05-validation.md`](05-validation.md)
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# New Service - Validation Checklist
|
|
2
|
+
|
|
3
|
+
> **Purpose**: Final quality check before completing service creation.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Code Quality Checklist
|
|
8
|
+
|
|
9
|
+
### Service Class
|
|
10
|
+
- [ ] File created at correct location (based on placement from pre-questions Q3)
|
|
11
|
+
- [ ] Class has proper JSDoc with `@public` tag
|
|
12
|
+
- [ ] Methods have JSDoc with `@param`, `@returns`, `@example`
|
|
13
|
+
- [ ] Uses `LoggerProxy` for all logging (no `console.log`)
|
|
14
|
+
- [ ] Error handling uses `getErrorDetails` pattern (logs and re-throws)
|
|
15
|
+
- [ ] Module name constant defined (`SERVICE_FILE`)
|
|
16
|
+
- [ ] Method name constants defined (`METHODS`)
|
|
17
|
+
|
|
18
|
+
### Types & Constants
|
|
19
|
+
- [ ] Types placed in the correct location:
|
|
20
|
+
- Folder-based service: service folder's `types.ts`
|
|
21
|
+
- Single-file service: root `src/types.ts`
|
|
22
|
+
- Sub-module: parent service's `types.ts`
|
|
23
|
+
- [ ] Constants: no duplicates — every constant was searched across the hierarchy before adding:
|
|
24
|
+
- `src/constants.ts` (SDK-wide: file names, method names, global settings)
|
|
25
|
+
- `src/services/constants.ts` (shared: API gateways, auth, network)
|
|
26
|
+
- `src/metrics/constants.ts` (all metric event names)
|
|
27
|
+
- `src/services/config/constants.ts` (endpoint maps, pagination, agent states)
|
|
28
|
+
- `src/services/{ServiceName}/constants.ts` (service-specific only)
|
|
29
|
+
- [ ] Constants placed at the correct level (not duplicated at a lower level when shared exists)
|
|
30
|
+
- [ ] New `constants.ts` file created ONLY if service is folder-based AND no existing file AND constants are service-specific
|
|
31
|
+
- [ ] All public types have JSDoc
|
|
32
|
+
- [ ] Response types match actual API response
|
|
33
|
+
- [ ] Parameter types define all optional/required fields
|
|
34
|
+
|
|
35
|
+
### Metrics
|
|
36
|
+
- [ ] `metricsManager.timeEvent` called at method entry with success + failure event names
|
|
37
|
+
- [ ] `metricsManager.trackEvent` called on success path
|
|
38
|
+
- [ ] `metricsManager.trackEvent` called on failure path (in catch block)
|
|
39
|
+
- [ ] Metric event names added to `src/metrics/constants.ts` (`METRIC_EVENT_NAMES`)
|
|
40
|
+
|
|
41
|
+
### Integration
|
|
42
|
+
- [ ] Service initialized at the correct integration point:
|
|
43
|
+
- Folder-based / single-file: in `cc.ts` or `Services` singleton (depends on AQM vs non-AQM)
|
|
44
|
+
- Sub-module: instantiated by parent service
|
|
45
|
+
- [ ] Types re-exported from `src/types.ts` (if public)
|
|
46
|
+
|
|
47
|
+
### Tests
|
|
48
|
+
- [ ] Test file created mirroring source path under `test/unit/spec/`
|
|
49
|
+
- [ ] LoggerProxy mocked
|
|
50
|
+
- [ ] Success cases tested
|
|
51
|
+
- [ ] Error cases tested
|
|
52
|
+
- [ ] Metrics tracking verified (timeEvent and trackEvent calls asserted)
|
|
53
|
+
- [ ] Tests pass: `yarn workspace @webex/contact-center test:unit`
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Pattern Compliance
|
|
58
|
+
|
|
59
|
+
### LoggerProxy Usage
|
|
60
|
+
```typescript
|
|
61
|
+
// ✅ Correct
|
|
62
|
+
LoggerProxy.info('Starting operation', {
|
|
63
|
+
module: SERVICE_FILE,
|
|
64
|
+
method: METHODS.GET_ITEMS,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// ❌ Wrong
|
|
68
|
+
console.log('Starting operation');
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Error Handling
|
|
72
|
+
```typescript
|
|
73
|
+
// ✅ Correct
|
|
74
|
+
catch (error) {
|
|
75
|
+
LoggerProxy.error(`Failed: ${error}`, {
|
|
76
|
+
module: SERVICE_FILE,
|
|
77
|
+
method: METHODS.GET_ITEMS,
|
|
78
|
+
error,
|
|
79
|
+
});
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ❌ Wrong - swallowing error
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error(error);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Type Exports
|
|
90
|
+
```typescript
|
|
91
|
+
// ✅ Correct - in src/types.ts
|
|
92
|
+
export type {
|
|
93
|
+
ServiceItem,
|
|
94
|
+
ServiceSearchParams,
|
|
95
|
+
ServiceListResponse,
|
|
96
|
+
} from './services/ServiceName';
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Build & Test Verification
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Lint
|
|
105
|
+
yarn workspace @webex/contact-center test:styles
|
|
106
|
+
|
|
107
|
+
# Test unit tests
|
|
108
|
+
yarn workspace @webex/contact-center test:unit
|
|
109
|
+
|
|
110
|
+
# Build
|
|
111
|
+
yarn workspace @webex/contact-center build:src
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
All should pass without errors.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Documentation
|
|
119
|
+
|
|
120
|
+
### Update Root AGENTS.md?
|
|
121
|
+
If this is a significant new service, update the root [`AGENTS.md`](../../../AGENTS.md):
|
|
122
|
+
- [ ] Added new service to the [Service Routing Table](../../../AGENTS.md#service-routing-table)
|
|
123
|
+
- [ ] Added to repository structure tree
|
|
124
|
+
- [ ] Added usage example if applicable
|
|
125
|
+
|
|
126
|
+
### Create Service ai-docs?
|
|
127
|
+
For complex services, create service-level documentation (use [`create-agents-md.md`](../documentation/create-agents-md.md) and [`create-architecture-md.md`](../documentation/create-architecture-md.md) templates):
|
|
128
|
+
- [ ] `src/services/ServiceName/ai-docs/AGENTS.md` — usage guide, API reference
|
|
129
|
+
- [ ] `src/services/ServiceName/ai-docs/ARCHITECTURE.md` — technical deep-dive, data flow
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Final Review
|
|
134
|
+
|
|
135
|
+
Ask yourself:
|
|
136
|
+
1. Can another developer understand this service by reading the JSDoc?
|
|
137
|
+
2. Are all error paths properly handled and logged?
|
|
138
|
+
3. Do tests cover the main use cases?
|
|
139
|
+
4. Is the API surface clean and consistent with other services?
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Complete!
|
|
144
|
+
|
|
145
|
+
Service creation is complete when all checkboxes are checked.
|