Skip to content

Takeda Salesforce field mappings and audit

Status: Historical MCP audit | Last reviewed: 2026-10-07

The native replacement is documented in Takeda native Salesforce workflows, including the controls for each mapping and the revised completion rule. The audit below describes the earlier MCP path and remains relevant to retained legacy versions.

Subsequent native readback: Subject values in the tables are request inputs. Salesforce's DCC_Construct_and_update_Case_subject flow replaces displayed Case titles with Case number, Origin and the Reason label. See Salesforce-owned Case titles for its controls and branches.

Use these tables to find the source of each Case, Task, summary and handoff value on the Vanguard Genesys AI route. Read the action logic reference for execution order and workflow migration options. The schema mappings checked out, but the completion logic has confirmed defects; the implementation is not fully verified as correct.

Scope and evidence

The October 7 audit read Vanguard's published agent 4463:v28, workflows 1856:v5, 1918:v1, 1857:v7, legacy 1855:v5, and their tool bindings. It inspected the current local handler/renderer source, queried DevSDO field metadata, and read existing records. It did not write Salesforce records, publish workflows, or change the application implementation.

The source implementation is not independently tied to a deployed image/revision by this audit. The behavioral reproductions exercise that source with simulated Salesforce responses; they establish code defects, not that each defect occurred in a live call.

Private evidence is under .local-data/takeda-demo/mapping-audit-2026-10-07/: read-only-report.json, sample-report.json, their read-only scripts, and edge-cases.ts. Keep record-level evidence and credentials out of documentation and Git.

The read-only sample selected the 12 most recent distinct calls with workflow 1918 executions. It found 12 parent Cases and 22 children:

  • All parent reasons were MultiPatientAccessReview.
  • Every sampled parent had one correctly linked voice Task.
  • All child parent links, external keys, inherited record types and status flags matched.
  • Twenty-one children had CareRequest/source Case links consistent with that request's Member Account and historical Case. One had neither optional link; absence is permitted by the handler and is not proof that a link should exist.
  • All parents had HTML; four had no Customer Intents. The MCP does not write Customer Intents.

This is a limited sample, not an audit of every record, Salesforce automation or record-type-specific picklist rule.

Names used in the mappings

Name Source
id Lowercased, validated original Genesys conversation UUID
K(suffix) takeda:00000000-0000-0000-0000-000000000001:genesys:<id>:<suffix>
ctx.caseId / ctx.activityId Verified parent Case / inbound Task IDs
ctx.coordinatorId / ctx.contactId Selected coordinator Account / Person Contact IDs
ctx.coordinatorName Parent Account.Name on readback
patient One entry in this call's Account-ID-based roster, selected by pN
saved Child records validated against this call and roster
params Nested sessionEnd.params overlaid with top-level sessionEnd

The field payloads live in genesys-call.ts. Constants and object-field names in these tables are code-owned unless the table says otherwise.

Parent Case

prepareCall creates this record. saveRosterPatientOutcome and the finalizer can later update it.

Salesforce field Source/value When written
External_ID__c K("parent") Create
AccountId Selected coordinator Account ID Create
ContactId Selected coordinator Person Contact ID Create
RecordTypeId 012Kd000000pk1VIAQ — Agnostic Case Create
Subject Takeda Clearway \| Multi-Patient Access Review Create
Reason API value MultiPatientAccessReview Create
Status New Create
Origin Voice Create
Priority Medium Create
DCC_Case_Summary__c summaryHtml(ctx, saved) Patient save; limited finalizer repair
Status Closed unless String(params.session_escalated) === "true" Finalization

The MCP does not explicitly set parent ParentId, Description, OwnerId, or DCC_Customer_Intents__c. Defaults and Salesforce automation can populate omitted fields. The parent remains open on the explicit escalation branch.

The matching Account's name is not accepted as the final identity merely because it appeared in an input: the returned callContext takes Account.Name from parent readback. Existing parent reuse does not revalidate every configured default, such as Reason, Subject, Origin or the exact configured record type.

Inbound call Task

Salesforce field Source/value When written
External_ID__c K("interaction") Create / missing-Task upsert key
WhatId @{parent.id} in Composite; existing parent ID in recovery Create/recovery
WhoId Coordinator Person Contact ID Create/recovery
CallObject Original Genesys conversation UUID Create/recovery
Subject Inbound Voice Create/recovery
Type Voice Create/recovery
CallType Inbound Create/recovery
Status In Progress Create/recovery
Priority Normal Create/recovery
Description Deterministic saved-child summary plus job warnings in background mode Finalization
Status In Progress for explicit escalation; otherwise Completed Finalization

With backgroundUpdates=false, Description instead takes params.summary, limited to 8,000 characters. The configured end workflow enables background mode, so it replaces that input with the record-derived summary. That generated branch does not apply the 8,000-character cut.

The MCP does not explicitly write Task ownership or Customer Intents. Task completion describes the call activity, not completion of a historical payer submission.

Roster-based patient child Case

saveRosterPatientOutcome creates at most one child per Account under a given call's parent.

Salesforce field Source/value
External_ID__c K("patient:" + patient.id)
ParentId ctx.caseId
DCC_Related_Case__c Also ctx.caseId; not the historical source Case
AccountId patient.id
RecordTypeId Parent's actual RecordTypeId
Reason Linked historical Case's Reason; fallback MultiPatientAccessReview
Subject Voice - plus the Reason API value, not its label
Origin Voice
ContactId Patient Account.PersonContactId, when returned
Takeda_Request__c Latest returned CareRequest ID, when present
Takeda_Source_Case__c That CareRequest's CareRequestCaseId, when present
Status, IsEscalated, Description Effective disposition below
Disposition Status / escalation flag Exact description
discussed New / false Recorded the caller’s patient inquiry. The discussion is in progress.
completed Closed / false Completed the caller’s patient inquiry. No historical request or submission was changed.
escalated Escalated / true Caller accepted a case-manager handoff for this patient’s inquiry.

Existing-child updates normally write only Status, IsEscalated, and Description; source links are verified, not silently rebound. Equal-status saves do not repair Description. A delayed lower disposition keeps the existing higher state.

IsClosed is read-only in DevSDO and derived from Status. The payload does not write it. Child Priority and OwnerId are omitted. Closing a child means the call's inquiry is complete; it does not approve the underlying authorization or close the historical request Case.

The finalizer separately closes every New child and writes the completed description. This bypasses the normal disposition decision and is one of the audit findings.

Legacy child differences

Workflow 1855's savePatientOutcome uses fixed names and K("outcome:thomas") / K("outcome:renee"), not Account-ID keys.

Outcome Fixed name Reason / status / description
thomas Thomas Whitfield StepTherapyAppeal; Closed; Completed the caller’s appeal-status inquiry and recorded its outcome. No historical appeal Task was changed.
renee Renee Catellano PriorAuthorizationFollowUp; Escalated; Caller accepted a case-manager handoff for the prior authorization follow-up.

Other create fields are parent links, patient Account, inherited record type, Subject="Voice - " + reason, Origin=Voice, and Renee's escalation flag. It omits patient Contact, CareRequest and source Case links.

Patient facts and call context

loadPatientContext sets these roster fields:

Roster value Salesforce source
id, name, optional contactId Enrollee AccountId, Account.Name, Account.PersonContactId
reference p1, p2, … after deduplication and sorting by Account ID
requestId Latest CareRequest.Id for MemberId=patient.id
sourceCaseId CareRequest.CareRequestCaseId
reason Source Case Reason, otherwise MultiPatientAccessReview

The brief is a startup snapshot, not refreshed on every turn:

Brief label Source
Records loaded on Current UTC date
Patient reference / Name Generated roster reference / patient Account name
Request CareRequest.Name
Recorded request status Source Case.Status
Requested date / Decision date CareRequest.RequestedDate / DecisionDate, date portion
Decision notes / Recorded cause notes CareRequest.DecisionNotes / RootCauseNotes
Recorded policy effective date CareRequest.Takeda_Policy_Effective_Date__c
Recorded prior / current criteria CareRequest.Takeda_Prior_Criteria__c / Takeda_Current_Criteria__c
Recorded payer average days CareRequest.Takeda_Payer_Average_Days__c
Case notes Source Case.Description
Activity Source Task Subject, Status, ActivityDate, Description
Event Source Event Subject, Description

Missing facts are omitted, missing Task details receive explicit “not recorded”/“none” text, and a missing CareRequest produces “No care request is recorded.” No payer endpoint is called.

Workflow 1856 exposes:

Workflow output Configured source
context_status patients.ok=true → ready; otherwise unavailable
coordinator_first_name First space-delimited token of records.callContext.coordinatorName
patient_brief patients.patientBrief when ready; otherwise empty
call_context Enriched patient context when ready; otherwise records context
transfer_params records.transferParams

The raw patient action also returns a first-name value, but the workflow uses the records expression above. For compound first names, the current greeting takes only the first token.

Four different summaries

Output Generator and content Important distinction
Parent Case.DCC_Case_Summary__c HTML renderer: coordinator, one card per verified child, badges, optional coaching/handoff paragraph Fixed wording from saved record state; no transcript summarization
Task Description transferParams(...).summary plus background-job warnings Plain text such as “Patient’s inquiry was recorded as completed.”
VoiceCall DCC_Summary__c First 255 characters of final Task summary Can omit later patients or warnings because of truncation
Human wrap-up draft Apex getTakedaSummary Separate bullets from saved children, clinical-note fields and activity receipts

Parent HTML labels IsClosed=true, IsEscalated=false as Resolved; open/escalated as Escalated; both false as In progress. Inconsistent flags become Needs review and missing flags become Pending verification.

Its per-card description recognizes only StepTherapyAppeal and PriorAuthorizationFollowUp; all other reasons display Patient support inquiry. Names are HTML-escaped. A verified escalated child adds fixed case-manager coaching and a handoff sentence.

The plain-text formatter uses different checks: escalation flag first, then closed flag, otherwise in progress. It does not share the HTML renderer's full contradictory-flag policy.

Changing the agent's spoken prompt or sending a different params.summary does not customize the background-mode parent HTML or final summary. Neither transcriptSummarySaved nor a “Resolved” badge proves that transcript details or clinical resolution were recorded.

VoiceCall final fields

The finalizer matches VendorCallKey LIKE '%:<id>:call.%', allows at most one match, and checks that RelatedRecordId is empty or already points to this parent.

Field Source
RelatedRecordId ctx.caseId
DCC_Summary__c Final plain-text summary, first 255 characters
DCC_Call_Reason_Display__c Ending params.reason, first 255 characters
DCC_Caller_Name__c Verified coordinator name

The displayed Call Reason therefore receives a machine ending reason such as case_manager_requested, not Case.Reason or its human label. Decide whether this is the desired display.

This action does not write DCC_CaseId__c, DCC_TaskId__c, or DCC_Call_Reason__c. Genesys/Salesforce integration and handoff recovery have separate mappings. Recovery can restore Case/Task links and copy a sibling summary or stripped parent HTML; it preserves an existing nonblank summary.

Transfer fields and their freshness

end_session.params is bound to startup transfer_params. Background save results are not merged back into it.

Field Formatter rule Value on the current startup projection
CaseId, parentCaseId Parent Case ID Verified parent
ActivityId Inbound Task ID Verified Task
Name Coordinator name Verified name
coordinatorAccountId Coordinator Account Verified Account
childCaseIds JSON-encoded array of saved child IDs String "[]"
escalatedCaseId First escalated child's ID Empty
patientAccountId First escalated patient's Account, else first child's Empty
journeyStatus complete only with children all closed/escalated and HTML saved partial
transcriptSummarySaved String(summarySaved) String "false"
summary Saved-child sentences or fallback Call records are ready; no patient outcome saves have been verified.

The richer formatter results returned by patient saves are available inside that action but are discarded by the current voice-tool output mapping. Genesys/human consumers must read saved Salesforce outcomes instead of treating startup fields as a final child list.

An accepted escalation submission triggers end_session with literal session_escalated="true". That routing signal is separate from a persisted child receipt and can precede the Salesforce write.

Customer Intents and human wrap-up

The MCP sets child Reason; it does not set parent or Task DCC_Customer_Intents__c.

Salesforce applyTakedaDefaults validates the call parent/Task relationship, collects valid existing parent intents plus generic patient-child Reasons that are active Customer Intent values, sorts/deduplicates them, and proposes them in the wrap-up form. It also proposes parent status Closed. Loading the form does not persist those proposals; the existing Complete action owns the save.

getTakedaSummary separately builds the human's summary and suggested follow-up Tasks from saved records. Human edits, appeal intake and payer/demo actions therefore have their own Salesforce owners; they are not configurable through this MCP.

What the schema audit verified

DevSDO's describe responses confirmed:

  • Every mapped write field exists and is writable for the configured integration.
  • Case and Task External_ID__c are both unique external-ID fields.
  • Record type 012Kd000000pk1VIAQ is active and available, developer name DCC_Agnostic_Case.
  • Configured Reason, Status, Origin, Type, CallType and Priority API values appear in active object-level picklists.
  • Case.IsClosed is read-only; Closed is a closed CaseStatus and Escalated is open.
  • Parent HTML capacity is 131,072 characters; Task Description 32,000; the three VoiceCall text fields 255 each.

This does not establish record-type-specific allowed values, validation-rule success for every possible input, or that arbitrary inherited Reasons will produce the intended display.

Confirmed problems

These reproductions call the current TypeScript functions against simulated Salesforce state, including IsClosed changing when a parent is closed.

Finding Reproduction/result Required correction before equivalence is claimed
Unfinished inquiry is declared completed Save discussed; finish with only reason=caller_disconnected. Child/parent become Closed, Task Completed. Define explicit completion/disconnect policy; do not infer resolution from call end
Late workers can be blocked Leave a job pending for the 30-second wait; finalizer closes parent. Subsequent patient save fails the active-parent check. Preserve pending work and permit safe reconciliation
Finalization is not retry-safe Finish a non-escalated call, then retry. verifiedCall rejects its closed parent before linking/reconciling. Separate ownership validation from “must still be open”
Child mutation precedes validation Add an unrecognized New child beneath the parent; finish. Child is closed before roster validation throws. Verify every target child before any write
Stale parent HTML can remain Complete a child, replace parent HTML with stale text, finish with no New children. Returns ok=true; HTML remains stale. Reconcile HTML independently of whether children were closed

The normal patient-save path does validate children before writing and verifies its summary. These finalizer findings do not invalidate that distinction.

Gaps and decisions

  • Ending display: confirm whether VoiceCall Call Reason should show the machine ending reason, the parent's label, or the escalated patient's reason.
  • Narrative detail: current summaries record inquiry state, not what was explained, promised or agreed. Decide which verified facts belong in each destination before changing templates.
  • Optional source links: explicitly distinguish “no request exists” from “request data could not be loaded.”
  • Roster scope: all matching programs are included, with no active-membership filter.
  • Readback coverage: final Task, parent closure and VoiceCall PATCHes have no independent final readback.
  • Length coverage: the HTML, generated Task summary, child Subject and coordinator name are not checked against every destination's length. A 500-patient roster can exceed the parent HTML capacity if enough children are discussed.
  • Operation-list drift: the saved MCP tool's filter lists five operations and omits takeda_save_roster_patient. Workflow 1918 still explicitly calls it through the MCP executor, which does not use that list as an execution allow-list. Align discovery metadata; do not describe the filter as a security boundary.
  • Shared code: handler and HTML renderer changes affect callers independently of agent/workflow publication. Pin or version this dependency during a migration.

Verification performed

Thirty-four existing focused tests passed across the handler, generic patient configuration, and backup-flow definition suites:

cd apps/ai-manager
node --import tsx --test \
  lib/takeda-demo/genesys-call.test.ts \
  scripts/takeda-demo/dynamic-patient-definition.test.ts \
  scripts/takeda-demo/genesys-backup-definition.test.ts

Those tests include assertions for the current automatic-closing behavior; passing them does not establish that this business policy is correct. The private edge-case script reproduced the five problems above without live writes. The existing fake does not automatically mark a PATCHed parent closed; the audit fixture adds that Salesforce behavior to expose the retry/late-worker failures.

No end-to-end live-call qualification or record repair was performed as part of this documentation audit.

See also