# GWT AAF — agent implementation reference

Use this file **after** the developer answers the three questions in `DEVELOPER.md` (copy/paste contract). Do not surface this content in the first reply.

## SDK surface (`aaf_sdk.js` → helpers)

Every `client.<service>.<method>` has a typed wrapper under `app/aaf/`. Do not call the raw client from components.

| ECC service / namespace | Helper file | When to use |
|-------------------------|-------------|-------------|
| `globalData` | `gwtAafSdk.ts` | Read/update tickets, campaigns, agent session (`get`, `update`, `getTickets`, `addNote`, `bulkUpdate`, `bulkAction`, `transfer`, `invoke`) |
| `globalEvent` | `gwtGlobalEvents.ts` | CTI events (call, chat, CRM, video) — only names in `GWT_GLOBAL_EVENTS_ECC` |
| `lifeCycle` | `gwtLifeCycle.ts` | `appModalClose`, `appUnload` |
| `interface` | `gwtInterface.ts` | Toasts, desktop notifications, open ticket/customer forms |
| `httpRequest` | `gwtHttpRequest.ts` | Ameyo REST path or external HTTPS via host |
| `contextData` | `gwtContextData.ts` | Dial, change customer, add customer in slot |
| `contextEvent` | (low-level `client.contextEvent`) | Slot-local: `tabChange`, `ticketSavedByUser`, `customerLinkingChangedOnUi`, … |
| `instance` | `gwtInstance.ts` | Spawn modal/popup instances, `sendData` / `receiveData` |
| `appConf` | `gwtAppConf.ts` | Persistent per-app DB config |
| `augmentModel` | `gwtAugmentModel.ts` | `add("userAttributes", …)` only |
| `request` | `gwtRequest.ts` | Whitelisted APIs (`GwtRequestApi` / `RequestApiEnum`) |
| `store` | `gwtStore.ts` | Runtime-only key/value (lost on reload) |

Payload shapes and error codes: **`GWT_AAF_SDK_REFERENCE.md`**.

## Pick events by use case

Register only what the agreed use case needs. Combine `globalEvent` with the listed helpers.

### A. Voice / call-handling

| Use case | `globalEvent.register` | Other calls |
|----------|------------------------|-------------|
| Screen-pop on inbound | `callRinging`, `customerCallMemberCreated`, `voiceCustomerLinked` | `interface.open("openCustomerDetail", …)` / `newCustomerForm` |
| Active-call companion | `callConnected`, `customerCallMemberCreated`, `callHold`, `callHungup`, `callHungupStatus` | `globalData.get("getAgentSession")`, `globalData.get("ongingCallTicket")`, `httpRequest.invoke` |
| Wrap-up / disposition | `callHungup`, `callHungupStatus`, `crmStateChange` | `globalData.invoke("changeStatusTicket", …)`, `globalData.update("ticket", …)` |
| Hold tracking | `callHold` | `httpRequest.invoke` to your service |
| Outbound click-to-dial | `campaignSelectionChange` | `contextData.trigger("dialPhone" \| "dialCustomer", …)` |
| Add caller mid-call | `callRinging`, `voiceCustomerLinked` | `interface.open("newCustomerForm", …)` or `contextData.trigger("addCustomer", …)` |
| Missed-call follow-up | `missedCallAdded`, `missedCallModified`, `missedCallRemoved` | `globalData.getTickets("getAllTickets", …)` |
| Agent state tile | `userStateChange` | `globalData.get("getAgentSession")`, `get("loggedInUser")` |
| AQ / queue monitor | `aqRequestAdded`, `aqRequestRemoved` | `globalData.get("selectedCampaigns")` |
| Conference / transfer tracker | `userCallMemberCreated`, `userCallMemberDeleted`, `customerCallMemberCreated`, `customerCallMemberDeleted` | (display only) |

### B. Chat / messaging

| Use case | Events | Other |
|----------|--------|-------|
| Chat assistant | `customerChatMemberCreated`, `chatConnected`, `newChatMessageAdded`, `chatHungup` | `globalData.invoke("setAnswered", …)` |
| Suggest-reply on focus | `chatDialogFocus`, `newChatMessageAdded` | payload on event |
| Chat wrap-up | `chatHungup`, `crmStateChange` | `changeStatusTicket` |

### C. CRM / ticket sync

| Use case | Events | Other |
|----------|--------|-------|
| External ticket sync | `crmStateChange`, `customerStateChange` | `globalData.update`, `httpRequest.invoke` |
| Attachments | `attachmentAddedInTicket`, `attachmentMetadataUpdated` | `invokeAmeyoMultiPart` |
| Disposition override | `crmStateChange` | `lifeCycle` + `modalCloseConfirmation` |

### D. Video

| Use case | Events |
|----------|--------|
| Video status panel | `videoCallRinging`, `videoCallConnected`, `videoCallEnded`, `canDisposeVideoStateChange` |
| Video + attachments | `videoCallEnded`, `attachmentAddedInTicket` |

### E. Page / shell

| Use case | Mechanism |
|----------|-----------|
| Pause when tab hidden | `pageVisibilityChange` |
| Modal graceful close | `lifeCycle.register("appModalClose")` + `modalCloseConfirmation` |
| Ticket/tab changes in slot | `contextEvent.register("tabChange"`, …) — **not** `globalEvent` |

### F–I. Other services

See **`DEVELOPER.md`** troubleshooting and `gwtInstance.ts` / `gwtAppConf.ts` / `gwtRequest.ts` helpers for multi-instance, config, augment, and `request.api`.

### J. Debugging only

**`global-events-logger`** template — `EventLoggerView` already registers all 28 ECC `globalEvent` names and exposes a Methods playground.

## Agent sanity rules

1. Only register names in `GWT_GLOBAL_EVENTS_ECC` (`gwtGlobalEvents.ts`). Doc aliases (`callEnded`, `chatEnded`, …) always fail with `121`.
2. Use helpers from `gwtAafSdk.ts` / `gwt*.ts` — not raw `client.*`.
3. `globalData.get("loggedInUser")` — plain string, not `{ dataObject: "…" }`.
4. `campaignId` from `campaignSelectionChange` or `get("selectedCampaigns")` — never hard-code.
5. `store` = runtime only; `appConf` = persistent DB config.
6. `contextEvent` ≠ `globalEvent` for tab/ticket UI events.
7. **Light theme only** — keep `ExotelThemeProvider defaultMode="light"`, `index.html` `class="light"`, no dark mode toggle.
