Unclassified

Account Success Flow Trace

Step-by-step trace of a Salesforce account flowing through the entire IntegrateWise pipeline.


Current Surface-Binding Doctrine

  • Operational Workbench = the primary work surface; left sidebar nav; Twin sidebar pops out when needed.
  • Twin Workbench = full AI ecosystem surface (skills, knowledge, agents, prompts, conversational library).
  • Governance is embedded at every layer — not a separate workbench.
  • OpenWebUI is not the customer-facing product shell.
  • Twin / OpenWebUI runtime surfaces use the canonical Forest + Paper system language.
  • Midnight Executive is investor-deck / fundraising language only.

Use older L1/L2 / workspace / knowledge-UI language in this file through that boundary if any historical phrasing remains.


Scenario

A CSM connects their Salesforce instance. The account "Acme Corporation" flows through the system and surfaces an insight in the CSM Hub: "Acme Corp usage dropped 40% — renewal in 45 days."


Step 1: OAuth Connection

User clicks "Connect Salesforce" → OAuth redirect → Salesforce login → Authorization grant
→ Callback to /api/connectors/salesforce/callback
→ Access token + refresh token encrypted and stored in connector_credentials table
→ Connector status set to "active" for workspace_id = ws_abc123
DetailValue
Workerconnector-auth
Duration~3s (user interaction)
OutputEncrypted tokens in Spine DB, connector record created

Step 2: Loader — Fetch from Salesforce

Loader Worker triggered by connector activation event
→ Reads connector config: object = "Account", fields = [Name, Industry, AnnualRevenue, ...]
→ Calls Salesforce REST API: GET /services/data/v59.0/query?q=SELECT+...+FROM+Account
→ Receives 847 account records (paginated, 200 per page)
→ Each record wrapped in envelope: { source: "salesforce", workspace_id: "ws_abc123", raw: {...} }
→ Enqueued to normalizer-queue (Cloudflare Queue)
DetailValue
Workerloader-salesforce
Duration~4.2s for 847 records
Output847 messages on normalizer-queue
Rate limitingRespects Salesforce API daily limit (15,000 calls)

Step 3: Normalizer — Map to Canonical Schema

Normalizer Worker consumes message from normalizer-queue
→ Reads field mapping config for Salesforce Account → IntegrateWise Account
→ Maps: SF.Name → iw.name, SF.Industry → iw.industry, SF.AnnualRevenue → iw.arr
→ Applies transformations: currency normalization, date format standardization
→ Validates required fields present (name, external_id)
→ Outputs canonical entity: { type: "account", name: "Acme Corporation", industry: "Technology", arr: 125000, external_ids: { salesforce: "001ABC123" } }
→ Enqueued to resolver-queue
DetailValue
Workernormalizer
Duration~12ms per record
OutputCanonical entity on resolver-queue

Step 4: Resolver — Identity Matching

Resolver Worker consumes from resolver-queue
→ Checks deterministic rules: external_id "001ABC123" → no existing match (first sync)
→ Checks probabilistic: name "Acme Corporation" → no fuzzy match above threshold
→ Decision: CREATE new entity
→ Assigns entity_id: ent_acme_001
→ Creates identity_link: { entity_id: "ent_acme_001", source: "salesforce", external_id: "001ABC123" }
→ Enqueued to router-queue with action: "create"

On subsequent syncs with Zendesk data:

→ Zendesk org "Acme Corp" has email domain acme.com
→ Deterministic: domain match with Salesforce account (Website field = acme.com)
→ Confidence: 0.96 → auto-merge
→ identity_link added: { entity_id: "ent_acme_001", source: "zendesk", external_id: "org_789" }
DetailValue
Workerresolver
Duration~45ms per record (includes DB lookup)
OutputEntity ID assignment + identity links on router-queue

Step 5: Router — Determine Entity Type and Destination

Router Worker consumes from router-queue
→ Reads entity type: "account"
→ Routes to account-writer-queue (not contact-writer-queue or opportunity-writer-queue)
→ Attaches routing metadata: { table: "entities_account", partition: "ws_abc123" }
→ Enqueued to writer-queue
DetailValue
Workerrouter
Duration~3ms per record
OutputRouted message on writer-queue

Step 6: Writer — Persist to Spine

Writer Worker consumes from writer-queue
→ Upserts to entities_account table in Spine DB:
  INSERT INTO entities_account (entity_id, workspace_id, name, industry, arr, ...)
  VALUES ('ent_acme_001', 'ws_abc123', 'Acme Corporation', 'Technology', 125000, ...)
  ON CONFLICT (entity_id) DO UPDATE SET ...
→ Writes source_attribution record: { entity_id, field: "arr", source: "salesforce", confidence: 0.95, synced_at: now() }
→ Emits entity_changed event to assembler-queue
DetailValue
Workerwriter
Duration~25ms per record (DB round-trip)
OutputRow in Spine + entity_changed event on assembler-queue

Step 7: Assembler — Build Entity 360

Assembler Worker consumes entity_changed event
→ Reads all source data for ent_acme_001 from Spine tables
→ Merges: Salesforce account data + Zendesk ticket history + Amplitude usage + Stripe billing
→ Resolves field conflicts using trust rules (highest-confidence-wins for ARR)
→ Computes health score: weighted formula across usage (40%), support (25%), engagement (20%), billing (15%)
→ Health score = 48 (usage dropped, support tickets up)
→ Builds Entity 360 response object and caches at edge (Cloudflare KV, 60s TTL)
→ Emits entity_assembled event to trigger-queue
DetailValue
Workerassembler
Duration~85ms (multi-table read + computation)
OutputCached Entity 360 + entity_assembled event on trigger-queue

Step 8: Twin Trigger Engine — Evaluate and Generate Insight

Twin Worker consumes entity_assembled event
→ Fetches Entity 360 snapshot for ent_acme_001
→ Evaluates 14 trigger conditions:
  ✗ usage_decline: usage dropped 42% over 30 days → FIRES (severity: high)
  ✗ renewal_risk: renewal in 45 days + health 48 → FIRES (severity: critical)
  ✓ support_spike: 2 tickets (below threshold of 3) → does not fire
  ... (11 more evaluated, none fire)
→ Creates 2 insights:
  1. { trigger: "usage_decline", severity: "high", evidence: "DAU dropped from 89 to 52 over 30 days", action: "Schedule usage review call" }
  2. { trigger: "renewal_risk", severity: "critical", evidence: "Renewal in 45 days, health score 48, usage declining", action: "Escalate to manager, schedule executive sponsor call" }
→ Writes to twin_insights table (NOT to Spine entity tables)
→ Emits insight_created events to notification-queue
DetailValue
Workertwin-trigger
Duration~120ms (Entity 360 fetch + 14 evaluations + 2 writes)
Output2 insights in twin_insights + notification events

Step 9: Insight Displayed in CSM Hub

Notification Worker routes insights to CSM Hub:
→ Realtime subscription (Spine DB Realtime) pushes to connected CSM browser
→ CSM Hub morning briefing updates:
  "🔴 Acme Corporation — Usage dropped 42%, renewal in 45 days"
  Recommended: "Schedule usage review call, escalate to manager"
→ Account card updates: health badge changes from yellow to red
→ Timeline entry added: "Twin detected usage decline and renewal risk"
DetailValue
DeliverySpine DB Realtime (WebSocket)
Latency< 200ms from insight write to UI update
OutputCSM sees actionable insight with evidence and recommended action

End-to-End Timing Summary

StageWorkerLatencyCumulative
OAuthconnector-auth~3s (user)3s
Loaderloader-salesforce~4.2s7.2s
Normalizernormalizer~12ms7.2s
Resolverresolver~45ms7.3s
Routerrouter~3ms7.3s
Writerwriter~25ms7.3s
Assemblerassembler~85ms7.4s
Twintwin-trigger~120ms7.5s
Notificationnotifier~200ms7.7s

From first Salesforce fetch to insight in CSM Hub: ~7.7 seconds (excluding OAuth user interaction).