@webex/contact-center 3.12.0-next.17 → 3.12.0-next.170

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 (328) hide show
  1. package/.sdd/manifest.json +887 -0
  2. package/AGENTS.md +94 -0
  3. package/ai-docs/ARCHITECTURE.md +168 -0
  4. package/ai-docs/CONTRACTS.md +62 -0
  5. package/ai-docs/GETTING_STARTED.md +168 -0
  6. package/ai-docs/GLOSSARY.md +43 -0
  7. package/ai-docs/README.md +138 -0
  8. package/ai-docs/REVIEW_CHECKLIST.md +41 -0
  9. package/ai-docs/RULES.md +444 -0
  10. package/ai-docs/SECURITY.md +52 -0
  11. package/ai-docs/SERVICE_STATE.md +52 -0
  12. package/ai-docs/SPEC_INDEX.md +65 -0
  13. package/ai-docs/adr/0001-spec-source-policy.md +55 -0
  14. package/ai-docs/adr/README.md +8 -0
  15. package/ai-docs/adr/_adr-template.md +31 -0
  16. package/ai-docs/contact-center-spec.md +385 -0
  17. package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -0
  18. package/ai-docs/features/contact-owner-change-refactor.md +78 -0
  19. package/ai-docs/features/generated-spec-conformance-fidelity-remediation/spec/feature-spec.md +117 -0
  20. package/ai-docs/features/residual-warning-coverage-completion/spec/feature-spec.md +203 -0
  21. package/ai-docs/features/validator-code-fidelity-drift-fix/spec/feature-spec.md +315 -0
  22. package/ai-docs/patterns/event-driven-patterns.md +485 -0
  23. package/ai-docs/patterns/testing-patterns.md +480 -0
  24. package/ai-docs/patterns/typescript-patterns.md +365 -0
  25. package/ai-docs/templates/README.md +102 -0
  26. package/ai-docs/templates/documentation/create-agents-md.md +240 -0
  27. package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
  28. package/ai-docs/templates/existing-service/bug-fix.md +254 -0
  29. package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
  30. package/ai-docs/templates/new-method/00-master.md +80 -0
  31. package/ai-docs/templates/new-method/01-requirements.md +232 -0
  32. package/ai-docs/templates/new-method/02-implementation.md +295 -0
  33. package/ai-docs/templates/new-method/03-tests.md +201 -0
  34. package/ai-docs/templates/new-method/04-validation.md +141 -0
  35. package/ai-docs/templates/new-service/00-master.md +109 -0
  36. package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
  37. package/ai-docs/templates/new-service/02-code-generation.md +346 -0
  38. package/ai-docs/templates/new-service/03-integration.md +178 -0
  39. package/ai-docs/templates/new-service/04-test-generation.md +205 -0
  40. package/ai-docs/templates/new-service/05-validation.md +145 -0
  41. package/dist/cc.js +888 -49
  42. package/dist/cc.js.map +1 -1
  43. package/dist/config.js +13 -0
  44. package/dist/config.js.map +1 -1
  45. package/dist/constants.js +38 -3
  46. package/dist/constants.js.map +1 -1
  47. package/dist/index.js +54 -17
  48. package/dist/index.js.map +1 -1
  49. package/dist/metrics/MetricsManager.js +16 -0
  50. package/dist/metrics/MetricsManager.js.map +1 -1
  51. package/dist/metrics/behavioral-events.js +185 -0
  52. package/dist/metrics/behavioral-events.js.map +1 -1
  53. package/dist/metrics/constants.js +54 -4
  54. package/dist/metrics/constants.js.map +1 -1
  55. package/dist/services/AddressBook.js +18 -15
  56. package/dist/services/AddressBook.js.map +1 -1
  57. package/dist/services/AnswerCallOnWebexService.js +202 -0
  58. package/dist/services/AnswerCallOnWebexService.js.map +1 -0
  59. package/dist/services/ApiAiAssistant.js +369 -14
  60. package/dist/services/ApiAiAssistant.js.map +1 -1
  61. package/dist/services/EntryPoint.js +46 -68
  62. package/dist/services/EntryPoint.js.map +1 -1
  63. package/dist/services/Queue.js +27 -22
  64. package/dist/services/Queue.js.map +1 -1
  65. package/dist/services/UserPreference.js +427 -0
  66. package/dist/services/UserPreference.js.map +1 -0
  67. package/dist/services/WebCallingService.js +10 -2
  68. package/dist/services/WebCallingService.js.map +1 -1
  69. package/dist/services/WebexCrossClientService.js +225 -0
  70. package/dist/services/WebexCrossClientService.js.map +1 -0
  71. package/dist/services/WxAppTelephonyMercurySync.js +111 -0
  72. package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
  73. package/dist/services/config/Util.js +48 -48
  74. package/dist/services/config/Util.js.map +1 -1
  75. package/dist/services/config/constants.js +56 -78
  76. package/dist/services/config/constants.js.map +1 -1
  77. package/dist/services/config/index.js +100 -226
  78. package/dist/services/config/index.js.map +1 -1
  79. package/dist/services/config/types.js +93 -24
  80. package/dist/services/config/types.js.map +1 -1
  81. package/dist/services/constants.js +11 -1
  82. package/dist/services/constants.js.map +1 -1
  83. package/dist/services/core/Err.js.map +1 -1
  84. package/dist/services/core/Utils.js +131 -32
  85. package/dist/services/core/Utils.js.map +1 -1
  86. package/dist/services/core/WebexRequest.js +6 -2
  87. package/dist/services/core/WebexRequest.js.map +1 -1
  88. package/dist/services/core/aqm-reqs.js +17 -11
  89. package/dist/services/core/aqm-reqs.js.map +1 -1
  90. package/dist/services/core/constants.js +9 -1
  91. package/dist/services/core/constants.js.map +1 -1
  92. package/dist/services/core/types.js.map +1 -1
  93. package/dist/services/core/websocket/WebSocketManager.js +19 -2
  94. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  95. package/dist/services/core/websocket/types.js.map +1 -1
  96. package/dist/services/index.js +1 -1
  97. package/dist/services/index.js.map +1 -1
  98. package/dist/services/task/Task.js +955 -0
  99. package/dist/services/task/Task.js.map +1 -0
  100. package/dist/services/task/TaskFactory.js +50 -0
  101. package/dist/services/task/TaskFactory.js.map +1 -0
  102. package/dist/services/task/TaskManager.js +1272 -605
  103. package/dist/services/task/TaskManager.js.map +1 -1
  104. package/dist/services/task/TaskUtils.js +221 -27
  105. package/dist/services/task/TaskUtils.js.map +1 -1
  106. package/dist/services/task/WebexCallingUtils.js +70 -0
  107. package/dist/services/task/WebexCallingUtils.js.map +1 -0
  108. package/dist/services/task/constants.js +19 -2
  109. package/dist/services/task/constants.js.map +1 -1
  110. package/dist/services/task/contact.js +29 -0
  111. package/dist/services/task/contact.js.map +1 -1
  112. package/dist/services/task/digital/Digital.js +78 -0
  113. package/dist/services/task/digital/Digital.js.map +1 -0
  114. package/dist/services/task/state-machine/TaskStateMachine.js +982 -0
  115. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
  116. package/dist/services/task/state-machine/actions.js +572 -0
  117. package/dist/services/task/state-machine/actions.js.map +1 -0
  118. package/dist/services/task/state-machine/constants.js +161 -0
  119. package/dist/services/task/state-machine/constants.js.map +1 -0
  120. package/dist/services/task/state-machine/guards.js +379 -0
  121. package/dist/services/task/state-machine/guards.js.map +1 -0
  122. package/dist/services/task/state-machine/index.js +53 -0
  123. package/dist/services/task/state-machine/index.js.map +1 -0
  124. package/dist/services/task/state-machine/types.js +54 -0
  125. package/dist/services/task/state-machine/types.js.map +1 -0
  126. package/dist/services/task/state-machine/uiControlsComputer.js +703 -0
  127. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
  128. package/dist/services/task/taskDataNormalizer.js +99 -0
  129. package/dist/services/task/taskDataNormalizer.js.map +1 -0
  130. package/dist/services/task/types.js +215 -5
  131. package/dist/services/task/types.js.map +1 -1
  132. package/dist/services/task/voice/Voice.js +1504 -0
  133. package/dist/services/task/voice/Voice.js.map +1 -0
  134. package/dist/services/task/voice/WebRTC.js +152 -0
  135. package/dist/services/task/voice/WebRTC.js.map +1 -0
  136. package/dist/services/task/voice/wxAppOfferObservability.js +145 -0
  137. package/dist/services/task/voice/wxAppOfferObservability.js.map +1 -0
  138. package/dist/services/task/voice/wxAppVoiceMethods.js +395 -0
  139. package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
  140. package/dist/services/wxAppDiagnosticLogging.js +159 -0
  141. package/dist/services/wxAppDiagnosticLogging.js.map +1 -0
  142. package/dist/services/wxAppTelephonyUtils.js +19 -0
  143. package/dist/services/wxAppTelephonyUtils.js.map +1 -0
  144. package/dist/types/cc.d.ts +152 -9
  145. package/dist/types/config.d.ts +13 -0
  146. package/dist/types/constants.d.ts +36 -1
  147. package/dist/types/index.d.ts +54 -20
  148. package/dist/types/metrics/MetricsManager.d.ts +6 -0
  149. package/dist/types/metrics/constants.d.ts +48 -1
  150. package/dist/types/services/AddressBook.d.ts +2 -1
  151. package/dist/types/services/AnswerCallOnWebexService.d.ts +38 -0
  152. package/dist/types/services/ApiAiAssistant.d.ts +67 -5
  153. package/dist/types/services/EntryPoint.d.ts +7 -5
  154. package/dist/types/services/Queue.d.ts +5 -3
  155. package/dist/types/services/UserPreference.d.ts +118 -0
  156. package/dist/types/services/WebexCrossClientService.d.ts +32 -0
  157. package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
  158. package/dist/types/services/config/Util.d.ts +4 -8
  159. package/dist/types/services/config/constants.d.ts +49 -76
  160. package/dist/types/services/config/index.d.ts +16 -64
  161. package/dist/types/services/config/types.d.ts +240 -114
  162. package/dist/types/services/constants.d.ts +9 -0
  163. package/dist/types/services/core/Err.d.ts +2 -0
  164. package/dist/types/services/core/Utils.d.ts +43 -13
  165. package/dist/types/services/core/WebexRequest.d.ts +1 -0
  166. package/dist/types/services/core/constants.d.ts +7 -0
  167. package/dist/types/services/core/types.d.ts +2 -0
  168. package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -0
  169. package/dist/types/services/core/websocket/types.d.ts +1 -1
  170. package/dist/types/services/index.d.ts +1 -1
  171. package/dist/types/services/task/Task.d.ts +186 -0
  172. package/dist/types/services/task/TaskFactory.d.ts +14 -0
  173. package/dist/types/services/task/TaskUtils.d.ts +54 -2
  174. package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
  175. package/dist/types/services/task/constants.d.ts +17 -0
  176. package/dist/types/services/task/contact.d.ts +4 -0
  177. package/dist/types/services/task/digital/Digital.d.ts +23 -0
  178. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1442 -0
  179. package/dist/types/services/task/state-machine/actions.d.ts +10 -0
  180. package/dist/types/services/task/state-machine/constants.d.ts +107 -0
  181. package/dist/types/services/task/state-machine/guards.d.ts +103 -0
  182. package/dist/types/services/task/state-machine/index.d.ts +13 -0
  183. package/dist/types/services/task/state-machine/types.d.ts +277 -0
  184. package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
  185. package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
  186. package/dist/types/services/task/types.d.ts +738 -66
  187. package/dist/types/services/task/voice/Voice.d.ts +241 -0
  188. package/dist/types/services/task/voice/WebRTC.d.ts +54 -0
  189. package/dist/types/services/task/voice/wxAppOfferObservability.d.ts +39 -0
  190. package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +68 -0
  191. package/dist/types/services/wxAppDiagnosticLogging.d.ts +63 -0
  192. package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
  193. package/dist/types/types.d.ts +213 -11
  194. package/dist/types/utils/PageCache.d.ts +20 -3
  195. package/dist/types/webex.d.ts +1 -0
  196. package/dist/types.js +168 -6
  197. package/dist/types.js.map +1 -1
  198. package/dist/utils/PageCache.js +19 -5
  199. package/dist/utils/PageCache.js.map +1 -1
  200. package/dist/webex.js +22 -2
  201. package/dist/webex.js.map +1 -1
  202. package/package.json +16 -12
  203. package/src/cc.ts +1137 -67
  204. package/src/config.ts +13 -0
  205. package/src/constants.ts +39 -1
  206. package/src/index.ts +62 -15
  207. package/src/metrics/MetricsManager.ts +16 -0
  208. package/src/metrics/ai-docs/AGENTS.md +350 -0
  209. package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
  210. package/src/metrics/ai-docs/metrics-spec.md +971 -0
  211. package/src/metrics/behavioral-events.ts +190 -0
  212. package/src/metrics/constants.ts +59 -4
  213. package/src/services/AddressBook.ts +17 -6
  214. package/src/services/AnswerCallOnWebexService.ts +239 -0
  215. package/src/services/ApiAiAssistant.ts +494 -15
  216. package/src/services/EntryPoint.ts +59 -60
  217. package/src/services/Queue.ts +29 -12
  218. package/src/services/UserPreference.ts +509 -0
  219. package/src/services/WebCallingService.ts +16 -2
  220. package/src/services/WebexCrossClientService.ts +298 -0
  221. package/src/services/WxAppTelephonyMercurySync.ts +142 -0
  222. package/src/services/agent/ai-docs/AGENTS.md +240 -0
  223. package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
  224. package/src/services/agent/ai-docs/agent-spec.md +505 -0
  225. package/src/services/ai-docs/AGENTS.md +386 -0
  226. package/src/services/ai-docs/services-spec.md +512 -0
  227. package/src/services/config/Util.ts +54 -84
  228. package/src/services/config/ai-docs/AGENTS.md +250 -0
  229. package/src/services/config/ai-docs/ARCHITECTURE.md +413 -0
  230. package/src/services/config/ai-docs/config-spec.md +669 -0
  231. package/src/services/config/constants.ts +63 -85
  232. package/src/services/config/index.ts +116 -277
  233. package/src/services/config/types.ts +229 -125
  234. package/src/services/constants.ts +10 -0
  235. package/src/services/core/Err.ts +1 -0
  236. package/src/services/core/Utils.ts +151 -37
  237. package/src/services/core/WebexRequest.ts +3 -1
  238. package/src/services/core/ai-docs/AGENTS.md +381 -0
  239. package/src/services/core/ai-docs/ARCHITECTURE.md +698 -0
  240. package/src/services/core/ai-docs/core-spec.md +797 -0
  241. package/src/services/core/aqm-reqs.ts +18 -12
  242. package/src/services/core/constants.ts +8 -0
  243. package/src/services/core/types.ts +33 -1
  244. package/src/services/core/websocket/WebSocketManager.ts +28 -2
  245. package/src/services/core/websocket/types.ts +1 -1
  246. package/src/services/index.ts +1 -1
  247. package/src/services/task/Task.ts +1211 -0
  248. package/src/services/task/TaskFactory.ts +82 -0
  249. package/src/services/task/TaskManager.ts +1585 -724
  250. package/src/services/task/TaskUtils.ts +316 -25
  251. package/src/services/task/WebexCallingUtils.ts +136 -0
  252. package/src/services/task/ai-docs/AGENTS.md +457 -0
  253. package/src/services/task/ai-docs/ARCHITECTURE.md +595 -0
  254. package/src/services/task/ai-docs/task-spec.md +1501 -0
  255. package/src/services/task/constants.ts +18 -0
  256. package/src/services/task/contact.ts +30 -0
  257. package/src/services/task/digital/Digital.ts +102 -0
  258. package/src/services/task/state-machine/TaskStateMachine.ts +1320 -0
  259. package/src/services/task/state-machine/actions.ts +741 -0
  260. package/src/services/task/state-machine/ai-docs/AGENTS.md +460 -0
  261. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1156 -0
  262. package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2247 -0
  263. package/src/services/task/state-machine/constants.ts +172 -0
  264. package/src/services/task/state-machine/guards.ts +442 -0
  265. package/src/services/task/state-machine/index.ts +28 -0
  266. package/src/services/task/state-machine/types.ts +258 -0
  267. package/src/services/task/state-machine/uiControlsComputer.ts +1135 -0
  268. package/src/services/task/taskDataNormalizer.ts +137 -0
  269. package/src/services/task/types.ts +918 -70
  270. package/src/services/task/voice/Voice.ts +1878 -0
  271. package/src/services/task/voice/WebRTC.ts +194 -0
  272. package/src/services/task/voice/wxAppOfferObservability.ts +204 -0
  273. package/src/services/task/voice/wxAppVoiceMethods.ts +575 -0
  274. package/src/services/wxAppDiagnosticLogging.ts +286 -0
  275. package/src/services/wxAppTelephonyUtils.ts +14 -0
  276. package/src/types.ts +272 -13
  277. package/src/utils/AGENTS.md +289 -0
  278. package/src/utils/PageCache.ts +38 -5
  279. package/src/utils/ai-docs/utils-spec.md +391 -0
  280. package/src/webex.js +10 -0
  281. package/test/unit/fixtures/aiSummaryTestUtils.ts +40 -0
  282. package/test/unit/spec/cc.ts +3553 -107
  283. package/test/unit/spec/index.ts +885 -0
  284. package/test/unit/spec/logger-proxy.ts +70 -0
  285. package/test/unit/spec/metrics/MetricsManager.ts +25 -0
  286. package/test/unit/spec/metrics/behavioral-events.ts +60 -0
  287. package/test/unit/spec/services/AddressBook.ts +37 -6
  288. package/test/unit/spec/services/AnswerCallOnWebexService.ts +264 -0
  289. package/test/unit/spec/services/ApiAiAssistant.ts +442 -23
  290. package/test/unit/spec/services/EntryPoint.ts +87 -40
  291. package/test/unit/spec/services/Queue.ts +123 -12
  292. package/test/unit/spec/services/UserPreference.ts +401 -0
  293. package/test/unit/spec/services/WebCallingService.ts +45 -1
  294. package/test/unit/spec/services/WebexCrossClientService.ts +509 -0
  295. package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +136 -0
  296. package/test/unit/spec/services/config/Util.ts +501 -0
  297. package/test/unit/spec/services/config/index.ts +317 -547
  298. package/test/unit/spec/services/core/Utils.ts +447 -8
  299. package/test/unit/spec/services/core/WebexRequest.ts +8 -7
  300. package/test/unit/spec/services/core/aqm-reqs.ts +142 -1
  301. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +129 -53
  302. package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
  303. package/test/unit/spec/services/task/Task.ts +2723 -0
  304. package/test/unit/spec/services/task/TaskFactory.ts +116 -0
  305. package/test/unit/spec/services/task/TaskManager.ts +4734 -1769
  306. package/test/unit/spec/services/task/TaskUtils.ts +307 -0
  307. package/test/unit/spec/services/task/WebexCallingUtils.ts +153 -0
  308. package/test/unit/spec/services/task/contact.ts +33 -0
  309. package/test/unit/spec/services/task/digital/Digital.ts +105 -0
  310. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +4060 -0
  311. package/test/unit/spec/services/task/state-machine/guards.ts +839 -0
  312. package/test/unit/spec/services/task/state-machine/types.ts +18 -0
  313. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +3101 -0
  314. package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
  315. package/test/unit/spec/services/task/voice/Voice.ts +2355 -0
  316. package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
  317. package/test/unit/spec/services/task/voice/wxAppOfferObservability.ts +361 -0
  318. package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +719 -0
  319. package/test/unit/spec/services/wxAppDiagnosticLogging.ts +179 -0
  320. package/test/unit/spec/wellnessSampleUtils.ts +288 -0
  321. package/typedoc.md +1 -1
  322. package/umd/contact-center.min.js +2 -2
  323. package/umd/contact-center.min.js.map +1 -1
  324. package/dist/services/task/index.js +0 -1530
  325. package/dist/services/task/index.js.map +0 -1
  326. package/dist/types/services/task/index.d.ts +0 -650
  327. package/src/services/task/index.ts +0 -1806
  328. package/test/unit/spec/services/task/index.ts +0 -2205
@@ -0,0 +1,669 @@
1
+ # Config — SPEC
2
+
3
+ > Start here → root [`AGENTS.md`](../../../../AGENTS.md) · router [`SPEC_INDEX.md`](../../../../ai-docs/SPEC_INDEX.md) · system [`ARCHITECTURE.md`](../../../../ai-docs/ARCHITECTURE.md). This is the module's canonical specification.
4
+
5
+ ## Metadata
6
+
7
+ | Field | Value |
8
+ |---|---|
9
+ | Module id | `config` |
10
+ | Source path(s) | `src/services/config` |
11
+ | Doc kind | Module spec |
12
+ | Coverage score | Partial (manifest-authoritative); 15/15 required document fields present |
13
+ | Generated from | `module-spec` @ SDLC template library `0.2.1` |
14
+ | generated_by / approved_by / updated_at | Codex generator / developer-approved desktop-login aggregate migration delta / 2026-10-05 |
15
+ | Validation status | Agent Wellness Break v0.4 delta independently validated by claude-code on 2026-09-07; coverage remains Partial until the remaining baseline promotion criteria are satisfied |
16
+
17
+ ## Evidence Rules
18
+ Every requirement cites stable source and test file paths. Code/tests are the behavioral referee; routed source text supplies explicit intent and rationale. Missing or contradictory evidence blocks promotion.
19
+
20
+ ## Source Material Register
21
+ | Source material | Scope | Decision | Detail location or disposition |
22
+ |---|---|---|---|
23
+ | Reviewed prior module guides and architecture material | overview / architecture / API / tests | used and code-checked | Content is placed by meaning throughout this specification; exact routing remains in the manifest. |
24
+
25
+ ## Overview
26
+ Config is one of nine confirmed Contact Center SDK modules. Own retrieval and aggregation of remote organization, agent, team, profile, auxiliary-code, dial-plan, and feature configuration. Existing reviewed documentation is migrated by meaning and code/tests remain the behavioral referee.
27
+
28
+ The Config Service is an **internal service** that builds the comprehensive AgentProfile (`Profile` type) by:
29
+
30
+ 1. Fetching the user desktop-login aggregate (agent identity plus `agentProfile`)
31
+
32
+ 2. Fetching the organization desktop-login aggregate (org info, org settings, tenant configuration, URL mappings, AI feature, Microsoft/Webex config)
33
+
34
+ 3. Fetching teams
35
+
36
+ 4. Fetching aux codes (idle/wrapup codes)
37
+
38
+ 5. Fetching site and, when the agent profile enables it, dial-plan data
39
+
40
+ 6. Aggregating all data into a single AgentProfile
41
+
42
+ The AgentProfile is the central configuration object required for an agent to operate within the contact center. It is built during the registration flow (`cc.register()`) and contains all the data an agent needs: identity, team assignments, dial plans, aux codes, login options, and feature flags. Once constructed, the AgentProfile is stored on the `ContactCenter` plugin instance as `this.agentConfig` and is used by other services (Agent, Task) throughout the session.
43
+
44
+ - **AgentProfile Aggregation**: Combines data from 6 API endpoints (5 when the agent profile disables dial plans)
45
+
46
+ - **Aux Codes Fetching**: Gets all idle and wrapup codes with pagination
47
+
48
+ - **Team Data**: Retrieves agent's team assignments
49
+
50
+ - **Dial Plan**: Fetches number transformation rules
51
+
52
+ - **Outdial ANI**: Retrieves outbound caller ID options (standalone, publicly exposed via `cc.ts`)
53
+
54
+ - **Multimedia Profile**: Fetches channel capacity and blending config (standalone, not yet publicly exposed)
55
+
56
+ - **Paginated Data Access**: `getListOfTeams` and `getListOfAuxCodes` support custom pagination independent of profile building. `getListOfTeams` takes a `userDbId` — the `user.dbId` carried by the user desktop-login aggregate, not the CI user id — rather than a list of team ids
57
+
58
+ ## Purpose / Responsibility
59
+ Own retrieval and aggregation of remote organization, agent, team, profile, auxiliary-code, dial-plan, and feature configuration.
60
+
61
+ ## Stack
62
+ TypeScript 5.4 REST client, Promise-based parallel aggregation, Jest 27.
63
+
64
+ ## Folder / Package Structure
65
+ ```text
66
+ src/services/config/
67
+ ├── Util.ts
68
+ ├── constants.ts
69
+ ├── index.ts
70
+ ├── types.ts
71
+ ```
72
+
73
+ ```text
74
+ services/config/
75
+ ├── index.ts # AgentConfigService class
76
+ ├── types.ts # Profile, CC_EVENTS, types
77
+ ├── constants.ts # API endpoints, defaults
78
+ ├── Util.ts # parseAgentConfigs helper
79
+ └── ai-docs/
80
+ ├── AGENTS.md # Usage documentation
81
+ └── ARCHITECTURE.md # Preserved legacy migration source (non-canonical)
82
+ ```
83
+
84
+ ## Key Files (source of truth)
85
+ | File | Holds |
86
+ |---|---|
87
+ | `src/services/config/index.ts` | Authoritative Config implementation or contract source. |
88
+ | `src/services/config/Util.ts` | Authoritative Config implementation or contract source. |
89
+ | `src/services/config/types.ts` | Authoritative Config implementation or contract source. |
90
+ | `src/services/config/constants.ts` | Authoritative Config implementation or contract source. |
91
+
92
+ ## Public Surface
93
+ | Surface | Contract | Source |
94
+ |---|---|---|
95
+ | `getAgentConfig(orgId, agentId)` | staged, all-or-nothing `Promise<Profile>` aggregation | `src/services/config/index.ts` |
96
+ | User/profile/site/team/aux-code fetches | typed REST methods including pagination helpers | `src/services/config/index.ts`, `src/services/config/types.ts` |
97
+ | `getOrgDesktopLoginConfig(orgId)` | `OrgDesktopLoginResponse` from `organization/{orgId}/desktop-login` | `src/services/config/index.ts`, `src/services/config/constants.ts` |
98
+ | `getUserDesktopLoginConfig(orgId, ciUserId)` | `UserDesktopLoginResponse` from `organization/{orgId}/v2/user/by-ci-user-id/{ciUserId}/desktop-login` | `src/services/config/index.ts`, `src/services/config/constants.ts` |
99
+ | `Profile.aiFeature` | optional `aiFeature` section of the organization aggregate, mapped by `parseAgentConfigs` | `src/services/config/Util.ts`, `src/services/config/types.ts` |
100
+ | Multimedia profile | `MultimediaProfileResponse` | `src/services/config/types.ts` |
101
+ | Organization masking | `OrgSettings.maskSensitiveData` | `src/services/config/types.ts`, `src/services/config/Util.ts` |
102
+ | Auxiliary-code list URL | includes `desktopProfileFilter=true` | `src/services/config/constants.ts` |
103
+ | Outdial ANI entries | public wrapper through ContactCenter | `src/services/config/index.ts`, `src/cc.ts` |
104
+ | `Profile.isWellnessBreakEnabled` | required effective flag derived from backend AI feature configuration and organization license quantity | `src/services/config/Util.ts`, `src/services/config/types.ts` |
105
+ | `getWellbeingBreakIdleCode(orgId)` | paginated exact lookup for the active system idle code named `WellbeingBreak`, exposed and registration-cached by ContactCenter | `src/services/config/index.ts`, `src/services/config/constants.ts`, `src/cc.ts` |
106
+
107
+ The service has no `TeamList.channelMap` contract. Exact package exports are indexed in root `CONTRACTS.md`.
108
+
109
+ ## Requires (dependencies)
110
+ - WebexRequest
111
+ - WCC organization/profile/team/site/tenant APIs
112
+ - ContactCenter registration flow
113
+
114
+ ## Requirements
115
+ | ID | WHAT | WHY | Source Evidence | Test / Example Evidence | Assumptions / Gaps | Confidence |
116
+ |---|---|---|---|---|---|---|
117
+ | CONFIG-R-001 | Fetch the user desktop-login aggregate first, then aggregate five dependent promises: the organization desktop-login aggregate, auxiliary codes, teams, site, and the conditional dial plan. | Dependent IDs and all-or-nothing consistency require staged orchestration. | `src/services/config/index.ts` | `test/unit/spec/services/config/index.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
118
+ | CONFIG-R-002 | Include the organization aggregate's `aiFeature` section in `parseAgentConfigs` so `Profile.aiFeature` reflects the organization feature contract. | ApiAIAssistant behavior is gated by the remote organization feature contract. | `src/services/config/index.ts` | `test/unit/spec/services/config/index.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
119
+ | CONFIG-R-003 | Paginate teams and auxiliary codes until completion and include `desktopProfileFilter=true` for auxiliary-code requests. | A partial or unfiltered set yields invalid profile/team/auxiliary choices. | `src/services/config/constants.ts` | `test/unit/spec/services/config/index.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
120
+ | CONFIG-R-004 | Expose current response/field names: `MultimediaProfileResponse`, `OrgSettings.maskSensitiveData`, and real TeamList fields only. | Type-name drift causes invalid consumer code and incorrect privacy behavior. | `src/services/config/types.ts` | `test/unit/spec/services/config/index.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
121
+ | CONFIG-R-005 | Reject the entire profile aggregation when any required dependent request fails. | Consumers must never receive an internally inconsistent partial Profile. | `src/services/config/index.ts` | `test/unit/spec/services/config/index.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
122
+ | CONFIG-R-006 | Always populate `Profile.isWellnessBreakEnabled`; set it true only when `agentWellbeing.enable` is true, `wellnessBreakReminders` is `ENABLED`, and `OrgSettings.aiAssistantQuantity` is greater than zero. Missing or null inputs fail closed. | Hosts need one license-and-server-rollout-aware signal rather than reconstructing partial configuration. | `src/services/config/Util.ts`, `src/services/config/types.ts` | `test/unit/spec/services/config/Util.ts` | The supported SDK contracts expose no separate rollout response field; backend delivery of enabled `agentWellbeing` configuration is the rollout decision. | PRESENT |
123
+ | CONFIG-R-007 | Retrieve the wellness idle code from `/v2/auxiliary-code` using `workType=IDLE_CODE`, `customFilter=isSystemCode==true`, and `desktopProfileFilter=false`; follow pagination and accept only the exact active system code name `WellbeingBreak`. | The dedicated state must be independent of desktop-profile filtering and must never fall back to a similarly named or non-system code. | `src/services/config/index.ts`, `src/services/config/constants.ts` | `test/unit/spec/services/config/index.ts` | None. | PRESENT |
124
+
125
+ ## Design Overview
126
+ Config separates its stable consumption boundary from collaborators so ownership and failure behavior stay explicit. Profile creation is all-or-nothing across dependent API calls so consumers never receive internally inconsistent partial configuration.
127
+
128
+ > **Purpose**: Fetch and aggregate agent configuration data from multiple API endpoints to build the AgentProfile.
129
+ >
130
+ > **Scope Authority**: This is the authoritative documentation for the **Config** service scope. See [Root AGENTS.md](../../../../AGENTS.md) for the orchestrator and cross-scope rules.
131
+
132
+ ```typescript
133
+ // Config service is used internally during the registration flow.
134
+ // Inside cc.ts → connectWebsocket(), after WebSocket connection is established:
135
+ const agentId = data.agentId;
136
+ const orgId = this.$webex.credentials.getOrgId();
137
+ this.agentConfig = await this.services.config.getAgentConfig(orgId, agentId);
138
+
139
+ // The returned AgentProfile contains all agent configuration:
140
+ LoggerProxy.info(`Agent ID: ${this.agentConfig.agentId}`, {
141
+ module: 'cc',
142
+ method: 'connectWebsocket',
143
+ });
144
+ LoggerProxy.info(`Teams: ${this.agentConfig.teams}`, {
145
+ module: 'cc',
146
+ method: 'connectWebsocket',
147
+ });
148
+ ```
149
+
150
+ The AgentProfile is defined as the [`Profile`](../types.ts) type. This is not an exhaustive list — see [`types.ts`](../types.ts) for the full 50+ field definition. Key fields:
151
+
152
+ | Field | Type | Description |
153
+ |---|---|---|
154
+ | `agentId` | string | Unique agent identifier |
155
+ | `agentName` | string | Display name |
156
+ | `agentMailId` | string | Email address |
157
+ | `teams` | [`TeamList[]`](../types.ts) | Assigned teams (runtime data from `getAllTeams()` — `Profile` type declares `Team[]` but actual objects are `TeamList` with `id`, `name`, `teamType`, `siteId`, etc.) |
158
+ | `defaultDn` | string | Default dial number |
159
+ | `idleCodes` | [`Entity[]`](../types.ts) | Available idle codes |
160
+ | `wrapupCodes` | [`Entity[]`](../types.ts) | Available wrapup codes |
161
+ | `webRtcEnabled` | boolean | WebRTC calling enabled |
162
+ | `loginVoiceOptions` | [`LoginOption[]`](../types.ts) | Available login types |
163
+ | `dialPlan` | [`DialPlan`](../types.ts) | Number transformation rules |
164
+ | `isOutboundEnabledForAgent` | boolean | Outbound calling allowed |
165
+ | `outDialEp` | string | Outbound entry point ID |
166
+ | `allowConsultToQueue` | boolean | Whether consult-to-queue is enabled on the Desktop Profile |
167
+ | `accessQueue` | `'ALL' \| 'SPECIFIC' \| 'NONE'` | Collaboration tab queue access scope from Desktop Profile |
168
+ | `accessEntryPoint` | `'ALL' \| 'SPECIFIC' \| 'NONE'` | Collaboration tab entry-point access scope from Desktop Profile |
169
+ | `accessBuddyTeam` | `'ALL' \| 'SPECIFIC' \| 'NONE'` | Collaboration tab buddy-team access scope from Desktop Profile |
170
+ | `isWellnessBreakEnabled` | boolean | Effective wellness gate derived from backend enablement/reminder configuration and positive AI Assistant license quantity |
171
+
172
+ `parseAgentConfigs()` maps the three `access*` fields from the user aggregate's `AgentProfile` section onto the public `Profile` returned by `cc.register()`.
173
+
174
+ The following diagram shows how `getAgentConfig` orchestrates six API calls and combines their results into the AgentProfile via `parseAgentConfigs()`:
175
+
176
+ ```text
177
+ getUserDesktopLoginConfig ──┐ (awaited first; supplies dbId, siteId, dialPlanEnabled)
178
+ │
179
+ getOrgDesktopLoginConfig ───┤ (org info, org settings, tenant config, urlMappings,
180
+ │ aiFeature, microsoftConfig, webexConfig)
181
+ getAllAuxCodes ─────────────┼──► parseAgentConfigs() ──► AgentProfile
182
+ │
183
+ getAllTeams ────────────────┤ (filtered by userId == user.dbId)
184
+ │
185
+ getSiteInfo ────────────────┤ (team → site fallback for multimediaProfileId)
186
+ │
187
+ getDialPlanData ────────────┘ (only when agentProfile.dialPlanEnabled)
188
+ ```
189
+
190
+ Types used by the config service, all defined in [`types.ts`](../types.ts):
191
+
192
+ | Type | Description |
193
+ |---|---|
194
+ | `Profile` | Final aggregated agent config returned by `getAgentConfig()` |
195
+ | `OrgDesktopLoginResponse` | Response from `getOrgDesktopLoginConfig()` — `organization`, `organizationSetting`, `tenantConfiguration`, `urlMappings`, `aiFeature`, `microsoftConfig`, `webexConfig` |
196
+ | `UserDesktopLoginResponse` | Response from `getUserDesktopLoginConfig()` — `user` and `agentProfile` sections |
197
+ | `AgentResponse` | `user` section of the user aggregate — agent metadata, `dbId`, `siteId`, `agentProfileId` |
198
+ | `AgentProfile` | `agentProfile` section of the user aggregate — layout, dial-plan enablement, login options |
199
+ | `TeamList` | Team record from API — `id`, `name`, `teamType`, `siteId`, `multiMediaProfileId` |
200
+ | `ListTeamsResponse` | Paginated wrapper around `TeamList[]` with `meta` for pagination |
201
+ | `OrgInfo` | Organization info — `tenantId`, timezone |
202
+ | `OrgSettings` | Org feature flags — `webRtcEnabled`, `maskSensitiveData` |
203
+ | `TenantData` | Tenant-level config — inactivity timeout, `forceDefaultDn`, `outdialEnabled` |
204
+ | `SiteInfo` | Site config — `id`, `name`, `multimediaProfileId` |
205
+ | `OrgUrlMappings` | Keyed external URL mappings — `ACQUEON_API_URL`, `ACQUEON_CONSOLE_URL` |
206
+ | `MicrosoftConfig` | Org-level Microsoft presence config — `showUserDetails`, `stateSynchronization` |
207
+ | `WebexConfig` | Org-level Webex presence config — `showUserDetails`, `stateSynchronization` |
208
+ | `MultimediaProfileResponse` | Multimedia profile — channel capacities and settings |
209
+ | `AuxCode` | Auxiliary code record — `id`, `name`, `description`, `workTypeCode` |
210
+ | `ListAuxCodesResponse` | Paginated wrapper around `AuxCode[]` with `meta` |
211
+ | `DialPlanEntity` | Dial plan rule — regex pattern, prefix, strip digits, `active` |
212
+ | `Entity` | Basic entity info — `isSystem`, `name`, `id`, `description` |
213
+ | `WrapupData` | Wrap-up config — auto-wrapup settings, available wrapup codes |
214
+ | `OutdialAniParams` | Parameters for `getOutdialAniEntries()` — ANI ID, pagination, filtering |
215
+
216
+ ```typescript
217
+ // In register() -> connectWebsocket()
218
+ const agentId = data.agentId;
219
+ const orgId = this.$webex.credentials.getOrgId();
220
+ this.agentConfig = await this.services.config.getAgentConfig(orgId, agentId);
221
+ ```
222
+
223
+ > **Purpose**: Technical documentation for agent configuration aggregation.
224
+
225
+ For endpoints with pagination (teams, aux codes):
226
+
227
+ ```typescript
228
+ import {DEFAULT_PAGE} from './constants'; // DEFAULT_PAGE = 0
229
+
230
+ public async getAllTeams(orgId, pageSize, userDbId): Promise<TeamList[]> {
231
+ let allTeams: TeamList[] = [];
232
+ let page = DEFAULT_PAGE;
233
+
234
+ // First request to get totalPages
235
+ const firstResponse = await this.getListOfTeams(orgId, page, pageSize, userDbId);
236
+ allTeams = allTeams.concat(firstResponse.data);
237
+ const totalPages = firstResponse.meta.totalPages;
238
+
239
+ // Parallel requests for remaining pages
240
+ const requests = [];
241
+ for (page = DEFAULT_PAGE + 1; page < totalPages; page += 1) {
242
+ requests.push(this.getListOfTeams(orgId, page, pageSize, userDbId));
243
+ }
244
+
245
+ const responses = await Promise.all(requests);
246
+ for (const response of responses) {
247
+ allTeams = allTeams.concat(response.data);
248
+ }
249
+
250
+ return allTeams;
251
+ }
252
+ ```
253
+
254
+ `parseAgentConfigs` in Util.ts combines all data into a unified `Profile` object. See [types.ts](../types.ts) for full type definitions.
255
+
256
+ The service fetches data from multiple APIs with these response structures:
257
+
258
+ | API Method | Response Type | Key Fields | Usage |
259
+ |---|---|---|---|
260
+ | `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 |
261
+ | `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 |
262
+ | `getAllTeams` | `TeamList[]` | real `TeamList` fields from `src/services/config/types.ts` | Team identity, name, type, and site assignment; channel capacities belong to `MultimediaProfileResponse` |
263
+ | `getAllAuxCodes` | `AuxCode[]` | `id`, `name`, `workTypeCode`, `active`, `isSystemCode`, `defaultCode` | Auxiliary codes for idle/wrap-up states |
264
+ | `getDialPlanData` | `DialPlanEntity[]` | `id`, `name`, `regularExpression`, `prefix`, `strippedChars`, `active` | Dial plan rules for outbound calling |
265
+ | `getSiteInfo` | `SiteInfo` | Site-specific configuration | Site details, including the `multimediaProfileId` fallback |
266
+
267
+ These responses are parsed and aggregated into a single `Profile` object by the `parseAgentConfigs` function.
268
+
269
+ ```typescript
270
+ // See full implementation in Util.ts
271
+ function parseAgentConfigs(profileData: {
272
+ orgConfig: OrgDesktopLoginResponse; // See types.ts:OrgDesktopLoginResponse
273
+ userData: AgentResponse; // `user` section; see types.ts:AgentResponse
274
+ agentProfileData: AgentProfile; // `agentProfile` section; see types.ts:AgentProfile
275
+ teamData: TeamList[]; // See types.ts:TeamList
276
+ auxCodes: AuxCode[]; // See types.ts:AuxCode
277
+ dialPlanData: DialPlanEntity[]; // See types.ts:DialPlanEntity
278
+ multimediaProfileId: string;
279
+ }): Profile { // See types.ts:Profile
280
+ const { orgConfig, userData, agentProfileData, teamData, auxCodes,
281
+ dialPlanData } = profileData;
282
+ const {
283
+ organization: orgInfoData,
284
+ organizationSetting: orgSettingsData,
285
+ tenantConfiguration: tenantData,
286
+ urlMappings,
287
+ aiFeature,
288
+ microsoftConfig,
289
+ webexConfig,
290
+ } = orgConfig;
291
+
292
+ // Aux code filtering via getFilterAuxCodes():
293
+ // - checks auxCode.workTypeCode and auxCode.active
294
+ // - the aggregate returns the full org pool, so no per-agent restriction is applied
295
+ // - maps to Entity {id, name, isSystem, isDefault}
296
+ const wrapupCodes = getFilterAuxCodes(auxCodes, WRAP_UP_CODE);
297
+ const idleCodes = getFilterAuxCodes(auxCodes, IDLE_CODE);
298
+
299
+ // Hardcoded "Available" state always appended to idle codes
300
+ idleCodes.push({ id: '0', name: 'Available', isSystem: false, isDefault: false });
301
+
302
+ return {
303
+ agentId: userData.ciUserId, // NOTE: uses ciUserId for agent identification
304
+ analyserUserId: userData.id, // NOTE: userData.id is used for analytics/reporting
305
+ agentName: `${userData.firstName} ${userData.lastName}`,
306
+ teams: teamData, // TeamList[] straight from the team API; Profile.teams is TeamList[]
307
+ idleCodes, // NOTE: Filtered via getFilterAuxCodes() + hardcoded "Available" state
308
+ wrapupCodes, // NOTE: Filtered via getFilterAuxCodes()
309
+ webRtcEnabled: orgSettingsData.webRtcEnabled,
310
+ loginVoiceOptions: agentProfileData.loginVoiceOptions ?? [],
311
+ enterpriseId: orgInfoData.tenantId,
312
+ tenantTimezone: orgInfoData.timezone,
313
+ multimediaProfileId: profileData.multimediaProfileId,
314
+ aiFeature,
315
+ // ... 30+ more fields — see Util.ts for full implementation
316
+ };
317
+ }
318
+ ```
319
+
320
+ ## Data Flow
321
+ ```mermaid
322
+ flowchart TD
323
+ Start[getAgentConfig orgId + agentId] --> User[getUserDesktopLoginConfig awaited first]
324
+ Start --> Org[getOrgDesktopLoginConfig]
325
+ Start --> Aux[getAllAuxCodes]
326
+ User --> Site[getSiteInfo siteId]
327
+ User --> Teams[getAllTeams filtered by dbId]
328
+ User --> Dial{agentProfile.dialPlanEnabled?}
329
+ Dial -->|yes| DialPlan[getDialPlanData]
330
+ Dial -->|no| Empty[empty dial plan]
331
+ Site --> All[Promise.all of five result promises]
332
+ Teams --> All
333
+ DialPlan --> All
334
+ Empty --> All
335
+ Org --> All
336
+ Aux --> All
337
+ All --> Mm[multimediaProfileId: team value else site value]
338
+ Mm --> Parse[parseAgentConfigs with orgConfig + userData + agentProfileData]
339
+ Parse --> Result[Profile with aiFeature + maskSensitiveData]
340
+ ```
341
+
342
+ ## Sequence Diagram(s)
343
+ Sequence coverage:
344
+
345
+ | Operation group | Diagram | Failure / recovery coverage |
346
+ |---|---|---|
347
+ | Profile aggregation and AI feature flags | Profile aggregation | Any required request rejection rejects `getAgentConfig`; no partial Profile is returned. |
348
+ | Team/aux-code pagination | Pagination | Continue until page metadata is exhausted; any page rejection rejects the operation. |
349
+
350
+ AI-feature retrieval shares the same actors, ordering, Promise aggregation, and all-or-nothing failure outcome as the other profile dependencies, so it is represented in the Profile aggregation diagram rather than duplicated.
351
+
352
+ ### Profile aggregation
353
+
354
+ ```mermaid
355
+ sequenceDiagram
356
+ participant CC as ContactCenter
357
+ participant Cfg as AgentConfigService
358
+ participant API as WCC APIs
359
+ participant Util as parseAgentConfigs
360
+ CC->>Cfg: getAgentConfig(orgId, agentId)
361
+ par requests started before user data resolves
362
+ Cfg->>API: getUserDesktopLoginConfig
363
+ Cfg->>API: getOrgDesktopLoginConfig
364
+ Cfg->>API: getAllAuxCodes
365
+ end
366
+ API-->>Cfg: user.dbId / user.siteId / agentProfile.dialPlanEnabled
367
+ par user-dependent requests
368
+ Cfg->>API: getSiteInfo + getAllTeams(filter userId==dbId)
369
+ Cfg->>API: conditional dial plan gated on agentProfile.dialPlanEnabled
370
+ end
371
+ Note over Cfg,API: Promise.all awaits 5 result promises after the user aggregate
372
+ alt all succeed
373
+ API-->>Cfg: five results
374
+ Cfg->>Util: parseAgentConfigs(orgConfig, userData, agentProfileData, ...)
375
+ Util-->>CC: Profile including aiFeature
376
+ else any fails
377
+ Cfg-->>CC: throw; no partial Profile
378
+ end
379
+ ```
380
+
381
+ ### Pagination
382
+
383
+ ```mermaid
384
+ sequenceDiagram
385
+ participant Caller
386
+ participant Cfg as AgentConfigService
387
+ participant WR as WebexRequest
388
+ participant API as WCC API
389
+ Caller->>Cfg: getAllTeams(orgId, pageSize, userDbId) / getAllAuxCodes(orgId, pageSize, filters)
390
+ Cfg->>WR: request page 0
391
+ WR->>API: authenticated GET
392
+ alt first page succeeds
393
+ API-->>Cfg: page 0 data + meta.totalPages
394
+ par remaining pages 1..totalPages-1
395
+ Cfg->>WR: Promise.all(page requests)
396
+ WR->>API: authenticated GETs
397
+ API-->>Cfg: remaining page responses
398
+ end
399
+ alt every remaining page succeeds
400
+ Cfg->>Cfg: concatenate responses in request order
401
+ Cfg-->>Caller: complete accumulated list
402
+ else any remaining page rejects
403
+ Cfg-->>Caller: reject; do not return a partial list
404
+ end
405
+ else first page rejects
406
+ Cfg-->>Caller: reject
407
+ end
408
+ ```
409
+
410
+ ## Class / Component Relationships
411
+ ```mermaid
412
+ classDiagram
413
+ class ContactCenter
414
+ class AgentConfigService
415
+ class WebexRequest
416
+ class parseAgentConfigs
417
+ class Profile
418
+ ContactCenter --> AgentConfigService : getAgentConfig
419
+ AgentConfigService --> WebexRequest : six dependent requests
420
+ AgentConfigService --> parseAgentConfigs : aggregate results
421
+ parseAgentConfigs --> Profile : aiFeature + maskSensitiveData
422
+ ```
423
+
424
+ | Component | File | Responsibility |
425
+ |---|---|---|
426
+ | `AgentConfigService` | `config/index.ts` | Main config service class |
427
+ | `parseAgentConfigs` | `config/Util.ts` | Profile parsing/aggregation |
428
+ | `endPointMap` | `config/constants.ts` | API endpoint definitions |
429
+ | `types` | `config/types.ts` | Types, events, interfaces |
430
+
431
+ ## Use Cases
432
+ - **UC-1 Two-wave profile aggregation:** retrieve the user desktop-login aggregate first, run five dependent promises including the organization aggregate, then parse one complete Profile or reject the whole operation. Evidence: `src/services/config/index.ts`, `src/services/config/Util.ts`, `test/unit/spec/services/config/index.ts`.
433
+ - **UC-2 Paginated teams/aux codes:** follow backend page metadata to completion; auxiliary-code requests include `desktopProfileFilter=true`. Evidence: `src/services/config/index.ts`, `test/unit/spec/services/config/index.ts`.
434
+ - **UC-3 Dial plan and URL mappings:** request dial-plan data only when the agent profile enables it, keep only `active` plans, and map the organization aggregate's `urlMappings` into the profile. Evidence: `src/services/config/index.ts`, `src/services/config/Util.ts`, `test/unit/spec/services/config/index.ts`.
435
+ - **UC-4 Outdial ANI retrieval:** return the organization-scoped ANI list through authenticated WebexRequest and propagate failures without a partial substitute. Evidence: `src/services/config/index.ts`, `test/unit/spec/services/config/index.ts`.
436
+ - **UC-5 Wellness configuration:** produce one fail-closed effective profile flag and retrieve the exact system wellness idle code across pages. Evidence: `src/services/config/Util.ts`, `src/services/config/index.ts`, `test/unit/spec/services/config/Util.ts`, `test/unit/spec/services/config/index.ts`.
437
+
438
+ ## Business Rules & Invariants
439
+ - `getAgentConfig` rejects when any required dependent request rejects; it never returns a partial Profile.
440
+ - `Profile.aiFeature` is derived from the AI-feature response, and sensitive-data masking uses the real `maskSensitiveData` field.
441
+ - Team data has no `channelMap` contract; multimedia profile responses use `MultimediaProfileResponse`.
442
+ - `isWellnessBreakEnabled` is always boolean and defaults false when any gate is absent, disabled, or unlicensed.
443
+ - The system wellness code lookup is separate from profile auxiliary-code aggregation and uses `desktopProfileFilter=false`.
444
+
445
+ ## Concurrency & Reactive Flow
446
+ - The initial user desktop-login lookup supplies identifiers for a five-promise `Promise.all`; pagination loops await pages in order and stop from returned metadata.
447
+
448
+ ## Protocol / Wire Format
449
+ All Config operations are authenticated REST calls through WebexRequest. Important current routes include:
450
+
451
+ | Operation | Resource shape |
452
+ |---|---|
453
+ | Organization desktop-login aggregate | `organization/{orgId}/desktop-login` |
454
+ | User desktop-login aggregate | `organization/{orgId}/v2/user/by-ci-user-id/{ciUserId}/desktop-login` |
455
+ | Teams | `organization/{orgId}/v2/team?page={page}&pageSize={pageSize}&agentView=true&filter=userId=={userDbId}` — the wire field is `userId` but the value is the user's database id; filter value unquoted, no `attributes=` projection |
456
+ | Auxiliary codes | pagination/filter/attributes plus `desktopProfileFilter=true` |
457
+ | Wellness system idle code | `organization/{orgId}/v2/auxiliary-code?page={page}&pageSize={pageSize}&workType=IDLE_CODE&customFilter=isSystemCode==true&desktopProfileFilter=false` |
458
+ | Multimedia profile | organization-scoped multimedia-profile resource |
459
+ | Dial plan | organization-scoped dial-plan resource when the agent profile enables it |
460
+
461
+ Exact resources live in `src/services/config/constants.ts`; response/profile fields live in `src/services/config/types.ts`.
462
+
463
+ ## Error Handling & Failure Modes
464
+ | Condition | Signal (error/code/result) | Caller recovery |
465
+ |---|---|---|
466
+ | Dependency rejection | Typed/rethrown error or failure event | Inspect structured details, preserve tracking id, and retry only when the operation is safe. |
467
+ | Timeout or missing async completion | Timeout/recovery state | Follow the module-specific recovery path; never synthesize success. |
468
+
469
+ All API methods within the config service throw errors on failure. After `getUserDesktopLoginConfig`, `getAgentConfig` awaits five dependent requests via `Promise.all`: site, conditional dial plan, teams, the organization desktop-login aggregate, and all auxiliary codes. A failure in any required request, including `getOrgDesktopLoginConfig`, causes the entire AgentProfile fetch to fail. There is no partial profile — either all data is successfully fetched and aggregated, or the operation throws.
470
+
471
+ ```typescript
472
+ try {
473
+ const profile = await this.services.config.getAgentConfig(orgId, agentId);
474
+ } catch (error) {
475
+ LoggerProxy.error(`Config fetch failed: ${error}`, {
476
+ module: 'ConfigService',
477
+ method: 'getAgentConfig',
478
+ });
479
+ throw error;
480
+ }
481
+ ```
482
+
483
+ Each method follows consistent error handling:
484
+
485
+ ```typescript
486
+ public async getUserDesktopLoginConfig(
487
+ orgId: string,
488
+ ciUserId: string
489
+ ): Promise<UserDesktopLoginResponse> {
490
+ LoggerProxy.info('Fetching user desktop-login configuration', {
491
+ module: CONFIG_FILE_NAME,
492
+ method: METHODS.GET_USER_DESKTOP_LOGIN_CONFIG,
493
+ });
494
+
495
+ try {
496
+ const resource = endPointMap.userDesktopLogin(orgId, ciUserId);
497
+ const response = await this.webexReq.request({
498
+ service: WCC_API_GATEWAY,
499
+ resource,
500
+ method: HTTP_METHODS.GET,
501
+ });
502
+
503
+ if (response.statusCode !== 200) {
504
+ throw new Error(`API call failed with ${response.statusCode}`);
505
+ }
506
+
507
+ LoggerProxy.log('getUserDesktopLoginConfig api success.', {
508
+ module: CONFIG_FILE_NAME,
509
+ method: METHODS.GET_USER_DESKTOP_LOGIN_CONFIG,
510
+ });
511
+
512
+ return Promise.resolve(response.body);
513
+ } catch (error) {
514
+ LoggerProxy.error(`getUserDesktopLoginConfig API call failed with ${error}`, {
515
+ module: CONFIG_FILE_NAME,
516
+ method: METHODS.GET_USER_DESKTOP_LOGIN_CONFIG,
517
+ });
518
+ throw error;
519
+ }
520
+ }
521
+ ```
522
+
523
+ **Cause**: One of the parallel API calls failed (network error, 401/403/404/500 response)
524
+
525
+ **Log patterns to search for:**
526
+
527
+ ```typescript
528
+ // General config failure
529
+ "getAgentConfig call failed"
530
+ "module": "config/index.ts", "method": "getAgentConfig"
531
+
532
+ // Specific API method failures
533
+ "getUserDesktopLoginConfig API call failed"
534
+ "getOrgDesktopLoginConfig API call failed"
535
+ "getAllTeams API call failed"
536
+ "getAllAuxCodes API call failed"
537
+
538
+ // Look for HTTP error codes
539
+ "API call failed with 401" // Authentication
540
+ "API call failed with 403" // Authorization
541
+ "API call failed with 404" // Not found
542
+ "API call failed with 500" // Server error
543
+ ```
544
+
545
+ **Solution**:
546
+
547
+ 1. Check logs for specific API that failed
548
+
549
+ 2. Verify orgId and agentId are correct
550
+
551
+ 3. Ensure authentication tokens are valid
552
+
553
+ 4. Check network connectivity to WCC API Gateway
554
+
555
+ **Cause**: Pagination not completing or filter parameters incorrect
556
+
557
+ **Log patterns:**
558
+
559
+ ```typescript
560
+ "getAllTeams API call failed"
561
+ "getAllAuxCodes API call failed"
562
+ "method": "getListOfTeams"
563
+ "method": "getListOfAuxCodes"
564
+ ```
565
+
566
+ **Solution**:
567
+
568
+ 1. Check `totalPages` in first response
569
+
570
+ 2. Verify the team filter carries a valid `userDbId` (`user.dbId`, not the CI user id) and that aux-code filters contain valid IDs
571
+
572
+ 3. Check if pageSize is appropriate (default: 100)
573
+
574
+ 4. Ensure all pages are fetched in Promise.all()
575
+
576
+ **Cause**: Organization or tenant settings have feature disabled
577
+
578
+ **Log patterns:**
579
+
580
+ ```typescript
581
+ "getOrgDesktopLoginConfig api success."
582
+ "getUserDesktopLoginConfig api success."
583
+ ```
584
+
585
+ **Solution**:
586
+
587
+ 1. Check `orgSettingsData.webRtcEnabled` in response
588
+
589
+ 2. Check `tenantData.outdialEnabled` for outbound features
590
+
591
+ 3. Verify feature is enabled in admin portal settings
592
+
593
+ 4. Confirm agentProfileData has correct feature flags
594
+
595
+ **Cause**: `dialPlanEnabled` is false in desktop profile
596
+
597
+ **Solution**:
598
+
599
+ 1. Check `agentProfileData.dialPlanEnabled` value
600
+
601
+ 2. Verify dial plans are assigned in agent profile configuration
602
+
603
+ 3. Note: dial plan fetch only happens if `dialPlanEnabled === true`
604
+
605
+ **Cause**: Expected auxiliary codes missing from the returned pool
606
+
607
+ **Log patterns:**
608
+
609
+ ```typescript
610
+ "method": "getFilterAuxCodes"
611
+ ```
612
+
613
+ **Solution**:
614
+
615
+ 1. `getFilterAuxCodes` no longer applies a per-agent restriction list — the full organization pool is returned for every agent
616
+
617
+ 2. `Profile.idleCodesAccess` / `wrapupCodesAccess` still report `ALL` or `SPECIFIC` from `agentProfileData`
618
+
619
+ 3. Ensure aux codes have `active: true` status and the expected `workTypeCode`
620
+
621
+ 4. Note: "Available" state is always appended to idle codes
622
+
623
+ ## Pitfalls
624
+ - `getUserDesktopLoginConfig` must complete before site/team/dial-plan requests are constructed, while the five dependent promises remain all-or-nothing.
625
+ - The `aiFeature` section is part of the organization aggregate and must be passed into `parseAgentConfigs`; omitting it silently removes `Profile.aiFeature`.
626
+ - The team filter value must stay unquoted (`filter=userId=={dbId}`) — the quoted form returns HTTP 400 — and must not carry an `attributes=` projection, which would strip `multiMediaProfileId`, `teamType` and `siteName`.
627
+ - Team responses do not own channel configuration, and auxiliary-code requests require `desktopProfileFilter=true` during profile construction.
628
+
629
+ ## Module Do's / Don'ts
630
+ - DO preserve the user-first dependency boundary and the exact five-promise result order.
631
+ - DO paginate team and auxiliary-code endpoints until their metadata indicates completion.
632
+ - DON'T return a partially assembled Profile after any required dependency fails.
633
+ - DON'T invent TeamList fields such as `channelMap` or omit `maskSensitiveData`/`aiFeature` mappings.
634
+
635
+ ## Key Design Trade-off
636
+ - Profile creation is all-or-nothing across dependent API calls so consumers never receive internally inconsistent partial configuration.
637
+
638
+ ## Test-Case Strategy (module)
639
+ `test/unit/spec/services/config/index.ts` must cover staged user-first orchestration, five-promise aggregation, AI-feature mapping, conditional dial plan, the `userDbId` team filter, pagination, auxiliary-code URL filtering, real response field names, and whole-profile rejection on any required failure.
640
+
641
+ | Behavior / Requirement | Existing test evidence | Gap |
642
+ |---|---|---|
643
+ | `CONFIG-R-001` | `test/unit/spec/services/config/index.ts` | None. |
644
+ | `CONFIG-R-002` | `test/unit/spec/services/config/index.ts` | None. |
645
+ | `CONFIG-R-003` | `test/unit/spec/services/config/index.ts` | None. |
646
+ | `CONFIG-R-004` | `test/unit/spec/services/config/index.ts` | None. |
647
+ | `CONFIG-R-005` | `test/unit/spec/services/config/index.ts` | Keep an explicit rejection assertion for each required dependency category. |
648
+ | `CONFIG-R-006` | `test/unit/spec/services/config/Util.ts` | None. |
649
+ | `CONFIG-R-007` | `test/unit/spec/services/config/index.ts` | None. |
650
+
651
+ ## Traceability
652
+ - Repo architecture: `../../../../ai-docs/ARCHITECTURE.md` · Registry: `../../../../ai-docs/SPEC_INDEX.md`
653
+ - Coverage state and contracts baseline: `../../../../.sdd/manifest.json`
654
+
655
+ - [Root AGENTS.md](../../../../AGENTS.md) - Orchestrator and cross-scope rules
656
+
657
+ - [types.ts](../types.ts) - Type definitions
658
+
659
+ - [Util.ts](../Util.ts) - AgentProfile parsing utilities
660
+
661
+ - [constants.ts](../constants.ts) - API endpoints
662
+
663
+ - [index.ts](../index.ts) - Service implementation with all API methods
664
+
665
+ - [types.ts](../types.ts) - Complete type definitions and event constants
666
+
667
+ - [Util.ts](../Util.ts) - Profile parsing utilities (parseAgentConfigs, getFilterAuxCodes, etc.)
668
+
669
+ - [constants.ts](../constants.ts) - API endpoints, default values, and method names