Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .sdd/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"package": "@webex/cc-store",
"path": "packages/contact-center/store",
"spec": "packages/contact-center/store/ai-docs/store-spec.md",
"responsibility": "MobX singleton holding global CC state; proxies SDK events; sole SDK access point.",
"responsibility": "MobX singleton holding global CC state; proxies SDK events; sole SDK access point; owns pure conference Drop roster derivation.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes may not be needed. This feature is just an addition among serveral other features and explicitly adding it in manifest is not required

"coverageState": "DRAFT",
"tier": 1
},
Expand All @@ -41,7 +41,7 @@
"package": "@webex/cc-components",
"path": "packages/contact-center/cc-components",
"spec": "packages/contact-center/cc-components/ai-docs/cc-components-spec.md",
"responsibility": "Shared presentational React UI primitives consumed by widget packages.",
"responsibility": "Shared presentational React UI primitives, including the CallControlCAD participant Drop experience.",
"coverageState": "DRAFT",
"tier": 1
},
Expand All @@ -50,7 +50,7 @@
"package": "@webex/cc-widgets",
"path": "packages/contact-center/cc-widgets",
"spec": "packages/contact-center/cc-widgets/ai-docs/cc-widgets-spec.md",
"responsibility": "r2wc Web Component wrappers aggregating widget packages for framework-agnostic consumption.",
"responsibility": "r2wc Web Component wrappers aggregating widget packages; existing CallControlCAD wrapper inherits participant Drop without new properties.",
"coverageState": "DRAFT",
"tier": 1
},
Expand Down Expand Up @@ -86,7 +86,7 @@
"package": "@webex/cc-task",
"path": "packages/contact-center/task",
"spec": "packages/contact-center/task/ai-docs/task-spec.md",
"responsibility": "Task widget bundle: CallControl, CallControlCAD, IncomingTask, OutdialCall, TaskList.",
"responsibility": "Task widget bundle: CallControl, CallControlCAD with participant Drop orchestration, IncomingTask, OutdialCall, TaskList.",
"coverageState": "DRAFT",
"tier": 1,
"subWidgets": ["CallControl", "CallControlCAD", "IncomingTask", "OutdialCall", "TaskList"]
Expand Down
6 changes: 3 additions & 3 deletions ai-docs/CONTRACTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,22 @@ The aggregator package `@webex/cc-widgets` re-exports every widget plus the `sto
| cc-widgets.UserState | `@webex/cc-user-state` | `UserState` | React component; custom element `widget-cc-user-state`; prop `onStateChange` (function) | stable semver | `packages/contact-center/user-state/ai-docs/user-state-spec.md` | `packages/contact-center/user-state/src/index.ts` |
| cc-widgets.IncomingTask | `@webex/cc-task` | `IncomingTask` | React component; custom element `widget-cc-incoming-task`; props `incomingTask` (json), `onAccepted`, `onRejected` (functions) | stable semver | `packages/contact-center/task/ai-docs/task-spec.md` | `packages/contact-center/task/src/index.ts` |
| cc-widgets.CallControl | `@webex/cc-task` | `CallControl` | React component; custom element `widget-cc-call-control`; props `onHoldResume`, `onEnd`, `onWrapUp`, `onRecordingToggle` (functions) | stable semver | `packages/contact-center/task/ai-docs/task-spec.md` | `packages/contact-center/task/src/index.ts` |
| cc-widgets.CallControlCAD | `@webex/cc-task` | `CallControlCAD` | React component; custom element `widget-cc-call-control-cad`; props `onHoldResume`, `onEnd`, `onWrapUp`, `onRecordingToggle` (functions) | stable semver | `packages/contact-center/task/ai-docs/task-spec.md` | `packages/contact-center/task/src/index.ts` |
| cc-widgets.CallControlCAD | `@webex/cc-task` | `CallControlCAD` | React component; custom element `widget-cc-call-control-cad`; props `onHoldResume`, `onEnd`, `onWrapUp`, `onRecordingToggle` (functions); owner-aware participant Drop is store-driven and adds no prop/attribute | stable semver | `packages/contact-center/task/ai-docs/task-spec.md`; `ai-docs/features/participant-drop-intake.md` | `packages/contact-center/task/src/index.ts` |
| cc-widgets.TaskList | `@webex/cc-task` | `TaskList` | React component; custom element `widget-cc-task-list`; props `onTaskAccepted`, `onTaskDeclined`, `onTaskSelected` (functions), `hasCampaignPreviewEnabled` (boolean) | stable semver | `packages/contact-center/task/ai-docs/task-spec.md` | `packages/contact-center/task/src/index.ts` |
| cc-widgets.OutdialCall | `@webex/cc-task` | `OutdialCall` | React component; custom element `widget-cc-outdial-call`; no declared props | stable semver | `packages/contact-center/task/ai-docs/task-spec.md` | `packages/contact-center/task/src/index.ts` |
| cc-widgets.RealTimeTranscript | `@webex/cc-task` | `RealTimeTranscript` | React component; custom element `widget-cc-realtime-transcript`; props `liveTranscriptEntries` (json), `className` (string) | stable semver | `packages/contact-center/task/ai-docs/task-spec.md` | `packages/contact-center/task/src/index.ts` |
| cc-widgets.DigitalChannels | `@webex/cc-digital-channels` | `DigitalChannels` | React component; custom element `widget-cc-digital-channels`; no declared props | stable semver | `packages/contact-center/cc-digital-channels/ai-docs/cc-digital-channels-spec.md` | `packages/contact-center/cc-digital-channels/src/index.ts` |
| cc-widgets.store | `@webex/cc-store` | `store` | MobX singleton (`Store.getInstance()`); `init(options: InitParams, setupEventListeners): Promise<void>`; sole SDK access point via `store.cc.*` | stable semver | `packages/contact-center/store/ai-docs/store-spec.md` | `packages/contact-center/store/src/index.ts:1,4` |
| store.types | `@webex/cc-store` | Type re-exports (`IContactCenter`, `ITask`, `Profile`, `Team`, `AgentLogin`, `IStore`, `ILogger`, `InitParams`, `IWebex`, `RealTimeTranscriptionData`, plus ~20 more) | TypeScript `type`/`interface` exports describing the SDK-backed domain surface | stable semver; SDK-shaped types track SDK | `@webex/contact-center` types (`node_modules/@webex/contact-center/dist/types/index.d.ts`) (SDK source); `packages/contact-center/store/ai-docs/store-spec.md` | `packages/contact-center/store/src/store.types.ts:334-366` |
| store.constants | `@webex/cc-store` | Value/enum re-exports (`CC_EVENTS`, `TASK_EVENTS`, `LoginOptions`, `ConsultStatus`, `CAMPAIGN_PREVIEW_OUTBOUND_TYPES`, `DESKTOP`, `EXTENSION`, etc.) | Exported consts/enums for event names and login/consult/campaign domain values | stable semver | `packages/contact-center/store/ai-docs/store-spec.md` | `packages/contact-center/store/src/store.types.ts:368-403` |
| store.task-utils | `@webex/cc-store` | Pure task helpers (`isIncomingTask`, `getTaskStatus`, `getConsultStatus`, `getConferenceParticipants`, `isInteractionOnHold`, `findHoldStatus`, etc.) | `(task: ITask, agentId?: string) => boolean \| string \| number \| Participant[]` selectors over SDK task objects | stable semver | `packages/contact-center/store/ai-docs/store-spec.md` | `packages/contact-center/store/src/task-utils.ts` |
| store.task-utils | `@webex/cc-store` | Pure task helpers (`isIncomingTask`, `getTaskStatus`, `getConsultStatus`, `getConferenceParticipants`, `getConferenceParticipantDropRoster`, `isInteractionOnHold`, `findHoldStatus`, etc.) | Read-only selectors over SDK task objects; the Drop selector returns an owner-aware main-leg roster plus the current Entry Point/EP-DN consult destination (dialed number while ringing, answering Agent name before merge), or `null` for Customer-only/terminal calls | stable semver | `packages/contact-center/store/ai-docs/store-spec.md`; `ai-docs/features/participant-drop-intake.md` | `packages/contact-center/store/src/task-utils.ts` |
| ui-logging.withMetrics | `@webex/cc-ui-logging` | `withMetrics` | `withMetrics<P extends object>(Component, widgetName: string): React.MemoExoticComponent` HOC that auto-emits mount/unmount/error metrics; every widget export is wrapped with it | stable semver; signature change is breaking | `packages/contact-center/ui-logging/ai-docs/ui-logging-spec.md` | `packages/contact-center/ui-logging/src/index.ts` |
| ui-logging.WidgetMetrics | `@webex/cc-ui-logging` | `WidgetMetrics` (type) | `{ widgetName; event: 'WIDGET_MOUNTED' \| 'ERROR' \| 'WIDGET_UNMOUNTED' \| 'PROPS_UPDATED'; props?; timestamp; additionalContext? }` | stable semver; narrowing the `event` union or removing a field is breaking | `packages/contact-center/ui-logging/ai-docs/ui-logging-spec.md` | `packages/contact-center/ui-logging/src/index.ts` |

## Requires — what this repo depends on
| Dependency (service / package / datastore) | What is consumed | Schema / detail link | Availability assumption | Fallback on failure | Version floor |
|---|---|---|---|---|---|
| `@webex/contact-center` SDK | The entire CC runtime: `Webex.init()`, `webex.cc.*` methods, CC/task event stream, agent `Profile`, `webex.credentials.getUserToken()` | `@webex/contact-center` types (`node_modules/@webex/contact-center/dist/types/index.d.ts`); consumed only via the store (`packages/contact-center/store/src/storeEventsWrapper.ts`) | Host establishes the authenticated Webex session; SDK assumed reachable | `Store.init()` rejects after a 6s init timeout; widgets stay inert and surface error UI (`packages/contact-center/store/src/store.ts:140-142`) | Pinned by the SDK dependency in each package's `package.json` |
| `@webex/contact-center` SDK | The entire CC runtime: `Webex.init()`, `webex.cc.*` methods, `ITask.dropConferenceParticipant({participantId})`, CC/task event stream, agent `Profile`, `webex.credentials.getUserToken()` | `@webex/contact-center` types (`node_modules/@webex/contact-center/dist/types/index.d.ts`); consumed only via the store/task object | Host establishes the authenticated Webex session; SDK and routing backend are assumed reachable and authoritative | `Store.init()` rejects after a 6s init timeout; participant Drop rejects and `CallControlCAD` shows generic feedback | Pinned by the SDK dependency in each package's `package.json`; Participant Drop requires the published SDK version recorded in the feature intake |
| `react` / `react-dom` (18) | Component runtime; consumer peer dependency | React docs | Provided by host or bundled | N/A (build-time/runtime peer) | React 18 |
| `mobx` / `mobx-react-lite` | Store reactivity (`runInAction`, `observer`) | MobX docs | Bundled with store package | N/A | per `package.json` |
| `@r2wc/react-to-web-component` | Wraps React widgets as custom elements (`packages/contact-center/cc-widgets/src/wc.ts:1`) | r2wc docs | Bundled with `cc-widgets` | N/A | per `package.json` |
Expand Down
3 changes: 2 additions & 1 deletion ai-docs/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This repo is a client-side React/Web-Component widget library. It hosts no netwo

## Authentication & Authorization Model
- **Authentication:** Owned by the host app and the Webex SDK, not this repo. The host supplies either a live `webex` instance or `{webexConfig, access_token}`; the store passes the token to `Webex.init({credentials: {access_token}})` and otherwise treats identity as opaque (`packages/contact-center/store/src/store.ts:144-151`). Token retrieval for downstream SDK features delegates to the SDK: `getAccessToken()` calls `webex.credentials.getUserToken()` (`packages/contact-center/store/src/storeEventsWrapper.ts:988-998`).
- **Authorization:** Owned by the SDK / back end. The store surfaces the agent's capabilities as read-only feature flags derived from the SDK-provided `Profile` (`packages/contact-center/store/src/util.ts:3-36`); widgets use these only to show/hide UI. There is no access-decision logic enforced in this repo.
- **Authorization:** Owned by the SDK / back end. The store surfaces the agent's capabilities as read-only feature flags derived from the SDK-provided `Profile` (`packages/contact-center/store/src/util.ts:3-36`); widgets use these only to show/hide UI. Participant Drop additionally hides actions unless `interaction.owner === currentAgentId`, but that client rule is not an authorization boundary; the backend must authorize every request.
- **Default posture:** Widgets are inert until the host completes `Store.init()`; with no valid host-supplied session the SDK never initializes (`Webex.init` rejects after a 6s timeout — `packages/contact-center/store/src/store.ts:140-142`), so no agent data flows.

## Secret & Credential Handling
Expand All @@ -42,6 +42,7 @@ This repo is a client-side React/Web-Component widget library. It hosts no netwo
|---|---|---|---|
| `ui-logging` metrics props | Widget props are logged without sanitization — acknowledged in the `havePropsChanged` JSDoc `@remarks` (`metricsLogger.ts:73-76`) | Callers must not pass PII-bearing objects as metrics props; sanitization is noted as a future enhancement | cc-ui-logging maintainers |
| `getAccessToken()` SDK gap | `webex.credentials.getUserToken()` is `@ts-expect-error`-typed (SDK API not yet typed) (`storeEventsWrapper.ts:990-992`) | Token value is returned to the caller and never logged; failures log only an error message | cc-store maintainers |
| Participant Drop identity | Target IDs can be agent identifiers or customer ANI/DNIS and therefore may be sensitive | Derive in memory, pass only to `task.dropConferenceParticipant`, render through React text escaping, and log only static context plus generic feedback | cc-store / cc-task maintainers |

## Reporting & Review
- Security-relevant changes (anything touching the store init/credential path, the `@webex/contact-center` SDK boundary, logging, or the public export/custom-element surface) require review by the package CODEOWNERS on the `next`-targeted PR, following `.github/PULL_REQUEST_TEMPLATE.md` (FedRAMP/GAI sections). Suspected vulnerabilities: report through the Webex internal security channel, not a public issue.
Expand Down
9 changes: 5 additions & 4 deletions ai-docs/SPEC_INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
## Module Registry
| Module | Responsibility | Manifest coverage state | Start here |
|---|---|---|---|
| `store/` | MobX singleton; global CC state; proxies SDK events; sole SDK access point | DRAFT | `packages/contact-center/store/ai-docs/store-spec.md` |
| `cc-components/` | Shared presentational React UI primitives | DRAFT | `packages/contact-center/cc-components/ai-docs/cc-components-spec.md` |
| `cc-widgets/` | r2wc Web Component wrappers (aggregator) | DRAFT | `packages/contact-center/cc-widgets/ai-docs/cc-widgets-spec.md` |
| `store/` | MobX singleton; global CC state; SDK event proxy; pure conference Drop roster derivation | DRAFT | `packages/contact-center/store/ai-docs/store-spec.md` |
| `cc-components/` | Shared presentational React UI primitives, including the CallControlCAD Drop experience | DRAFT | `packages/contact-center/cc-components/ai-docs/cc-components-spec.md` |
| `cc-widgets/` | r2wc Web Component wrappers; existing CallControlCAD wrapper inherits Drop behavior | DRAFT | `packages/contact-center/cc-widgets/ai-docs/cc-widgets-spec.md` |
| `cc-digital-channels/` | Digital channels (chat/email/social) widget | DRAFT | `packages/contact-center/cc-digital-channels/ai-docs/cc-digital-channels-spec.md` |
| `station-login/` | Agent login: team + device selection | DRAFT | `packages/contact-center/station-login/ai-docs/station-login-spec.md` |
| `user-state/` | Agent state: state, idle codes, timer | DRAFT | `packages/contact-center/user-state/ai-docs/user-state-spec.md` |
| `task/` | Task widget bundle: CallControl, IncomingTask, OutdialCall, TaskList, CallControlCAD | DRAFT | `packages/contact-center/task/ai-docs/task-spec.md` |
| `task/` | Task widget bundle; CallControlCAD owns participant Drop orchestration | DRAFT | `packages/contact-center/task/ai-docs/task-spec.md` |
| `ai-assistant/` | AI Assistant widget: chrome + Real-time Assist requests, transcript, feedback | DRAFT | `packages/contact-center/ai-assistant/ai-docs/ai-assistant-spec.md` |
| `ui-logging/` | Metrics/telemetry: `withMetrics`, `metricsLogger` | DRAFT | `packages/contact-center/ui-logging/ai-docs/ui-logging-spec.md` |
| `test-fixtures/` | Shared test mocks/helpers | DRAFT | `packages/contact-center/test-fixtures/ai-docs/test-fixtures-spec.md` |
Expand Down Expand Up @@ -67,5 +67,6 @@ The intake record confirms scope/modules **against the code** and sets the chang
| Decision records | `ai-docs/adr/` | Standing ADRs — why the architecture is the way it is |
| Review catalog | `ai-docs/REVIEW_CHECKLIST.md` | 6-core + 4-coverage + 3-cross-cutting review checks |
| SDK reference | `@webex/contact-center` types (`node_modules/@webex/contact-center/dist/types/index.d.ts`) | installed SDK `.d.ts` surface — verify every SDK call |
| Participant Drop intake | `ai-docs/features/participant-drop-intake.md` | Cross-repository SDK/widget contract, behavior, delivery gates, and verification |

_No `DATA_MODEL.md`: this repo owns no persistent datastore (all domain data comes from the SDK at runtime)._
Loading