@webex/contact-center 3.12.0-next.8 → 3.12.0-task-refactor.1
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 +556 -532
- 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 +366 -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 +256 -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 +369 -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 +567 -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 +409 -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 +295 -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 +529 -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
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
# Feature Enhancement Template
|
|
2
|
+
|
|
3
|
+
> **Purpose**: Workflow for adding new features to existing services.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Step 0: Feature Placement Triage (MANDATORY)
|
|
8
|
+
|
|
9
|
+
**STOP. Before any implementation, present these triage questions to the developer and wait for answers.**
|
|
10
|
+
|
|
11
|
+
> **Note:** If you arrived here via **Type F (Modify Existing Method)** from the root [`AGENTS.md`](../../../AGENTS.md), skip this Step 0 entirely — the method already exists in an existing service. Jump to Step 0B (Pre-Enhancement Questions).
|
|
12
|
+
|
|
13
|
+
### Triage Questions — Always Ask These (All Mandatory)
|
|
14
|
+
|
|
15
|
+
> **All 6 questions must be answered before proceeding.** If the developer is unsure about a question, help them reason through it using the decision signals below. Do not skip questions or infer answers — each one informs the placement decision.
|
|
16
|
+
|
|
17
|
+
1. **"Does this feature fit within the responsibility of an existing service, or does it introduce a new domain/responsibility?"**
|
|
18
|
+
|
|
19
|
+
2. **"Do you expect this feature to grow into multiple related methods in future iterations?"**
|
|
20
|
+
|
|
21
|
+
3. **"Should this feature have independent ownership (its own state, events, dependencies) separate from current services?"**
|
|
22
|
+
|
|
23
|
+
4. **"Is there an existing service you want to add this to? Or should it be a new standalone service/module?"**
|
|
24
|
+
|
|
25
|
+
5. **"Are there backward compatibility constraints if we add this to an existing service?"**
|
|
26
|
+
|
|
27
|
+
6. **"If this becomes a new service, do you have a preferred name for it?"**
|
|
28
|
+
|
|
29
|
+
### Triage Decision Guide
|
|
30
|
+
|
|
31
|
+
After the developer answers, use these signals to decide placement:
|
|
32
|
+
|
|
33
|
+
**Existing service** when:
|
|
34
|
+
- Feature naturally extends current service responsibility
|
|
35
|
+
- Only 1-2 methods are needed in the same domain
|
|
36
|
+
- Existing service already owns required events/state/API integration
|
|
37
|
+
- Developer explicitly says "add it to [service]"
|
|
38
|
+
|
|
39
|
+
**New service** when:
|
|
40
|
+
- Feature introduces a distinct domain boundary/responsibility
|
|
41
|
+
- It needs its own lifecycle/dependencies/state orchestration
|
|
42
|
+
- It is expected to grow into multiple related methods/classes
|
|
43
|
+
- Adding it to an existing service would create low cohesion or cross-domain coupling
|
|
44
|
+
- Developer explicitly wants a standalone module
|
|
45
|
+
|
|
46
|
+
### Routing Rule
|
|
47
|
+
|
|
48
|
+
- If triage => **existing service**: continue with this template (Step 0B below).
|
|
49
|
+
- If triage => **new service**: switch to [`../new-service/00-master.md`](../new-service/00-master.md).
|
|
50
|
+
- If still unclear after developer answers: ask one more clarifying question rather than guessing.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Step 0B: Pre-Enhancement Questions (MANDATORY)
|
|
55
|
+
|
|
56
|
+
**Present these questions to the developer and wait for answers.** Do not start designing or implementing until all MANDATORY fields have explicit answers.
|
|
57
|
+
|
|
58
|
+
### 1. Feature Definition (MANDATORY)
|
|
59
|
+
|
|
60
|
+
7. **"What is this feature called? (Brief name)"**
|
|
61
|
+
|
|
62
|
+
8. **"What does this feature do? Describe the expected behavior."**
|
|
63
|
+
|
|
64
|
+
9. **"When would a developer use this feature? What is the use case?"**
|
|
65
|
+
|
|
66
|
+
### 2. Scope and Placement (MANDATORY)
|
|
67
|
+
|
|
68
|
+
10. **"Which existing files will be affected?"**
|
|
69
|
+
- [ ] `cc.ts` (main plugin)
|
|
70
|
+
- [ ] `services/[name]/index.ts`
|
|
71
|
+
- [ ] `types.ts`
|
|
72
|
+
- [ ] Other: ___
|
|
73
|
+
|
|
74
|
+
11. **"Will this introduce any breaking changes to existing APIs?"**
|
|
75
|
+
- If yes: "What is the migration path?"
|
|
76
|
+
|
|
77
|
+
### 3. API Contract (MANDATORY)
|
|
78
|
+
|
|
79
|
+
For each new or updated API call, ask:
|
|
80
|
+
|
|
81
|
+
12. **"What API endpoint does this feature call? Provide:"**
|
|
82
|
+
|
|
83
|
+
| Field | What to Ask |
|
|
84
|
+
|---|---|
|
|
85
|
+
| HTTP Method | "Is this a GET, POST, PUT, PATCH, or DELETE?" |
|
|
86
|
+
| Endpoint | "What is the full resource path?" |
|
|
87
|
+
| Request Payload | "What fields does the request contain? Which are required vs optional?" |
|
|
88
|
+
| Response Structure | "What does the response look like? (`data`, `trackingId`, metadata)" |
|
|
89
|
+
| Error Shape | "What error reason codes can this return?" |
|
|
90
|
+
|
|
91
|
+
**If any field is unknown, STOP and ask the developer. Do not guess.**
|
|
92
|
+
|
|
93
|
+
### 4. Event Contract (MANDATORY if the feature uses events, otherwise skip)
|
|
94
|
+
|
|
95
|
+
13. **"Does this feature emit or listen to any events?"**
|
|
96
|
+
- If YES, for each event ask:
|
|
97
|
+
|
|
98
|
+
| Field | What to Ask |
|
|
99
|
+
|---|---|
|
|
100
|
+
| Event Name | "What is the event name?" |
|
|
101
|
+
| Direction | "Is this incoming (WebSocket) or outgoing (emitted by SDK)?" |
|
|
102
|
+
| Emitted/Received On | "On which object is this event emitted or received?" (`cc`, `task`, `taskManager`, or a service instance) |
|
|
103
|
+
| Payload Type/Shape | "What data does the event carry?" |
|
|
104
|
+
| Emitted From | "Which class/file emits this event?" |
|
|
105
|
+
| Emission Trigger | "What causes this event to fire?" |
|
|
106
|
+
|
|
107
|
+
- If NO: note "No events"
|
|
108
|
+
|
|
109
|
+
### 5. Dependencies (MANDATORY)
|
|
110
|
+
|
|
111
|
+
14. **"Does this feature require new API endpoints that don't exist yet?"**
|
|
112
|
+
|
|
113
|
+
15. **"Does this feature require new types?"**
|
|
114
|
+
- If yes: "What should the type names be?"
|
|
115
|
+
|
|
116
|
+
### Completion Gate
|
|
117
|
+
|
|
118
|
+
**Before proceeding, verify:**
|
|
119
|
+
|
|
120
|
+
- [ ] Feature name and description provided by developer
|
|
121
|
+
- [ ] Use case described
|
|
122
|
+
- [ ] Placement decision confirmed (existing service or new service)
|
|
123
|
+
- [ ] Affected files identified
|
|
124
|
+
- [ ] Breaking changes assessed
|
|
125
|
+
- [ ] API contract fully specified (or developer confirmed no new API calls)
|
|
126
|
+
- [ ] Event contract captured (or developer confirmed no events)
|
|
127
|
+
- [ ] Dependencies identified
|
|
128
|
+
|
|
129
|
+
**If any MANDATORY field is missing, ask a follow-up question. Do not proceed.**
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Spec Summary (MANDATORY — present before implementation)
|
|
134
|
+
|
|
135
|
+
Once all questions are answered, present this summary to the developer:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
## Spec Summary — Feature Enhancement
|
|
139
|
+
|
|
140
|
+
**Feature**: [name]
|
|
141
|
+
**Description**: [what it does]
|
|
142
|
+
**Use case**: [when a developer would use this]
|
|
143
|
+
**Placement**: [existing service name] (or rerouted to new service)
|
|
144
|
+
**Breaking changes**: [Yes/No — details if yes]
|
|
145
|
+
|
|
146
|
+
### Affected Files:
|
|
147
|
+
1. [file path] — [what changes]
|
|
148
|
+
2. [file path] — [what changes]
|
|
149
|
+
|
|
150
|
+
### API Contract:
|
|
151
|
+
| Method | HTTP | Endpoint | Request | Response |
|
|
152
|
+
|---|---|---|---|---|
|
|
153
|
+
| [method] | [verb] | [path] | [payload] | [response] |
|
|
154
|
+
(or "No new API calls")
|
|
155
|
+
|
|
156
|
+
### Events:
|
|
157
|
+
| Event | Direction | Object | Payload | Trigger |
|
|
158
|
+
|---|---|---|---|---|
|
|
159
|
+
| [event] | [in/out] | [object] | [payload] | [trigger] |
|
|
160
|
+
(or "No events")
|
|
161
|
+
|
|
162
|
+
### New Types: [list or "None"]
|
|
163
|
+
### New Constants: [list or "None"]
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
Does this match your intent? (Yes / No / Adjust)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Wait for developer approval. Do not proceed to implementation until confirmed.**
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Step 1: Design the Feature
|
|
174
|
+
|
|
175
|
+
Define the public API contract and data flow before writing any implementation code.
|
|
176
|
+
|
|
177
|
+
### API Design
|
|
178
|
+
|
|
179
|
+
Define the public interface:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
/**
|
|
183
|
+
* What the feature does
|
|
184
|
+
* @param params - Description
|
|
185
|
+
* @returns Description
|
|
186
|
+
*/
|
|
187
|
+
async featureName(params: FeatureParams): Promise<FeatureResponse>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Data Flow
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
User calls cc.featureName(params)
|
|
194
|
+
|
|
|
195
|
+
v
|
|
196
|
+
Validate input
|
|
197
|
+
|
|
|
198
|
+
v
|
|
199
|
+
Call service/API
|
|
200
|
+
|
|
|
201
|
+
v
|
|
202
|
+
Process response
|
|
203
|
+
|
|
|
204
|
+
v
|
|
205
|
+
Return/emit result
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Step 2: Update Types
|
|
211
|
+
|
|
212
|
+
### Add New Types
|
|
213
|
+
|
|
214
|
+
In appropriate types file:
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
/**
|
|
218
|
+
* Parameters for feature operation
|
|
219
|
+
* @public
|
|
220
|
+
*/
|
|
221
|
+
export type FeatureParams = {
|
|
222
|
+
/** Description */
|
|
223
|
+
field: string;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Response from feature operation
|
|
228
|
+
* @public
|
|
229
|
+
*/
|
|
230
|
+
export type FeatureResponse = {
|
|
231
|
+
/** Description */
|
|
232
|
+
data: FeatureData;
|
|
233
|
+
};
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Export Types
|
|
237
|
+
|
|
238
|
+
In `src/types.ts`:
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
export type {FeatureParams, FeatureResponse} from './services/[location]';
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Step 3: Implement Feature
|
|
247
|
+
|
|
248
|
+
### Service Layer (if needed)
|
|
249
|
+
|
|
250
|
+
Add method to existing service:
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
// In services/[name]/index.ts
|
|
254
|
+
featureMethod: routing.req((p: {data: FeatureParams}) => ({
|
|
255
|
+
url: '/v1/feature',
|
|
256
|
+
host: WCC_API_GATEWAY,
|
|
257
|
+
data: p.data,
|
|
258
|
+
err: createErrDetailsObject,
|
|
259
|
+
method: HTTP_METHODS.POST,
|
|
260
|
+
notifSuccess: {
|
|
261
|
+
bind: {type: CC_EVENTS.FEATURE_SUCCESS, data: {type: CC_EVENTS.FEATURE_SUCCESS}},
|
|
262
|
+
msg: {} as FeatureResponse,
|
|
263
|
+
},
|
|
264
|
+
notifFail: {
|
|
265
|
+
bind: {type: CC_EVENTS.FEATURE_FAILED, data: {type: CC_EVENTS.FEATURE_FAILED}},
|
|
266
|
+
errId: 'Service.aqm.feature.failed',
|
|
267
|
+
},
|
|
268
|
+
})),
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Public API Layer — if the feature is exposed to consumers
|
|
272
|
+
|
|
273
|
+
> **Determine the owning object.** Public methods are added to the object that owns the feature's scope. Currently the SDK exposes:
|
|
274
|
+
> - **`cc`** (in `cc.ts`) — SDK-level operations (e.g., `cc.stationLogin()`, `cc.setAgentState()`)
|
|
275
|
+
> - **`task`** (in `Task.ts`) — per-interaction operations (e.g., `task.hold()`, `task.transfer()`, `task.end()`)
|
|
276
|
+
>
|
|
277
|
+
> New public objects may be introduced in the future. If the feature is internal to a service or only consumed by other services, skip this step entirely.
|
|
278
|
+
|
|
279
|
+
Add public method:
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
/**
|
|
283
|
+
* Feature description.
|
|
284
|
+
*
|
|
285
|
+
* @param {FeatureParams} params - Parameters
|
|
286
|
+
* @returns {Promise<FeatureResponse>} Result
|
|
287
|
+
* @throws {Error} If operation fails
|
|
288
|
+
*
|
|
289
|
+
* @public
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
* ```typescript
|
|
293
|
+
* const result = await cc.featureName({
|
|
294
|
+
* field: 'value',
|
|
295
|
+
* });
|
|
296
|
+
* ```
|
|
297
|
+
*/
|
|
298
|
+
public async featureName(params: FeatureParams): Promise<FeatureResponse> {
|
|
299
|
+
LoggerProxy.info('Starting feature operation', {
|
|
300
|
+
module: CC_FILE,
|
|
301
|
+
method: METHODS.FEATURE_NAME,
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
this.metricsManager.timeEvent([
|
|
306
|
+
METRIC_EVENT_NAMES.FEATURE_SUCCESS,
|
|
307
|
+
METRIC_EVENT_NAMES.FEATURE_FAILED,
|
|
308
|
+
]);
|
|
309
|
+
|
|
310
|
+
const result = await this.services.someService.featureMethod({
|
|
311
|
+
data: params,
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
this.metricsManager.trackEvent(
|
|
315
|
+
METRIC_EVENT_NAMES.FEATURE_SUCCESS,
|
|
316
|
+
{...MetricsManager.getCommonTrackingFieldForAQMResponse(result)},
|
|
317
|
+
['behavioral', 'operational']
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
LoggerProxy.log('Feature operation completed successfully', {
|
|
321
|
+
module: CC_FILE,
|
|
322
|
+
method: METHODS.FEATURE_NAME,
|
|
323
|
+
trackingId: result.trackingId,
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
return result;
|
|
327
|
+
} catch (error) {
|
|
328
|
+
const failure = error.details as Failure;
|
|
329
|
+
this.metricsManager.trackEvent(
|
|
330
|
+
METRIC_EVENT_NAMES.FEATURE_FAILED,
|
|
331
|
+
{...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(failure)},
|
|
332
|
+
['behavioral', 'operational']
|
|
333
|
+
);
|
|
334
|
+
const {error: detailedError} = getErrorDetails(error, METHODS.FEATURE_NAME, CC_FILE);
|
|
335
|
+
throw detailedError;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## Step 4: Add Constants
|
|
343
|
+
|
|
344
|
+
### Method Constants
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
// src/constants.ts
|
|
348
|
+
export const METHODS = {
|
|
349
|
+
// ... existing
|
|
350
|
+
FEATURE_NAME: 'featureName',
|
|
351
|
+
} as const;
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### Metric Constants
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
// src/metrics/constants.ts
|
|
358
|
+
export const METRIC_EVENT_NAMES = {
|
|
359
|
+
// ... existing
|
|
360
|
+
FEATURE_SUCCESS: 'feature success',
|
|
361
|
+
FEATURE_FAILED: 'feature failed',
|
|
362
|
+
} as const;
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Event Constants (if needed)
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
// services/config/types.ts
|
|
369
|
+
export const CC_FEATURE_EVENTS = {
|
|
370
|
+
FEATURE_SUCCESS: 'FeatureSuccess',
|
|
371
|
+
FEATURE_FAILED: 'FeatureFailed',
|
|
372
|
+
} as const;
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Step 5: Update Tests
|
|
378
|
+
|
|
379
|
+
### Add Feature Tests
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
describe('cc.featureName', () => {
|
|
383
|
+
const mockParams = {
|
|
384
|
+
field: 'value',
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
const mockResponse = {
|
|
388
|
+
data: { /* ... */ },
|
|
389
|
+
trackingId: 'track-123',
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
it('should complete feature operation successfully', async () => {
|
|
393
|
+
mockServicesInstance.someService.featureMethod.mockResolvedValue(mockResponse);
|
|
394
|
+
|
|
395
|
+
const result = await webex.cc.featureName(mockParams);
|
|
396
|
+
|
|
397
|
+
expect(result).toEqual(mockResponse);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
it('should handle errors correctly', async () => {
|
|
401
|
+
mockServicesInstance.someService.featureMethod.mockRejectedValue(mockError);
|
|
402
|
+
|
|
403
|
+
await expect(webex.cc.featureName(mockParams)).rejects.toThrow();
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## Step 6: Update Documentation
|
|
411
|
+
|
|
412
|
+
### Update Service-Level Docs
|
|
413
|
+
|
|
414
|
+
If the affected service has ai-docs, update them (find the right file via the root [`AGENTS.md` Service Routing Table](../../../AGENTS.md#service-routing-table)):
|
|
415
|
+
- Service `AGENTS.md` — add new method to API reference, add usage example
|
|
416
|
+
- Service `ARCHITECTURE.md` — update data flow if architecture changed
|
|
417
|
+
|
|
418
|
+
### Update Root AGENTS.md
|
|
419
|
+
|
|
420
|
+
If feature is significant, update the root [`AGENTS.md`](../../../AGENTS.md):
|
|
421
|
+
- Add to relevant section
|
|
422
|
+
- Update examples if needed
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## Validation Checklist
|
|
427
|
+
|
|
428
|
+
- [ ] Types defined with JSDoc
|
|
429
|
+
- [ ] Types exported from `src/types.ts`
|
|
430
|
+
- [ ] Method implemented following patterns
|
|
431
|
+
- [ ] LoggerProxy used throughout
|
|
432
|
+
- [ ] MetricsManager tracking added
|
|
433
|
+
- [ ] Error handling follows pattern
|
|
434
|
+
- [ ] Constants added (methods, metrics, events)
|
|
435
|
+
- [ ] Unit tests added
|
|
436
|
+
- [ ] All tests pass
|
|
437
|
+
- [ ] Build succeeds
|
|
438
|
+
- [ ] Documentation updated
|
|
439
|
+
|
|
440
|
+
```bash
|
|
441
|
+
yarn workspace @webex/contact-center test:style
|
|
442
|
+
yarn workspace @webex/contact-center test:unit
|
|
443
|
+
yarn workspace @webex/contact-center build:src
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## Complete!
|
|
449
|
+
|
|
450
|
+
Feature enhancement is complete when all checkboxes are checked.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# New Method - Master Template
|
|
2
|
+
|
|
3
|
+
> **Purpose**: Orchestrator for adding new methods or features to existing services and utils.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Use Case
|
|
8
|
+
|
|
9
|
+
Use this template when:
|
|
10
|
+
- Adding a new method or feature to an existing service or util
|
|
11
|
+
- Adding a new public API method to any public object (`cc` for SDK-level operations, `task` for per-interaction operations, or future public objects)
|
|
12
|
+
- Extending service capabilities
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Workflow Overview
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Step 1: Requirements → Step 2: Implementation → Step 3: Tests → Step 4: Validation
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Step-by-Step Process
|
|
25
|
+
|
|
26
|
+
### Step 1: Gather Requirements
|
|
27
|
+
**Template**: [`01-requirements.md`](01-requirements.md)
|
|
28
|
+
|
|
29
|
+
Define:
|
|
30
|
+
- Method signature (name, parameters, return type)
|
|
31
|
+
- API endpoint (if calling backend)
|
|
32
|
+
- Events to emit (if any)
|
|
33
|
+
- Success/error scenarios
|
|
34
|
+
|
|
35
|
+
### Step 2: Implementation
|
|
36
|
+
**Template**: [`02-implementation.md`](02-implementation.md)
|
|
37
|
+
|
|
38
|
+
Implement:
|
|
39
|
+
- Method with LoggerProxy logging
|
|
40
|
+
- MetricsManager tracking
|
|
41
|
+
- Error handling pattern
|
|
42
|
+
- JSDoc documentation
|
|
43
|
+
|
|
44
|
+
### Step 3: Tests
|
|
45
|
+
**Template**: [`03-tests.md`](03-tests.md)
|
|
46
|
+
|
|
47
|
+
Create:
|
|
48
|
+
- Success test case
|
|
49
|
+
- Error test case
|
|
50
|
+
- Edge case tests
|
|
51
|
+
|
|
52
|
+
### Step 4: Validation
|
|
53
|
+
**Template**: [`04-validation.md`](04-validation.md)
|
|
54
|
+
|
|
55
|
+
Verify:
|
|
56
|
+
- Patterns followed
|
|
57
|
+
- Tests pass
|
|
58
|
+
- Types exported
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Patterns to Load
|
|
63
|
+
|
|
64
|
+
Before implementing, read:
|
|
65
|
+
1. [`../../patterns/typescript-patterns.md`](../../patterns/typescript-patterns.md) — Types, interfaces, constants
|
|
66
|
+
2. [`../../patterns/event-driven-patterns.md`](../../patterns/event-driven-patterns.md) — Event emission and handling
|
|
67
|
+
3. [`../../patterns/testing-patterns.md`](../../patterns/testing-patterns.md) — Unit test conventions
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Quick Checklist
|
|
72
|
+
|
|
73
|
+
- [ ] Method added with proper signature
|
|
74
|
+
- [ ] LoggerProxy used for logging
|
|
75
|
+
- [ ] MetricsManager tracks success/failure
|
|
76
|
+
- [ ] Error handling follows pattern
|
|
77
|
+
- [ ] JSDoc added with `@public`
|
|
78
|
+
- [ ] Types defined and exported
|
|
79
|
+
- [ ] Unit tests added
|
|
80
|
+
- [ ] All tests pass
|