@webex/contact-center 3.12.0-llmrefactor.2 → 3.12.0-llmrefactor.4
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/.sdd/manifest.json +5 -4
- package/ai-docs/ARCHITECTURE.md +1 -1
- package/ai-docs/CONTRACTS.md +6 -2
- package/ai-docs/SECURITY.md +1 -1
- package/ai-docs/contact-center-spec.md +22 -4
- package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -0
- package/dist/cc.js +440 -10
- package/dist/cc.js.map +1 -1
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +10 -2
- package/dist/constants.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics/behavioral-events.js +13 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +2 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/AddressBook.js +18 -15
- package/dist/services/AddressBook.js.map +1 -1
- package/dist/services/AnswerCallOnWebexService.js +174 -0
- package/dist/services/AnswerCallOnWebexService.js.map +1 -0
- package/dist/services/EntryPoint.js +46 -68
- package/dist/services/EntryPoint.js.map +1 -1
- package/dist/services/Queue.js +27 -22
- package/dist/services/Queue.js.map +1 -1
- package/dist/services/WebexCrossClientService.js +171 -0
- package/dist/services/WebexCrossClientService.js.map +1 -0
- package/dist/services/WxAppTelephonyMercurySync.js +93 -0
- package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
- package/dist/services/config/Util.js +3 -0
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +10 -6
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/types.js +4 -0
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/WebexRequest.js +6 -2
- package/dist/services/core/WebexRequest.js.map +1 -1
- package/dist/services/core/aqm-reqs.js +28 -14
- package/dist/services/core/aqm-reqs.js.map +1 -1
- package/dist/services/core/types.js.map +1 -1
- package/dist/services/task/Task.js +73 -7
- package/dist/services/task/Task.js.map +1 -1
- package/dist/services/task/TaskFactory.js +8 -4
- package/dist/services/task/TaskFactory.js.map +1 -1
- package/dist/services/task/TaskManager.js +353 -21
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/WebexCallingUtils.js +70 -0
- package/dist/services/task/WebexCallingUtils.js.map +1 -0
- package/dist/services/task/constants.js +4 -1
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/contact.js +29 -0
- package/dist/services/task/contact.js.map +1 -1
- package/dist/services/task/digital/Digital.js +3 -2
- package/dist/services/task/digital/Digital.js.map +1 -1
- package/dist/services/task/state-machine/TaskStateMachine.js +135 -37
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -1
- package/dist/services/task/state-machine/actions.js +6 -1
- package/dist/services/task/state-machine/actions.js.map +1 -1
- package/dist/services/task/state-machine/guards.js +38 -11
- package/dist/services/task/state-machine/guards.js.map +1 -1
- package/dist/services/task/state-machine/types.js.map +1 -1
- package/dist/services/task/state-machine/uiControlsComputer.js +118 -18
- package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -1
- package/dist/services/task/types.js +16 -1
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +350 -14
- package/dist/services/task/voice/Voice.js.map +1 -1
- package/dist/services/task/voice/WebRTC.js +4 -1
- package/dist/services/task/voice/WebRTC.js.map +1 -1
- package/dist/services/task/voice/wxAppVoiceMethods.js +201 -0
- package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
- package/dist/services/wxAppTelephonyUtils.js +19 -0
- package/dist/services/wxAppTelephonyUtils.js.map +1 -0
- package/dist/types/cc.d.ts +77 -4
- package/dist/types/config.d.ts +7 -0
- package/dist/types/constants.d.ts +8 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/metrics/constants.d.ts +2 -0
- package/dist/types/services/AddressBook.d.ts +2 -1
- package/dist/types/services/AnswerCallOnWebexService.d.ts +37 -0
- package/dist/types/services/EntryPoint.d.ts +7 -5
- package/dist/types/services/Queue.d.ts +5 -3
- package/dist/types/services/WebexCrossClientService.d.ts +28 -0
- package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
- package/dist/types/services/config/constants.d.ts +8 -5
- package/dist/types/services/config/types.d.ts +17 -4
- package/dist/types/services/core/Err.d.ts +2 -0
- package/dist/types/services/core/WebexRequest.d.ts +1 -0
- package/dist/types/services/core/types.d.ts +2 -0
- package/dist/types/services/task/Task.d.ts +20 -2
- package/dist/types/services/task/TaskFactory.d.ts +2 -1
- package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
- package/dist/types/services/task/constants.d.ts +3 -0
- package/dist/types/services/task/contact.d.ts +4 -0
- package/dist/types/services/task/digital/Digital.d.ts +2 -2
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +260 -56
- package/dist/types/services/task/state-machine/guards.d.ts +6 -5
- package/dist/types/services/task/state-machine/types.d.ts +9 -1
- package/dist/types/services/task/types.d.ts +81 -4
- package/dist/types/services/task/voice/Voice.d.ts +48 -9
- package/dist/types/services/task/voice/WebRTC.d.ts +2 -2
- package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +52 -0
- package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
- package/dist/types/types.d.ts +14 -8
- package/dist/types/utils/PageCache.d.ts +20 -3
- package/dist/types.js +7 -2
- package/dist/types.js.map +1 -1
- package/dist/utils/PageCache.js +19 -5
- package/dist/utils/PageCache.js.map +1 -1
- package/dist/webex.js +1 -1
- package/package.json +9 -9
- package/src/cc.ts +506 -9
- package/src/config.ts +7 -0
- package/src/constants.ts +8 -0
- package/src/index.ts +2 -0
- package/src/metrics/ai-docs/metrics-spec.md +9 -3
- package/src/metrics/behavioral-events.ts +14 -0
- package/src/metrics/constants.ts +2 -0
- package/src/services/AddressBook.ts +17 -6
- package/src/services/AnswerCallOnWebexService.ts +206 -0
- package/src/services/EntryPoint.ts +59 -60
- package/src/services/Queue.ts +29 -12
- package/src/services/WebexCrossClientService.ts +212 -0
- package/src/services/WxAppTelephonyMercurySync.ts +115 -0
- package/src/services/ai-docs/AGENTS.md +10 -10
- package/src/services/ai-docs/services-spec.md +6 -1
- package/src/services/config/Util.ts +3 -0
- package/src/services/config/ai-docs/AGENTS.md +1 -1
- package/src/services/config/ai-docs/ARCHITECTURE.md +2 -2
- package/src/services/config/ai-docs/config-spec.md +6 -0
- package/src/services/config/constants.ts +10 -6
- package/src/services/config/types.ts +16 -4
- package/src/services/core/Err.ts +1 -0
- package/src/services/core/WebexRequest.ts +3 -1
- package/src/services/core/ai-docs/core-spec.md +5 -1
- package/src/services/core/aqm-reqs.ts +30 -15
- package/src/services/core/types.ts +2 -0
- package/src/services/task/Task.ts +79 -8
- package/src/services/task/TaskFactory.ts +8 -3
- package/src/services/task/TaskManager.ts +522 -16
- package/src/services/task/WebexCallingUtils.ts +136 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +1 -0
- package/src/services/task/ai-docs/task-spec.md +152 -2
- package/src/services/task/constants.ts +3 -0
- package/src/services/task/contact.ts +30 -0
- package/src/services/task/digital/Digital.ts +4 -2
- package/src/services/task/state-machine/TaskStateMachine.ts +210 -63
- package/src/services/task/state-machine/actions.ts +5 -2
- package/src/services/task/state-machine/ai-docs/AGENTS.md +8 -4
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +17 -8
- package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +56 -24
- package/src/services/task/state-machine/guards.ts +64 -11
- package/src/services/task/state-machine/types.ts +16 -1
- package/src/services/task/state-machine/uiControlsComputer.ts +206 -32
- package/src/services/task/types.ts +114 -4
- package/src/services/task/voice/Voice.ts +462 -12
- package/src/services/task/voice/WebRTC.ts +5 -1
- package/src/services/task/voice/wxAppVoiceMethods.ts +307 -0
- package/src/services/wxAppTelephonyUtils.ts +14 -0
- package/src/types.ts +33 -9
- package/src/utils/AGENTS.md +21 -10
- package/src/utils/PageCache.ts +38 -5
- package/src/utils/ai-docs/utils-spec.md +21 -11
- package/test/unit/spec/cc.ts +1274 -0
- package/test/unit/spec/metrics/behavioral-events.ts +18 -0
- package/test/unit/spec/services/AddressBook.ts +37 -6
- package/test/unit/spec/services/AnswerCallOnWebexService.ts +223 -0
- package/test/unit/spec/services/EntryPoint.ts +87 -40
- package/test/unit/spec/services/Queue.ts +123 -12
- package/test/unit/spec/services/WebexCrossClientService.ts +261 -0
- package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +113 -0
- package/test/unit/spec/services/config/Util.ts +85 -0
- package/test/unit/spec/services/core/WebexRequest.ts +3 -1
- package/test/unit/spec/services/core/aqm-reqs.ts +113 -1
- package/test/unit/spec/services/task/Task.ts +200 -0
- package/test/unit/spec/services/task/TaskFactory.ts +39 -2
- package/test/unit/spec/services/task/TaskManager.ts +1294 -1
- package/test/unit/spec/services/task/WebexCallingUtils.ts +153 -0
- package/test/unit/spec/services/task/contact.ts +33 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +854 -72
- package/test/unit/spec/services/task/state-machine/guards.ts +210 -8
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +445 -7
- package/test/unit/spec/services/task/voice/Voice.ts +874 -0
- package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +459 -0
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
package/.sdd/manifest.json
CHANGED
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
"canonical_spec": "ai-docs/contact-center-spec.md",
|
|
52
52
|
"contracts": {
|
|
53
53
|
"provides": [
|
|
54
|
-
"Published @webex/contact-center package; ContactCenter WebexPlugin; public SDK methods, events, types, Task, AddressBook, ApiAIAssistant, UserPreference, cc.userPreference, exported user-preference request/response types, and preview-campaign methods acceptPreviewContact/skipPreviewContact/removePreviewContact"
|
|
54
|
+
"Published @webex/contact-center package; ContactCenter WebexPlugin; public SDK methods, events, types, Task with ordered action-specific consult/transfer destination controls, AddressBook, ApiAIAssistant, UserPreference, cc.userPreference, existing getQueues/getEntryPoints methods with consult/transfer defaults, full Queue records, and mapped EntryPoint records with optional numbers, exported user-preference request/response types, and preview-campaign methods acceptPreviewContact/skipPreviewContact/removePreviewContact",
|
|
55
|
+
"WXCC-6026 wxApp Better Together: enableWxBetterTogether init config, isWxBetterTogetherEnabled read API, unified task telephony (task.accept/decline/toggleMute/transmitDtmf), TASK_WXAPP_MUTE_STATE_UPDATED event, optional main.keypad uiControl, multi-login supported; runtime toggle deferred to Phase 2 (private)"
|
|
55
56
|
],
|
|
56
57
|
"requires": [
|
|
57
58
|
"Webex SDK host/plugin runtime; Contact Center REST and WebSocket services; internal Webex calling, metrics, support, authorization, logger, and mercury packages"
|
|
@@ -137,7 +138,7 @@
|
|
|
137
138
|
"canonical_spec": "src/services/ai-docs/services-spec.md",
|
|
138
139
|
"contracts": {
|
|
139
140
|
"provides": [
|
|
140
|
-
"Services composition root; agent/config/contact/dialer factories; AddressBook, EntryPoint, Queue, UserPreference, ApiAiAssistant, and WebCalling integration; cc.userPreference exposes user-preference CRUD"
|
|
141
|
+
"Services composition root; agent/config/contact/dialer factories; AddressBook, EntryPoint, Queue, UserPreference, ApiAiAssistant, and WebCalling integration; existing Queue/EntryPoint list methods with SDK-owned defaults and compatible existing-parameter overrides; Queue returns full records and EntryPoint maps profile-scoped dial-number rows to typed records with optional numbers; cc.userPreference exposes user-preference CRUD"
|
|
141
142
|
],
|
|
142
143
|
"requires": [
|
|
143
144
|
"Core HTTP/WebSocket/AQM infrastructure; WCC APIs; @webex/calling; MetricsManager; PageCache"
|
|
@@ -308,7 +309,7 @@
|
|
|
308
309
|
"canonical_spec": "src/services/task/ai-docs/task-spec.md",
|
|
309
310
|
"contracts": {
|
|
310
311
|
"provides": [
|
|
311
|
-
"Task/Voice/WebRTC/Digital lifecycle APIs; TaskManager; task events/types; call-control and dialer operations including acceptPreviewContact, skipPreviewContact, and removePreviewContact"
|
|
312
|
+
"Task/Voice/WebRTC/Digital lifecycle APIs; TaskManager lifecycle correlation, narrowly scoped backend-authoritative ContactOwnerChanged recovery, and task-event publication, including routing owner-changing ContactUpdated through the existing task:hydrate event; task events/types; ordered action-specific consult/transfer destination controls; call-control and dialer operations including acceptPreviewContact, skipPreviewContact, and removePreviewContact"
|
|
312
313
|
],
|
|
313
314
|
"requires": [
|
|
314
315
|
"Contact/dialer AqmReqs; WebSocket managers; @webex/calling; MetricsManager; XState task-state module"
|
|
@@ -351,7 +352,7 @@
|
|
|
351
352
|
"canonical_spec": "src/services/task/state-machine/ai-docs/task-state-machine-spec.md",
|
|
352
353
|
"contracts": {
|
|
353
354
|
"provides": [
|
|
354
|
-
"Task state-machine factory; TaskState/TaskEvent contracts; guards/actions; state-derived UI-control computation"
|
|
355
|
+
"Task state-machine factory; TaskState/TaskEvent contracts; guards/actions; state/profile/interaction-derived UI-control and ordered consult/transfer destination computation"
|
|
355
356
|
],
|
|
356
357
|
"requires": [
|
|
357
358
|
"XState; TaskData/task event contracts; Task and TaskManager integration"
|
package/ai-docs/ARCHITECTURE.md
CHANGED
|
@@ -97,7 +97,7 @@ flowchart TD
|
|
|
97
97
|
| Agent/Profile | Remote WCC services; Config aggregates a local view | ContactCenter, Agent, Task |
|
|
98
98
|
| Task/Interaction | Remote WCC services; Task owns client representation | ContactCenter consumers |
|
|
99
99
|
| Metric event | Metrics module until submission; remote metrics backend after submit | Observability systems |
|
|
100
|
-
| Cached page | Utils PageCache (ephemeral only) | AddressBook,
|
|
100
|
+
| Cached page | Utils PageCache (ephemeral only) | AddressBook, Queue |
|
|
101
101
|
|
|
102
102
|
## Caching Catalog
|
|
103
103
|
|
package/ai-docs/CONTRACTS.md
CHANGED
|
@@ -10,16 +10,20 @@
|
|
|
10
10
|
| `contact-center.task` | Task | `Task`, `ITask`, task payload/control types | task instance and compatibility interface | semver public | `src/services/task/ai-docs/task-spec.md` | `src/index.ts` |
|
|
11
11
|
| `contact-center.events` | Agent/Task/Config | `AGENT_EVENTS`, `TASK_EVENTS`, `CC_AGENT_EVENTS`, `CC_TASK_EVENTS`, `CC_EVENTS` | typed string event contracts | additive; removals or semantic changes are breaking | owning module specs | `src/index.ts` |
|
|
12
12
|
| `contact-center.data` | Services/Utils | `AddressBook`, `ApiAIAssistant`, SDK data response/search types | SDK data and AI-assistant access | semver public | Services/Utils specs | `src/index.ts` |
|
|
13
|
+
| `contact-center.consult-transfer-lists` | Contact Center/Services | Existing `getQueues`, `getEntryPoints`, `ContactServiceQueueSearchParams`, `EntryPointSearchParams`, `ContactServiceQueuesResponse`, `EntryPointListResponse`, `ContactServiceQueue`, and `EntryPointRecord` with optional mapped `number` | Queue telephony eligibility/profile views/`name,ASC` and entry-point desktop-profile dial-number mapping/`entryPointName,ASC` are defaults on the existing methods; compatible search/filter/sort parameters remain available and backend row order is preserved | behavioral default correction on existing public methods; no specialized methods or projected response wrappers; `EntryPointRecord.number` is additive and raw configuration-only fields are optional | `ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md` | `src/cc.ts`, `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/types.ts` |
|
|
13
14
|
| `contact-center.user-preference` | Services/Config | `UserPreference`, `cc.userPreference`, `UserPreferenceData`, request/response types | `getUserPreference(params?)`, `createUserPreference(data)`, `updateUserPreference(userId, data)`, `deleteUserPreference(userId)` | semver public | `src/services/ai-docs/services-spec.md` | `src/index.ts`, `src/cc.ts`, `src/services/UserPreference.ts`, `src/services/config/types.ts` |
|
|
14
15
|
| `contact-center.preview-campaign` | Contact Center/Task | `acceptPreviewContact`, `skipPreviewContact`, `removePreviewContact` | `(payload: PreviewContactPayload) => Promise<TaskResponse>` | semver public | `ai-docs/contact-center-spec.md`, `src/services/task/ai-docs/task-spec.md` | `src/cc.ts`, `src/services/task/dialer.ts`, `src/services/task/types.ts` |
|
|
15
|
-
| `contact-center.state-controls` | Task state machine | `getDefaultUIControls`,
|
|
16
|
+
| `contact-center.state-controls` | Task state machine | `getDefaultUIControls`, `TaskUIControls` with ordered `consultTransferDestinations` arrays | Task controls include per-leg action state plus ordered `consult`/`transfer` destination categories derived from profile and interaction policy | additive semver public field; destination arrays are SDK-owned and first item is the consumer default | `src/services/task/state-machine/ai-docs/task-state-machine-spec.md` | `src/index.ts`, `src/services/task/types.ts`, `src/services/task/state-machine/uiControlsComputer.ts` |
|
|
17
|
+
| `contact-center.conference-participant-drop` | Task | `DropConferenceParticipantPayload`, `ITask.dropConferenceParticipant` | `(payload: {participantId: string}) => Promise<TaskResponse>`; Voice resolves from correlated `ParticipantLeftConference`, while non-voice base Task rejects as unsupported. Existing participant/consult lifecycle events may resolve one unique child-keyed task by `mainInteractionId`; no new public event is introduced. | semver public | `src/services/task/ai-docs/task-spec.md` | `src/index.ts`, `src/services/task/types.ts`, `src/services/task/voice/Voice.ts`, `src/services/task/contact.ts`, `src/services/task/TaskManager.ts` |
|
|
18
|
+
| `contact-center.wxapp-answer` | Contact Center / Task | `enableWxBetterTogether`, `isWxBetterTogetherEnabled()`, `getWxAppMuted`, `syncWxAppMuteFromCallDetails`, unified task telephony (`ITask.accept`, `decline`, `toggleMute({ muted?, lineOwnerId? })`, `transmitDtmf({ dtmf, lineOwnerId? })`) | init flag ON → usersub `true` + Mercury on supported station login **and silent relogin**; init flag OFF → force usersub `false` on supported station login **and silent relogin** (clears stale suppression after refresh); **Phase 1 init-only** — change flag via re-init; multi-login supported; mute backfill via GET call details + `getWxAppMuted()` on hydrate/refresh; shared-line `lineOwnerId` defaults from participant; SDK `Voice` routes wxApp telephony when flag active | semver public | `src/services/task/ai-docs/task-spec.md`, `ai-docs/contact-center-spec.md`, `src/services/ai-docs/services-spec.md` | `src/cc.ts`, `src/services/task/voice/Voice.ts`, `src/services/task/voice/wxAppVoiceMethods.ts` |
|
|
16
19
|
|
|
17
20
|
### Events
|
|
18
21
|
|
|
19
22
|
| Contract ID | Owner module | Event / topic | Direction | Payload schema link | Delivery guarantees | Compatibility / deprecation | Defined at |
|
|
20
23
|
|---|---|---|---|---|---|---|---|
|
|
21
24
|
| `agent.events` | Agent | `agent:*` | publish to application | agent spec/types | realtime; backend ordering/correlation | additive constants | `src/services/agent/types.ts` |
|
|
22
|
-
| `task.events` | Task | `task
|
|
25
|
+
| `task.events` | Task | `task:*`, including existing `task:hydrate` | consume/map backend task lifecycle events, then publish to application/task | task spec `TASK-R-010` / types | `ContactOwnerChanged` and owner-changing `ContactUpdated` route through `CONTACT_OWNER_CHANGED`; a complete promoted-current-Agent owner change may narrowly recover a missing task; consumers receive one `task:hydrate` and no synthetic `task:incoming` | compatible semantic extension of an existing event; no new event constant; backend `interaction.owner` remains authoritative | `src/services/task/TaskManager.ts`, `src/services/task/Task.ts`, `src/services/task/types.ts` |
|
|
26
|
+
| `task.wxapp-mute.events` | Task | `task:wxapp-mute-state-updated` | publish to application/task | task spec/types | event-driven | additive | `src/services/task/types.ts`, `src/services/task/voice/Voice.ts` |
|
|
23
27
|
| `cc.events` | Config/Core | backend CC_EVENTS | consume/map | config/core specs | remote WebSocket delivery; AQM correlation where configured | backend contract | `src/services/config/types.ts` |
|
|
24
28
|
| `rtd.events` | Task | realtime transcription/suggestion | consume then publish per task | task spec | websocket best-effort according to remote service | additive payloads | `src/services/task/TaskManager.ts` |
|
|
25
29
|
|
package/ai-docs/SECURITY.md
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
|---|---|---|---|
|
|
46
46
|
| Log upload | Runtime context could contain sensitive values | Shared error helpers upload only approved diagnostic context; never add credentials/payload dumps | Contact Center maintainers |
|
|
47
47
|
| WebSocket event parsing | Malformed/unexpected remote data | Parse defensively, map known event constants, ignore/reject invalid transitions | Core/Task maintainers |
|
|
48
|
-
| Public dial/contact inputs | PII
|
|
48
|
+
| Public dial/contact/participant-drop inputs | PII, external numbers, and participant identifiers | Validate and avoid logging raw values; sensitive AQM operations redact dynamic URLs and raw routing failures | Contact Center maintainers |
|
|
49
49
|
|
|
50
50
|
## Reporting & Review
|
|
51
51
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
| Doc kind | Module spec |
|
|
12
12
|
| Coverage score | Partial (manifest-authoritative); 15/15 required document fields present |
|
|
13
13
|
| Generated from | `module-spec` @ SDLC template library `0.2.1` |
|
|
14
|
-
| generated_by / approved_by / updated_at | Codex generator / developer-approved follow-up review remediation / 2026-
|
|
14
|
+
| generated_by / approved_by / updated_at | Codex generator / developer-approved follow-up review remediation / 2026-08-21 |
|
|
15
15
|
| Validation status | Follow-up validation passed (independent Claude fallback, 2026-07-21); 1 existing test-coverage gap; coverage remains Partial |
|
|
16
16
|
|
|
17
17
|
## Evidence Rules
|
|
@@ -37,6 +37,8 @@ The `@webex/contact-center` package is a Webex SDK plugin that provides a TypeSc
|
|
|
37
37
|
|
|
38
38
|
- **Metrics & Diagnostics**: Built-in telemetry and log upload
|
|
39
39
|
|
|
40
|
+
- **Answer on Webex**: Accept, Decline, Mute, and DTMF for voice offers when the agent uses Webex App desktop calling (`enableWxBetterTogether`).
|
|
41
|
+
|
|
40
42
|
## Purpose / Responsibility
|
|
41
43
|
Own the published Webex Contact Center SDK plugin surface, registration lifecycle, public method delegation, and application-facing event routing.
|
|
42
44
|
|
|
@@ -66,14 +68,17 @@ src/
|
|
|
66
68
|
| `src/config.ts` | Authoritative Contact Center implementation or contract source. |
|
|
67
69
|
| `src/services/UserPreference.ts` | User-preference CRUD implementation exposed through `cc.userPreference`. |
|
|
68
70
|
| `src/services/task/dialer.ts` | Preview-campaign AQM request implementations. |
|
|
69
|
-
| `src/services/task/types.ts` | `PreviewContactPayload`, `TaskResponse`, and task contract types. |
|
|
71
|
+
| `src/services/task/types.ts` | `PreviewContactPayload`, `DropConferenceParticipantPayload`, `TaskResponse`, and task contract types. |
|
|
70
72
|
|
|
71
73
|
## Public Surface
|
|
72
74
|
| Contract ID | Type | Surface | Purpose | Compatibility / deprecation | Schema / detail link | Root index |
|
|
73
75
|
|---|---|---|---|---|---|---|
|
|
74
76
|
| `contact-center.surface` | SDK / event / internal API | Published `@webex/contact-center` exports and the `ContactCenter` (`cc`) WebexPlugin API. | Stable module consumption boundary. | Additive changes by default; breaking package exports require a major-version transition. | `src/index.ts` | `CONTRACTS.md` |
|
|
77
|
+
| `contact-center.consult-transfer-lists` | SDK data API | Existing `getQueues` and `getEntryPoints` methods, their existing search/response types, and full `ContactServiceQueue` / `EntryPointRecord` rows. | Provide consult/transfer telephony defaults without adding a parallel list API or projected destination model. | Behavioral default correction; explicit existing filter/sort/profile inputs remain overrides and full record types remain the response contract. | `src/cc.ts`, `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/types.ts` | `CONTRACTS.md` |
|
|
78
|
+
| `contact-center.consult-transfer-controls` | SDK task control API | Ordered `TaskUIControls.consultTransferDestinations` arrays using the existing destination values. | Give all Task consumers the same ordered, action-specific destination visibility without a second policy call. | Additive public field; consumers may hide SDK-allowed categories but must not enable omitted categories. | `src/cc.ts`, `src/services/task/types.ts`, `src/services/task/state-machine/uiControlsComputer.ts`, `src/index.ts` | `CONTRACTS.md` |
|
|
75
79
|
| `contact-center.user-preference` | SDK data API | Exported `UserPreference`, `cc.userPreference`, and user-preference request/response types. | Read and mutate user preferences through authenticated REST operations. | Additive public API; removals or signature changes are breaking. | `src/services/UserPreference.ts`, `src/services/config/types.ts` | `CONTRACTS.md` |
|
|
76
80
|
| `contact-center.preview-campaign` | SDK task API | `acceptPreviewContact`, `skipPreviewContact`, `removePreviewContact`. | Resolve campaign preview reservations through typed AQM operations. | Additive public API; removals or signature changes are breaking. | `src/cc.ts`, `src/services/task/dialer.ts`, `src/services/task/types.ts` | `CONTRACTS.md` |
|
|
81
|
+
| `contact-center.conference-participant-drop` | SDK task API | Exported `DropConferenceParticipantPayload` and `ITask.dropConferenceParticipant`. | Remove a conference participant through the media-specific task implementation and correlated AQM completion. | Additive public API; removals or signature changes are breaking. | `src/index.ts`, `src/services/task/types.ts`, `src/services/task/voice/Voice.ts` | `CONTRACTS.md` |
|
|
77
82
|
|
|
78
83
|
Compatibility notes:
|
|
79
84
|
- Do not remove or reinterpret exported symbols/events without a documented consumer migration.
|
|
@@ -88,7 +93,7 @@ Compatibility notes:
|
|
|
88
93
|
|---|---|---|---|---|---|---|
|
|
89
94
|
| CONTACT_CENTER-R-001 | Construct the service graph once after the host Webex SDK emits READY, before `register()` is invoked. | Collaborators require initialized host request, logger, and plugin configuration state. | `src/cc.ts` | `test/unit/spec/cc.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
|
|
90
95
|
| CONTACT_CENTER-R-002 | `register()` must attach connection/message listeners, connect the primary WebSocket, and return the fetched Profile or rethrow a logged failure. | Applications need an explicit readiness boundary and must never observe a synthetic successful registration. | `src/cc.ts` | `test/unit/spec/cc.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
|
|
91
|
-
| CONTACT_CENTER-R-003 | Delegate agent, task, data, user-preference, preview-campaign, AI-assistant, calling, and telemetry behavior to their owning collaborators while preserving typed package methods and events. Before preview delegation, reject disabled skip/remove actions from task campaign flags. | A stable façade
|
|
96
|
+
| CONTACT_CENTER-R-003 | Delegate agent, task, data, user-preference, preview-campaign, AI-assistant, calling, and telemetry behavior to their owning collaborators while preserving typed package methods and events. Existing `getQueues` and `getEntryPoints` delegate to their services with unchanged signatures and full-record responses; the services own consult/transfer telephony filter, profile-view, ordering, and cache defaults while honoring explicit existing-parameter overrides. Before preview delegation, reject disabled skip/remove actions from task campaign flags. | A thin stable façade avoids parallel consumer APIs while service-owned defaults keep ordinary widget calls consistent and preserve an override path for other consumers. | `src/cc.ts`, `src/types.ts`, `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/services/UserPreference.ts`, `src/services/task/dialer.ts` | `test/unit/spec/cc.ts`, `test/unit/spec/services/Queue.ts`, `test/unit/spec/services/EntryPoint.ts`, `test/unit/spec/services/UserPreference.ts`, `test/unit/spec/services/task/dialer.ts` | Public preview delegation is covered; the `campaignPreviewSkipDisabled` and `campaignPreviewRemoveDisabled` early-exit guards lack direct unit coverage. Independent review identified this gap on 2026-07-15. | PRESENT |
|
|
92
97
|
| CONTACT_CENTER-R-004 | `deregister()` must remove registered listeners, stop applicable host/calling resources, close primary and RTD WebSockets, clear agent configuration, and surface cleanup failures. | Listener or connection leaks create duplicate events and stale authenticated sessions in long-lived hosts. | `src/cc.ts` | `test/unit/spec/cc.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
|
|
93
98
|
| CONTACT_CENTER-R-005 | On `connectionLost`, ContactCenter must own recovery policy and invoke private `silentRelogin()` only when automated relogin is allowed. | ConnectionService reports transport state; only ContactCenter has agent profile and policy context for authentication recovery. | `src/cc.ts` | `test/unit/spec/cc.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
|
|
94
99
|
|
|
@@ -99,6 +104,19 @@ Direct data/configuration and user-preference operations return authenticated RE
|
|
|
99
104
|
|
|
100
105
|
Durable agent, task, and configuration records remain remote-system owned. The package owns only in-memory profile/task/listener/cache/connection state.
|
|
101
106
|
|
|
107
|
+
### wxApp Better Together (WXCC-6026)
|
|
108
|
+
|
|
109
|
+
Contract id: `contact-center.wxapp-answer` ([CONTRACTS.md](./CONTRACTS.md)). Task telephony routing, UI controls, and mute events are specified in [task-spec.md](../src/services/task/ai-docs/task-spec.md). Service collaborators: [services-spec.md](../src/services/ai-docs/services-spec.md).
|
|
110
|
+
|
|
111
|
+
- **Init flag:** `webex.init({ cc: { enableWxBetterTogether: boolean } })` — default `false`. When `true`, ContactCenter enables wxApp telephony routing on tasks after supported station login. **Compatible with `allowMultiLogin: true`** (multiple SDK sessions may receive offers; wxApp telephony is routed per active task instance). **Phase 1 is init-only** — to change the flag after SDK init, re-init with updated config.
|
|
112
|
+
- **Read API:** `cc.isWxBetterTogetherEnabled()` returns the current init flag value.
|
|
113
|
+
- **Phase 2 (internal/private):** `setManageWebexCallingInWxcc(enabled)` remains as a private implementation for future runtime toggle; hosts must not call it in Phase 1.
|
|
114
|
+
- **Post-login hooks:** `ensureWxAppPostStationLogin()` runs after successful `stationLogin()` and after `silentRelogin()` on socket reconnect. When the init flag is ON, it publishes usersub `true`, connects Mercury/device for mute sync, and backfills mute state on active tasks. Failures roll back wxApp config and release partial Mercury/device resources without failing station login. When OFF, it force-publishes usersub `false` (clears stale suppression after page refresh) and tears down wxApp Mercury resources.
|
|
115
|
+
- **Teardown:** `deregister()`, station logout, and wxApp teardown paths call `teardownWxAppLocalState()` — publish usersub `false`, unsubscribe Mercury, release CC-owned device/Mercury connections, and reset **session runtime** state (usersub active flag, Mercury subscriptions, task-manager wxApp routing) so stale session flags do not apply on relogin. The host init flag (`enableWxBetterTogether`) is **not** cleared on station logout — it persists until `deregister()` or re-init per Phase 1 contract. Local cleanup runs even when usersub publish fails.
|
|
116
|
+
- **Host telephony surface:** Hosts call unified `task.accept()`, `task.decline()`, `task.toggleMute({ muted? })`, and `task.transmitDtmf({ dtmf })`; SDK `Voice` routes wxApp legs internally when the flag is active. Shared-line `lineOwnerId` defaults from the wxApp agent participant when omitted.
|
|
117
|
+
|
|
118
|
+
Evidence: `src/cc.ts`, `src/config.ts`, `src/services/WebexCrossClientService.ts`, `src/services/WxAppTelephonyMercurySync.ts`, `test/unit/spec/cc.ts`.
|
|
119
|
+
|
|
102
120
|
## Data Flow
|
|
103
121
|
```mermaid
|
|
104
122
|
flowchart TD
|
|
@@ -326,7 +344,7 @@ The module registers as `cc` through the Webex SDK plugin system and depends on
|
|
|
326
344
|
- A single plugin surface centralizes compatibility and event routing, while specialized modules retain implementation ownership; this costs careful bootstrap and cleanup ordering.
|
|
327
345
|
|
|
328
346
|
## Test-Case Strategy (module)
|
|
329
|
-
`test/unit/spec/cc.ts` is the characterization baseline. Cover READY-time construction, registration success/failure, listener identity,
|
|
347
|
+
`test/unit/spec/cc.ts` is the characterization baseline. Cover READY-time construction, registration success/failure, listener identity, existing queue/entry-point method delegation, WebSocket event mapping, preview-campaign operations (including disabled skip/remove pre-guards), automated-relogin enabled/disabled branches, browser-calling conditions, and deregistration cleanup/error paths. Use Queue and EntryPoint service tests for default policy and explicit existing-parameter overrides, `test/unit/spec/services/UserPreference.ts` for user-preference CRUD, and `test/unit/spec/services/task/dialer.ts` for preview AQM request contracts. Preserve the package-wide 85% branch/function/line/statement threshold.
|
|
330
348
|
|
|
331
349
|
| Requirement | Existing evidence | Required revalidation |
|
|
332
350
|
|---|---|---|
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Feature Spec
|
|
3
|
+
title: Consult and transfer list policy
|
|
4
|
+
description: Centralize consult and transfer destination eligibility, request shaping, ordering, and cache policy in the Contact Center SDK.
|
|
5
|
+
tags: [feature, specification, contact-center, consult-transfer]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Consult and transfer list policy
|
|
9
|
+
|
|
10
|
+
This document owns the reusable consult/transfer destination-list policy. The SDK applies default telephony eligibility, ordering, profile views, and cache safety through the existing list methods; consumers use compatible existing parameters only when they need a different filter or sort.
|
|
11
|
+
|
|
12
|
+
Related context: [package architecture](../../../ARCHITECTURE.md) · [specification index](../../../SPEC_INDEX.md) · [package instructions](../../../../AGENTS.md)
|
|
13
|
+
|
|
14
|
+
## Metadata
|
|
15
|
+
|
|
16
|
+
| Field | Value |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| Feature key | `CAI-8354` |
|
|
19
|
+
| Owner | Webex Contact Center SDK maintainers |
|
|
20
|
+
| Status | Approved and implemented; diff-scoped drift validation PASS; independent validation pending |
|
|
21
|
+
| Work type | Defect |
|
|
22
|
+
| Change class | Contract |
|
|
23
|
+
| Source/intake | Developer-approved consult/transfer behavior review and current code/tests |
|
|
24
|
+
| Last verified | 2026-08-22 in the approved SDK/widgets worktrees |
|
|
25
|
+
|
|
26
|
+
## Applicability
|
|
27
|
+
|
|
28
|
+
| Condition ID | Status | Evidence or reason | Owned section |
|
|
29
|
+
| --- | --- | --- | --- |
|
|
30
|
+
| `feature.feature_nontrivial` | Applicable | `src/cc.ts`, `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/services/AddressBook.ts`, `src/services/task/Task.ts` | Feasibility and risks |
|
|
31
|
+
| `feature.feature_interactions` | Applicable | `src/cc.ts` | Interaction and scenario matrix |
|
|
32
|
+
| `feature.touches_data_shapes` | Applicable | `src/types.ts` | Requested data and fields |
|
|
33
|
+
| `feature.backward_compat` | Applicable | `src/types.ts`, `src/index.ts` | Migration expectations |
|
|
34
|
+
| `feature.perf_critical` | N/A | The change adds no new request fan-out; it corrects cache eligibility for query variants. | Scale and performance |
|
|
35
|
+
| `feature.security_compliance` | N/A | Existing host-authenticated request ownership is unchanged and no credentials are added to list inputs. | Security and compliance |
|
|
36
|
+
| `feature.needs_rollout` | N/A | No SDK feature flag or staged runtime branch is introduced. | Rollout and feature controls |
|
|
37
|
+
| `feature.serviceability` | Applicable | `src/cc.ts`, `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/services/AddressBook.ts` | Serviceability |
|
|
38
|
+
| `feature.doc_obligations` | Applicable | `ai-docs/contact-center-spec.md` | Documentation obligations |
|
|
39
|
+
| `feature.changes_ui` | N/A | The SDK has no user-visible screen or navigation ownership. | UI flow and design |
|
|
40
|
+
| `feature.changes_api` | Applicable | `src/cc.ts`, `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/services/AddressBook.ts`, `src/services/task/Task.ts` | API contract delta |
|
|
41
|
+
| `feature.changes_events` | N/A | No event name, payload, producer, consumer, or delivery order changes. | Event contract delta |
|
|
42
|
+
| `feature.changes_public_api` | Applicable | `src/index.ts`, `src/types.ts` | Public API and semver impact |
|
|
43
|
+
| `feature.cross_package` | Applicable | `src/index.ts` | Cross-package impact |
|
|
44
|
+
|
|
45
|
+
## Problem and goal
|
|
46
|
+
|
|
47
|
+
Consult/transfer list decisions were split across the SDK and widgets. Generic SDK query types exposed low-level request choices, while widgets always restricted buddy agents to Available, filtered queues after fetching them, rebuilt pagination metadata, and could independently affect presentation order. That produced inconsistent behavior between consumers.
|
|
48
|
+
|
|
49
|
+
The goal is to make the SDK the single owner of the default consult/transfer policy without adding parallel list methods or response signatures. The existing Queue method returns eligible full records, while the existing EntryPoint method maps profile-scoped dial-number rows to the established response wrapper. Queue, EntryPoint, and AddressBook request backend ordering, buddy-agent behavior is action-aware, CMS sort syntax is serialized correctly, and query variants that change results cannot reuse an incompatible cached page. Consumers render the response order and metadata without a second sort or filter.
|
|
50
|
+
|
|
51
|
+
## Stakeholders and open questions
|
|
52
|
+
|
|
53
|
+
| Stakeholder | Need or decision | Status |
|
|
54
|
+
| --- | --- | --- |
|
|
55
|
+
| Contact Center agents | Destination eligibility and order are consistent across consumers. | Decided |
|
|
56
|
+
| SDK consumers | Reusable defaults without duplicating backend query knowledge. | Decided |
|
|
57
|
+
| Widget maintainers | Thin calls that pass only UI/runtime context. | Decided in the paired widgets delta |
|
|
58
|
+
| SDK maintainers | Existing list APIs remain the only queue and entry-point public methods; existing parameters provide overrides. | Decided |
|
|
59
|
+
|
|
60
|
+
There are no open product decisions for this delta.
|
|
61
|
+
|
|
62
|
+
## Scope
|
|
63
|
+
|
|
64
|
+
### In scope
|
|
65
|
+
|
|
66
|
+
- Put consult/transfer defaults on the existing queue and entry-point list methods.
|
|
67
|
+
- Map Consult versus Transfer to the correct buddy-agent state behavior.
|
|
68
|
+
- Default omitted buddy-agent and queue media context to telephony.
|
|
69
|
+
- Retain the existing queue/entry-point parameter and response wrappers; keep full Queue records, map EntryPoint dial-number rows to truthful `EntryPointRecord` fields, and retain compatible filter/sort overrides without exposing the fixed entry-point profile-scoping flag.
|
|
70
|
+
- Default EntryPoint requests to backend `entryPointName,ASC` and AddressBook requests to `name,ASC` while allowing callers to pass another `sortBy`/`sortOrder` pair.
|
|
71
|
+
- Serialize CMS ordering as `sort=<field>,<ORDER>`.
|
|
72
|
+
- Bypass the base pagination cache for every filter/view/shape flag that changes a result.
|
|
73
|
+
- Keep the existing queue and entry-point method signatures and preserve explicit buddy-agent state callers.
|
|
74
|
+
- Compute ordered, action-specific destination availability once on each Task and expose it through `TaskUIControls`, using Desktop Profile access, media, direction, and outbound queue-transfer capability.
|
|
75
|
+
- Keep direct Entry Point available for eligible voice transfers and translate its public destination type to the backend EPDN value inside `Task.transfer()`.
|
|
76
|
+
|
|
77
|
+
### Out of scope
|
|
78
|
+
|
|
79
|
+
- Client-side sorting of agents, queues, or entry points.
|
|
80
|
+
- Changing backend order after a response is received.
|
|
81
|
+
- Adding parallel queue/entry-point APIs or projected destination response types.
|
|
82
|
+
- Changing generic queue ordering, address-book projection, events, authentication, retries, or metrics taxonomy.
|
|
83
|
+
- Adding a feature flag, data migration, commit, publication, or push.
|
|
84
|
+
- Adding a separate destination-policy fetch method that Task consumers must call before rendering.
|
|
85
|
+
|
|
86
|
+
## Prior work and evidence
|
|
87
|
+
|
|
88
|
+
| Source | What it establishes | Decision or disposition |
|
|
89
|
+
| --- | --- | --- |
|
|
90
|
+
| `src/cc.ts` | The public façade keeps the established list method names/signatures and owns buddy-agent action policy. | Used |
|
|
91
|
+
| `src/types.ts`, `src/index.ts` | Existing queue/entry-point request and response types remain the public list contracts; entry-point rows expose the mapped dialled number as optional `number`. | Used |
|
|
92
|
+
| `src/services/Queue.ts` | The existing Queue path owns default query serialization and view flags. | Used |
|
|
93
|
+
| `src/services/EntryPoint.ts` | The existing EntryPoint path owns the desktop-profile dial-number query, field mapping, and backend ordering. | Used |
|
|
94
|
+
| `src/services/core/WebexRequest.ts` | The shared request wrapper forwards optional per-request headers needed by the dial-number endpoint while leaving other requests unchanged. | Used |
|
|
95
|
+
| `src/services/AddressBook.ts` | AddressBook owns its backend ordering default and caller override. | Used |
|
|
96
|
+
| `src/utils/PageCache.ts` | Cache eligibility must include every result- or shape-changing query option. | Used |
|
|
97
|
+
| `test/unit/spec/cc.ts` | Action mapping and thin delegation through the existing list methods are asserted. | Used |
|
|
98
|
+
| `test/unit/spec/services/Queue.ts`, `test/unit/spec/services/EntryPoint.ts`, `test/unit/spec/services/AddressBook.ts` | Default policy, existing-parameter overrides, CMS sort serialization, view flags, and cache behavior are asserted. | Used |
|
|
99
|
+
| `src/services/task/state-machine/uiControlsComputer.ts`, `src/services/task/types.ts` | Task UI controls are the existing SDK-owned decision surface and can carry ordered destination availability. | Used |
|
|
100
|
+
| `test/unit/spec/services/task/state-machine/uiControlsComputer.ts`, `test/unit/spec/services/task/TaskFactory.ts` | Profile/media/direction gating, outbound flag path, ordering, and factory propagation are asserted. | Used |
|
|
101
|
+
| `src/services/task/Task.ts`, `src/services/task/constants.ts`, `test/unit/spec/services/task/Task.ts` | Direct entry-point transfer routing is translated to the backend EPDN value and sent through the vteam transfer path. | Used |
|
|
102
|
+
| `docs/samples/contact-center/app.js` | The sample renders buddy-agent state labels and mapped entry-point numbers while using the existing list methods and Task destination controls. | Used |
|
|
103
|
+
|
|
104
|
+
## Requirements
|
|
105
|
+
|
|
106
|
+
| ID | WHAT | WHY | Source evidence | Test or example evidence | Assumptions or gaps | Confidence |
|
|
107
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
108
|
+
| `SDK-LIST-R-001` | Existing `getQueues` must retain `ContactServiceQueueSearchParams` and `ContactServiceQueuesResponse`, default to inbound active telephony queues ordered by backend name ascending with desktop-profile/agent/first-level views, avoid field projection, and honor defined caller-supplied existing parameters as overrides. Optional properties explicitly set to `undefined` retain defaults; explicit `false` flags and an explicit empty filter remain overrides. | Queue eligibility and ordering are consistent for ordinary calls without a new method or misleading projected/full-record type mismatch, while other consumers retain an explicit override path. Defined-only merging prevents a normally constructed optional-parameter object from accidentally disabling safe defaults. | `src/cc.ts`, `src/services/Queue.ts`, `src/types.ts` | `test/unit/spec/cc.ts`, `test/unit/spec/services/Queue.ts` | Backend honors the documented CMS query flags. | Present |
|
|
109
|
+
| `SDK-LIST-R-002` | Existing `getEntryPoints` must retain `EntryPointSearchParams` and `EntryPointListResponse`, query `/v3/dial-number` with organization/internal-data headers, fixed desktop-profile filtering, entry-point names, required mapping attributes, and backend `entryPointName,ASC`, then map each row to the existing `EntryPointRecord` as `id=entryPointId`, `name=entryPointName`, and optional `number=dialledNumber` without reordering. Caller-supplied compatible search, filter, attributes, and sort parameters remain available. | The visible entry-point number belongs to the dial-number mapping. Owning that mapping in the existing SDK method keeps consumers thin without exposing a parallel request or response type. | `src/cc.ts`, `src/services/EntryPoint.ts`, `src/services/config/constants.ts`, `src/services/core/WebexRequest.ts`, `src/types.ts` | `test/unit/spec/services/EntryPoint.ts`, `test/unit/spec/services/core/WebexRequest.ts` | The v3 response includes entry-point identifiers/names when `includeEntryPointName=true`. | Present |
|
|
110
|
+
| `SDK-LIST-R-003` | Buddy-agent requests using `Transfer` must add state `Available`; requests using `Consult` must omit the state filter; omitted action-based media defaults to telephony; both `BuddyAgents` branches reuse one private supported-media union. | Transfer and Consult have different eligible populations, and one media allowlist prevents action-based callers from issuing unsupported buddy requests without adding another public type. | `src/cc.ts`, `src/types.ts` | `test/unit/spec/cc.ts` | The backend determines the Consult-eligible states when state is omitted. | Present |
|
|
111
|
+
| `SDK-LIST-R-004` | Explicit buddy-agent state requests and existing queue/entry-point/address-book parameters must remain supported; caller-supplied filters and sort values override service defaults. | Existing SDK consumers need specialized behavior without a second list API. | `src/cc.ts`, `src/types.ts`, `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/services/AddressBook.ts` | `test/unit/spec/cc.ts`, `test/unit/spec/services/Queue.ts`, `test/unit/spec/services/EntryPoint.ts`, `test/unit/spec/services/AddressBook.ts` | Existing callers that pass explicit `state` continue to use that branch. | Present |
|
|
112
|
+
| `SDK-LIST-R-005` | Queue, EntryPoint, and AddressBook services must serialize ordering as CMS `sort=<field>,<ORDER>`, not separate `sortBy`/`sortOrder` query keys. Queue and AddressBook default to `name,ASC`; EntryPoint maps the public default `name` field to backend `entryPointName,ASC`; a Queue `sortOrder` without `sortBy` uses `name`. | Correct wire syntax and SDK-owned defaults make backend ordering consistent and prevent a caller's explicit direction from being silently ignored. | `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/services/AddressBook.ts` | `test/unit/spec/services/Queue.ts`, `test/unit/spec/services/EntryPoint.ts`, `test/unit/spec/services/AddressBook.ts` | None. | Present |
|
|
113
|
+
| `SDK-LIST-R-006` | PageCache must reject cache use when search, filter, attributes, a non-default/effective sort, or an enabled desktop-profile/provisioning/single-object flag is present. This includes a Queue `sortOrder` supplied without `sortBy`. Default Queue calls bypass simple-page caching because their eligibility filter and enabled views change the result set; profile-scoped EntryPoint requests are made directly without PageCache; AddressBook retains cache eligibility for its invariant default order. | The cache key does not encode result variants, so default policy requests and explicit query variants cannot safely share a page. | `src/utils/PageCache.ts`, `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/services/AddressBook.ts` | `test/unit/spec/services/Queue.ts`, `test/unit/spec/services/EntryPoint.ts`, `test/unit/spec/services/AddressBook.ts` | Service-level behavior covers default and override cases. | Present |
|
|
114
|
+
| `SDK-LIST-R-007` | The SDK must not JavaScript-sort or reorder list response arrays. EntryPoint may rename/map fields row-for-row while preserving response order and pagination metadata. | Backend-requested order is authoritative, while field mapping must not alter list membership or order. | `src/cc.ts`, `src/services/Queue.ts`, `src/services/EntryPoint.ts` | `test/unit/spec/cc.ts`, `test/unit/spec/services/EntryPoint.ts` | The backend is the source of final row order. | Present |
|
|
115
|
+
| `SDK-LIST-R-008` | The existing `BuddyAgents` input and `TaskUIControls.consultTransferDestinations` field must carry action/media and ordered destination typing without exporting one-off aliases; queue and entry-point consumers continue to use the established request/response wrappers. `EntryPointRecord` must strongly type optional mapped `number`, while configuration-only fields absent from the mapped list are optional. | Public consumers need a truthful compile-time contract without extra public aliases, destination abstractions, response wrappers, or casts for the displayed entry-point number. | `src/types.ts`, `src/services/task/types.ts`, `src/index.ts`, `src/cc.ts` | `test/unit/spec/cc.ts`, `test/unit/spec/services/EntryPoint.ts`, `test/unit/spec/services/task/state-machine/uiControlsComputer.ts`, `package.json` | None. | Present |
|
|
116
|
+
| `SDK-LIST-R-009` | Buddy-agent, queue, and entry-point failures must preserve their existing measured/logged rejection semantics and must not return a synthetic successful list. | Callers need to distinguish a real empty result from a transport or backend failure. | `src/cc.ts`, `src/services/Queue.ts`, `src/services/EntryPoint.ts` | `test/unit/spec/cc.ts`, `test/unit/spec/services/Queue.ts`, `test/unit/spec/services/EntryPoint.ts` | Consumer UI fallback behavior remains outside the SDK. | Present |
|
|
117
|
+
| `SDK-LIST-R-010` | AddressBook must request backend `name,ASC` ordering by default and must accept caller-supplied `sortBy`/`sortOrder` overrides without a consult-specific façade method. | Widgets and other ordinary consumers receive backend-ordered dial numbers out of the box, while consumers with another requirement retain control. | `src/services/AddressBook.ts` | `test/unit/spec/services/AddressBook.ts` | Backend honors the documented CMS sort value. | Present |
|
|
118
|
+
| `SDK-LIST-R-011` | Non-default queue media eligibility must be supplied through the existing RSQL `filter` parameter; the SDK never interpolates an unvalidated media string into a filter. | Reusing the established filter contract avoids a second media-bearing signature and removes the prior filter-injection path. | `src/services/Queue.ts`, `src/types.ts` | `test/unit/spec/services/Queue.ts` | Consumers that construct explicit RSQL filters remain responsible for supplying valid backend syntax. | Present |
|
|
119
|
+
| `SDK-LIST-R-012` | Every Task must expose `uiControls.consultTransferDestinations` with ordered `consult` and `transfer` arrays. Order is Agent, Queue, Dial Number, Entry Point after gating: profile `NONE` removes agent/queue/entry point; voice Consult queue requires `allowConsultToQueue`; voice Transfer queue requires inbound direction or outbound plus `interaction.callProcessingDetails.outdialTransferToQueueEnabled === true`; unknown voice direction does not allow queue Transfer; digital exposes only allowed agent/queue categories. | All consumers need the same destination decision out of the box, without reading raw profile flags, interpreting task payload paths, or calling another policy API. | `src/cc.ts`, `src/services/task/TaskFactory.ts`, `src/services/task/types.ts`, `src/services/task/state-machine/uiControlsComputer.ts` | `test/unit/spec/cc.ts`, `test/unit/spec/services/task/TaskFactory.ts`, `test/unit/spec/services/task/state-machine/uiControlsComputer.ts` | Consumers may hide an SDK-allowed category for host UX, but cannot enable one the SDK omitted. | Present |
|
|
120
|
+
| `SDK-LIST-R-013` | A direct `Task.transfer()` to the public `entryPoint` destination must remain available for eligible voice tasks, translate internally to backend destination type `entrypointDialNumber`, and use `vteamTransfer`; callers continue to pass the selected entry-point identifier and do not perform backend translation. | Entry-point transfer is a supported vteam operation, while sending the public value unchanged through `blindTransfer` selects the wrong backend operation and makes SDK-owned controls advertise a failing action. | `src/services/task/Task.ts`, `src/services/task/constants.ts`, `src/services/task/types.ts` | `test/unit/spec/services/task/Task.ts` | The existing entry-point identifier remains a valid fallback when no analyzer identifier is exposed, matching the established transfer policy. | Present |
|
|
121
|
+
| `SDK-LIST-R-014` | The Contact Center sample must treat a present empty Task destination array as an explicit “no destinations” decision by clearing and disabling the selector; only a missing/undefined control uses backward-compatible sample defaults. | An empty SDK policy result must not be replaced with categories the Task explicitly disallowed, while the sample still needs to run against older SDK builds that do not expose the field. | `docs/samples/contact-center/app.js` | Manual sample flow | The sample has no dedicated DOM unit suite. | Present |
|
|
122
|
+
|
|
123
|
+
## Defect context (when applicable)
|
|
124
|
+
|
|
125
|
+
- Observed versus expected behavior: widgets and SDK callers could construct different destination requests, the services serialized sort with keys the CMS list API does not consume, and cache eligibility ignored view/shape flags; expected behavior is one SDK-owned default policy and unchanged backend response order.
|
|
126
|
+
- Reproduction and environment: issue Consult and Transfer destination requests for the same task media and compare query parameters and results across SDK consumers.
|
|
127
|
+
- Regression range or last known good state: unknown; the existing APIs and older query serialization predate the corrected defaults.
|
|
128
|
+
- Severity, frequency, and workaround: user-visible whenever eligibility/order differs; consumers could manually duplicate flags, but that perpetuates the ownership defect.
|
|
129
|
+
- Diagnostic evidence: `src/cc.ts`, `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/utils/PageCache.ts`.
|
|
130
|
+
|
|
131
|
+
## MODIFIED Requirements
|
|
132
|
+
|
|
133
|
+
### MOD-001 — Contact Center façade policy (`CONTACT_CENTER-R-003`)
|
|
134
|
+
|
|
135
|
+
- **WHAT**: Retain the existing `getQueues`, `getEntryPoints`, and `getBuddyAgents` method names. Buddy-agent behavior is action-aware; Queue retains its parameter/full-record response and owns telephony eligibility/views/order, while EntryPoint retains its parameter/response wrapper and owns the profile-scoped dial-number query, row mapping, order, and cache policy.
|
|
136
|
+
- **WHY**: A stable public owner prevents every UI consumer from reconstructing eligibility and query details.
|
|
137
|
+
- **Evidence:** `src/cc.ts`, `src/types.ts`, `src/index.ts`, `test/unit/spec/cc.ts`.
|
|
138
|
+
- **Acceptance:** Façade tests cover Consult, Transfer, and unchanged existing-method delegation; service tests cover default policy, explicit existing-filter overrides, and exact responses.
|
|
139
|
+
|
|
140
|
+
### MOD-002 — Direct REST list services (`SERVICES-R-002`, `SERVICES-R-007`)
|
|
141
|
+
|
|
142
|
+
- **WHAT**: Queue, EntryPoint, and AddressBook must serialize CMS sorting as a combined `sort` value and honor explicit compatible caller overrides. Queue must apply its defaults when optional properties are absent or `undefined`, while retaining explicit `false` and empty-filter overrides. Queue and AddressBook default to `name,ASC`; EntryPoint requests profile-scoped `/v3/dial-number` rows with `entryPointName,ASC` and maps them into the established response wrapper while retaining direct HTTP completion/error semantics.
|
|
143
|
+
- **WHY**: SDK defaults are effective only when service wire parameters match the backend contract.
|
|
144
|
+
- **Evidence:** `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/services/AddressBook.ts`, `test/unit/spec/services/Queue.ts`, `test/unit/spec/services/EntryPoint.ts`, `test/unit/spec/services/AddressBook.ts`.
|
|
145
|
+
- **Acceptance:** Service tests assert Queue/AddressBook `sort=name,ASC`, EntryPoint `sort=entryPointName,ASC`, Queue defaults with undefined optional fields, explicit Queue overrides, required views/mapping fields, and row-for-row EntryPoint mapping.
|
|
146
|
+
|
|
147
|
+
### MOD-003 — Buddy-agent request contract (`AGENT-R-003`)
|
|
148
|
+
|
|
149
|
+
- **WHAT**: Preserve the existing `BuddyAgents` options object and correlated request/response contract while allowing its optional `action` field to derive state from `Consult` or `Transfer`. `mediaType` defaults to telephony, and an explicit `state` takes precedence over the action default.
|
|
150
|
+
- **WHY**: Eligibility changes must not alter AQM settlement or invent UI-side filtering.
|
|
151
|
+
- **Evidence:** `src/cc.ts`, `src/services/agent/index.ts`, `test/unit/spec/cc.ts`, `test/unit/spec/services/agent/index.ts`.
|
|
152
|
+
- **Acceptance:** Transfer sends `Available`; Consult sends no state; explicit state callers remain typed and supported.
|
|
153
|
+
|
|
154
|
+
### MOD-004 — Query-aware cache eligibility (`UTILS-R-001`, `UTILS-R-006`)
|
|
155
|
+
|
|
156
|
+
- **WHAT**: Treat enabled profile/response-shape flags and non-default sorts as cache-disqualifying inputs. Existing Queue requests bypass cache through their fixed filters/views, EntryPoint makes its profile-scoped requests directly without PageCache, and default `name,ASC` AddressBook pages remain cache-eligible because that ordering is invariant for its base cache key.
|
|
157
|
+
- **WHY**: A page keyed only by scope/page/pageSize cannot safely represent query variants, but it can safely represent one invariant default order.
|
|
158
|
+
- **Evidence:** `src/utils/PageCache.ts`, `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `test/unit/spec/services/Queue.ts`, `test/unit/spec/services/EntryPoint.ts`.
|
|
159
|
+
- **Acceptance:** Two identical Queue view-filtered or custom-sort calls make two backend requests; EntryPoint always makes the requested backend call; repeated default-sorted AddressBook pagination remains cache-eligible.
|
|
160
|
+
|
|
161
|
+
### MOD-005 — Direct entry-point transfer routing (`TASK-R-003`, `TASK-R-009`)
|
|
162
|
+
|
|
163
|
+
- **WHAT**: Keep Entry Point in eligible voice Transfer destination controls. When `Task.transfer()` receives the public `entryPoint` destination, translate it internally to `entrypointDialNumber` and invoke `contact.vteamTransfer`; Queue remains on `vteamTransfer`, while Agent and Dial Number remain on `blindTransfer`.
|
|
164
|
+
- **WHY**: Consumers must be able to follow Task controls directly without knowing backend routing values, and supported entry-point transfers must use the same vteam operation as the established transfer policy.
|
|
165
|
+
- **Evidence:** `src/services/task/Task.ts`, `src/services/task/constants.ts`, `src/services/task/types.ts`, `test/unit/spec/services/task/Task.ts`.
|
|
166
|
+
- **Acceptance:** Task tests assert the exact EPDN vteam payload, no blind-transfer call, and unchanged Queue/Agent dispatch.
|
|
167
|
+
|
|
168
|
+
## Acceptance criteria
|
|
169
|
+
|
|
170
|
+
- [x] Transfer buddy lookup sends state `Available`; Consult omits state; action-based media defaults to telephony (`MOD-003`, `SDK-LIST-R-003`).
|
|
171
|
+
- [x] Existing `getQueues` sends the default inbound/active/telephony filter, backend name ascending order, desktop-profile, agent, and first-level views without a field projection (`MOD-001`, `MOD-002`, `SDK-LIST-R-001`).
|
|
172
|
+
- [x] Queue optional fields set to `undefined` retain safe defaults, while explicit `false` and an explicit empty filter remain overrides (`MOD-002`, `SDK-LIST-R-001`).
|
|
173
|
+
- [x] Existing `getEntryPoints` requests desktop-profile-filtered `/v3/dial-number` mappings with required headers, entry-point names, and backend `entryPointName,ASC`, then exposes each dialled number as `EntryPointRecord.number` without changing row order (`SDK-LIST-R-002`, `SDK-LIST-R-007`).
|
|
174
|
+
- [x] Caller-supplied existing queue filters override its telephony default; compatible EntryPoint filters/sorts override its v3 mapping defaults while profile scoping remains fixed (`SDK-LIST-R-001`, `SDK-LIST-R-002`, `SDK-LIST-R-011`).
|
|
175
|
+
- [x] AddressBook sends backend name ascending order by default and honors a caller-supplied descending override (`MOD-002`, `SDK-LIST-R-004`, `SDK-LIST-R-010`).
|
|
176
|
+
- [x] Queue, EntryPoint, and AddressBook serialize CMS ordering as the combined `sort` query value (`MOD-002`, `SDK-LIST-R-005`).
|
|
177
|
+
- [x] Queue `sortOrder` without `sortBy` serializes as `sort=name,<ORDER>` and bypasses the simple-page cache (`SDK-LIST-R-005`, `SDK-LIST-R-006`).
|
|
178
|
+
- [x] Default Queue policy and other view/filter/shape/custom-sort requests bypass PageCache, EntryPoint makes its profile-scoped requests directly, and default-sorted AddressBook pages remain cacheable (`MOD-004`, `SDK-LIST-R-006`).
|
|
179
|
+
- [x] No SDK façade or service sorts returned arrays in JavaScript (`SDK-LIST-R-007`).
|
|
180
|
+
- [x] Existing queue and entry-point methods retain their response wrappers; `EntryPointRecord` additively types mapped `number` and marks configuration-only fields optional because the v3 mapping response does not provide them (`SDK-LIST-R-008`).
|
|
181
|
+
- [x] The Contact Center sample uses the existing Task/list surfaces, labels buddy-agent availability, and displays `EntryPointRecord.number` when present (`SDK-LIST-R-002`, `SDK-LIST-R-008`).
|
|
182
|
+
- [x] The Contact Center sample clears and disables its destination selector for a present empty Task destination array, while missing controls retain backward compatibility (`SDK-LIST-R-014`).
|
|
183
|
+
- [x] Direct entry-point transfer remains SDK-advertised for eligible voice tasks and is sent through `vteamTransfer` as `entrypointDialNumber`, with no widgets-side translation (`MOD-005`, `SDK-LIST-R-013`).
|
|
184
|
+
- [x] The package builds and the complete Contact Center unit and style suites pass (`SDK-LIST-R-008`).
|
|
185
|
+
|
|
186
|
+
## Scenarios and applicable change views
|
|
187
|
+
|
|
188
|
+
| Scenario | Actor | Preconditions | Expected behavior | Failure or boundary behavior | Requirements |
|
|
189
|
+
| --- | --- | --- | --- | --- | --- |
|
|
190
|
+
| Consult buddy agents | SDK consumer | `action=Consult` | Telephony defaults when absent; state is omitted; backend order is preserved. | Request rejection is measured/logged and rethrown. | `SDK-LIST-R-003`, `SDK-LIST-R-007` |
|
|
191
|
+
| Transfer buddy agents | SDK consumer | `action=Transfer` | State `Available` is sent for the selected media. | Explicit state and action cannot be combined by the public type. | `SDK-LIST-R-003`, `SDK-LIST-R-008` |
|
|
192
|
+
| Queue list | SDK consumer | Existing method called with page/search and optional filter override | SDK applies the default telephony policy and returns full records unchanged; an explicit existing filter overrides eligibility. | HTTP failure is propagated without a synthetic page. | `SDK-LIST-R-001`, `SDK-LIST-R-007`, `SDK-LIST-R-011` |
|
|
193
|
+
| Entry-point list | SDK consumer | Existing method called with page/search and optional compatible overrides | SDK fetches desktop-profile dial-number mappings, preserves backend order/meta, and returns `{id, name, number?}` rows through `EntryPointListResponse`. | HTTP failure is propagated without a synthetic page. | `SDK-LIST-R-002`, `SDK-LIST-R-007`, `SDK-LIST-R-008`, `SDK-LIST-R-009` |
|
|
194
|
+
| Dial-number list | SDK consumer | AddressBook page/search supplied | AddressBook applies backend `name,ASC` by default and returns the response unchanged. | A custom sort overrides the default and bypasses the default-order cache. | `SDK-LIST-R-010` |
|
|
195
|
+
| Specialized list consumer | SDK consumer | Uses an existing list method with explicit parameters | Explicit filter/sort/profile inputs override defaults. | No parallel consult/transfer method or projected response type is required. | `SDK-LIST-R-004`, `SDK-LIST-R-005` |
|
|
196
|
+
| Direct entry-point transfer | SDK consumer | Voice Task exposes Entry Point in the Transfer destination array | `Task.transfer({to, destinationType: 'entryPoint'})` sends `{to, destinationType: 'entrypointDialNumber'}` through `vteamTransfer`. | Vteam rejection is measured and rethrown; `blindTransfer` is not invoked. | `SDK-LIST-R-012`, `SDK-LIST-R-013` |
|
|
197
|
+
| Sample receives an empty destination array | Sample user | Task exposes the requested action with `[]` | Destination selector is cleared and disabled. | Missing/undefined destination controls use the sample's compatibility defaults. | `SDK-LIST-R-014` |
|
|
198
|
+
|
|
199
|
+
### Interaction and scenario matrix
|
|
200
|
+
|
|
201
|
+
| Context or interacting state | Trigger | Expected result | Invalid or conflicting result | Requirements |
|
|
202
|
+
| --- | --- | --- | --- | --- |
|
|
203
|
+
| Consult + agent | Action request | No state filter | Applying Transfer-only `Available` | `SDK-LIST-R-003` |
|
|
204
|
+
| Transfer + agent | Action request | `state=Available` | Returning idle agents through an omitted state filter | `SDK-LIST-R-003` |
|
|
205
|
+
| Queue + social media | Existing list request with filter override | Caller supplies `channelType==SOCIAL_CHANNEL` through `filter` | Adding a second media-bearing method signature | `SDK-LIST-R-001`, `SDK-LIST-R-011` |
|
|
206
|
+
| View-filtered Queue or profile-scoped EntryPoint | Repeated page request | Backend called for each request | Simple-page cache hit | `SDK-LIST-R-006` |
|
|
207
|
+
| Existing Queue or AddressBook | Sort omitted | Backend receives `sort=name,ASC` | Consumer must provide the default itself | `SDK-LIST-R-005`, `SDK-LIST-R-010` |
|
|
208
|
+
| Existing EntryPoint | Sort omitted | Backend receives `sort=entryPointName,ASC` and mapped rows remain in that order | Widget sorts or requests the mapping itself | `SDK-LIST-R-002`, `SDK-LIST-R-005`, `SDK-LIST-R-007` |
|
|
209
|
+
| Existing Queue, EntryPoint, or AddressBook | Custom sort supplied | Backend receives the requested field/order | SDK overwrites the caller's explicit behavior | `SDK-LIST-R-004`, `SDK-LIST-R-010` |
|
|
210
|
+
| Backend result | Response received | Array and metadata returned in backend order | JavaScript `.sort()` or consumer-specific reorder | `SDK-LIST-R-007` |
|
|
211
|
+
| Voice Transfer + entry point | Destination selected | SDK maps `entryPoint` to backend `entrypointDialNumber` and calls `vteamTransfer` | Sending `entryPoint` through `blindTransfer` or hiding the supported category | `SDK-LIST-R-013` |
|
|
212
|
+
| Sample + present empty controls | Task selection changes | Selector has no options and is disabled | Sample substitutes legacy defaults for an explicit empty array | `SDK-LIST-R-014` |
|
|
213
|
+
|
|
214
|
+
### API contract delta
|
|
215
|
+
|
|
216
|
+
| API or operation | Change | Consumer impact | Compatibility expectation | Canonical definition |
|
|
217
|
+
| --- | --- | --- | --- | --- |
|
|
218
|
+
| Buddy-agent input | Add optional `action` to the existing options object and make `mediaType` optional with a telephony default. | Consumers may pass Consult/Transfer instead of choosing state. | Additive public option; explicit-state callers remain supported and take precedence. | `src/types.ts` |
|
|
219
|
+
| Existing queue list | Apply the telephony filter, profile views, and `name,ASC` by default. | Thin clients call `getQueues`; other consumers use existing parameters for overrides. | Intentional default correction; method and response signature unchanged. | `src/cc.ts`, `src/services/Queue.ts` |
|
|
220
|
+
| Existing entry-point list | Fetch desktop-profile `/v3/dial-number` mappings with the required organization/internal-data headers, request entry-point names, map fields row-for-row, and use `entryPointName,ASC` by default. | Thin clients call `getEntryPoints` and receive the displayed number without joining another endpoint. | Intentional default correction; method and response wrapper unchanged. | `src/cc.ts`, `src/services/EntryPoint.ts`, `src/services/config/constants.ts`, `src/services/core/WebexRequest.ts` |
|
|
221
|
+
| `EntryPointRecord` | Add optional mapped `number`; make configuration-only `type`, `isActive`, and `orgId` optional for truthful mapped-list typing. | Consumers can render the dialled number without a cast and cannot assume absent configuration fields. | Additive field with a type-correctness adjustment; no new response wrapper. | `src/types.ts` |
|
|
222
|
+
| Task destination controls | Add ordered `consultTransferDestinations.consult` and `.transfer` arrays to `TaskUIControls`. | Task consumers render availability directly; no separate policy call or raw profile injection is needed. | Additive public field using the existing destination values; no new standalone public alias. | `src/services/task/types.ts`, `src/services/task/state-machine/uiControlsComputer.ts`, `src/index.ts` |
|
|
223
|
+
| Existing `Task.transfer` entry-point input | Correct internal transport and backend destination translation. | Consumers keep passing `{to, destinationType: 'entryPoint'}` from the Task control array. | Behavioral bug fix; no method or public payload signature change. | `src/services/task/Task.ts`, `src/services/task/constants.ts` |
|
|
224
|
+
|
|
225
|
+
### Public API and semver impact
|
|
226
|
+
|
|
227
|
+
| Export or entry point | Change | Affected consumers | Required version change | Deprecation or migration |
|
|
228
|
+
| --- | --- | --- | --- | --- |
|
|
229
|
+
| Existing `getQueues` / `getEntryPoints` | Default request behavior changes; signatures do not | Widgets and other SDK consumers | Behavioral semver review | Pass compatible existing filters/sorts when different behavior is required; entry-point profile scoping remains SDK-owned. |
|
|
230
|
+
| `BuddyAgents` | Add optional action-based defaults to the existing options object while retaining explicit state | Existing and new consumers | Minor | Existing explicit-state calls remain valid and override action defaults. |
|
|
231
|
+
| `TaskUIControls` | Add inline ordered, action-specific destination availability using existing destination values | Task UI consumers | Minor | Read the matching action array; first item is the default category. |
|
|
232
|
+
| `Task.transfer` | Route the existing public `entryPoint` value through vteam transfer as backend `entrypointDialNumber` | Existing voice-task consumers | Patch/behavioral correction | No caller migration; backend translation is SDK-owned. |
|
|
233
|
+
| `EntryPointRecord` | Add optional mapped `number`; configuration-only fields become optional | Entry-point list consumers | Behavioral/type-contract review | Render `number` when present and handle configuration-only fields as optional. |
|
|
234
|
+
|
|
235
|
+
### Cross-package impact
|
|
236
|
+
|
|
237
|
+
| Package | Change | Dependency direction | Release sequencing | Owner |
|
|
238
|
+
| --- | --- | --- | --- | --- |
|
|
239
|
+
| `@webex/contact-center` | Owns action/default/filter/order/cache policy and Task destination visibility/order decisions. | SDK → consumers | Build/release first. | SDK maintainers |
|
|
240
|
+
| `@webex/cc-store` | Delegates entry points directly to the existing SDK method; uses the existing queue `filter` parameter only for a non-telephony active task. | store → SDK | Consume a compatible SDK release. | Widgets maintainers |
|
|
241
|
+
| `@webex/cc-task` and `@webex/cc-components` | Supply action and render results. | UI → store → SDK | Release after compatible store/SDK. | Widgets maintainers |
|
|
242
|
+
|
|
243
|
+
## Contracts delta
|
|
244
|
+
|
|
245
|
+
**Provides — MODIFIED:** The package keeps the existing queue, entry-point, buddy-agent, and Task transfer methods. Queue retains its established request/full-response signature and telephony defaults; EntryPoint retains its request/response wrapper while mapping desktop-profile dial-number rows to typed `{id, name, number?}` records in backend order; buddy agents accept action-aware input through `BuddyAgents`; `TaskUIControls` exposes inline ordered action-specific destination availability; direct entry-point transfer uses SDK-owned EPDN/vteam translation without changing the public payload.
|
|
246
|
+
|
|
247
|
+
**Requires — MODIFIED:** Queue, EntryPoint, and AddressBook services require CMS list endpoints to honor the combined sort value. Queue requires its profile/agent/first-level views; EntryPoint requires `/v3/dial-number` to honor the organization/internal-data headers, desktop-profile filtering, `includeEntryPointName`, and mapping attributes. Direct entry-point transfer requires the WCC vteam transfer operation to accept the established `entrypointDialNumber` destination and selected entry-point identifier. The SDK continues to rely on host-authenticated Webex requests and backend response ordering.
|
|
248
|
+
|
|
249
|
+
No event contract changes.
|
|
250
|
+
|
|
251
|
+
## Success and guardrail metrics
|
|
252
|
+
|
|
253
|
+
| Metric | Baseline | Target | Measurement source |
|
|
254
|
+
| --- | --- | --- | --- |
|
|
255
|
+
| Consumers that must recreate the default queue/entry-point policy | Widgets did | 0 for ordinary existing-method calls | `src/services/Queue.ts`, `src/services/EntryPoint.ts` |
|
|
256
|
+
| JavaScript-side destination sorts in the changed SDK path | 0 | 0 | `src/cc.ts`, `src/services/Queue.ts`, `src/services/EntryPoint.ts` |
|
|
257
|
+
| Cache hits for view/filter/shape query variants | Possible | 0 | `test/unit/spec/services/Queue.ts`, `test/unit/spec/services/EntryPoint.ts` |
|
|
258
|
+
| Contact Center unit failures | Unknown before change | 0 | `test/unit/spec` |
|
|
259
|
+
| Contact Center build/style errors | Unknown before change | 0 | Package build and style commands |
|
|
260
|
+
|
|
261
|
+
## Requested data and fields
|
|
262
|
+
|
|
263
|
+
| Entity or payload | Requested field or shape | Purpose | Ownership | Privacy, retention, or compatibility constraint |
|
|
264
|
+
| --- | --- | --- | --- | --- |
|
|
265
|
+
| Buddy-agent input | Existing options object with optional `action`, `mediaType`, and explicit `state`; explicit state takes precedence | Derive Consult/Transfer eligibility without a parallel public input type. | SDK public type | No credential or persistent data. |
|
|
266
|
+
| Queue search input | Existing page, page size, search, filter, sort, and profile parameters | Consumer-controlled pagination plus optional default overrides. | Existing SDK public type | No second media-bearing request type. |
|
|
267
|
+
| Queue backend query | Default inbound/active/telephony filter, name ascending, desktop-profile/agent/first-level views, and no field projection | Full queue result using the default list policy. | Queue service | Fixed filter/views bypass simple-page caching. |
|
|
268
|
+
| Entry-point backend query | `/v3/dial-number`, `X-ORGANIZATION-ID`, `x-ignore-internal-data=false`, `desktopProfileFilter=true`, `includeEntryPointName=true`, required mapping attributes, and `entryPointName,ASC` | Return profile-scoped EP-DN rows with the visible dialled number. | EntryPoint service and shared WebexRequest wrapper | The service does not use PageCache for these profile-scoped requests. |
|
|
269
|
+
| Entry-point response row | `id=entryPointId`, `name=entryPointName`, optional `number=dialledNumber` | Let consumers route by entry-point ID and display the mapped dialled number without a cast or second request. | `EntryPointRecord` public type | Mapping preserves response order and pagination metadata. |
|
|
270
|
+
| Direct entry-point transfer payload | Caller-selected `to`; public `entryPoint` translated internally to `entrypointDialNumber` | Invoke the supported vteam transfer operation without consumer-side backend knowledge. | Task service | Translation is transport-only; metrics retain the caller-facing destination type and no new public field is required. |
|
|
271
|
+
| AddressBook backend query | Existing caller-selected fields plus name ascending by default | Backend-ordered dial numbers without a specialized façade. | AddressBook service | A non-default sort bypasses the default-order cache. |
|
|
272
|
+
|
|
273
|
+
## Impacted domains
|
|
274
|
+
|
|
275
|
+
| Repository or module | Impact | Owner |
|
|
276
|
+
| --- | --- | --- |
|
|
277
|
+
| `src` | Public façade and exports | SDK maintainers |
|
|
278
|
+
| `src/services` | Queue/EntryPoint/AddressBook wire query construction | SDK maintainers |
|
|
279
|
+
| `src/services/agent` | Existing correlated buddy-agent operation receives façade-derived state | SDK maintainers |
|
|
280
|
+
| `src/services/task` | Direct entry-point transfer dispatch and backend destination translation | SDK maintainers |
|
|
281
|
+
| `src/utils` | Cache eligibility for query variants | SDK maintainers |
|
|
282
|
+
| Webex widgets repository | Thin consumer of the new defaults | Widgets maintainers |
|
|
283
|
+
|
|
284
|
+
## Feasibility and risks
|
|
285
|
+
|
|
286
|
+
| Risk or assumption | Evidence | Mitigation or decision owner |
|
|
287
|
+
| --- | --- | --- |
|
|
288
|
+
| CMS ignores ordering when encoded as legacy separate keys. | `src/services/Queue.ts`, `src/services/EntryPoint.ts` | Use and test combined `sort=<field>,<ORDER>` serialization. |
|
|
289
|
+
| Simple cache returns a page created under a different view. | `src/utils/PageCache.ts` | Make every result/shape flag cache-disqualifying and retain repeated-call tests. |
|
|
290
|
+
| New EntryPoint/AddressBook ordering defaults affect generic callers. | `src/services/EntryPoint.ts`, `src/services/AddressBook.ts` | Make the correction explicit, retain caller overrides, and test both default and custom order. |
|
|
291
|
+
| A consumer re-sorts backend results. | `test/unit/spec/cc.ts` | Return the delegated response unchanged and document backend order as authoritative. |
|
|
292
|
+
| Direct entry-point transfer is sent to the blind-transfer operation or with the public destination literal. | `src/services/task/Task.ts`, established transfer-policy behavior | Route through `vteamTransfer`, translate to `entrypointDialNumber`, and assert the exact payload. |
|
|
293
|
+
| Entry-point configuration records do not contain the visible dialled number, and widget runtime returned no provisional `dbId`. | The backend `/v3/dial-number` contract returns `dialledNumber`, `entryPointId`, and `entryPointName`. | Move the EP-DN request/mapping into existing `getEntryPoints`, type `number`, and keep widget rendering declarative. |
|
|
294
|
+
|
|
295
|
+
## Error Matrix
|
|
296
|
+
|
|
297
|
+
| Failure | SDK behavior | Consumer-visible result | Evidence |
|
|
298
|
+
| --- | --- | --- | --- |
|
|
299
|
+
| Buddy-agent AQM rejection | Record failure context and rethrow. | Promise rejects; no synthetic agent list. | `src/cc.ts`, `test/unit/spec/cc.ts` |
|
|
300
|
+
| Queue HTTP rejection | Service metrics/logging remain active and the error propagates. | Promise rejects; no synthetic paginated result. | `src/services/Queue.ts`, `test/unit/spec/services/Queue.ts` |
|
|
301
|
+
| Entry-point HTTP rejection | Service metrics/logging remain active and the error propagates. | Promise rejects; no synthetic paginated result. | `src/services/EntryPoint.ts`, `test/unit/spec/services/EntryPoint.ts` |
|
|
302
|
+
| Missing action-based media | Default to telephony. | Valid request with predictable channel. | `src/cc.ts`, `test/unit/spec/cc.ts` |
|
|
303
|
+
| Non-default queue media eligibility | Consumer supplies a complete allowlisted RSQL value through the existing `filter` field; the SDK performs no media-string interpolation. | Existing queue method returns matching records or propagates the backend error. | `src/services/Queue.ts`, service tests |
|
|
304
|
+
| Direct entry-point vteam transfer rejection | Preserve existing Task transfer error normalization, failure metrics, and rethrow semantics. | `Task.transfer()` rejects; no fallback blind-transfer request is made. | `src/services/task/Task.ts`, `test/unit/spec/services/task/Task.ts` |
|
|
305
|
+
|
|
306
|
+
## Resilience
|
|
307
|
+
|
|
308
|
+
- Existing methods make one delegated list request and add no retry or request fan-out.
|
|
309
|
+
- Queue, EntryPoint, and AddressBook callers use compatible explicit existing parameters when they require non-default behavior.
|
|
310
|
+
- View/filter/shape queries bypass cache rather than risk stale or cross-policy results.
|
|
311
|
+
- Errors remain caller-visible; the SDK does not manufacture an empty success response.
|
|
312
|
+
|
|
313
|
+
## Observability
|
|
314
|
+
|
|
315
|
+
- Existing buddy-agent success/failure metrics retain media and derived state context plus count, without logging agent identities.
|
|
316
|
+
- Existing Queue and EntryPoint request/success/failure metrics continue to cover the default and overridden calls.
|
|
317
|
+
- Existing Task transfer success/failure metrics continue to report the caller-facing entry-point destination while transport uses the backend EPDN value.
|
|
318
|
+
- No new metric taxonomy, PII-bearing log, credential log, trace, or alert is introduced.
|
|
319
|
+
|
|
320
|
+
## Operations
|
|
321
|
+
|
|
322
|
+
- Build and run the complete Contact Center unit suite and style check before publishing.
|
|
323
|
+
- Release the SDK before or with widgets that require the corrected existing-method defaults and Task controls.
|
|
324
|
+
- Rollback is a coordinated package-version/code rollback; no persisted state, schema, or cache migration is required.
|
|
325
|
+
|
|
326
|
+
## Migration expectations
|
|
327
|
+
|
|
328
|
+
- Compatibility: list method names and response wrappers remain unchanged; explicit buddy-agent state remains supported; optional `EntryPointRecord.number` is additive and configuration-only entry-point fields are now optional. Queue/AddressBook request `name,ASC`; EntryPoint requests mapped, profile-scoped `entryPointName,ASC` rows while retaining compatible filter/sort overrides.
|
|
329
|
+
- Data or consumer transition: thin consumers continue using `getQueues` and `getEntryPoints`; consumers needing different behavior pass existing query overrides.
|
|
330
|
+
- Coexistence period: no parallel list surface exists.
|
|
331
|
+
- Completion and rollback outcome: consumers no longer own the default consult/transfer policy; rollback restores prior calls without data cleanup.
|
|
332
|
+
|
|
333
|
+
## Serviceability
|
|
334
|
+
|
|
335
|
+
| Signal or support surface | Required change | Consumer or operator | Acceptance evidence |
|
|
336
|
+
| --- | --- | --- | --- |
|
|
337
|
+
| Buddy-agent operational metrics | Report derived action state and media without identities. | SDK maintainers | `test/unit/spec/cc.ts` |
|
|
338
|
+
| Queue request metrics/logs | Preserve existing request success/failure coverage for default and overridden calls. | SDK maintainers | `test/unit/spec/services/Queue.ts` |
|
|
339
|
+
| Entry-point request metrics/logs | Preserve existing request success/failure coverage for default and overridden calls. | SDK maintainers | `test/unit/spec/services/EntryPoint.ts` |
|
|
340
|
+
|
|
341
|
+
## Documentation obligations
|
|
342
|
+
|
|
343
|
+
- This approved delta modifies `CONTACT_CENTER-R-003`, `SERVICES-R-002`, `SERVICES-R-007`, `AGENT-R-003`, `UTILS-R-001`, and `UTILS-R-006` without overwriting protected canonical specs.
|
|
344
|
+
- Direct entry-point routing additionally modifies `TASK-R-003` and `TASK-R-009` through this approved MODIFIED delta; the protected Task canonical spec remains unchanged until a future reconciliation/promotion.
|
|
345
|
+
- The paired widgets feature spec must reference this SDK delta as the owner of queue eligibility/order/profile views and entry-point dial-number mapping/order; widgets delegate entry points without media filtering and may pass a queue filter for an active non-telephony task.
|
|
346
|
+
- A future canonical-spec promotion must fold this delta into the routed module specs and reconcile the delta path rather than duplicate the requirements.
|
|
347
|
+
|
|
348
|
+
## Decision and change log
|
|
349
|
+
|
|
350
|
+
| Date | Decision or change | Rationale | Owner |
|
|
351
|
+
| --- | --- | --- | --- |
|
|
352
|
+
| 2026-08-21 | Replaced provisional `dbId` with typed `EntryPointRecord.number` populated from the backend `/v3/dial-number` mapping, and kept the existing `getEntryPoints` method/response wrapper. | Runtime testing showed no `dbId`; the dialled number belongs to the EP-DN mapping, and consumers should not join or reinterpret backend data. | Developer + Codex |
|
|
353
|
+
| 2026-08-21 | Made Queue defaults resilient to optional properties explicitly set to `undefined`, retained explicit false/empty overrides, and made the sample honor a present empty destination array. | Common object-building patterns must not silently disable safe SDK defaults, and an explicit Task policy decision must not be replaced by sample fallback categories. | Developer + Codex |
|
|
354
|
+
| 2026-08-21 | Superseded the provisional optional `EntryPointRecord.dbId` experiment. | Runtime validation established that the displayed field is `dialledNumber` from the EP-DN mapping, now exposed as `number`. | Developer + Codex |
|
|
355
|
+
| 2026-08-20 | Kept Entry Point available for eligible voice transfers and corrected `Task.transfer()` to use vteam routing with internal `entrypointDialNumber` translation. | The backend transfer policy supports direct entry-point transfer; hiding it would remove valid functionality, while consumers should not know the backend EPDN literal. | Developer + Codex |
|
|
356
|
+
| 2026-08-19 | Kept action/media typing inside `BuddyAgents`, inlined the destination arrays on `TaskUIControls`, removed the new root aliases, and removed `dbId` additions from queue/entry-point records. | The established methods and types already express the required behavior; consumers do not need standalone aliases or an unused record field. | Developer + Codex |
|
|
357
|
+
| 2026-08-19 | Approved this exact MODIFIED delta path. | Preserve protected canonical specs while maintaining spec-currency with the implementation. | Developer |
|
|
358
|
+
| 2026-08-19 | Assigned all reusable eligibility, query, ordering, and cache decisions to the SDK. | Keep widgets thin and prevent cross-consumer behavior drift. | Developer + Codex |
|
|
359
|
+
| 2026-08-19 | Made backend response order authoritative and prohibited SDK-side JavaScript sorting. | One backend ordering decision must reach every consumer unchanged. | Developer + Codex |
|
|
360
|
+
| 2026-08-19 | Moved EntryPoint and AddressBook `name,ASC` ordering to service defaults and removed the specialized dial-number façade. | Widgets must work without supplying SDK-owned decisions; other consumers can pass explicit sort overrides. | Developer + Codex |
|
|
361
|
+
| 2026-08-19 | Removed the specialized queue/entry-point methods and destination response/options types and kept default policy on existing `getQueues`/`getEntryPoints` with existing overrides. | Consumers should keep established method signatures; a parallel list abstraction adds needless public surface and projection complexity. The later EP-DN correction retained the response wrapper while mapping truthful fields. | Developer + Codex |
|
|
362
|
+
| 2026-08-19 | Put ordered Consult/Transfer destination availability directly on every Task's `uiControls` instead of adding `getConsultTransferDestinationPolicy`. | The Task already owns UI decisions and live interaction data, so consumers should not make a second request or reproduce profile/media/direction rules. | Developer + Codex |
|