@webex/contact-center 3.12.0-next.13 → 3.12.0-next.130
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 +884 -0
- package/AGENTS.md +94 -0
- package/ai-docs/ARCHITECTURE.md +168 -0
- package/ai-docs/CONTRACTS.md +53 -0
- package/ai-docs/GETTING_STARTED.md +168 -0
- package/ai-docs/GLOSSARY.md +43 -0
- package/ai-docs/README.md +138 -0
- package/ai-docs/REVIEW_CHECKLIST.md +41 -0
- package/ai-docs/RULES.md +444 -0
- package/ai-docs/SECURITY.md +52 -0
- package/ai-docs/SERVICE_STATE.md +52 -0
- package/ai-docs/SPEC_INDEX.md +65 -0
- package/ai-docs/adr/0001-spec-source-policy.md +55 -0
- package/ai-docs/adr/README.md +8 -0
- package/ai-docs/adr/_adr-template.md +31 -0
- package/ai-docs/contact-center-spec.md +382 -0
- package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -0
- package/ai-docs/features/contact-owner-change-refactor.md +78 -0
- package/ai-docs/features/generated-spec-conformance-fidelity-remediation/spec/feature-spec.md +117 -0
- package/ai-docs/features/residual-warning-coverage-completion/spec/feature-spec.md +203 -0
- package/ai-docs/features/validator-code-fidelity-drift-fix/spec/feature-spec.md +315 -0
- package/ai-docs/patterns/event-driven-patterns.md +485 -0
- package/ai-docs/patterns/testing-patterns.md +480 -0
- package/ai-docs/patterns/typescript-patterns.md +365 -0
- package/ai-docs/templates/README.md +102 -0
- package/ai-docs/templates/documentation/create-agents-md.md +240 -0
- package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
- package/ai-docs/templates/existing-service/bug-fix.md +254 -0
- package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
- package/ai-docs/templates/new-method/00-master.md +80 -0
- package/ai-docs/templates/new-method/01-requirements.md +232 -0
- package/ai-docs/templates/new-method/02-implementation.md +295 -0
- package/ai-docs/templates/new-method/03-tests.md +201 -0
- package/ai-docs/templates/new-method/04-validation.md +141 -0
- package/ai-docs/templates/new-service/00-master.md +109 -0
- package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
- package/ai-docs/templates/new-service/02-code-generation.md +346 -0
- package/ai-docs/templates/new-service/03-integration.md +178 -0
- package/ai-docs/templates/new-service/04-test-generation.md +205 -0
- package/ai-docs/templates/new-service/05-validation.md +145 -0
- package/dist/cc.js +971 -42
- package/dist/cc.js.map +1 -1
- package/dist/config.js +13 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +31 -3
- package/dist/constants.js.map +1 -1
- package/dist/index.js +45 -15
- package/dist/index.js.map +1 -1
- package/dist/metrics/MetricsManager.js +16 -0
- package/dist/metrics/MetricsManager.js.map +1 -1
- package/dist/metrics/behavioral-events.js +205 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +48 -4
- 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 +202 -0
- package/dist/services/AnswerCallOnWebexService.js.map +1 -0
- package/dist/services/ApiAiAssistant.js +269 -9
- package/dist/services/ApiAiAssistant.js.map +1 -1
- 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/UserPreference.js +427 -0
- package/dist/services/UserPreference.js.map +1 -0
- package/dist/services/WebexCrossClientService.js +222 -0
- package/dist/services/WebexCrossClientService.js.map +1 -0
- package/dist/services/WxAppTelephonyMercurySync.js +108 -0
- package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
- package/dist/services/config/Util.js +11 -4
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +41 -7
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/index.js +51 -0
- package/dist/services/config/index.js.map +1 -1
- package/dist/services/config/types.js +57 -12
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/Utils.js +111 -32
- package/dist/services/core/Utils.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/core/websocket/WebSocketManager.js +2 -1
- package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
- package/dist/services/core/websocket/types.js.map +1 -1
- package/dist/services/index.js +1 -1
- package/dist/services/index.js.map +1 -1
- package/dist/services/task/Task.js +754 -0
- package/dist/services/task/Task.js.map +1 -0
- package/dist/services/task/TaskFactory.js +49 -0
- package/dist/services/task/TaskFactory.js.map +1 -0
- package/dist/services/task/TaskManager.js +1172 -521
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +211 -27
- package/dist/services/task/TaskUtils.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 +12 -2
- 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/dialer.js +78 -0
- package/dist/services/task/dialer.js.map +1 -1
- package/dist/services/task/digital/Digital.js +78 -0
- package/dist/services/task/digital/Digital.js.map +1 -0
- package/dist/services/task/state-machine/TaskStateMachine.js +982 -0
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
- package/dist/services/task/state-machine/actions.js +572 -0
- package/dist/services/task/state-machine/actions.js.map +1 -0
- package/dist/services/task/state-machine/constants.js +161 -0
- package/dist/services/task/state-machine/constants.js.map +1 -0
- package/dist/services/task/state-machine/guards.js +379 -0
- package/dist/services/task/state-machine/guards.js.map +1 -0
- package/dist/services/task/state-machine/index.js +53 -0
- package/dist/services/task/state-machine/index.js.map +1 -0
- package/dist/services/task/state-machine/types.js +54 -0
- package/dist/services/task/state-machine/types.js.map +1 -0
- package/dist/services/task/state-machine/uiControlsComputer.js +703 -0
- package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
- package/dist/services/task/taskDataNormalizer.js +99 -0
- package/dist/services/task/taskDataNormalizer.js.map +1 -0
- package/dist/services/task/types.js +228 -5
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +1485 -0
- package/dist/services/task/voice/Voice.js.map +1 -0
- package/dist/services/task/voice/WebRTC.js +152 -0
- package/dist/services/task/voice/WebRTC.js.map +1 -0
- package/dist/services/task/voice/wxAppVoiceMethods.js +354 -0
- package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
- package/dist/services/wxAppDiagnosticLogging.js +122 -0
- package/dist/services/wxAppDiagnosticLogging.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 +193 -6
- package/dist/types/config.d.ts +13 -0
- package/dist/types/constants.d.ts +29 -1
- package/dist/types/index.d.ts +35 -8
- package/dist/types/metrics/MetricsManager.d.ts +6 -0
- package/dist/types/metrics/constants.d.ts +43 -1
- package/dist/types/services/AddressBook.d.ts +2 -1
- package/dist/types/services/AnswerCallOnWebexService.d.ts +38 -0
- package/dist/types/services/ApiAiAssistant.d.ts +56 -5
- package/dist/types/services/EntryPoint.d.ts +7 -5
- package/dist/types/services/Queue.d.ts +5 -3
- package/dist/types/services/UserPreference.d.ts +118 -0
- package/dist/types/services/WebexCrossClientService.d.ts +32 -0
- package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
- package/dist/types/services/config/constants.d.ts +34 -5
- package/dist/types/services/config/types.d.ts +197 -12
- package/dist/types/services/core/Err.d.ts +6 -0
- package/dist/types/services/core/Utils.d.ts +35 -13
- package/dist/types/services/core/WebexRequest.d.ts +1 -0
- package/dist/types/services/core/types.d.ts +2 -0
- package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -0
- package/dist/types/services/core/websocket/types.d.ts +1 -1
- package/dist/types/services/index.d.ts +1 -1
- package/dist/types/services/task/Task.d.ts +175 -0
- package/dist/types/services/task/TaskFactory.d.ts +13 -0
- package/dist/types/services/task/TaskUtils.d.ts +48 -2
- package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
- package/dist/types/services/task/constants.d.ts +10 -0
- package/dist/types/services/task/contact.d.ts +4 -0
- package/dist/types/services/task/dialer.d.ts +30 -0
- package/dist/types/services/task/digital/Digital.d.ts +22 -0
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1442 -0
- package/dist/types/services/task/state-machine/actions.d.ts +10 -0
- package/dist/types/services/task/state-machine/constants.d.ts +107 -0
- package/dist/types/services/task/state-machine/guards.d.ts +103 -0
- package/dist/types/services/task/state-machine/index.d.ts +13 -0
- package/dist/types/services/task/state-machine/types.d.ts +277 -0
- package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
- package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
- package/dist/types/services/task/types.d.ts +680 -66
- package/dist/types/services/task/voice/Voice.d.ts +227 -0
- package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
- package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +55 -0
- package/dist/types/services/wxAppDiagnosticLogging.d.ts +51 -0
- package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
- package/dist/types/types.d.ts +205 -9
- package/dist/types/utils/PageCache.d.ts +20 -3
- package/dist/types/webex.d.ts +1 -0
- package/dist/types.js +162 -4
- 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 +22 -2
- package/dist/webex.js.map +1 -1
- package/package.json +16 -12
- package/src/cc.ts +1289 -112
- package/src/config.ts +13 -0
- package/src/constants.ts +29 -1
- package/src/index.ts +36 -5
- package/src/metrics/MetricsManager.ts +16 -0
- package/src/metrics/ai-docs/AGENTS.md +350 -0
- package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
- package/src/metrics/ai-docs/metrics-spec.md +921 -0
- package/src/metrics/behavioral-events.ts +212 -0
- package/src/metrics/constants.ts +52 -4
- package/src/services/AddressBook.ts +17 -6
- package/src/services/AnswerCallOnWebexService.ts +239 -0
- package/src/services/ApiAiAssistant.ts +356 -9
- package/src/services/EntryPoint.ts +59 -60
- package/src/services/Queue.ts +29 -12
- package/src/services/UserPreference.ts +509 -0
- package/src/services/WebexCrossClientService.ts +293 -0
- package/src/services/WxAppTelephonyMercurySync.ts +142 -0
- package/src/services/agent/ai-docs/AGENTS.md +240 -0
- package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
- package/src/services/agent/ai-docs/agent-spec.md +505 -0
- package/src/services/ai-docs/AGENTS.md +386 -0
- package/src/services/ai-docs/services-spec.md +505 -0
- package/src/services/config/Util.ts +12 -3
- package/src/services/config/ai-docs/AGENTS.md +255 -0
- package/src/services/config/ai-docs/ARCHITECTURE.md +426 -0
- package/src/services/config/ai-docs/config-spec.md +686 -0
- package/src/services/config/constants.ts +46 -6
- package/src/services/config/index.ts +65 -0
- package/src/services/config/types.ts +197 -13
- package/src/services/core/Err.ts +3 -0
- package/src/services/core/Utils.ts +127 -37
- package/src/services/core/WebexRequest.ts +3 -1
- package/src/services/core/ai-docs/AGENTS.md +381 -0
- package/src/services/core/ai-docs/ARCHITECTURE.md +698 -0
- package/src/services/core/ai-docs/core-spec.md +787 -0
- package/src/services/core/aqm-reqs.ts +30 -15
- package/src/services/core/types.ts +2 -0
- package/src/services/core/websocket/WebSocketManager.ts +2 -0
- package/src/services/core/websocket/types.ts +1 -1
- package/src/services/index.ts +1 -1
- package/src/services/task/Task.ts +908 -0
- package/src/services/task/TaskFactory.ts +60 -0
- package/src/services/task/TaskManager.ts +1419 -608
- package/src/services/task/TaskUtils.ts +303 -25
- package/src/services/task/WebexCallingUtils.ts +136 -0
- package/src/services/task/ai-docs/AGENTS.md +457 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +595 -0
- package/src/services/task/ai-docs/task-spec.md +1474 -0
- package/src/services/task/constants.ts +10 -0
- package/src/services/task/contact.ts +30 -0
- package/src/services/task/dialer.ts +80 -0
- package/src/services/task/digital/Digital.ts +97 -0
- package/src/services/task/state-machine/TaskStateMachine.ts +1320 -0
- package/src/services/task/state-machine/actions.ts +741 -0
- package/src/services/task/state-machine/ai-docs/AGENTS.md +460 -0
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1156 -0
- package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2247 -0
- package/src/services/task/state-machine/constants.ts +172 -0
- package/src/services/task/state-machine/guards.ts +442 -0
- package/src/services/task/state-machine/index.ts +28 -0
- package/src/services/task/state-machine/types.ts +258 -0
- package/src/services/task/state-machine/uiControlsComputer.ts +1135 -0
- package/src/services/task/taskDataNormalizer.ts +137 -0
- package/src/services/task/types.ts +819 -70
- package/src/services/task/voice/Voice.ts +1851 -0
- package/src/services/task/voice/WebRTC.ts +191 -0
- package/src/services/task/voice/wxAppVoiceMethods.ts +516 -0
- package/src/services/wxAppDiagnosticLogging.ts +174 -0
- package/src/services/wxAppTelephonyUtils.ts +14 -0
- package/src/types.ts +262 -11
- package/src/utils/AGENTS.md +289 -0
- package/src/utils/PageCache.ts +38 -5
- package/src/utils/ai-docs/utils-spec.md +391 -0
- package/src/webex.js +10 -0
- package/test/unit/spec/cc.ts +2210 -119
- package/test/unit/spec/logger-proxy.ts +70 -0
- package/test/unit/spec/metrics/MetricsManager.ts +25 -0
- package/test/unit/spec/metrics/behavioral-events.ts +60 -0
- package/test/unit/spec/services/AddressBook.ts +37 -6
- package/test/unit/spec/services/AnswerCallOnWebexService.ts +264 -0
- package/test/unit/spec/services/ApiAiAssistant.ts +311 -21
- package/test/unit/spec/services/EntryPoint.ts +87 -40
- package/test/unit/spec/services/Queue.ts +123 -12
- package/test/unit/spec/services/UserPreference.ts +401 -0
- package/test/unit/spec/services/WebCallingService.ts +7 -1
- package/test/unit/spec/services/WebexCrossClientService.ts +467 -0
- package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +136 -0
- package/test/unit/spec/services/config/Util.ts +129 -0
- package/test/unit/spec/services/config/index.ts +97 -29
- package/test/unit/spec/services/core/Utils.ts +425 -8
- 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/core/websocket/WebSocketManager.ts +66 -40
- package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
- package/test/unit/spec/services/task/Task.ts +745 -0
- package/test/unit/spec/services/task/TaskFactory.ts +99 -0
- package/test/unit/spec/services/task/TaskManager.ts +2518 -1494
- package/test/unit/spec/services/task/TaskUtils.ts +235 -0
- 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/dialer.ts +190 -0
- package/test/unit/spec/services/task/digital/Digital.ts +105 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +4060 -0
- package/test/unit/spec/services/task/state-machine/guards.ts +839 -0
- package/test/unit/spec/services/task/state-machine/types.ts +18 -0
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +3101 -0
- package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
- package/test/unit/spec/services/task/voice/Voice.ts +2061 -0
- package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
- package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +603 -0
- package/test/unit/spec/services/wxAppDiagnosticLogging.ts +143 -0
- package/test/unit/spec/wellnessSampleUtils.ts +288 -0
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
- package/dist/services/task/index.js +0 -1525
- package/dist/services/task/index.js.map +0 -1
- package/dist/types/services/task/index.d.ts +0 -650
- package/src/services/task/index.ts +0 -1801
- package/test/unit/spec/services/task/index.ts +0 -2184
|
@@ -0,0 +1,921 @@
|
|
|
1
|
+
# Metrics — 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 | `metrics` |
|
|
10
|
+
| Source path(s) | `src/metrics` |
|
|
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 Agent Wellness Break delta / 2026-09-02 |
|
|
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
|
+
Metrics is one of nine confirmed Contact Center SDK modules. Own timing, taxonomy, queuing, payload preparation, and submission for Contact Center behavioral, operational, and business telemetry. Existing reviewed documentation is migrated by meaning and code/tests remain the behavioral referee.
|
|
27
|
+
|
|
28
|
+
- **Singleton Pattern**: Single `MetricsManager` instance shared across the entire SDK
|
|
29
|
+
|
|
30
|
+
- **Three Metric Types**: Behavioral (user actions), operational (system events), business (business-level analytics)
|
|
31
|
+
|
|
32
|
+
- **Event Timing**: `timeEvent` + `trackEvent` pattern automatically calculates `duration_ms`
|
|
33
|
+
|
|
34
|
+
- **Queued Submission**: Events are queued until the Webex SDK is ready, then submitted in order
|
|
35
|
+
|
|
36
|
+
- **Behavioral Taxonomy**: Structured `product.agent.target.verb` naming convention for behavioral events
|
|
37
|
+
|
|
38
|
+
- **Webex Together behavioral naming**: Webex Together (wxApp) events use `*_webex_together` compound targets (e.g. `wxcc_sdk.user.task_accept_webex_together.complete`). Operational/business wire names remain `WXCC_SDK_WXAPP_*` unchanged.
|
|
39
|
+
|
|
40
|
+
- **Payload Preparation**: Automatic cleanup of empty fields, space-to-underscore conversion, and `tabHidden` metadata
|
|
41
|
+
|
|
42
|
+
- **AQM Response Helpers**: Static methods to extract common tracking fields from AQM responses
|
|
43
|
+
|
|
44
|
+
## Purpose / Responsibility
|
|
45
|
+
Own timing, taxonomy, queuing, payload preparation, and submission for Contact Center behavioral, operational, and business telemetry.
|
|
46
|
+
|
|
47
|
+
## Stack
|
|
48
|
+
TypeScript 5.4 singleton service, Webex internal metrics APIs, LoggerProxy, Jest 27.
|
|
49
|
+
|
|
50
|
+
## Folder / Package Structure
|
|
51
|
+
```text
|
|
52
|
+
src/metrics/
|
|
53
|
+
├── MetricsManager.ts
|
|
54
|
+
├── behavioral-events.ts
|
|
55
|
+
├── constants.ts
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
src/metrics/
|
|
60
|
+
├── MetricsManager.ts # Singleton metrics manager
|
|
61
|
+
├── behavioral-events.ts # Behavioral event taxonomy mapping
|
|
62
|
+
├── constants.ts # METRIC_EVENT_NAMES constants
|
|
63
|
+
└── ai-docs/
|
|
64
|
+
├── AGENTS.md # Usage documentation (see PR #4762)
|
|
65
|
+
└── ARCHITECTURE.md # Preserved legacy, noncanonical architecture guide
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Key Files (source of truth)
|
|
69
|
+
| File | Holds |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `src/metrics/MetricsManager.ts` | Authoritative Metrics implementation or contract source. |
|
|
72
|
+
| `src/metrics/behavioral-events.ts` | Authoritative Metrics implementation or contract source. |
|
|
73
|
+
| `src/metrics/constants.ts` | Authoritative Metrics implementation or contract source. |
|
|
74
|
+
|
|
75
|
+
## Public Surface
|
|
76
|
+
| Contract ID | Type | Surface | Purpose | Compatibility / deprecation | Schema / detail link | Root index |
|
|
77
|
+
|---|---|---|---|---|---|---|
|
|
78
|
+
| `metrics.surface` | SDK / event / internal API | Internal `MetricsManager` singleton, metric event constants, taxonomy lookup, timing, and tracking helpers. | Stable module consumption boundary. | Additive changes by default; breaking package exports require a major-version transition. | `src/metrics/MetricsManager.ts` | `../../../ai-docs/CONTRACTS.md` |
|
|
79
|
+
|
|
80
|
+
Compatibility notes:
|
|
81
|
+
- Do not remove or reinterpret exported symbols/events without a documented consumer migration.
|
|
82
|
+
|
|
83
|
+
Returns the singleton instance. On first call with `{webex}`, binds to the Webex SDK and begins listening for the `ready` event.
|
|
84
|
+
|
|
85
|
+
**Parameters**:
|
|
86
|
+
|
|
87
|
+
- `options` (object, optional): `{webex: WebexSDK}` - The Webex SDK instance
|
|
88
|
+
|
|
89
|
+
**Returns**: `MetricsManager`
|
|
90
|
+
|
|
91
|
+
**Example**:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// During initialization (called internally by cc.register())
|
|
95
|
+
const metrics = MetricsManager.getInstance({webex});
|
|
96
|
+
|
|
97
|
+
// Subsequent calls (no webex needed)
|
|
98
|
+
const metrics = MetricsManager.getInstance();
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Starts a timer for one or more event keys. When a matching `trackEvent` / `trackBehavioralEvent` / `trackOperationalEvent` / `trackBusinessEvent` is called, `duration_ms` is automatically added to the payload.
|
|
102
|
+
|
|
103
|
+
**Parameters**:
|
|
104
|
+
|
|
105
|
+
- `keys` (string | string[]): One or more `METRIC_EVENT_NAMES` values. The first key is the tracking key; all keys in the array will resolve the same timer.
|
|
106
|
+
|
|
107
|
+
**Returns**: `void`
|
|
108
|
+
|
|
109
|
+
**Example**:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// Single key
|
|
113
|
+
metrics.timeEvent(METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS);
|
|
114
|
+
|
|
115
|
+
// Multiple keys (success/failure share one timer)
|
|
116
|
+
metrics.timeEvent([
|
|
117
|
+
METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS,
|
|
118
|
+
METRIC_EVENT_NAMES.STATION_LOGIN_FAILED,
|
|
119
|
+
]);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Tracks an event across one or more metric services.
|
|
123
|
+
|
|
124
|
+
**Parameters**:
|
|
125
|
+
|
|
126
|
+
- `name` (METRIC_EVENT_NAMES): The event name constant
|
|
127
|
+
|
|
128
|
+
- `payload` (EventPayload, optional): Key-value pairs of event data
|
|
129
|
+
|
|
130
|
+
- `metricServices` (MetricsType[], optional): Array of `'behavioral'` | `'operational'` | `'business'` (default: `['behavioral']`)
|
|
131
|
+
|
|
132
|
+
**Returns**: `void`
|
|
133
|
+
|
|
134
|
+
**Example**:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// Behavioral only (default)
|
|
138
|
+
metrics.trackEvent(METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS, {agentId: '123'});
|
|
139
|
+
|
|
140
|
+
// Multiple services
|
|
141
|
+
metrics.trackEvent(
|
|
142
|
+
METRIC_EVENT_NAMES.TASK_ACCEPT_SUCCESS,
|
|
143
|
+
{interactionId: 'abc'},
|
|
144
|
+
['behavioral', 'operational']
|
|
145
|
+
);
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Tracks a single behavioral event. Looks up the event taxonomy from `behavioral-events.ts` and submits via `webex.internal.newMetrics.submitBehavioralEvent`.
|
|
149
|
+
|
|
150
|
+
**Parameters**:
|
|
151
|
+
|
|
152
|
+
- `name` (METRIC_EVENT_NAMES): The event name
|
|
153
|
+
|
|
154
|
+
- `options` (EventPayload, optional): Additional payload data
|
|
155
|
+
|
|
156
|
+
**Returns**: `void`
|
|
157
|
+
|
|
158
|
+
Tracks a single operational event. Prefixes the event name with `WXCC_SDK_` and submits via `webex.internal.newMetrics.submitOperationalEvent`.
|
|
159
|
+
|
|
160
|
+
**Parameters**:
|
|
161
|
+
|
|
162
|
+
- `name` (METRIC_EVENT_NAMES): The event name
|
|
163
|
+
|
|
164
|
+
- `options` (EventPayload, optional): Additional payload data
|
|
165
|
+
|
|
166
|
+
**Returns**: `void`
|
|
167
|
+
|
|
168
|
+
Tracks a single business event. Prefixes the event name with `WXCC_SDK_` and submits via `webex.internal.newMetrics.submitBusinessEvent` with `appType: 'wxcc_sdk'`.
|
|
169
|
+
|
|
170
|
+
**Parameters**:
|
|
171
|
+
|
|
172
|
+
- `name` (METRIC_EVENT_NAMES): The event name
|
|
173
|
+
|
|
174
|
+
- `options` (EventPayload, optional): Additional payload data
|
|
175
|
+
|
|
176
|
+
**Returns**: `void`
|
|
177
|
+
|
|
178
|
+
Enables or disables metrics collection. When disabled, all pending events are cleared and new events are dropped.
|
|
179
|
+
|
|
180
|
+
**Parameters**:
|
|
181
|
+
|
|
182
|
+
- `disabled` (boolean): `true` to disable, `false` to enable
|
|
183
|
+
|
|
184
|
+
**Returns**: `void`
|
|
185
|
+
|
|
186
|
+
Static helper that extracts common tracking fields from an AQM success response.
|
|
187
|
+
|
|
188
|
+
**Parameters**:
|
|
189
|
+
|
|
190
|
+
- `response` (any): The AQM response object
|
|
191
|
+
|
|
192
|
+
**Returns**: `Record<string, any>` with fields: `agentId`, `agentSessionId`, `teamId`, `siteId`, `orgId`, `eventType`, `trackingId`, `notifTrackingId`
|
|
193
|
+
|
|
194
|
+
**Example**:
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
const fields = MetricsManager.getCommonTrackingFieldForAQMResponse(aqmResponse);
|
|
198
|
+
metrics.trackEvent(METRIC_EVENT_NAMES.TASK_ACCEPT_SUCCESS, {
|
|
199
|
+
...fields,
|
|
200
|
+
interactionId: task.interactionId,
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Resets the singleton instance. Used for testing only.
|
|
205
|
+
|
|
206
|
+
**Returns**: `void`
|
|
207
|
+
|
|
208
|
+
All event names are defined in `METRIC_EVENT_NAMES` (`constants.ts`). Events follow a `<Category> <Action> <Result>` pattern.
|
|
209
|
+
|
|
210
|
+
| Constant | Value | Description |
|
|
211
|
+
|---|---|---|
|
|
212
|
+
| `STATION_LOGIN_SUCCESS` | `'Station Login Success'` | Agent station login succeeded |
|
|
213
|
+
| `STATION_LOGIN_FAILED` | `'Station Login Failed'` | Agent station login failed |
|
|
214
|
+
| `STATION_LOGOUT_SUCCESS` | `'Station Logout Success'` | Agent station logout succeeded |
|
|
215
|
+
| `STATION_LOGOUT_FAILED` | `'Station Logout Failed'` | Agent station logout failed |
|
|
216
|
+
| `STATION_RELOGIN_SUCCESS` | `'Station Relogin Success'` | Silent relogin succeeded |
|
|
217
|
+
| `STATION_RELOGIN_FAILED` | `'Station Relogin Failed'` | Silent relogin failed |
|
|
218
|
+
| `AGENT_STATE_CHANGE_SUCCESS` | `'Agent State Change Success'` | State change succeeded |
|
|
219
|
+
| `AGENT_STATE_CHANGE_FAILED` | `'Agent State Change Failed'` | State change failed |
|
|
220
|
+
| `FETCH_BUDDY_AGENTS_SUCCESS` | `'Fetch Buddy Agents Success'` | Buddy agents fetch succeeded |
|
|
221
|
+
| `FETCH_BUDDY_AGENTS_FAILED` | `'Fetch Buddy Agents Failed'` | Buddy agents fetch failed |
|
|
222
|
+
| `AGENT_RONA` | `'Agent RONA'` | Agent Ring-On-No-Answer triggered |
|
|
223
|
+
| `AGENT_CONTACT_ASSIGN_FAILED` | `'Agent Contact Assign Failed'` | Contact assignment failed |
|
|
224
|
+
| `AGENT_INVITE_FAILED` | `'Agent Invite Failed'` | Agent invite failed |
|
|
225
|
+
| `AGENT_DEVICE_TYPE_UPDATE_SUCCESS` | `'Agent Device Type Update Success'` | Device type update succeeded |
|
|
226
|
+
| `AGENT_DEVICE_TYPE_UPDATE_FAILED` | `'Agent Device Type Update Failed'` | Device type update failed |
|
|
227
|
+
| `TASK_ACCEPT_SUCCESS` / `FAILED` | `'Task Accept ...'` | Task accept result |
|
|
228
|
+
| `TASK_DECLINE_SUCCESS` / `FAILED` | `'Task Decline ...'` | Task decline result |
|
|
229
|
+
| `TASK_END_SUCCESS` / `FAILED` | `'Task End ...'` | Task end result |
|
|
230
|
+
| `TASK_WRAPUP_SUCCESS` / `FAILED` | `'Task Wrapup ...'` | Task wrapup result |
|
|
231
|
+
| `TASK_HOLD_SUCCESS` / `FAILED` | `'Task Hold ...'` | Task hold result |
|
|
232
|
+
| `TASK_RESUME_SUCCESS` / `FAILED` | `'Task Resume ...'` | Task resume result |
|
|
233
|
+
| `TASK_CONSULT_START_SUCCESS` / `FAILED` | `'Task Consult Start ...'` | Consult start result |
|
|
234
|
+
| `TASK_CONSULT_END_SUCCESS` / `FAILED` | `'Task Consult End ...'` | Consult end result |
|
|
235
|
+
| `TASK_TRANSFER_SUCCESS` / `FAILED` | `'Task Transfer ...'` | Transfer result |
|
|
236
|
+
| `TASK_PAUSE_RECORDING_SUCCESS` / `FAILED` | `'Task Pause Recording ...'` | Pause recording result |
|
|
237
|
+
| `TASK_RESUME_RECORDING_SUCCESS` / `FAILED` | `'Task Resume Recording ...'` | Resume recording result |
|
|
238
|
+
| `TASK_ACCEPT_CONSULT_SUCCESS` / `FAILED` | `'Task Accept Consult ...'` | Accept consult result |
|
|
239
|
+
| `TASK_AUTO_ANSWER_SUCCESS` / `FAILED` | `'Task Auto Answer ...'` | Auto-answer result |
|
|
240
|
+
| `TASK_OUTDIAL_SUCCESS` / `FAILED` | `'Task Outdial ...'` | Outdial result |
|
|
241
|
+
| `WXAPP_TASK_MUTE_SUCCESS` / `FAILED` | `'WxApp Task Mute ...'` | Webex Together task mute/unmute toggle (`wxcc_sdk.user.task_mute_webex_together.complete\|fail`). Mute telephony is queued per task via tail promise chain (`Voice.wxAppMuteToggleTail`) so concurrent toggles do not overwrite the shared `timeEvent` timer or reorder requests. |
|
|
242
|
+
| `WXAPP_TASK_DTMF_SUCCESS` / `FAILED` | `'WxApp Task Dtmf ...'` | Webex Together DTMF/keypad (`wxcc_sdk.user.task_dtmf_webex_together.complete\|fail`). DTMF telephony is queued per task via tail promise chain (`Voice.wxAppDtmfTail`) so concurrent keypad input does not overwrite the shared `timeEvent` timer or reorder digits. |
|
|
243
|
+
| `WXAPP_TASK_ACCEPT_SUCCESS` / `FAILED` | `'WxApp Task Accept ...'` | Webex Together accept/answer (`wxcc_sdk.user.task_accept_webex_together.complete\|fail`) |
|
|
244
|
+
| `WXAPP_TASK_DECLINE_SUCCESS` / `FAILED` | `'WxApp Task Decline ...'` | Webex Together reject/decline (`wxcc_sdk.user.task_reject_webex_together.complete\|fail`). Inbound offers: telephony `rejectCall` via `runWxAppReject`. wxApp outdial cancellations: CC `cancelTask` via `runWxAppOutdialDecline` (additive with `TASK_DECLINE_*`). Outdial failure payloads merge AQM `error.details` via `getCommonTrackingFieldForAQMResponseFailed` so wxApp metrics and diagnostic logs preserve `trackingId` / structured failure reason. |
|
|
245
|
+
| `WXAPP_SESSION_INIT_SUCCESS` / `FAILED` | `'WxApp Session Init ...'` | Webex Together session orchestration (`wxcc_sdk.user.webex_together_session_init.complete\|fail`) |
|
|
246
|
+
| `WXAPP_SESSION_SKIPPED` | `'WxApp Session Skipped'` | Webex Together session skipped (`wxcc_sdk.user.webex_together_session_init.ignore`) |
|
|
247
|
+
| `WXAPP_USERSUB_PUBLISH_SUCCESS` / `FAILED` | `'WxApp Usersub Publish ...'` | Cross-client usersub publish (`wxcc_sdk.user.webex_together_usersub_publish.complete\|fail`). Preflight failures (missing `userId` or device URL before HTTP publish) emit `WXAPP_USERSUB_PUBLISH_FAILED` with `skipReason` (`user_id_unavailable` / `device_url_unavailable`) and no `timeEvent` timer. Stale-generation discards (teardown or concurrent disable while HTTP publish is in flight) call `cancelTimedEvent` without emitting success/fail only when the completing publish still owns the active timer (`usersubPublishMetricsId` guard — a newer overlapping publish must not have its timer cleared). |
|
|
248
|
+
| `WXAPP_MERCURY_SUBSCRIBE_SUCCESS` / `FAILED` | `'WxApp Mercury Subscribe ...'` | Telephony Mercury mute-sync subscribe (`wxcc_sdk.user.webex_together_mercury_subscribe.complete\|fail`) |
|
|
249
|
+
| `TASK_CONFERENCE_START_SUCCESS` / `FAILED` | `'Task Conference Start ...'` | Conference start result |
|
|
250
|
+
| `TASK_CONFERENCE_END_SUCCESS` / `FAILED` | `'Task Conference End ...'` | Conference end result |
|
|
251
|
+
| `TASK_CONFERENCE_TRANSFER_SUCCESS` / `FAILED` | `'Task Conference Transfer ...'` | Conference transfer result |
|
|
252
|
+
| `TASK_CONFERENCE_EXIT_SUCCESS` / `FAILED` | `'Task Conference Exit ...'` | Conference exit result |
|
|
253
|
+
| `TASK_CONFERENCE_PARTICIPANT_DROP_SUCCESS` / `FAILED` | `'Task Conference Participant Drop ...'` | Participant Drop result |
|
|
254
|
+
| `TASK_SWITCH_CALL_SUCCESS` / `FAILED` | `'Task Switch Call ...'` | Switch call result |
|
|
255
|
+
| `WEBSOCKET_REGISTER_SUCCESS` / `FAILED` | `'Websocket Register ...'` | WebSocket registration result |
|
|
256
|
+
| `WEBSOCKET_DEREGISTER_SUCCESS` / `FAIL` | `'Websocket Deregister ...'` | WebSocket deregistration result |
|
|
257
|
+
| `WEBSOCKET_EVENT_RECEIVED` | `'Websocket Event Received'` | WebSocket event received |
|
|
258
|
+
| `UPLOAD_LOGS_SUCCESS` / `FAILED` | `'Upload Logs ...'` | Log upload result |
|
|
259
|
+
| `ENTRYPOINT_FETCH_SUCCESS` / `FAILED` | `'Entrypoint Fetch ...'` | Entry point fetch result |
|
|
260
|
+
| `ADDRESSBOOK_FETCH_SUCCESS` / `FAILED` | `'AddressBook Fetch ...'` | Address book fetch result |
|
|
261
|
+
| `QUEUE_FETCH_SUCCESS` / `FAILED` | `'Queue Fetch ...'` | Queue fetch result |
|
|
262
|
+
| `OUTDIAL_ANI_EP_FETCH_SUCCESS` / `FAILED` | `'Outdial ANI Entries Fetch ...'` | Outdial ANI entries fetch result |
|
|
263
|
+
| `AI_ASSISTANT_WELLNESS_ACTION_ACCEPTED` / `FAILED` | `'AI Assistant Wellness Action ...'` | Direct wellness custom-event result |
|
|
264
|
+
| `AI_ASSISTANT_WELLNESS_EVENT_INVALID` | `'AI Assistant Wellness Event Invalid'` | Malformed or mismatched wellness notification ignored |
|
|
265
|
+
| `WELLBEING_BREAK_IDLE_CODE_FETCH_SUCCESS` / `FAILED` | `'Wellbeing Break Idle Code Fetch ...'` | System wellness idle-code lookup result |
|
|
266
|
+
|
|
267
|
+
All event names are defined in `constants.ts` as `METRIC_EVENT_NAMES`. Events follow a `{Domain} {Action} {Success|Failed}` naming convention:
|
|
268
|
+
|
|
269
|
+
| Category | Success Event | Failure Event |
|
|
270
|
+
|---|---|---|
|
|
271
|
+
| Station Login | `STATION_LOGIN_SUCCESS` | `STATION_LOGIN_FAILED` |
|
|
272
|
+
| Station Logout | `STATION_LOGOUT_SUCCESS` | `STATION_LOGOUT_FAILED` |
|
|
273
|
+
| Station Relogin | `STATION_RELOGIN_SUCCESS` | `STATION_RELOGIN_FAILED` |
|
|
274
|
+
| State Change | `AGENT_STATE_CHANGE_SUCCESS` | `AGENT_STATE_CHANGE_FAILED` |
|
|
275
|
+
| Buddy Agents | `FETCH_BUDDY_AGENTS_SUCCESS` | `FETCH_BUDDY_AGENTS_FAILED` |
|
|
276
|
+
| WebSocket Register | `WEBSOCKET_REGISTER_SUCCESS` | `WEBSOCKET_REGISTER_FAILED` |
|
|
277
|
+
| Task Accept | `TASK_ACCEPT_SUCCESS` | `TASK_ACCEPT_FAILED` |
|
|
278
|
+
| Task Decline | `TASK_DECLINE_SUCCESS` | `TASK_DECLINE_FAILED` |
|
|
279
|
+
| Task End | `TASK_END_SUCCESS` | `TASK_END_FAILED` |
|
|
280
|
+
| Task Wrapup | `TASK_WRAPUP_SUCCESS` | `TASK_WRAPUP_FAILED` |
|
|
281
|
+
| Task Hold | `TASK_HOLD_SUCCESS` | `TASK_HOLD_FAILED` |
|
|
282
|
+
| Task Resume | `TASK_RESUME_SUCCESS` | `TASK_RESUME_FAILED` |
|
|
283
|
+
| Task Consult Start | `TASK_CONSULT_START_SUCCESS` | `TASK_CONSULT_START_FAILED` |
|
|
284
|
+
| Task Consult End | `TASK_CONSULT_END_SUCCESS` | `TASK_CONSULT_END_FAILED` |
|
|
285
|
+
| Task Transfer | `TASK_TRANSFER_SUCCESS` | `TASK_TRANSFER_FAILED` |
|
|
286
|
+
| Task Resume Recording | `TASK_RESUME_RECORDING_SUCCESS` | `TASK_RESUME_RECORDING_FAILED` |
|
|
287
|
+
| Task Pause Recording | `TASK_PAUSE_RECORDING_SUCCESS` | `TASK_PAUSE_RECORDING_FAILED` |
|
|
288
|
+
| Task Accept Consult | `TASK_ACCEPT_CONSULT_SUCCESS` | `TASK_ACCEPT_CONSULT_FAILED` |
|
|
289
|
+
| Task Auto Answer | `TASK_AUTO_ANSWER_SUCCESS` | `TASK_AUTO_ANSWER_FAILED` |
|
|
290
|
+
| Conference Start | `TASK_CONFERENCE_START_SUCCESS` | `TASK_CONFERENCE_START_FAILED` |
|
|
291
|
+
| Conference End | `TASK_CONFERENCE_END_SUCCESS` | `TASK_CONFERENCE_END_FAILED` |
|
|
292
|
+
| Conference Transfer | `TASK_CONFERENCE_TRANSFER_SUCCESS` | `TASK_CONFERENCE_TRANSFER_FAILED` |
|
|
293
|
+
| Conference Exit | `TASK_CONFERENCE_EXIT_SUCCESS` | `TASK_CONFERENCE_EXIT_FAILED` |
|
|
294
|
+
| Conference Participant Drop | `TASK_CONFERENCE_PARTICIPANT_DROP_SUCCESS` | `TASK_CONFERENCE_PARTICIPANT_DROP_FAILED` |
|
|
295
|
+
| Switch Call | `TASK_SWITCH_CALL_SUCCESS` | `TASK_SWITCH_CALL_FAILED` |
|
|
296
|
+
| Outdial | `TASK_OUTDIAL_SUCCESS` | `TASK_OUTDIAL_FAILED` |
|
|
297
|
+
| WxApp Task Mute | `WXAPP_TASK_MUTE_SUCCESS` | `WXAPP_TASK_MUTE_FAILED` |
|
|
298
|
+
| WxApp Task DTMF | `WXAPP_TASK_DTMF_SUCCESS` | `WXAPP_TASK_DTMF_FAILED` |
|
|
299
|
+
| WxApp Task Accept | `WXAPP_TASK_ACCEPT_SUCCESS` | `WXAPP_TASK_ACCEPT_FAILED` |
|
|
300
|
+
| WxApp Task Decline | `WXAPP_TASK_DECLINE_SUCCESS` | `WXAPP_TASK_DECLINE_FAILED` |
|
|
301
|
+
| WxApp Session Init | `WXAPP_SESSION_INIT_SUCCESS` | `WXAPP_SESSION_INIT_FAILED` |
|
|
302
|
+
| WxApp Usersub Publish | `WXAPP_USERSUB_PUBLISH_SUCCESS` | `WXAPP_USERSUB_PUBLISH_FAILED` |
|
|
303
|
+
| WxApp Mercury Subscribe | `WXAPP_MERCURY_SUBSCRIBE_SUCCESS` | `WXAPP_MERCURY_SUBSCRIBE_FAILED` |
|
|
304
|
+
| Upload Logs | `UPLOAD_LOGS_SUCCESS` | `UPLOAD_LOGS_FAILED` |
|
|
305
|
+
| WebSocket Deregister | `WEBSOCKET_DEREGISTER_SUCCESS` | `WEBSOCKET_DEREGISTER_FAIL` |
|
|
306
|
+
| Device Type Update | `AGENT_DEVICE_TYPE_UPDATE_SUCCESS` | `AGENT_DEVICE_TYPE_UPDATE_FAILED` |
|
|
307
|
+
| EntryPoint | `ENTRYPOINT_FETCH_SUCCESS` | `ENTRYPOINT_FETCH_FAILED` |
|
|
308
|
+
| AddressBook | `ADDRESSBOOK_FETCH_SUCCESS` | `ADDRESSBOOK_FETCH_FAILED` |
|
|
309
|
+
| Queue | `QUEUE_FETCH_SUCCESS` | `QUEUE_FETCH_FAILED` |
|
|
310
|
+
| Outdial ANI Entries | `OUTDIAL_ANI_EP_FETCH_SUCCESS` | `OUTDIAL_ANI_EP_FETCH_FAILED` |
|
|
311
|
+
|
|
312
|
+
### Webex Together behavioral taxonomy
|
|
313
|
+
|
|
314
|
+
Webex Together events (`WXAPP_*` constants) use `*_webex_together` compound targets. Assembled Amplitude names follow `wxcc_sdk.user.{target}.{verb}`:
|
|
315
|
+
|
|
316
|
+
| Feature | Behavioral target | Success name | Failure name | Skip name |
|
|
317
|
+
|---|---|---|---|---|
|
|
318
|
+
| Task accept / answer | `task_accept_webex_together` | `wxcc_sdk.user.task_accept_webex_together.complete` | `wxcc_sdk.user.task_accept_webex_together.fail` | — |
|
|
319
|
+
| Task reject / decline | `task_reject_webex_together` | `wxcc_sdk.user.task_reject_webex_together.complete` | `wxcc_sdk.user.task_reject_webex_together.fail` | — |
|
|
320
|
+
| Task mute / unmute toggle | `task_mute_webex_together` | `wxcc_sdk.user.task_mute_webex_together.complete` | `wxcc_sdk.user.task_mute_webex_together.fail` | — |
|
|
321
|
+
| Task DTMF / keypad | `task_dtmf_webex_together` | `wxcc_sdk.user.task_dtmf_webex_together.complete` | `wxcc_sdk.user.task_dtmf_webex_together.fail` | — |
|
|
322
|
+
| Usersub publish | `webex_together_usersub_publish` | `wxcc_sdk.user.webex_together_usersub_publish.complete` | `wxcc_sdk.user.webex_together_usersub_publish.fail` | — |
|
|
323
|
+
| Mercury subscribe | `webex_together_mercury_subscribe` | `wxcc_sdk.user.webex_together_mercury_subscribe.complete` | `wxcc_sdk.user.webex_together_mercury_subscribe.fail` | — |
|
|
324
|
+
| Session init | `webex_together_session_init` | `wxcc_sdk.user.webex_together_session_init.complete` | `wxcc_sdk.user.webex_together_session_init.fail` | `wxcc_sdk.user.webex_together_session_init.ignore` |
|
|
325
|
+
|
|
326
|
+
Operational and business wire names are unchanged (`WXCC_SDK_WXAPP_*`).
|
|
327
|
+
|
|
328
|
+
Special events (no success/failure pair):
|
|
329
|
+
|
|
330
|
+
- `AGENT_RONA` — has behavioral taxonomy (`service.agent_rona.set`)
|
|
331
|
+
|
|
332
|
+
- `AGENT_CONTACT_ASSIGN_FAILED` — has behavioral taxonomy (`service.agent_contact_assign.fail`)
|
|
333
|
+
|
|
334
|
+
- `AGENT_INVITE_FAILED` — has behavioral taxonomy (`service.agent_invite.fail`)
|
|
335
|
+
|
|
336
|
+
- `WEBSOCKET_EVENT_RECEIVED` — **no** behavioral taxonomy (not in `eventTaxonomyMap`)
|
|
337
|
+
|
|
338
|
+
- `WXAPP_SESSION_SKIPPED` — has behavioral taxonomy (`wxcc_sdk.user.webex_together_session_init.ignore`)
|
|
339
|
+
|
|
340
|
+
Of the 116 defined metric names, 96 have behavioral taxonomy and 20 do not. The Agent Wellness Break names are intentionally operational-only and therefore have no `eventTaxonomyMap` entries.
|
|
341
|
+
|
|
342
|
+
### Complete METRIC_EVENT_NAMES catalog
|
|
343
|
+
|
|
344
|
+
This table contains all 116 names from `src/metrics/constants.ts`; taxonomy presence is checked against `src/metrics/behavioral-events.ts`: 96 mapped and 20 unmapped.
|
|
345
|
+
|
|
346
|
+
| Constant | Emitted name | Behavioral taxonomy? |
|
|
347
|
+
|---|---|---|
|
|
348
|
+
| `STATION_LOGIN_SUCCESS` | `Station Login Success` | yes |
|
|
349
|
+
| `STATION_LOGIN_FAILED` | `Station Login Failed` | yes |
|
|
350
|
+
| `STATION_LOGOUT_SUCCESS` | `Station Logout Success` | yes |
|
|
351
|
+
| `STATION_LOGOUT_FAILED` | `Station Logout Failed` | yes |
|
|
352
|
+
| `STATION_RELOGIN_SUCCESS` | `Station Relogin Success` | yes |
|
|
353
|
+
| `STATION_RELOGIN_FAILED` | `Station Relogin Failed` | yes |
|
|
354
|
+
| `AGENT_STATE_CHANGE_SUCCESS` | `Agent State Change Success` | yes |
|
|
355
|
+
| `AGENT_STATE_CHANGE_FAILED` | `Agent State Change Failed` | yes |
|
|
356
|
+
| `FETCH_BUDDY_AGENTS_SUCCESS` | `Fetch Buddy Agents Success` | yes |
|
|
357
|
+
| `FETCH_BUDDY_AGENTS_FAILED` | `Fetch Buddy Agents Failed` | yes |
|
|
358
|
+
| `WEBSOCKET_REGISTER_SUCCESS` | `Websocket Register Success` | yes |
|
|
359
|
+
| `WEBSOCKET_REGISTER_FAILED` | `Websocket Register Failed` | yes |
|
|
360
|
+
| `AGENT_RONA` | `Agent RONA` | yes |
|
|
361
|
+
| `AGENT_CONTACT_ASSIGN_FAILED` | `Agent Contact Assign Failed` | yes |
|
|
362
|
+
| `AGENT_INVITE_FAILED` | `Agent Invite Failed` | yes |
|
|
363
|
+
| `TASK_ACCEPT_SUCCESS` | `Task Accept Success` | yes |
|
|
364
|
+
| `TASK_ACCEPT_FAILED` | `Task Accept Failed` | yes |
|
|
365
|
+
| `TASK_DECLINE_SUCCESS` | `Task Decline Success` | yes |
|
|
366
|
+
| `TASK_DECLINE_FAILED` | `Task Decline Failed` | yes |
|
|
367
|
+
| `TASK_END_SUCCESS` | `Task End Success` | yes |
|
|
368
|
+
| `TASK_END_FAILED` | `Task End Failed` | yes |
|
|
369
|
+
| `TASK_WRAPUP_SUCCESS` | `Task Wrapup Success` | yes |
|
|
370
|
+
| `TASK_WRAPUP_FAILED` | `Task Wrapup Failed` | yes |
|
|
371
|
+
| `TASK_HOLD_SUCCESS` | `Task Hold Success` | yes |
|
|
372
|
+
| `TASK_HOLD_FAILED` | `Task Hold Failed` | yes |
|
|
373
|
+
| `TASK_RESUME_SUCCESS` | `Task Resume Success` | yes |
|
|
374
|
+
| `TASK_RESUME_FAILED` | `Task Resume Failed` | yes |
|
|
375
|
+
| `TASK_CONSULT_START_SUCCESS` | `Task Consult Start Success` | yes |
|
|
376
|
+
| `TASK_CONSULT_START_FAILED` | `Task Consult Start Failed` | yes |
|
|
377
|
+
| `TASK_CONSULT_END_SUCCESS` | `Task Consult End Success` | yes |
|
|
378
|
+
| `TASK_CONSULT_END_FAILED` | `Task Consult End Failed` | yes |
|
|
379
|
+
| `TASK_TRANSFER_SUCCESS` | `Task Transfer Success` | yes |
|
|
380
|
+
| `TASK_TRANSFER_FAILED` | `Task Transfer Failed` | yes |
|
|
381
|
+
| `TASK_RESUME_RECORDING_SUCCESS` | `Task Resume Recording Success` | yes |
|
|
382
|
+
| `TASK_RESUME_RECORDING_FAILED` | `Task Resume Recording Failed` | yes |
|
|
383
|
+
| `TASK_PAUSE_RECORDING_SUCCESS` | `Task Pause Recording Success` | yes |
|
|
384
|
+
| `TASK_PAUSE_RECORDING_FAILED` | `Task Pause Recording Failed` | yes |
|
|
385
|
+
| `TASK_ACCEPT_CONSULT_SUCCESS` | `Task Accept Consult Success` | yes |
|
|
386
|
+
| `TASK_ACCEPT_CONSULT_FAILED` | `Task Accept Consult Failed` | yes |
|
|
387
|
+
| `TASK_AUTO_ANSWER_SUCCESS` | `Task Auto Answer Success` | yes |
|
|
388
|
+
| `TASK_AUTO_ANSWER_FAILED` | `Task Auto Answer Failed` | yes |
|
|
389
|
+
| `TASK_CONFERENCE_START_SUCCESS` | `Task Conference Start Success` | yes |
|
|
390
|
+
| `TASK_CONFERENCE_START_FAILED` | `Task Conference Start Failed` | yes |
|
|
391
|
+
| `TASK_CONFERENCE_END_SUCCESS` | `Task Conference End Success` | yes |
|
|
392
|
+
| `TASK_CONFERENCE_END_FAILED` | `Task Conference End Failed` | yes |
|
|
393
|
+
| `TASK_CONFERENCE_TRANSFER_SUCCESS` | `Task Conference Transfer Success` | yes |
|
|
394
|
+
| `TASK_CONFERENCE_TRANSFER_FAILED` | `Task Conference Transfer Failed` | yes |
|
|
395
|
+
| `TASK_CONFERENCE_EXIT_SUCCESS` | `Task Conference Exit Success` | yes |
|
|
396
|
+
| `TASK_CONFERENCE_EXIT_FAILED` | `Task Conference Exit Failed` | yes |
|
|
397
|
+
| `TASK_CONFERENCE_PARTICIPANT_DROP_SUCCESS` | `Task Conference Participant Drop Success` | yes |
|
|
398
|
+
| `TASK_CONFERENCE_PARTICIPANT_DROP_FAILED` | `Task Conference Participant Drop Failed` | yes |
|
|
399
|
+
| `TASK_SWITCH_CALL_SUCCESS` | `Task Switch Call Success` | yes |
|
|
400
|
+
| `TASK_SWITCH_CALL_FAILED` | `Task Switch Call Failed` | yes |
|
|
401
|
+
| `TASK_OUTDIAL_SUCCESS` | `Task Outdial Success` | yes |
|
|
402
|
+
| `TASK_OUTDIAL_FAILED` | `Task Outdial Failed` | yes |
|
|
403
|
+
| `WXAPP_TASK_MUTE_SUCCESS` | `WxApp Task Mute Success` | yes |
|
|
404
|
+
| `WXAPP_TASK_MUTE_FAILED` | `WxApp Task Mute Failed` | yes |
|
|
405
|
+
| `WXAPP_TASK_DTMF_SUCCESS` | `WxApp Task Dtmf Success` | yes |
|
|
406
|
+
| `WXAPP_TASK_DTMF_FAILED` | `WxApp Task Dtmf Failed` | yes |
|
|
407
|
+
| `WXAPP_TASK_ACCEPT_SUCCESS` | `WxApp Task Accept Success` | yes |
|
|
408
|
+
| `WXAPP_TASK_ACCEPT_FAILED` | `WxApp Task Accept Failed` | yes |
|
|
409
|
+
| `WXAPP_TASK_DECLINE_SUCCESS` | `WxApp Task Decline Success` | yes |
|
|
410
|
+
| `WXAPP_TASK_DECLINE_FAILED` | `WxApp Task Decline Failed` | yes |
|
|
411
|
+
| `WXAPP_SESSION_INIT_SUCCESS` | `WxApp Session Init Success` | yes |
|
|
412
|
+
| `WXAPP_SESSION_INIT_FAILED` | `WxApp Session Init Failed` | yes |
|
|
413
|
+
| `WXAPP_SESSION_SKIPPED` | `WxApp Session Skipped` | yes |
|
|
414
|
+
| `WXAPP_USERSUB_PUBLISH_SUCCESS` | `WxApp Usersub Publish Success` | yes |
|
|
415
|
+
| `WXAPP_USERSUB_PUBLISH_FAILED` | `WxApp Usersub Publish Failed` | yes |
|
|
416
|
+
| `WXAPP_MERCURY_SUBSCRIBE_SUCCESS` | `WxApp Mercury Subscribe Success` | yes |
|
|
417
|
+
| `WXAPP_MERCURY_SUBSCRIBE_FAILED` | `WxApp Mercury Subscribe Failed` | yes |
|
|
418
|
+
| `UPLOAD_LOGS_SUCCESS` | `Upload Logs Success` | yes |
|
|
419
|
+
| `UPLOAD_LOGS_FAILED` | `Upload Logs Failed` | yes |
|
|
420
|
+
| `WEBSOCKET_DEREGISTER_SUCCESS` | `Websocket Deregister Success` | no |
|
|
421
|
+
| `WEBSOCKET_DEREGISTER_FAIL` | `Websocket Deregister Failed` | no |
|
|
422
|
+
| `AGENT_DEVICE_TYPE_UPDATE_SUCCESS` | `Agent Device Type Update Success` | yes |
|
|
423
|
+
| `AGENT_DEVICE_TYPE_UPDATE_FAILED` | `Agent Device Type Update Failed` | yes |
|
|
424
|
+
| `WEBSOCKET_EVENT_RECEIVED` | `Websocket Event Received` | no |
|
|
425
|
+
| `ENTRYPOINT_FETCH_SUCCESS` | `Entrypoint Fetch Success` | yes |
|
|
426
|
+
| `ENTRYPOINT_FETCH_FAILED` | `Entrypoint Fetch Failed` | yes |
|
|
427
|
+
| `ADDRESSBOOK_FETCH_SUCCESS` | `AddressBook Fetch Success` | yes |
|
|
428
|
+
| `ADDRESSBOOK_FETCH_FAILED` | `AddressBook Fetch Failed` | yes |
|
|
429
|
+
| `QUEUE_FETCH_SUCCESS` | `Queue Fetch Success` | yes |
|
|
430
|
+
| `QUEUE_FETCH_FAILED` | `Queue Fetch Failed` | yes |
|
|
431
|
+
| `OUTDIAL_ANI_EP_FETCH_SUCCESS` | `Outdial ANI Entries Fetch Success` | yes |
|
|
432
|
+
| `OUTDIAL_ANI_EP_FETCH_FAILED` | `Outdial ANI Entries Fetch Failed` | yes |
|
|
433
|
+
| `CAMPAIGN_PREVIEW_ACCEPT_SUCCESS` | `Campaign Preview Accept Success` | yes |
|
|
434
|
+
| `CAMPAIGN_PREVIEW_ACCEPT_FAILED` | `Campaign Preview Accept Failed` | yes |
|
|
435
|
+
| `CAMPAIGN_PREVIEW_SKIP_SUCCESS` | `Campaign Preview Skip Success` | yes |
|
|
436
|
+
| `CAMPAIGN_PREVIEW_SKIP_FAILED` | `Campaign Preview Skip Failed` | yes |
|
|
437
|
+
| `CAMPAIGN_PREVIEW_REMOVE_SUCCESS` | `Campaign Preview Remove Success` | yes |
|
|
438
|
+
| `CAMPAIGN_PREVIEW_REMOVE_FAILED` | `Campaign Preview Remove Failed` | yes |
|
|
439
|
+
| `AI_ASSISTANT_SEND_EVENT_SUCCESS` | `AI Assistant Send Event Success` | no |
|
|
440
|
+
| `AI_ASSISTANT_SEND_EVENT_FAILED` | `AI Assistant Send Event Failed` | no |
|
|
441
|
+
| `AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_SUCCESS` | `AI Assistant Get Real Time Assistance Success` | no |
|
|
442
|
+
| `AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_FAILED` | `AI Assistant Get Real Time Assistance Failed` | no |
|
|
443
|
+
| `AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_SUCCESS` | `AI Assistant Send Real Time Assistance User Action Success` | no |
|
|
444
|
+
| `AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_FAILED` | `AI Assistant Send Real Time Assistance User Action Failed` | no |
|
|
445
|
+
| `AI_ASSISTANT_FETCH_HISTORIC_TRANSCRIPTS_SUCCESS` | `AI Assistant Fetch Historic Transcripts Success` | no |
|
|
446
|
+
| `AI_ASSISTANT_FETCH_HISTORIC_TRANSCRIPTS_FAILED` | `AI Assistant Fetch Historic Transcripts Failed` | no |
|
|
447
|
+
| `AI_ASSISTANT_WELLNESS_ACTION_ACCEPTED` | `AI Assistant Wellness Action Accepted` | no |
|
|
448
|
+
| `AI_ASSISTANT_WELLNESS_ACTION_FAILED` | `AI Assistant Wellness Action Failed` | no |
|
|
449
|
+
| `AI_ASSISTANT_WELLNESS_EVENT_INVALID` | `AI Assistant Wellness Event Invalid` | no |
|
|
450
|
+
| `WELLBEING_BREAK_IDLE_CODE_FETCH_SUCCESS` | `Wellbeing Break Idle Code Fetch Success` | no |
|
|
451
|
+
| `WELLBEING_BREAK_IDLE_CODE_FETCH_FAILED` | `Wellbeing Break Idle Code Fetch Failed` | no |
|
|
452
|
+
| `USER_PREFERENCE_GET_SUCCESS` | `User Preference Get Success` | yes |
|
|
453
|
+
| `USER_PREFERENCE_GET_FAILED` | `User Preference Get Failed` | yes |
|
|
454
|
+
| `USER_PREFERENCE_CREATE_SUCCESS` | `User Preference Create Success` | yes |
|
|
455
|
+
| `USER_PREFERENCE_CREATE_FAILED` | `User Preference Create Failed` | yes |
|
|
456
|
+
| `USER_PREFERENCE_UPDATE_SUCCESS` | `User Preference Update Success` | yes |
|
|
457
|
+
| `USER_PREFERENCE_UPDATE_FAILED` | `User Preference Update Failed` | yes |
|
|
458
|
+
| `USER_PREFERENCE_DELETE_SUCCESS` | `User Preference Delete Success` | yes |
|
|
459
|
+
| `USER_PREFERENCE_DELETE_FAILED` | `User Preference Delete Failed` | yes |
|
|
460
|
+
|
|
461
|
+
Defined names without an `eventTaxonomyMap` entry: `WEBSOCKET_DEREGISTER_SUCCESS`, `WEBSOCKET_DEREGISTER_FAIL`, `WEBSOCKET_EVENT_RECEIVED`, all eight AI Assistant request names, and the seven Agent Wellness Break notification/action/system-code/ASC names listed above.
|
|
462
|
+
|
|
463
|
+
## Requires (dependencies)
|
|
464
|
+
- `webex.internal.newMetrics` submission APIs
|
|
465
|
+
- Webex ready lifecycle
|
|
466
|
+
- LoggerProxy and browser visibility metadata
|
|
467
|
+
|
|
468
|
+
- **`@webex/internal-plugin-metrics`**: Provides `webex.internal.newMetrics` for actual metric submission (`submitBehavioralEvent`, `submitOperationalEvent`, `submitBusinessEvent`)
|
|
469
|
+
|
|
470
|
+
- **`LoggerProxy`**: Used for error logging within the metrics module
|
|
471
|
+
|
|
472
|
+
- **`Failure` type** (from `services/core/GlobalTypes`): Used in `getCommonTrackingFieldForAQMResponseFailed`
|
|
473
|
+
|
|
474
|
+
- **`PRODUCT_NAME`** (from `constants.ts`): Set to `'wxcc_sdk'`, used as the product identifier in behavioral taxonomy and as prefix for operational/business event names
|
|
475
|
+
|
|
476
|
+
## Requirements
|
|
477
|
+
| ID | WHAT | WHY | Source Evidence | Test / Example Evidence | Assumptions / Gaps | Confidence |
|
|
478
|
+
|---|---|---|---|---|---|---|
|
|
479
|
+
| METRICS-R-001 | Track only names defined by METRIC_EVENT_NAMES and keep the canonical catalog synchronized with the const object. | Telemetry queries and dashboards depend on exact stable event names. | `src/metrics/constants.ts` | `test/unit/spec/metrics/MetricsManager.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
|
|
480
|
+
| METRICS-R-002 | Map behavioral events through eventTaxonomyMap and explicitly identify defined names without taxonomy. | Undefined taxonomy must not be mistaken for an emitted or classified behavioral event. | `src/metrics/behavioral-events.ts` | `test/unit/spec/metrics/behavioral-events.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
|
|
481
|
+
| METRICS-R-003 | When metrics are disabled, clear pending events and make `timeEvent` plus all tracking methods return without recording/submitting. | Telemetry must never block or alter product behavior and disablement must be comprehensive. | `src/metrics/MetricsManager.ts` | `test/unit/spec/metrics/MetricsManager.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
|
|
482
|
+
| METRICS-R-004 | Queue submissions until the host SDK is ready and flush through the correct behavioral/operational/business service. | Early lifecycle telemetry must not be lost solely because the host is not ready. | `src/metrics/MetricsManager.ts` | `test/unit/spec/metrics/MetricsManager.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
|
|
483
|
+
| METRICS-R-005 | Submit through the host SDK's `webex.internal.newMetrics` client without storing credentials or implementing authorization policy in MetricsManager. | Host-owned authentication keeps telemetry credential handling outside the Contact Center metrics module. | `src/metrics/MetricsManager.ts` | `test/unit/spec/metrics/MetricsManager.ts` | None; authentication is inherited and credential ownership is explicitly N/A. | PRESENT |
|
|
484
|
+
| METRICS-R-006 | Track wellness action, invalid notification, system-code lookup, and ASC state-change outcomes as operational metrics using fixed names and reason-only/context-minimized payloads. | The feature needs diagnosable lifecycle signals without logging wellness payloads or agent PII. | `src/metrics/constants.ts`, `src/cc.ts`, `src/services/ApiAiAssistant.ts` | `test/unit/spec/cc.ts`, `test/unit/spec/services/ApiAiAssistant.ts` | These names intentionally have no behavioral taxonomy. | PRESENT |
|
|
485
|
+
|
|
486
|
+
## Design Overview
|
|
487
|
+
Metrics separates its stable consumption boundary from collaborators so ownership and failure behavior stay explicit. Telemetry is deliberately non-blocking and queue-backed so product behavior never waits for metrics; failures are logged rather than propagated.
|
|
488
|
+
|
|
489
|
+
> **Purpose**: Track behavioral, operational, and business metrics for Contact Center SDK operations using a singleton `MetricsManager`. Provides event timing, payload preparation, batching, and submission to the Webex metrics backend.
|
|
490
|
+
|
|
491
|
+
Each behavioral event maps to a structured taxonomy in `behavioral-events.ts`:
|
|
492
|
+
|
|
493
|
+
```text
|
|
494
|
+
{product}.{agent}.{target}.{verb}
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
- **product**: Always `'wxcc_sdk'` (from `PRODUCT_NAME`)
|
|
498
|
+
|
|
499
|
+
- **agent**: `'user'` for user-initiated actions, `'service'` for system-generated events
|
|
500
|
+
|
|
501
|
+
- **target**: Snake_case description of the action (e.g., `'station_login'`, `'task_accept'`)
|
|
502
|
+
|
|
503
|
+
- **verb**: `'complete'` for success, `'fail'` for failure, `'set'` for RONA events
|
|
504
|
+
|
|
505
|
+
**Example**: `STATION_LOGIN_SUCCESS` maps to `wxcc_sdk.user.station_login.complete`
|
|
506
|
+
|
|
507
|
+
> **Note**: The 20 names catalogued above as lacking `eventTaxonomyMap` entries, including all nine new wellness-related names, are operational-only.
|
|
508
|
+
>
|
|
509
|
+
> Calling `trackBehavioralEvent` with these event names will push an event with an `undefined` taxonomy.
|
|
510
|
+
|
|
511
|
+
> **Purpose**: Technical documentation for the metrics collection, batching, and submission system within the Contact Center SDK.
|
|
512
|
+
|
|
513
|
+
Each metric event name maps to a `BehavioralEventTaxonomy` with four fields:
|
|
514
|
+
|
|
515
|
+
```typescript
|
|
516
|
+
type BehavioralEventTaxonomy = {
|
|
517
|
+
product: MetricEventProduct; // Always PRODUCT_NAME ('wxcc_sdk')
|
|
518
|
+
agent: MetricEventAgent; // 'user' or 'service'
|
|
519
|
+
target: string; // e.g., 'station_login', 'task_accept'
|
|
520
|
+
verb: MetricEventVerb; // 'complete' for success, 'fail' for failure
|
|
521
|
+
};
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
The final behavioral event name is constructed as: `{product}.{agent}.{target}.{verb}`
|
|
525
|
+
|
|
526
|
+
Example: `wxcc_sdk.user.station_login.complete`
|
|
527
|
+
|
|
528
|
+
The mapping is defined in `behavioral-events.ts` via `eventTaxonomyMap` and accessed through `getEventTaxonomy(name)`.
|
|
529
|
+
|
|
530
|
+
Participant Drop uses target `task_conference_participant_drop` with `complete` for success and `fail` for failure. Its metric payload is limited to task/request correlation and standard AQM tracking fields; participant IDs, numbers, names, URLs, headers, and raw routing payloads are excluded.
|
|
531
|
+
|
|
532
|
+
```mermaid
|
|
533
|
+
flowchart LR
|
|
534
|
+
A[timeEvent keys] --> B[runningEvents stores startTime + key Set]
|
|
535
|
+
B --> C[trackEvent called with one of the keys]
|
|
536
|
+
C --> D[addDurationIfTimed matches key]
|
|
537
|
+
D --> E[Calculates duration_ms = now - startTime]
|
|
538
|
+
E --> F[Removes all keys for that operation]
|
|
539
|
+
F --> G[Attaches duration_ms to payload]
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
Usage pattern from `cc.ts`:
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
// Before operation
|
|
546
|
+
this.metricsManager.timeEvent([
|
|
547
|
+
METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS,
|
|
548
|
+
METRIC_EVENT_NAMES.STATION_LOGIN_FAILED,
|
|
549
|
+
]);
|
|
550
|
+
|
|
551
|
+
// On success
|
|
552
|
+
this.metricsManager.trackEvent(
|
|
553
|
+
METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS,
|
|
554
|
+
{ ...MetricsManager.getCommonTrackingFieldForAQMResponse(resp) },
|
|
555
|
+
['behavioral', 'operational', 'business']
|
|
556
|
+
);
|
|
557
|
+
|
|
558
|
+
// On failure
|
|
559
|
+
this.metricsManager.trackEvent(
|
|
560
|
+
METRIC_EVENT_NAMES.STATION_LOGIN_FAILED,
|
|
561
|
+
{ ...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(failure) },
|
|
562
|
+
['behavioral', 'operational', 'business']
|
|
563
|
+
);
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
Two static helpers extract standardized fields from AQM responses for metric payloads:
|
|
567
|
+
|
|
568
|
+
Extracts: `agentId`, `agentSessionId`, `teamId`, `siteId`, `orgId`, `eventType`, `trackingId`, `notifTrackingId`
|
|
569
|
+
|
|
570
|
+
## Data Flow
|
|
571
|
+
```mermaid
|
|
572
|
+
flowchart TD
|
|
573
|
+
A[cc.ts calls metricsManager.timeEvent] --> B[Store startTime + keys in runningEvents]
|
|
574
|
+
B --> C[Operation executes]
|
|
575
|
+
C --> D{Success or Failure?}
|
|
576
|
+
D -->|Success| E[cc.ts calls metricsManager.trackEvent with success name]
|
|
577
|
+
D -->|Failure| F[cc.ts calls metricsManager.trackEvent with failure name]
|
|
578
|
+
E --> G[addDurationIfTimed attaches duration_ms]
|
|
579
|
+
F --> G
|
|
580
|
+
G --> H[preparePayload cleans and enriches]
|
|
581
|
+
H --> I{Metric type?}
|
|
582
|
+
I -->|behavioral| J[Push to pendingBehavioralEvents]
|
|
583
|
+
I -->|operational| K[Push to pendingOperationalEvents]
|
|
584
|
+
I -->|business| L[Push to pendingBusinessEvents]
|
|
585
|
+
J --> M[submitPendingBehavioralEvents]
|
|
586
|
+
K --> N[submitPendingOperationalEvents]
|
|
587
|
+
L --> O[submitPendingBusinessEvents]
|
|
588
|
+
M --> P[webex.internal.newMetrics.submitBehavioralEvent]
|
|
589
|
+
N --> Q[webex.internal.newMetrics.submitOperationalEvent]
|
|
590
|
+
O --> R[webex.internal.newMetrics.submitBusinessEvent]
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
## Sequence Diagram(s)
|
|
594
|
+
Sequence coverage:
|
|
595
|
+
|
|
596
|
+
| Operation group | Diagram | Failure / recovery coverage |
|
|
597
|
+
|---|---|---|
|
|
598
|
+
| Time and track an event | Timing and tracking | Success/failure keys share one timer; missing timing data leaves the payload untimed. |
|
|
599
|
+
| Queue until SDK readiness | SDK readiness | A not-ready SDK retains events; READY drains them through the configured metrics service. |
|
|
600
|
+
| Submit behavioral/operational/business events | Category submission | The module does not retry or requeue after handing an event to `newMetrics`. |
|
|
601
|
+
| Disable metrics | Disablement | Pending queues are cleared and future timing/tracking calls return immediately. |
|
|
602
|
+
|
|
603
|
+
### Timing and tracking
|
|
604
|
+
|
|
605
|
+
```mermaid
|
|
606
|
+
sequenceDiagram
|
|
607
|
+
participant CC as ContactCenter (cc.ts)
|
|
608
|
+
participant MM as MetricsManager
|
|
609
|
+
participant NM as webex.internal.newMetrics
|
|
610
|
+
|
|
611
|
+
CC->>MM: timeEvent([SUCCESS_KEY, FAILURE_KEY])
|
|
612
|
+
Note over MM: Store startTime + key set in runningEvents
|
|
613
|
+
CC->>CC: Execute operation (e.g., stationLogin)
|
|
614
|
+
Note over MM: trackEvent defaults to ['behavioral'] only if no metricServices specified
|
|
615
|
+
alt Success
|
|
616
|
+
CC->>MM: trackEvent(SUCCESS_KEY, payload, ['behavioral', 'operational', 'business'])
|
|
617
|
+
else Failure
|
|
618
|
+
CC->>MM: trackEvent(FAILURE_KEY, payload, ['behavioral', 'operational', 'business'])
|
|
619
|
+
end
|
|
620
|
+
MM->>MM: addDurationIfTimed → attach duration_ms
|
|
621
|
+
MM->>MM: preparePayload → clean empty fields, add tabHidden
|
|
622
|
+
loop For each metric type
|
|
623
|
+
MM->>MM: Push to pending queue
|
|
624
|
+
alt readyToSubmitEvents
|
|
625
|
+
MM->>NM: submit[Behavioral|Operational|Business]Event
|
|
626
|
+
else not ready
|
|
627
|
+
Note over MM: Events stay queued until SDK ready
|
|
628
|
+
end
|
|
629
|
+
end
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### SDK readiness
|
|
633
|
+
|
|
634
|
+
```mermaid
|
|
635
|
+
sequenceDiagram
|
|
636
|
+
participant CC as ContactCenter
|
|
637
|
+
participant MM as MetricsManager
|
|
638
|
+
participant Webex as WebexSDK
|
|
639
|
+
|
|
640
|
+
CC->>MM: getInstance({webex})
|
|
641
|
+
MM->>MM: Create singleton (if needed)
|
|
642
|
+
MM->>MM: setWebex(webex)
|
|
643
|
+
opt webex.ready === true
|
|
644
|
+
MM->>MM: setReadyToSubmitEvents()
|
|
645
|
+
MM->>MM: submitPendingEvents()
|
|
646
|
+
end
|
|
647
|
+
MM->>Webex: webex.once('ready', callback)
|
|
648
|
+
Note over MM: 'ready' listener is always registered
|
|
649
|
+
Webex-->>MM: 'ready' event fires
|
|
650
|
+
MM->>MM: setReadyToSubmitEvents()
|
|
651
|
+
MM->>MM: submitPendingEvents()
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
### Category submission
|
|
655
|
+
|
|
656
|
+
```mermaid
|
|
657
|
+
sequenceDiagram
|
|
658
|
+
participant Caller
|
|
659
|
+
participant MM as MetricsManager
|
|
660
|
+
participant NM as webex.internal.newMetrics
|
|
661
|
+
Caller->>MM: trackEvent(name, payload, metricServices)
|
|
662
|
+
loop each requested metric service
|
|
663
|
+
alt behavioral
|
|
664
|
+
MM->>NM: submitBehavioralEvent(taxonomy + payload)
|
|
665
|
+
else operational
|
|
666
|
+
MM->>NM: submitOperationalEvent(WXCC_SDK_* + payload)
|
|
667
|
+
else business
|
|
668
|
+
MM->>NM: submitBusinessEvent(WXCC_SDK_* + appType)
|
|
669
|
+
else invalid metric service
|
|
670
|
+
MM->>MM: LoggerProxy.error(invalid type)
|
|
671
|
+
end
|
|
672
|
+
end
|
|
673
|
+
Note over MM,NM: No module-level retry or requeue after submission handoff
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
### Disablement
|
|
677
|
+
|
|
678
|
+
```mermaid
|
|
679
|
+
sequenceDiagram
|
|
680
|
+
participant Caller
|
|
681
|
+
participant MM as MetricsManager
|
|
682
|
+
Caller->>MM: setMetricsDisabled(true)
|
|
683
|
+
MM->>MM: clear pending behavioral/operational/business queues
|
|
684
|
+
Caller->>MM: timeEvent(...) / trackEvent(...)
|
|
685
|
+
alt metricsDisabled
|
|
686
|
+
MM-->>Caller: return without timing, queueing, or submission
|
|
687
|
+
else re-enabled
|
|
688
|
+
MM->>MM: use normal timing/queue flow
|
|
689
|
+
end
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
## Class / Component Relationships
|
|
693
|
+
```mermaid
|
|
694
|
+
classDiagram
|
|
695
|
+
class ContactCenter
|
|
696
|
+
class MetricsManager
|
|
697
|
+
class METRIC_EVENT_NAMES
|
|
698
|
+
class eventTaxonomyMap
|
|
699
|
+
class NewMetrics
|
|
700
|
+
ContactCenter --> MetricsManager : timeEvent / trackEvent
|
|
701
|
+
MetricsManager --> METRIC_EVENT_NAMES : canonical names
|
|
702
|
+
MetricsManager --> eventTaxonomyMap : behavioral taxonomy lookup
|
|
703
|
+
MetricsManager --> NewMetrics : submit queued event types
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
| Component | File | Responsibility |
|
|
707
|
+
|---|---|---|
|
|
708
|
+
| `MetricsManager` | `MetricsManager.ts` | Singleton that manages event queuing, timing, payload preparation, and submission |
|
|
709
|
+
| `BehavioralEventTaxonomy`| `behavioral-events.ts` | Maps metric event names to structured taxonomy for behavioral analytics |
|
|
710
|
+
| `METRIC_EVENT_NAMES` | `constants.ts` | Canonical constant object of all tracked metric event names |
|
|
711
|
+
|
|
712
|
+
`MetricsManager` uses a private constructor with a static `getInstance` factory:
|
|
713
|
+
|
|
714
|
+
```typescript
|
|
715
|
+
// MetricsManager.ts
|
|
716
|
+
export default class MetricsManager {
|
|
717
|
+
private static instance: MetricsManager;
|
|
718
|
+
private constructor() {}
|
|
719
|
+
|
|
720
|
+
public static getInstance(options?: {webex: WebexSDK}): MetricsManager {
|
|
721
|
+
if (!MetricsManager.instance) {
|
|
722
|
+
MetricsManager.instance = new MetricsManager();
|
|
723
|
+
}
|
|
724
|
+
if (!MetricsManager.instance.webex && options?.webex) {
|
|
725
|
+
MetricsManager.instance.setWebex(options.webex);
|
|
726
|
+
}
|
|
727
|
+
return MetricsManager.instance;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
public static resetInstance() {
|
|
731
|
+
MetricsManager.instance = undefined;
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
- The Webex SDK instance is set once via `setWebex()`, which listens for the `ready` event before flushing pending queues.
|
|
737
|
+
|
|
738
|
+
- `resetInstance()` sets the singleton to `undefined`, allowing a fresh instance to be created. Primarily used in tests.
|
|
739
|
+
|
|
740
|
+
## Use Cases
|
|
741
|
+
- **UC-1 Time and track an event:** `timeEvent` records the start against success/failure keys and `trackEvent` attaches `duration_ms` before preparing and queuing the payload. Evidence: `src/metrics/MetricsManager.ts`, `test/unit/spec/metrics/MetricsManager.ts`.
|
|
742
|
+
- **UC-2 Queue until SDK readiness:** events remain in the behavioral/operational/business pending queues until the host is ready, then the ready callback drains them. Evidence: `src/metrics/MetricsManager.ts`, `test/unit/spec/metrics/MetricsManager.ts`.
|
|
743
|
+
- **UC-3 Submit event categories:** each requested metric service uses its matching `webex.internal.newMetrics` submission method; taxonomy is applied only where `eventTaxonomyMap` contains the name. Evidence: `src/metrics/MetricsManager.ts`, `src/metrics/behavioral-events.ts`, `test/unit/spec/metrics/MetricsManager.ts`.
|
|
744
|
+
|
|
745
|
+
```typescript
|
|
746
|
+
import MetricsManager from '../metrics/MetricsManager';
|
|
747
|
+
import {METRIC_EVENT_NAMES} from '../metrics/constants';
|
|
748
|
+
|
|
749
|
+
// Get the singleton instance (webex is set during the ContactCenter READY callback)
|
|
750
|
+
const metrics = MetricsManager.getInstance();
|
|
751
|
+
|
|
752
|
+
// Time an operation, then track its result
|
|
753
|
+
metrics.timeEvent(METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS);
|
|
754
|
+
// ... perform the operation ...
|
|
755
|
+
metrics.trackEvent(METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS, {agentId: '123'});
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
The standard pattern used throughout the Contact Center SDK:
|
|
759
|
+
|
|
760
|
+
```typescript
|
|
761
|
+
const metrics = MetricsManager.getInstance();
|
|
762
|
+
|
|
763
|
+
// 1. Start timing before the operation
|
|
764
|
+
metrics.timeEvent([
|
|
765
|
+
METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS,
|
|
766
|
+
METRIC_EVENT_NAMES.STATION_LOGIN_FAILED,
|
|
767
|
+
]);
|
|
768
|
+
|
|
769
|
+
try {
|
|
770
|
+
const response = await performLogin(params);
|
|
771
|
+
|
|
772
|
+
// 2a. Track success (duration_ms auto-added)
|
|
773
|
+
metrics.trackEvent(METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS, {
|
|
774
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponse(response),
|
|
775
|
+
});
|
|
776
|
+
} catch (error) {
|
|
777
|
+
// 2b. Track failure (duration_ms auto-added)
|
|
778
|
+
metrics.trackEvent(METRIC_EVENT_NAMES.STATION_LOGIN_FAILED, {
|
|
779
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error),
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
## State Model
|
|
785
|
+
MetricsManager holds three pending queues, running timing entries, a readiness flag, a submission lock, and an independent disabled flag. Host READY enables draining; disabling metrics prevents both timing and tracking and clears pending events through the configured disable path.
|
|
786
|
+
|
|
787
|
+
`preparePayload()` processes every event payload before submission:
|
|
788
|
+
|
|
789
|
+
1. **Removes empty/null/undefined fields** — strips keys with `undefined`, `null`, `''`, any arrays, or empty objects
|
|
790
|
+
|
|
791
|
+
2. **Converts spaces to underscores** — `spacesToUnderscore()` applied to all key names
|
|
792
|
+
|
|
793
|
+
3. **Adds common metadata** — appends `tabHidden: document.hidden` in browser environments
|
|
794
|
+
|
|
795
|
+
## Business Rules & Invariants
|
|
796
|
+
- `timeEvent` and every tracking method return immediately while metrics are disabled.
|
|
797
|
+
- Only names present in `eventTaxonomyMap` receive behavioral taxonomy; 81 of 101 names are mapped and all 20 exceptions are explicitly catalogued as unmapped.
|
|
798
|
+
- `submittingEvents` prevents overlapping queue-drain executions.
|
|
799
|
+
- Authentication is inherited from the host Webex SDK's metrics client; MetricsManager owns no credentials, tokens, or authorization policy.
|
|
800
|
+
|
|
801
|
+
## Concurrency & Reactive Flow
|
|
802
|
+
- Queue insertion is synchronous. Submission is gated by host readiness and the submission lock; each metric type drains through its own host method without propagating telemetry failures to product callers.
|
|
803
|
+
|
|
804
|
+
MetricsManager maintains three independent pending event queues:
|
|
805
|
+
|
|
806
|
+
| Queue | Type | Submitted Via | Name Transform | Extra Metadata |
|
|
807
|
+
|---|---|---|---|---|
|
|
808
|
+
| `pendingBehavioralEvents` | behavioral | `webex.internal.newMetrics.submitBehavioralEvent` | Taxonomy-based (`{product}.{agent}.{target}.{verb}`) | None |
|
|
809
|
+
| `pendingOperationalEvents` | operational | `webex.internal.newMetrics.submitOperationalEvent` | `WXCC_SDK_` prefix + uppercase (e.g. `WXCC_SDK_STATION_LOGIN_SUCCESS`) | None |
|
|
810
|
+
| `pendingBusinessEvents` | business | `webex.internal.newMetrics.submitBusinessEvent` | `WXCC_SDK_` prefix + uppercase (same as operational) | `metadata: {appType: 'wxcc_sdk'}` |
|
|
811
|
+
|
|
812
|
+
## State Machine
|
|
813
|
+
```mermaid
|
|
814
|
+
stateDiagram-v2
|
|
815
|
+
[*] --> Buffering
|
|
816
|
+
Buffering --> ReadyToSubmit: host already ready / ready event
|
|
817
|
+
ReadyToSubmit --> Submitting: pending events and lock acquired
|
|
818
|
+
Submitting --> ReadyToSubmit: queues drained and lock released
|
|
819
|
+
Buffering --> Disabled: setMetricsDisabled(true)
|
|
820
|
+
ReadyToSubmit --> Disabled: setMetricsDisabled(true)
|
|
821
|
+
Disabled --> Buffering: enabled before host ready
|
|
822
|
+
Disabled --> ReadyToSubmit: enabled after host ready
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
- **readyToSubmitEvents**: Set to `true` only after `webex.once('ready')` fires. Events queue until then.
|
|
826
|
+
|
|
827
|
+
- **submittingEvents**: Lock flag to prevent concurrent `submitPendingEvents()` calls.
|
|
828
|
+
|
|
829
|
+
- **metricsDisabled**: When `true`, `timeEvent` and all `track*` methods return early, and `clearPendingEvents()` empties all queues.
|
|
830
|
+
|
|
831
|
+
## Pitfalls
|
|
832
|
+
- `METRIC_EVENT_NAMES` and `eventTaxonomyMap` are different inventories: 20 defined names intentionally have no behavioral taxonomy.
|
|
833
|
+
- `setMetricsDisabled(true)` clears pending queues but does not create a delivery receipt; callers must not infer that previously submitted events were accepted.
|
|
834
|
+
- Submission helpers hand events to `webex.internal.newMetrics` without a module-level retry/requeue policy, so telemetry must remain non-blocking and non-authoritative.
|
|
835
|
+
|
|
836
|
+
Static helper that extracts common tracking fields from an AQM failure response.
|
|
837
|
+
|
|
838
|
+
**Parameters**:
|
|
839
|
+
|
|
840
|
+
- `failureResponse` (Failure): The AQM failure response object
|
|
841
|
+
|
|
842
|
+
**Returns**: `Record<string, any>` with fields: `agentId`, `trackingId`, `notifTrackingId`, `orgId`, `failureType`, `failureReason`, `reasonCode`
|
|
843
|
+
|
|
844
|
+
MetricsManager is designed to be non-blocking. Metric failures do not propagate to callers:
|
|
845
|
+
|
|
846
|
+
- If `webex` is not yet ready, events are queued in `pendingBehavioralEvents`, `pendingOperationalEvents`, or `pendingBusinessEvents`
|
|
847
|
+
|
|
848
|
+
- Once `webex.ready` fires, all pending events are flushed
|
|
849
|
+
|
|
850
|
+
- If metrics are disabled via `setMetricsDisabled(true)`, all track methods silently return
|
|
851
|
+
|
|
852
|
+
- Invalid metric types log an error via `LoggerProxy` but do not throw
|
|
853
|
+
|
|
854
|
+
MetricsManager does not throw errors to callers. Instead:
|
|
855
|
+
|
|
856
|
+
- Invalid metric types are logged via `LoggerProxy.error`
|
|
857
|
+
|
|
858
|
+
- Empty `timeEvent` key arrays are logged and ignored
|
|
859
|
+
|
|
860
|
+
- Disabled state (`metricsDisabled`) prevents both timing and tracking and silently drops new events
|
|
861
|
+
|
|
862
|
+
- The `submittingEvents` lock prevents race conditions during concurrent submissions
|
|
863
|
+
|
|
864
|
+
Extracts: `agentId`, `trackingId`, `notifTrackingId`, `orgId`, `failureType`, `failureReason`, `reasonCode`
|
|
865
|
+
|
|
866
|
+
**Cause**: Webex SDK not yet ready when `trackEvent` is called
|
|
867
|
+
|
|
868
|
+
**Solution**: Events are automatically queued in `pending*Events` arrays and flushed once `webex.once('ready')` fires. Verify the SDK is initializing correctly.
|
|
869
|
+
|
|
870
|
+
**Cause**: `timeEvent` was not called before `trackEvent`, or the event name does not match any key in `runningEvents`
|
|
871
|
+
|
|
872
|
+
**Solution**: Ensure `timeEvent([SUCCESS_KEY, FAILURE_KEY])` is called before the operation, and that the exact `METRIC_EVENT_NAMES` constant is used in both calls.
|
|
873
|
+
|
|
874
|
+
**Cause**: `metricsDisabled` is set to `true`
|
|
875
|
+
|
|
876
|
+
**Solution**: Check if `setMetricsDisabled(true)` was called. This clears all pending queues and causes all `track*` methods to return early.
|
|
877
|
+
|
|
878
|
+
## Module Do's / Don'ts
|
|
879
|
+
- DO use `METRIC_EVENT_NAMES` and the matching category submitter instead of constructing event names manually.
|
|
880
|
+
- DO keep timing success/failure keys together so either outcome clears the same running timer.
|
|
881
|
+
- DON'T add a behavioral taxonomy entry unless the backend taxonomy contract exists.
|
|
882
|
+
- DON'T make product behavior depend on metrics delivery.
|
|
883
|
+
|
|
884
|
+
## Key Design Trade-off
|
|
885
|
+
- Telemetry is deliberately non-blocking and queue-backed so product behavior never waits for metrics; failures are logged rather than propagated.
|
|
886
|
+
|
|
887
|
+
## Test-Case Strategy (module)
|
|
888
|
+
Use `test/unit/spec/metrics/MetricsManager.ts` for readiness queues, timing/tracking, disabled behavior, submission categories, and failures. Use `test/unit/spec/metrics/behavioral-events.ts` to reconcile every taxonomy-backed name. Mechanically compare the complete constant catalog with taxonomy keys so newly defined events cannot disappear from the spec.
|
|
889
|
+
|
|
890
|
+
| Behavior / Requirement | Existing test evidence | Gap |
|
|
891
|
+
|---|---|---|
|
|
892
|
+
| `METRICS-R-001` | `test/unit/spec/metrics/MetricsManager.ts` | Add a catalog parity assertion if constants change. |
|
|
893
|
+
| `METRICS-R-002` | `test/unit/spec/metrics/behavioral-events.ts` | Keep explicit coverage for all 20 unmapped names. |
|
|
894
|
+
| `METRICS-R-003` | `test/unit/spec/metrics/MetricsManager.ts` | None. |
|
|
895
|
+
| `METRICS-R-004` | `test/unit/spec/metrics/MetricsManager.ts` | None. |
|
|
896
|
+
| `METRICS-R-005` | `test/unit/spec/metrics/MetricsManager.ts` | Authentication ownership is verified indirectly through the host metrics client. |
|
|
897
|
+
| `METRICS-R-006` | `test/unit/spec/cc.ts`, `test/unit/spec/services/ApiAiAssistant.ts` | Add direct catalog-parity coverage if metrics constants receive a dedicated test. |
|
|
898
|
+
|
|
899
|
+
## Traceability
|
|
900
|
+
- Repo architecture: `../../../ai-docs/ARCHITECTURE.md` · Registry: `../../../ai-docs/SPEC_INDEX.md`
|
|
901
|
+
- Coverage state and contracts baseline: `../../../.sdd/manifest.json`
|
|
902
|
+
|
|
903
|
+
- [`MetricsManager.ts`](../MetricsManager.ts) - Singleton metrics manager implementation
|
|
904
|
+
|
|
905
|
+
- [`behavioral-events.ts`](../behavioral-events.ts) - Event taxonomy mapping
|
|
906
|
+
|
|
907
|
+
- [`constants.ts`](../constants.ts) - `METRIC_EVENT_NAMES` definitions
|
|
908
|
+
|
|
909
|
+
- [`../../constants.ts`](../../constants.ts) - `PRODUCT_NAME` constant
|
|
910
|
+
|
|
911
|
+
- [`services/core/GlobalTypes.ts`](../../services/core/GlobalTypes.ts) - `Failure` type definition
|
|
912
|
+
|
|
913
|
+
- [MetricsManager.ts](../MetricsManager.ts) — Singleton metrics manager
|
|
914
|
+
|
|
915
|
+
- [behavioral-events.ts](../behavioral-events.ts) — Event taxonomy mapping
|
|
916
|
+
|
|
917
|
+
- [constants.ts](../constants.ts) — METRIC_EVENT_NAMES definitions
|
|
918
|
+
|
|
919
|
+
- [cc.ts](../../cc.ts) — Main plugin class (primary consumer)
|
|
920
|
+
|
|
921
|
+
- [constants.ts](../../constants.ts) — PRODUCT_NAME used in event prefixing
|