@webex/contact-center 3.12.0-next.149 → 3.12.0-next.150

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.
Files changed (37) hide show
  1. package/.sdd/manifest.json +1 -1
  2. package/ai-docs/CONTRACTS.md +1 -0
  3. package/dist/cc.js +4 -4
  4. package/dist/cc.js.map +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/services/config/Util.js +38 -45
  7. package/dist/services/config/Util.js.map +1 -1
  8. package/dist/services/config/constants.js +15 -71
  9. package/dist/services/config/constants.js.map +1 -1
  10. package/dist/services/config/index.js +49 -226
  11. package/dist/services/config/index.js.map +1 -1
  12. package/dist/services/config/types.js +33 -11
  13. package/dist/services/config/types.js.map +1 -1
  14. package/dist/types/cc.d.ts +3 -3
  15. package/dist/types/index.d.ts +16 -8
  16. package/dist/types/services/config/Util.d.ts +4 -8
  17. package/dist/types/services/config/constants.d.ts +15 -71
  18. package/dist/types/services/config/index.d.ts +16 -64
  19. package/dist/types/services/config/types.d.ts +97 -160
  20. package/dist/webex.js +1 -1
  21. package/package.json +1 -1
  22. package/src/cc.ts +4 -4
  23. package/src/index.ts +16 -8
  24. package/src/services/agent/ai-docs/AGENTS.md +1 -1
  25. package/src/services/config/Util.ts +43 -82
  26. package/src/services/config/ai-docs/AGENTS.md +34 -39
  27. package/src/services/config/ai-docs/ARCHITECTURE.md +88 -101
  28. package/src/services/config/ai-docs/config-spec.md +115 -132
  29. package/src/services/config/constants.ts +18 -80
  30. package/src/services/config/index.ts +52 -278
  31. package/src/services/config/types.ts +101 -185
  32. package/test/unit/spec/index.ts +6 -2
  33. package/test/unit/spec/services/config/Util.ts +442 -70
  34. package/test/unit/spec/services/config/index.ts +246 -544
  35. package/typedoc.md +1 -1
  36. package/umd/contact-center.min.js +2 -2
  37. package/umd/contact-center.min.js.map +1 -1
@@ -29,27 +29,23 @@ sequenceDiagram
29
29
  CC->>Cfg: getAgentConfig(orgId, agentId)
30
30
 
31
31
  par Wave 1 — fire immediately
32
- Cfg->>WR: getUserUsingCI
33
- Cfg->>WR: getOrgInfo
34
- Cfg->>WR: getOrganizationSetting
35
- Cfg->>WR: getTenantData
36
- Cfg->>WR: getURLMapping
32
+ Cfg->>WR: getUserDesktopLoginConfig
33
+ Cfg->>WR: getOrgDesktopLoginConfig
37
34
  Cfg->>WR: getAllAuxCodes
38
35
  end
39
36
 
40
- WR->>API: 6 parallel API calls
37
+ WR->>API: 3 parallel API calls
41
38
  API-->>WR: Responses
42
- Note over Cfg: await userConfigData (needed for wave 2)
39
+ Note over Cfg: await userConfig (supplies dbId, siteId, dialPlanEnabled)
43
40
 
44
- par Wave 2 — depends on userConfigData
45
- Cfg->>WR: getDesktopProfileById(agentProfileId)
46
- Cfg->>WR: getSiteInfo(siteId)
47
- Cfg->>WR: getAllTeams(teamIds)
41
+ par Wave 2 — depends on userConfig
42
+ Cfg->>WR: getSiteInfo(user.siteId)
43
+ Cfg->>WR: getAllTeams(user.dbId)
44
+ Cfg->>WR: getDialPlanData (only if agentProfile.dialPlanEnabled)
48
45
  end
49
46
 
50
- Note over Cfg: getDialPlanData chained off agentProfile<br/>(fires only if dialPlanEnabled)
51
-
52
- Note over Cfg: Single Promise.all() awaits all 9 promises<br/>(wave 1 + wave 2 + conditional dialPlan)
47
+ Note over Cfg: Single Promise.all() awaits 5 promises<br/>(org aggregate + aux codes + site + teams + conditional dialPlan)
48
+ Note over Cfg: multimediaProfileId = team value, else site value
53
49
 
54
50
  WR->>API: Remaining API calls
55
51
  API-->>WR: Responses
@@ -64,10 +60,11 @@ sequenceDiagram
64
60
 
65
61
  The config service uses multiple API endpoints to fetch agent configuration data. These endpoints are defined in `constants.ts` and include:
66
62
 
67
- - **Core user data**: User profile, agent settings, site information
68
- - **Team & organization**: Team memberships, organization settings, tenant configuration
63
+ - **User desktop-login aggregate**: agent identity plus the `agentProfile` section in one call
64
+ - **Organization desktop-login aggregate**: organization info, organization settings, tenant configuration, URL mappings, AI feature, Microsoft/Webex config in one call
65
+ - **Team & site**: Team memberships filtered by the agent's `userId`, plus site information
69
66
  - **Auxiliary codes**: Idle codes and wrap-up codes with pagination
70
- - **Communication settings**: Dial plans, URL mappings, multimedia profiles
67
+ - **Communication settings**: Dial plans, multimedia profiles
71
68
  - **Outbound features**: Queue lists, entry points, address books, outdial ANI entries
72
69
 
73
70
  ### Endpoint Definitions
@@ -76,56 +73,44 @@ All endpoints are relative to the WCC API Gateway base URL. Query parameters lik
76
73
 
77
74
  **Example Usage:**
78
75
  ```typescript
79
- // Fetch user data
80
- const resource = endPointMap.userByCI('org-123', 'agent-456');
81
- // Result: "organization/org-123/user/by-ci-user-id/agent-456"
76
+ // Fetch the user desktop-login aggregate
77
+ const resource = endPointMap.userDesktopLogin('org-123', 'agent-456');
78
+ // Result: "organization/org-123/v2/user/by-ci-user-id/agent-456/desktop-login"
82
79
 
83
- // Fetch teams with pagination and filtering
84
- const resource = endPointMap.listTeams('org-123', 0, 100, ['team-1', 'team-2']);
85
- // Result: "organization/org-123/v2/team?page=0&pageSize=100&filter=id=in=(team-1,team-2)"
80
+ // Fetch teams with pagination, filtered by the user's database id
81
+ const resource = endPointMap.listTeams('org-123', 0, 100, 'user-db-id');
82
+ // Result: "organization/org-123/v2/team?page=0&pageSize=100&agentView=true&filter=userId==user-db-id"
86
83
 
87
- // Fetch organization settings
88
- const resource = endPointMap.orgSettings('org-123');
89
- // Result: "organization/org-123/v2/organization-setting?agentView=true"
84
+ // Fetch the organization desktop-login aggregate
85
+ const resource = endPointMap.orgDesktopLogin('org-123');
86
+ // Result: "organization/org-123/desktop-login"
90
87
  ```
91
88
 
92
89
  **Full Endpoint Map:**
93
90
  ```typescript
94
91
  export const endPointMap = {
95
- userByCI: (orgId: string, agentId: string) =>
96
- `organization/${orgId}/user/by-ci-user-id/${agentId}`,
92
+ orgDesktopLogin: (orgId: string) =>
93
+ `organization/${orgId}/desktop-login`,
97
94
 
98
- desktopProfile: (orgId: string, desktopProfileId: string) =>
99
- `organization/${orgId}/agent-profile/${desktopProfileId}`,
95
+ userDesktopLogin: (orgId: string, ciUserId: string) =>
96
+ `organization/${orgId}/v2/user/by-ci-user-id/${ciUserId}/desktop-login`,
100
97
 
101
98
  multimediaProfile: (orgId: string, multimediaProfileId: string) =>
102
99
  `organization/${orgId}/multimedia-profile/${multimediaProfileId}`,
103
100
 
104
- listTeams: (orgId: string, page: number, pageSize: number, filter: string[]) =>
105
- `organization/${orgId}/v2/team?page=${page}&pageSize=${pageSize}${
106
- filter && filter.length > 0 ? `&filter=id=in=(${filter})` : ''
107
- }`,
101
+ // The filter value must stay unquoted — the quoted form returns HTTP 400.
102
+ listTeams: (orgId: string, page: number, pageSize: number, userDbId: string) =>
103
+ `organization/${orgId}/v2/team?page=${page}&pageSize=${pageSize}` +
104
+ `&agentView=true&filter=userId==${userDbId}`,
108
105
 
109
106
  listAuxCodes: (orgId: string, page: number, pageSize: number, filter: string[], attributes: string[]) =>
110
107
  `organization/${orgId}/v2/auxiliary-code?page=${page}&pageSize=${pageSize}${
111
108
  filter && filter.length > 0 ? `&filter=id=in=(${filter})` : ''
112
109
  }&attributes=${attributes}`,
113
110
 
114
- orgInfo: (orgId: string) =>
115
- `organization/${orgId}`,
116
-
117
- orgSettings: (orgId: string) =>
118
- `organization/${orgId}/v2/organization-setting?agentView=true`,
119
-
120
111
  siteInfo: (orgId: string, siteId: string) =>
121
112
  `organization/${orgId}/site/${siteId}`,
122
113
 
123
- tenantData: (orgId: string) =>
124
- `organization/${orgId}/v2/tenant-configuration?agentView=true`,
125
-
126
- urlMapping: (orgId: string) =>
127
- `organization/${orgId}/v2/org-url-mapping?sort=name,ASC`,
128
-
129
114
  dialPlan: (orgId: string) =>
130
115
  `organization/${orgId}/dial-plan?agentView=true`,
131
116
 
@@ -190,16 +175,12 @@ The service fetches data from multiple APIs with these response structures:
190
175
 
191
176
  | API Method | Response Type | Key Fields | Usage |
192
177
  |------------|---------------|------------|-------|
193
- | `getUserUsingCI` | `AgentResponse` | `ciUserId`, `id`, `firstName`, `lastName`, `email`, `teamIds`, `agentProfileId`, `siteId` | Primary agent identity and profile references |
194
- | `getDesktopProfileById` | `DesktopProfileResponse` | `dialPlanEnabled`, `autoAnswer`, `accessWrapUpCode`, `wrapUpCodes`, `accessIdleCode`, `idleCodes`, `loginVoiceOptions` | Agent desktop settings and feature enablement |
195
- | `getAllTeams` | `TeamList[]` | `id`, `name`, `type`, `channelMap` (+ 10 more fields) | Full team details with channel configurations |
196
- | `getTenantData` | `TenantData` | `outdialEnabled`, `forceDefaultDn`, `privacyShieldVisible`, `timeoutDesktopInactivityEnabled` | Tenant-level feature flags |
197
- | `getOrgInfo` | `OrgInfo` | `tenantId`, `timezone` | Organization metadata |
178
+ | `getUserDesktopLoginConfig` | `UserDesktopLoginResponse` | `user`: `ciUserId`, `id`, `dbId`, `firstName`, `lastName`, `email`, `agentProfileId`, `siteId`. `agentProfile`: `dialPlanEnabled`, `accessWrapUpCode`, `accessIdleCode`, `loginVoiceOptions`, `viewableStatistics` | Agent identity, team-filter id, site reference, and desktop settings in one call |
179
+ | `getOrgDesktopLoginConfig` | `OrgDesktopLoginResponse` | `organization`: `tenantId`, `timezone`. `organizationSetting`: `webRtcEnabled`, `maskSensitiveData`, `campaignManagerEnabled`, `aiAssistantQuantity`. `tenantConfiguration`: `outdialEnabled`, `forceDefaultDn`, `privacyShieldVisible`, `timeoutDesktopInactivityEnabled`. Optional `urlMappings`, `aiFeature`, `microsoftConfig`, `webexConfig` | All organization-, tenant- and feature-scoped configuration in one call |
180
+ | `getAllTeams` | `TeamList[]` | `id`, `name`, `teamType`, `siteId`, `siteName`, `multiMediaProfileId` (+ more) | Team details for the teams the agent belongs to |
198
181
  | `getAllAuxCodes` | `AuxCode[]` | `id`, `name`, `workTypeCode`, `active`, `isSystemCode`, `defaultCode` | Auxiliary codes for idle/wrap-up states |
199
- | `getOrganizationSetting` | `OrgSettings` | `webRtcEnabled`, `maskSensitiveData`, `campaignManagerEnabled` | Organization-level feature flags |
200
- | `getDialPlanData` | `DialPlanEntity[]` | `id`, `name`, `regularExpression`, `prefix`, `strippedChars` | Dial plan rules for outbound calling |
201
- | `getURLMapping` | `URLMapping[]` | `name`, `url` | External service URL mappings |
202
- | `getSiteInfo` | `SiteInfo` | Site-specific configuration | Site details |
182
+ | `getDialPlanData` | `DialPlanEntity[]` | `id`, `name`, `regularExpression`, `prefix`, `strippedChars`, `active` | Dial plan rules for outbound calling |
183
+ | `getSiteInfo` | `SiteInfo` | Site-specific configuration | Site details, including the `multimediaProfileId` fallback |
203
184
 
204
185
  These responses are parsed and aggregated into a single `Profile` object by the `parseAgentConfigs` function.
205
186
 
@@ -208,28 +189,32 @@ These responses are parsed and aggregated into a single `Profile` object by the
208
189
  ```typescript
209
190
  // See full implementation in Util.ts
210
191
  function parseAgentConfigs(profileData: {
211
- userData: AgentResponse; // See types.ts:AgentResponse
212
- teamData: Team[]; // NOTE: Declared as Team[] (teamId, teamName) but receives TeamList[] (id, name, + 12 more fields) at runtime
213
- tenantData: TenantData; // See types.ts:TenantData
214
- orgInfoData: OrgInfo; // See types.ts:OrgInfo
215
- auxCodes: AuxCode[]; // See types.ts:AuxCode
216
- orgSettingsData: OrgSettings; // See types.ts:OrgSettings
217
- agentProfileData: DesktopProfileResponse; // See types.ts:DesktopProfileResponse
218
- dialPlanData: DialPlanEntity[]; // See types.ts:DialPlanEntity
219
- urlMapping: URLMapping[]; // See types.ts:URLMapping
192
+ orgConfig: OrgDesktopLoginResponse; // See types.ts:OrgDesktopLoginResponse
193
+ userData: AgentResponse; // `user` section; see types.ts:AgentResponse
194
+ agentProfileData: AgentProfile; // `agentProfile` section; see types.ts:AgentProfile
195
+ teamData: TeamList[]; // See types.ts:TeamList
196
+ auxCodes: AuxCode[]; // See types.ts:AuxCode
197
+ dialPlanData: DialPlanEntity[]; // See types.ts:DialPlanEntity
220
198
  multimediaProfileId: string;
221
- }): Profile { // See types.ts:Profile
222
- const { userData, teamData, tenantData, orgInfoData, auxCodes,
223
- orgSettingsData, agentProfileData, dialPlanData, urlMapping } = profileData;
199
+ }): Profile { // See types.ts:Profile
200
+ const { orgConfig, userData, agentProfileData, teamData, auxCodes,
201
+ dialPlanData } = profileData;
202
+ const {
203
+ organization: orgInfoData,
204
+ organizationSetting: orgSettingsData,
205
+ tenantConfiguration: tenantData,
206
+ urlMappings,
207
+ aiFeature,
208
+ microsoftConfig,
209
+ webexConfig,
210
+ } = orgConfig;
224
211
 
225
212
  // Aux code filtering via getFilterAuxCodes():
226
- // - checks auxCode.active
227
- // - checks specificCodes access level (ALL → no filter, SPECIFIC → include list)
213
+ // - checks auxCode.workTypeCode and auxCode.active
214
+ // - the aggregate returns the full org pool, so no per-agent restriction is applied
228
215
  // - maps to Entity {id, name, isSystem, isDefault}
229
- const wrapupCodes = getFilterAuxCodes(auxCodes, WRAP_UP_CODE,
230
- agentProfileData.accessWrapUpCode === 'ALL' ? [] : agentProfileData.wrapUpCodes);
231
- const idleCodes = getFilterAuxCodes(auxCodes, IDLE_CODE,
232
- agentProfileData.accessIdleCode === 'ALL' ? [] : agentProfileData.idleCodes);
216
+ const wrapupCodes = getFilterAuxCodes(auxCodes, WRAP_UP_CODE);
217
+ const idleCodes = getFilterAuxCodes(auxCodes, IDLE_CODE);
233
218
 
234
219
  // Hardcoded "Available" state always appended to idle codes
235
220
  idleCodes.push({ id: '0', name: 'Available', isSystem: false, isDefault: false });
@@ -238,7 +223,7 @@ function parseAgentConfigs(profileData: {
238
223
  agentId: userData.ciUserId, // NOTE: uses ciUserId for agent identification
239
224
  analyserUserId: userData.id, // NOTE: userData.id is used for analytics/reporting
240
225
  agentName: `${userData.firstName} ${userData.lastName}`,
241
- teams: teamData, // NOTE: Raw TeamList[] passed directly without mapping
226
+ teams: teamData, // TeamList[] straight from the team API; Profile.teams is TeamList[]
242
227
  idleCodes, // NOTE: Filtered via getFilterAuxCodes() + hardcoded "Available" state
243
228
  wrapupCodes, // NOTE: Filtered via getFilterAuxCodes()
244
229
  webRtcEnabled: orgSettingsData.webRtcEnabled,
@@ -258,14 +243,17 @@ function parseAgentConfigs(profileData: {
258
243
  Each method follows consistent error handling:
259
244
 
260
245
  ```typescript
261
- public async getUserUsingCI(orgId: string, agentId: string): Promise<AgentResponse> {
262
- LoggerProxy.info('Fetching user data using CI', {
246
+ public async getUserDesktopLoginConfig(
247
+ orgId: string,
248
+ ciUserId: string
249
+ ): Promise<UserDesktopLoginResponse> {
250
+ LoggerProxy.info('Fetching user desktop-login configuration', {
263
251
  module: CONFIG_FILE_NAME,
264
- method: METHODS.GET_USER_USING_CI,
252
+ method: METHODS.GET_USER_DESKTOP_LOGIN_CONFIG,
265
253
  });
266
254
 
267
255
  try {
268
- const resource = endPointMap.userByCI(orgId, agentId);
256
+ const resource = endPointMap.userDesktopLogin(orgId, ciUserId);
269
257
  const response = await this.webexReq.request({
270
258
  service: WCC_API_GATEWAY,
271
259
  resource,
@@ -276,16 +264,16 @@ public async getUserUsingCI(orgId: string, agentId: string): Promise<AgentRespon
276
264
  throw new Error(`API call failed with ${response.statusCode}`);
277
265
  }
278
266
 
279
- LoggerProxy.log('getUserUsingCI api success.', {
267
+ LoggerProxy.log('getUserDesktopLoginConfig api success.', {
280
268
  module: CONFIG_FILE_NAME,
281
- method: METHODS.GET_USER_USING_CI,
269
+ method: METHODS.GET_USER_DESKTOP_LOGIN_CONFIG,
282
270
  });
283
271
 
284
272
  return Promise.resolve(response.body);
285
273
  } catch (error) {
286
- LoggerProxy.error(`getUserUsingCI API call failed with ${error}`, {
274
+ LoggerProxy.error(`getUserDesktopLoginConfig API call failed with ${error}`, {
287
275
  module: CONFIG_FILE_NAME,
288
- method: METHODS.GET_USER_USING_CI,
276
+ method: METHODS.GET_USER_DESKTOP_LOGIN_CONFIG,
289
277
  });
290
278
  throw error;
291
279
  }
@@ -309,8 +297,8 @@ public async getUserUsingCI(orgId: string, agentId: string): Promise<AgentRespon
309
297
  "module": "config/index.ts", "method": "getAgentConfig"
310
298
 
311
299
  // Specific API method failures
312
- "getUserUsingCI API call failed"
313
- "getDesktopProfileById API call failed"
300
+ "getUserDesktopLoginConfig API call failed"
301
+ "getOrgDesktopLoginConfig API call failed"
314
302
  "getAllTeams API call failed"
315
303
  "getAllAuxCodes API call failed"
316
304
 
@@ -341,7 +329,7 @@ public async getUserUsingCI(orgId: string, agentId: string): Promise<AgentRespon
341
329
 
342
330
  **Solution**:
343
331
  1. Check `totalPages` in first response
344
- 2. Verify filter array contains valid team/aux code IDs
332
+ 2. Verify the team filter carries a valid `userDbId` (`user.dbId`, not the CI user id) and that aux-code filters contain valid IDs
345
333
  3. Check if pageSize is appropriate (default: 100)
346
334
  4. Ensure all pages are fetched in Promise.all()
347
335
 
@@ -351,8 +339,8 @@ public async getUserUsingCI(orgId: string, agentId: string): Promise<AgentRespon
351
339
 
352
340
  **Log patterns:**
353
341
  ```typescript
354
- "getOrganizationSetting api success"
355
- "getTenantData api success"
342
+ "getOrgDesktopLoginConfig api success."
343
+ "getUserDesktopLoginConfig api success."
356
344
  ```
357
345
 
358
346
  **Solution**:
@@ -370,9 +358,7 @@ public async getUserUsingCI(orgId: string, agentId: string): Promise<AgentRespon
370
358
  2. Verify dial plans are assigned in agent profile configuration
371
359
  3. Note: dial plan fetch only happens if `dialPlanEnabled === true`
372
360
 
373
- #### Issue: Incorrect auxiliary code filtering
374
-
375
- **Cause**: Access level set to 'SPECIFIC' but missing code IDs
361
+ #### Issue: Expected auxiliary codes missing from the returned pool
376
362
 
377
363
  **Log patterns:**
378
364
  ```typescript
@@ -380,11 +366,10 @@ public async getUserUsingCI(orgId: string, agentId: string): Promise<AgentRespon
380
366
  ```
381
367
 
382
368
  **Solution**:
383
- 1. Check `agentProfileData.accessWrapUpCode` (should be 'ALL' or 'SPECIFIC')
384
- 2. Check `agentProfileData.accessIdleCode`
385
- 3. If 'SPECIFIC', verify `wrapUpCodes` and `idleCodes` arrays contain valid IDs
386
- 4. Ensure aux codes have `active: true` status
387
- 5. Note: "Available" state is always appended to idle codes
369
+ 1. `getFilterAuxCodes` no longer applies a per-agent restriction list — the full organization pool is returned for every agent
370
+ 2. `Profile.idleCodesAccess` / `wrapupCodesAccess` still report `ALL` or `SPECIFIC` from `agentProfileData`
371
+ 3. Ensure aux codes have `active: true` status and the expected `workTypeCode`
372
+ 4. Note: "Available" state is always appended to idle codes
388
373
 
389
374
  ---
390
375
 
@@ -396,10 +381,11 @@ The config service defines comprehensive TypeScript types for all data structure
396
381
 
397
382
  **Configuration Types:**
398
383
  - `Profile` - Unified agent profile after aggregation
399
- - `AgentResponse` - User data from userByCI endpoint
400
- - `DesktopProfileResponse` - Agent desktop settings
401
- - `TeamList` - Team data with full details (id, name, type, channelMap, etc.)
402
- - `Team` - Simplified team reference (teamId, teamName, desktopLayoutId)
384
+ - `OrgDesktopLoginResponse` - Organization desktop-login aggregate
385
+ - `UserDesktopLoginResponse` - User desktop-login aggregate (`user` + `agentProfile`)
386
+ - `AgentResponse` - `user` section of the user aggregate
387
+ - `AgentProfile` - `agentProfile` section of the user aggregate
388
+ - `TeamList` - Team data with full details (id, name, teamType, siteId, multiMediaProfileId, etc.)
403
389
  - `AuxCode` - Auxiliary code definition
404
390
  - `Entity` - Filtered code entity (used for idle/wrapup codes in Profile)
405
391
 
@@ -410,8 +396,9 @@ The config service defines comprehensive TypeScript types for all data structure
410
396
  - `SiteInfo` - Site-specific configuration
411
397
 
412
398
  **Communication Types:**
413
- - `DialPlanEntity` - Dial plan rule definition
414
- - `URLMapping` - External service URL mapping
399
+ - `DialPlanEntity` - Dial plan rule definition (includes `active`)
400
+ - `OrgUrlMappings` - Keyed external service URL mappings
401
+ - `MicrosoftConfig` / `WebexConfig` - Org-level presence configuration
415
402
  - `MultimediaProfile` - Multimedia profile configuration
416
403
 
417
404
  **Note:** The config service itself does not emit events. For agent and task events, see the Agent and Task services. Event constants are defined in [types.ts](../types.ts) under `CC_AGENT_EVENTS` and `CC_TASK_EVENTS`.