# Service Operations implementation

Updated 13 September 2026. Frontend: `apps/web/src/pages/ServiceOperations.tsx` and `OperationsConnections.tsx`. Backend: the separate `ChatBEV1` checkout, `apps/api/src/operations-*.ts` and `operations.ts`.

Open **Service Operations** in the tenant workspace, or `/operations`. Both repositories must be released together. No external provider has been configured or contacted as part of this implementation. Provider tests use intercepted responses; they verify adapter behavior, not live acceptance.

## What this release adds

- Tenant-owned support cases for support, delivery, returns, exchanges, refunds and warranty; assignment, priorities, recorded resolution and elapsed-hour SLA deadlines.
- Native HubSpot contact upserts and Zoho/Salesforce lead upserts, with encrypted credentials, explicit customer selection, provider response checks and manual token rotation.
- A visual ordered workflow builder with conditional ticket creation, human handoff, local lead-stage updates, CRM synchronization and reusable HTTPS API actions.
- Paused workflows, explicit enablement, immutable run snapshots, administrator approval/rejection and per-step execution traces. Each run is manually requested for a conversation.
- AI conversation QA with cited public-message evidence, a bounded sample and human review. Reports do not assign fabricated satisfaction, compliance or accuracy scores.
- Website, Google Docs, Notion and Confluence Cloud source synchronization. New text is staged, version-checked and explicitly reviewed before publication into the existing answer retrieval system. Hourly synchronization is opt-in.
- A capability map covering all 15 requested product areas and links to the existing commerce, channel, booking, recovery, intelligence and agent-release workspaces.

## Support cases and SLA

Administrators and staff can create and operate tickets. Every case must reference a conversation in the same tenant. Owners must be active tenant members. Resolution requires a note of at least 10 characters. Opening a refund case or marking a case resolved does not execute a refund, cancel an order or create an exchange.

The resolution SLA is 1–720 elapsed calendar hours from creation. There is no business-hours clock, first-response SLA, pause clock or automatic escalation. Reopening retains the original deadline. Resolved tickets preserve whether the recorded resolution missed the deadline. The workspace displays the latest 1,000 tickets and aggregate counts across all tickets; there is a 5,000-open-ticket limit.

## CRM setup

Use **CRM** in Service Operations. A saved token means configured; only a confirmed upsert means connected. Saving and rotating tokens do not run a provider request. Credentials are encrypted in backend persistence and excluded from API views and trace records.

| Provider | Configuration | Implemented operation |
| --- | --- | --- |
| HubSpot | `https://api.hubapi.com`; access token with contact write permission | `POST /crm/v3/objects/contacts/batch/upsert`, identified by customer email |
| Salesforce | Your `https://<domain>.my.salesforce.com` origin, including supported sandbox domains; access token with Lead write permission; create a unique external ID field such as `ConveRact_ID__c` on Lead | Lead upsert through `/services/data/v66.0/sobjects/Lead/<externalField>/<tenantId:conversationId>`; customer company is required |
| Zoho | Regional `https://www.zohoapis...` API origin and OAuth token with Leads upsert permission | `POST /crm/v8/Leads/upsert`, matching Email; no optional automation triggers requested |

HubSpot and Zoho require a valid email. Only recorded name, company, email and phone are mapped; absent optional fields are omitted. CRM record validation, custom mandatory fields and token scopes can reject a write. Provider errors stay visible. HTTP success containing per-record failure, or an unfinished HubSpot batch, is not reported as a confirmed sync.

There is no OAuth consent flow, automatic token refresh, CRM deletion, background bidirectional synchronization, field mapping editor, deal/opportunity synchronization or task/follow-up synchronization in these adapters. Use the token replacement control when an access token expires. Confirm required company/customer information in the conversation before syncing. Connecting multiple workspaces to the same CRM requires deliberate customer identity governance; email matching can target an existing shared contact.

Official contracts: [HubSpot contacts](https://developers.hubspot.com/docs/api-reference/legacy/crm/objects/contacts/guide), [Salesforce external ID upsert](https://developer.salesforce.com/docs/platform/api-rest/guide/dome-upsert.html), [Zoho upsert](https://www.zoho.com/crm/developer/docs/api/v8/upsert-records.html).

## Workflows and API actions

Create an ordered workflow with up to 12 steps. Conditions are **Always**, **Recorded negative sentiment**, and **Recorded high-intent/conversion buying stage**. Nonmatching steps are skipped; remaining steps continue in order. This is a conditional sequence builder, not a branching graph or autonomous planner. Local lead-stage updates require an existing lead.

New workflows and API actions start paused. Enable after configuration review, select a conversation and request a run. Editing a saved workflow checks its expected version, saves a new version and pauses it; older pending approvals cannot execute the revised configuration. The pending record snapshots the steps and version. Review the source conversation, destinations, API request templates and action list before approving. Approval executes immediately; rejection executes nothing. The requester may also be the reviewer; this is not mandatory separation of duties. Paused workflows cannot be approved. A run cannot be approved twice.

API actions support public HTTPS GET, POST and PATCH endpoints and an optional encrypted Bearer token. JSON string values can use `{{conversationId}}`, `{{customerName}}`, and `{{email}}`. Substitution operates on parsed JSON values rather than concatenating raw JSON. GET sends no request body. API actions currently return HTTP acceptance evidence rather than exposing response bodies or feeding responses into downstream steps. Response bodies are not stored in traces. Configure a new action for a different endpoint/template. Tokens can be replaced or erased; either operation pauses the action for review before re-enabling it.

HTTPS destinations are checked by the existing outbound guard: no embedded credentials, no private destinations, DNS pinning, TLS verification, bounded response size, timeouts and no redirect following. Never place credentials in endpoint queries or request templates; use the encrypted token field. Templates are visible to workspace administrators.

Each API action receives an `Idempotency-Key` based on run and step. Destination support for that header varies. There are no automatic write retries. A failed step stops the run; earlier successful steps remain applied. A restart marks interrupted runs failed and never automatically replays them. Inspect remote systems before requesting a new run because a timed-out request may still have succeeded remotely. Workflow execution is not a distributed transaction and does not promise exactly-once external effects. Retention is bounded to 5,000 runs per tenant; the screen shows the latest 200 runs and 1,000 traces.

## Knowledge synchronization and governance

Source configuration is administrator-only. Source names and text become customer-facing knowledge only after explicit publication. Publishing deliberately makes content available to the entire tenant's answering system; original document ACLs are not reproduced. Only connect and publish documents approved for that audience.

| Source | Setup and text coverage |
| --- | --- |
| Website | One public HTTPS page; HTML/plain text only, without credentials. No JavaScript rendering or site crawling. |
| Google Docs | `https://www.googleapis.com`, document ID, scoped Google access token. Plain-text document export; not arbitrary Drive files/folders. |
| Notion | `https://api.notion.com`, page ID, integration token with page read access. Paginated blocks, nested rich text and table rows. Images, attachments and database querying are not imported. |
| Confluence Cloud | `https://<site>.atlassian.net`, numeric page ID, account email and API token. Current page storage-body text. Macros and attachments may require manual supplementation. |

Manual synchronization is available while scheduled sync is paused. Opt-in hourly sync stages fresh text; it never automatically publishes changes. Source content must be 10–200,000 characters. Notion traversal is bounded to 40 requests, eight nested levels and a time budget; incomplete traversal fails instead of publishing a partial page. HTML extraction is plain text and requires review for lost formatting/context. PDFs/DOCX and other supported files continue through the existing Knowledge import workflow.

Publication checks the exact staged SHA-256 version and requires a sync within the previous hour. Previously approved content stays published while a new version awaits review or a transient fetch failure is investigated. A detected HTTP 401/403/404/410 withdraws published knowledge and clears staged text. Withdraw manually to archive published content, clear staged text, erase the token and pause scheduled sync. Access revocation detection depends on the next sync; paused sources are not polled. Renew expiring provider access tokens manually. The system does not promise immediate ACL propagation or federated enterprise search.

Official contracts: [Google Docs export](https://developers.google.com/workspace/drive/api/reference/rest/v3/files/export), [Notion block children](https://developers.notion.com/reference/get-block-children), [Confluence Cloud pages](https://developer.atlassian.com/cloud/confluence/rest/v2/api-group-page/).

## QA and observability

Administrators request AI review of one conversation; staff can read reports. At least two public messages are required. Internal notes/system messages are excluded. The latest 48 public messages are sampled and up to 1,200 characters per message are included. Obvious email addresses, phone numbers, links and credential patterns are redacted; this is not a guarantee that all personal information is removed.

Generated findings must cite IDs from the supplied evidence or no report is saved. Valid citations establish source membership, not that the model interpretation is correct. If the conversation is removed/anonymized during analysis, the report is rejected. At most 200 reports are retained per workspace; the screen shows 50. Successful requests impose a one-minute workspace cooldown. Existing AI service and usage gates apply. Automatic every-conversation analysis, custom rubrics, audio analysis and historical QA scores are not implemented.

Traces contain workflow/run reference, step type, status, timestamp, elapsed latency and bounded outcome text. They omit credentials, raw API bodies and customer messages. This release does not instrument the full agent retrieval/token/cost pipeline. Existing usage and intelligence views remain available for their existing metrics.

## API contract

Paths below are under `/api/v1/operations`, use the existing authenticated session cookie, and require `X-CSRF-Token` for writes. Platform admins cannot enter this tenant API. Tenant scope is derived from the session; client-supplied tenant IDs cannot select another workspace. Success uses `{ success: true, data: ... }`. These endpoints do not accept external workspace API keys.

| Method and path | Access and request |
| --- | --- |
| GET `/` | Admin/staff; staff do not receive connection credentials/configuration, workflow runs or traces |
| POST `/tickets` | Admin/staff; `conversationId`, `title`, optional category, priority, ownerId and slaHours |
| PATCH `/tickets/:id` | Admin/staff; status OPEN/IN_PROGRESS/RESOLVED, ownerId, resolution |
| POST `/connections` | Admin; name, provider HUBSPOT/SALESFORCE/ZOHO, origin, token, optional externalIdField |
| PATCH `/connections/:id` | Admin; replacement token or `disconnect: true` |
| POST `/connections/:id/sync` | Admin; conversationId, `confirmed: true` |
| POST `/actions` | Admin; name, HTTPS url, method GET/POST/PATCH, optional token, JSON body string |
| PATCH `/actions/:id` | Admin; enabled boolean, replacement token, or disconnect true |
| POST `/workflows` | Admin; name and steps array of kind, value, when |
| PATCH `/workflows/:id` | Admin; enabled boolean, or name, steps and expectedVersion to save a paused next version |
| POST `/workflows/:id/runs` | Admin; conversationId; creates pending approval only |
| POST `/runs/:id/review` | Admin; approve boolean and review note of 10–1,000 characters |
| POST `/qa` | Admin; conversationId |
| POST `/sources` | Admin; name, provider WEBSITE/GOOGLE_DOC/NOTION/CONFLUENCE, origin, optional documentId, token, accountEmail |
| GET `/sources/:id` | Admin; retrieves staged text and version hash on demand |
| PATCH `/sources/:id` | Admin; enabled boolean, replacement token, or withdraw true |
| POST `/sources/:id/sync` | Admin; empty object |
| POST `/sources/:id/publish` | Admin; reviewed true and exact staged hash |

Validation errors return 400; unauthenticated 401; forbidden/CSRF 403; unknown/cross-tenant record 404; service gates 402; stale state/duplicates/limits 409; unsupported content 422; cooldown 429; provider/model errors typically 502. A reviewed workflow with a failed step returns the persisted run with `status: FAILED`; the UI presents its error and traces rather than a success notice.

## Full requested scope: remaining engineering work

The 15-area request is **not fully implemented** by this release. A navigation card or generic API action is not a native integration or evidence of end-to-end task completion.

| Requested area | Remaining work beyond existing features and this release |
| --- | --- |
| Customer service/contact center | Automatic case creation/resolution, first-response/business-hours SLA, native helpdesk synchronization and automatic escalation |
| Commerce/sales | Validate complete provider cart/checkout/upsell journeys, broader store coverage and live sales outcome evidence |
| Voice | End-to-end outbound sales/collections, interruption/transfer quality tests and full call analytics |
| CRM automation | OAuth lifecycle, leads/contacts/deals/opportunities/tasks across all three providers, field mappings and durable event sync |
| Workflow automation | Event triggers, general branching/loops, durable delayed jobs, response data bindings and simulations for tool effects |
| Contact-center QA | Automatic full conversation coverage, custom rubrics, audio evaluation and validated semantic compliance checks |
| Lead generation/follow-up | External enrichment, broader consent-aware multichannel campaign orchestration and provider-confirmed meeting outcomes |
| Appointment booking | Native external calendar availability/reschedule/cancel/sync, durable reminders and CRM meeting synchronization |
| Collections/payment recovery | Installment policies, invoice aging workflows, escalation and live provider recovery acceptance |
| Retention/re-engagement | Validated churn prediction, general win-back/renewal campaigns and outcome attribution |
| Post-purchase operations | Native return/exchange/refund/warranty execution, logistics adapters and provider-confirmed outcomes |
| Enterprise knowledge | Folder/space discovery, arbitrary Drive files, source ACL enforcement per audience, refresh tokens and incremental event sync |
| Integration marketplace | Installable provider modules and native Zendesk/Freshdesk/ERP/logistics coverage |
| Enterprise agent platform | General graph composition, tool/voice simulation, enterprise identity features and deployment-scale evidence |
| Agent observability | Full retrieval/tool/model traces, token cost attribution, API failure linking and cross-workflow debugging |

## Validation and release

Relevant tests: backend `operations.test.ts`, `operations-connectivity.test.ts`, `intelligence.test.ts`, `rest-connectors.test.ts`, `roles.test.ts`; frontend `ServiceOperations.test.tsx`, `OperationsConnections.test.tsx`, existing intelligence and release tests. Run both repository type checks, lint, tests and builds before deploying both together.

The downloadable `/service-operations.openapi.json` documents the session API. `operations-openapi.test.ts` checks coverage of mounted methods. The browser allows up to three minutes for operational writes so multi-step execution, AI analysis and paginated source sync can finish; failed or timed-out operations must be investigated before another request.

Production acceptance requires isolated provider accounts, real scoped credentials, durable database configuration and explicit verification of each external result. No test result in this guide claims those external accounts were connected. Browser visual verification was blocked by the execution environment's automatic approval policy.

The pre-deployment live audit on 13 September 2026 found a healthy API and durable database/writer, but `/ready` returned 503 because the existing service runs in hosted demo mode. Self-service signup was disabled and the public legal contact email was unset. This release preserves that environment configuration: switching out of demo mode filters demo identities during hydration and requires a planned account transition. Configure and verify production administrators, billing, SMTP and a real legal contact before treating the site as a fully production-ready self-service launch.
