关于 field-service-data-capture-form-deployer-configure
该 Agent skill 根据已审核的 JSON 规格,在 Salesforce 中创建 Field Service Mobile 数据采集 Flow。它面向构建移动表单的管理员或 Agent,通过 Tooling API 写入 Flow,并以 Draft 状态交由用户审阅和激活。
主要功能
- 01从 JSON 规格生成 Flow
- 02通过 Tooling API 创建 Flow
- 03支持屏幕、字段及自动化
- 04报告缺失组件的回退项
- 05可附加待处理表单记录
- 06检查并调整页面布局相关列表
适用场景
- 01部署 Field Service 移动数据采集表单
- 02创建库存转移等多步骤流程
- 03将表单关联到 Work Order
- 04排查表单未显示在移动端
MCP 相关
README 指出共享环境通过 Headless 360 MCP 调度 REST 调用;该 skill 使用这些调用读取和写入 Salesforce org。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill field-service-data-capture-form-deployer-configure安装后在 Claude Code 中输入/field-service-data-capture-form-deployer-configure确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/inventory-transfer-spec.jsonsample-spec.jsonsectioned-spec.jsonreferences/field-types.mdflow-metadata-json.mdpost-screen-automation.md详细介绍
构建数据采集表单(现场服务移动版)
此技能会将中间 JSON 规范转换为已部署的 Salesforce Flow,并设置 processType=DataCaptureFlow。此流程假定规范已经过确认且正确——与用户确认的工作在上游的设计技能中完成。
运行时约定: 此技能中的所有组织交互都是通过 Codey 运行时分发的 REST 调用(在本地通过
dispatch/ 在共享界面中通过托管的 Headless 360 MCP)。此技能不依赖执行环境——不需要sfCLI、Shell 脚本、本地 Python 或临时文件。身份验证探测、记录读取和记录写入都是单次 REST 调用;Flow XML 由 Agent 根据参考文档内联编写。 请勿调用 Shell。
输入约定
符合 reference/field-types.md 中的架构、且可选地符合 reference/post-screen-automation.md 的 JSON 文件。规范示例:
- examples/sample-spec.json — 仅包含屏幕的最小 Flow。
- examples/inventory-transfer-spec.json — 完整示例,包含 Repeater、Radio、可见性、决策、查找、循环和记录创建。
必需的顶层键:formTitle、formType、screens。可选键:postScreen。
输出
通过单次 Tooling API 调用在组织中创建 Data Capture Flow——使用带有 JSON Metadata 主体的 POST /services/data/vXX.0/tooling/sobjects/Flow(不生成 .flow-meta.xml、zip 或 SFDX 项目)。Flow 创建时的状态为 Draft,用户需在 Flow Builder 中自行激活。
工作流
1. 验证组织身份验证
通过成本较低的身份验证探测,确认已连接的组织可访问——分发 SELECT Id FROM Organization LIMIT 1(GET /services/data/vXX.0/query):
- 返回 2xx 且
totalSize=1→ 会话令牌有效;继续。 - 返回 401/403 → 组织需要重新进行身份验证。告知用户并停止;不要部署。(Codey 运行时会解析并刷新已连接的组织——此技能不管理组织别名。)
2. 选择 Flow API 名称
如果设计技能已提供 <FlowApiName>,请使用该名称。否则根据 formTitle 生成:采用 PascalCase,不含空格,且必须匹配 ^[A-Z][A-Za-z0-9_]*$。如果无法转换标题,请询问用户。
3. 构建 Flow Metadata JSON
根据规范内联组装 Flow 的 Metadata 对象——Tooling Flow sObject 接受 JSON Metadata 数据块,因此无需编译 XML,也无需运行转换器。请遵循 reference/flow-metadata-json.md 和 reference/field-types.md 中的 JSON 结构和字段映射。
注意:
- JSON
Metadata的结构与 ToolingFlowGET 返回的完全相同(GET /tooling/sobjects/Flow/{id}→Metadata),因此在编写前,可以检索一个已知正确的同类 Flow 作为实时参考。 - 在整个 Flow 范围内对选项去重——两个字段若都使用
["Good","Fair","Poor"],则顶层choices数组中只需包含这三个条目一次。 - Repeater 子项作为
fields条目嵌套在父 Repeater 字段中。 Signature、UploadFile、UploadImage和Images会自动将parentRecordId/recordId连接到标准 DataCaptureFlow 输入变量。它们会部署为可正常使用的组件,无需在 Flow Builder 中进行清理。Lookup需要lookupObject规范键;如果没有,则输出带标签的dcTextInput占位组件。FileView需要fileName;否则使用相同的回退处理。收集所有此类回退,并在第 5 步告知用户。- 部署前进行自检:
processType为DataCaptureFlow,environments包含Offline,并且存在三个输入变量(parentObjectType、parentRecordId、recordId)。
4. 部署到组织
通过一次 Tooling API 调用创建流 — 发送 POST /services/data/vXX.0/tooling/sobjects/Flow,请求正文如下:
{
"FullName": "<FlowApiName>",
"Metadata": { "processType": "DataCaptureFlow", "environments": ["Offline"], "label": "...", "screens": [ ... ], "choices": [ ... ], "variables": [ ... ], "status": "Draft" }
}
FullName是流的 API 名称;Metadata是你在步骤 3 中组装的对象。- 返回 201 且
success: true时,会返回新的流版本 ID。Status保持为Draft(只有用户要求创建时激活,才设置Metadata.status: "Active"— 默认状态为 Draft,以便用户先在 Flow Builder 中检查)。 - 如果返回 400,响应正文中的
message会包含流验证错误 — 请根据步骤 5 的失败处理表进行诊断。
5. 返回结果
成功时:
- 使用 Tooling API 查询 FlowDefinition Id — 发送
GET /services/data/vXX.0/tooling/query,查询SELECT Id, ActiveVersionId FROM FlowDefinition WHERE DeveloperName = '<FlowApiName>'。 - 打印可点击的 Flow Builder URL:
<instanceUrl>/builder_platform_interaction/flowBuilder.app?flowId=<id>。 - 列出屏幕、字段总数,以及用户需要在 Flow Builder 中接线的任何回退字段(没有
lookupObject的 Lookup、没有fileName的 FileView)。 - 打印直接启动流的 URL:
<instanceUrl>/flow/<FlowApiName>— 这是最快的验证方式,可绕过 QuickActions、布局和 Forms 选项卡。
失败时(POST 返回 400 — 从响应正文的 message 中读取错误):
- 如果出现
Cannot find component 'runtime_service_fieldservice:dcXxx'→ 组织未启用 Field Service(或组件名称有误)。显示确切错误并停止。 - 对于流验证错误,原因通常是 fs-data-capture-reference/SKILL.md 中禁止模式表所列的某种模式。重试前请先阅读该文件。常见诊断:架构分组违规、
.AllItems与.AddedItems访问器不匹配、CUD 顺序错误、缺少nextOrFinishButtonLabel、IsLlmTargetable布尔值与字符串类型不匹配。 - 未向用户说明前,重试不要超过两次。
- 常见问题:如果某个屏幕的首个字段出现在显式
{ "section": "..." }标题之前,你输出了隐式Sec_General分区,那么两个这样的屏幕会因Duplicate developer name: Sec_General而冲突。请在 JSON 中为每个此类屏幕添加显式的开头分区,然后重新组装并重新发送 POST。
6. 使表单可见(可选,但通常需要)
部署流并不会让它显示在 Service Appointment、Work Order 或其他父级记录的 "Forms" 相关列表中。若要让已部署的流显示为技术人员可领取的待处理表单:
-
将
DynamicDataCapture记录附加到父级记录。 这是 SDO 标准的“待处理表单”模式 — 请参阅已随附的 SDO 表单(Job Safety、Vehicle Inspection、Job Completion)的接线方式。通过一次 sObject 插入创建记录 — 发送POST /services/data/vXX.0/sobjects/DynamicDataCapture,请求正文如下:{ "Name": "<Display Name>", "ParentRecordId": "<ParentRecordId>", "ActionDefinition": "<FlowApiName>", "ActionType": "Flow", "ProcessType": "DataCaptureFlow", "StatusCategory": "New", "IsRequired": true, "ExecutionOrder": 1 }如果调用方未提供显示名称,
Name默认采用<FlowApiName>并将下划线替换为空格;IsRequired是布尔值(true/false),而不是字符串。返回 201 且success: true时,会返回新的 DDC id。ParentRecordId是多态字段 — 可接受的父级类型包括ServiceAppointment、ServiceResource、TimeSheet、Visit、WorkOrder、WorkOrderLineItem。 -
对于 FSL Mobile / Service Appointment 上下文,请将记录附加到父级 Work Order,而不是 SA 本身。 FSL Mobile 的 Service Appointment 上的 Forms 选项卡通常会汇总该 SA 父级 Work Order 中的
DynamicDataCapture记录(通过ServiceAppointment.ParentRecordId)。直接附加到 SA 可能不会显示在移动端。先解析 SA 的父级 Work Order Id — 发送
GET /services/data/vXX.0/query,查询SELECT ParentRecordId FROM ServiceAppointment WHERE Id = '<SA_Id>',然后将记录附加(子步骤 1)到该 Work Order Id。 -
确认父级页面布局包含 Forms(DynamicDataCapture)相关列表。 不同的 SDO 会根据配置文件使用不同的布局。使用 Tooling API 查询 — 调用
GET /services/data/vXX.0/tooling/query并执行SELECT Layout.Name, Profile.Name FROM ProfileLayout WHERE TableEnumOrId = 'WorkOrder'。Layout本身是一个 Tooling sObject,带有 JSONMetadata字段,因此此处通过 REST 读取、修改并写回 — 无需 XML 文件,也无需部署。使用GET /services/data/vXX.0/tooling/sobjects/Layout/{layoutId}读取布局(从上面的查询结果中的ProfileLayout.LayoutId解析{layoutId}),检查Metadata.relatedLists中是否存在DynamicDataCapture条目;如果不存在,则追加此条目,并使用更新后的Metadata调用PATCH /services/data/vXX.0/tooling/sobjects/Layout/{layoutId}:{ "relatedList": "DynamicDataCapture", "fields": ["Name", "StatusCategory", "IsRequired"] } -
注意事项:
- 附加的表单必须具有
StatusCategory='New',才会显示为待处理。Completed记录会显示为历史记录。 ActionDefinition必须与已部署流的 API 名称完全一致(区分大小写)。- 必须设置
ProcessType='DataCaptureFlow'— SDO 有时也会使用DiscoveryFrameworkFlow。 - 如果父级配置文件的布局缺少 Forms 列表,附加 DDC 会在数据层成功,但表单不会显示在 UI 中。
- 附加的表单必须具有
-
每个配置文件都有自己的页面布局。 实际的 SDO 通常会将不同配置文件分配到不同的 Work Order 布局(例如,
System Administrator→SDO SFS Work Order Layout、Standard User→Work Order Layout、SDO-Service→FSL Work Order Layout)。只修补一个布局无法帮助使用其他布局的用户。对需要查看表单的每个配置文件运行上面的 ProfileLayout 查询,然后修补这些布局的并集。 -
对于 FSL Mobile,DDC 和 WorkPlan 的 OWD 必须设置为 Public Read/Write。 FSL Mobile 上的 Forms 选项卡使用 UI API(
/ui-api/related-list-records/<woId>/DynamicDataCaptures),该 API 会强制执行共享规则。如果DynamicDataCapture或WorkPlan的 OWD 为 Private(平台默认值),技术人员虽然通过 AssignedResource 共享获得了 WO,但对 DDC 本身没有任何行访问权限 — UI API 会返回INSUFFICIENT_ACCESS,Forms 选项卡则会静默显示“No forms available. We couldn't find any forms to display.”,并带有“Try Again”按钮。管理员通过桌面端执行 SOQL 时不会发现此问题,因为管理员不受共享规则限制。修复方法:
- 将
DynamicDataCapture和WorkPlan的组织级默认值设为 Public Read/Write。组织级共享默认值只能在 Setup 中设置 — 提供深层链接<instanceUrl>/lightning/setup/SecuritySharing/home,并让管理员将这两个对象的 Default Internal Access 设为 Public Read/Write。(这是点击操作,不是 shell 步骤。) - 通过 Tooling PATCH 将
doesShareSaParentWoWithAr和doesShareSaWithAr设为true— 调用GET /services/data/vXX.0/tooling/query并执行SELECT Id, Metadata FROM FieldServiceSettings读取单例,然后使用{"Metadata": {"doesShareSaParentWoWithAr": true, "doesShareSaWithAr": true}}调用PATCH /services/data/vXX.0/tooling/sobjects/FieldServiceSettings/{id}(合并 — 包含现有的 Metadata 键)。 - 重新保存现有的
AssignedResource记录以触发共享重新计算 — 对每条记录调用一次空操作PATCH /services/data/vXX.0/sobjects/AssignedResource/{id},即可重新触发共享规则。 - 用户必须退出 FSL Mobile 后重新登录 — 共享快照会在登录时缓存。
使用 Tooling API 查询进行验证 — 调用
GET /services/data/vXX.0/tooling/query并执行SELECT QualifiedApiName, InternalSharingModel FROM EntityDefinition WHERE QualifiedApiName IN ('DynamicDataCapture','WorkPlan')。两者都应返回ReadWrite。如果任一返回Private,即使 DDC 行存在,技术人员也无法使用 Forms 选项卡。 - 将
-
附加后,移动端可能需要刷新。 即使 OWD 设置正确,FSL Mobile Forms 选项卡也会缓存相关列表。要显示新附加的 DDC:在 Work Order 的 Forms 选项卡上下拉刷新。如果下拉刷新后仍未显示,请强制退出并重新打开应用。只有在共享设置发生变化时(#6),才需要退出登录后重新登录。
-
UI API 版本说明(仅限测试)。 即使共享设置正确,UI API v60 仍会返回
INSUFFICIENT_ACCESS;v62+ 则可以正常工作。iOS FSL Mobile 应用将版本硬编码为 v67,因此这不是生产环境问题,但在通过 curl 重现调用时需要注意。
范围
自动生成:
- 来自规范的字段标签、类型和必填状态。
- 原生类型:
ShortText、LongText、Name、Email、Phone、Numeric、Counter(含min/max/value)、Date、DateTime、Checkbox、Toggle、Picklist、Radio(dcRbGroup)、CheckboxGroup、DisplayText、Repeater。 - 专用 Field Service 组件:
Signature(自动连线parentRecordId+recordId)、UploadFile、UploadImage、Images(自动连线recordId→parentRecordId)、Address(复合组件)、Matrix(列选项 +questions行标签)、Lookup(使用lookupObject/lookupSearchFields/lookupMulti规范键)、FileView(使用fileName规范键)。 - 单个字段的条件可见性。
- 可选的
postScreen自动化:一个决策、多个recordLookups、一个loop、多个recordCreates,以及额外的非输入变量。
回退为可安全部署的占位符(由管理员在 Flow Builder 中替换):
- 未设置
lookupObject的Lookup→dcTextInput,前缀为[Lookup — set objectApiName in Flow Builder]。 - 未设置
fileName的FileView→dcTextInput,前缀为[FileView — set fileName in Flow Builder]。
完整映射请参阅 reference/field-types.md。
不在范围内:
postScreen中的多个决策/多个循环/嵌套循环。- 子流程、公式、文本模板、赋值。
- 视觉润色 HTML(横幅、进度条、提示框)——这些需手动编写。模式请参阅
fs-data-capture-reference技能。
此技能中的文件
此技能不含可执行脚本。权限检查、记录读取、DynamicDataCapture 附加以及 Flow 创建/部署,均通过 Codey 运行时分派为单个 REST 调用(步骤 1、4、5、6)。Flow Metadata JSON 由 Agent 在步骤 3 中根据以下参考文档直接组装。
reference/flow-metadata-json.md— ToolingFlow.MetadataJSON 结构(屏幕、选项、决策、变量、屏幕后续链)以及部署/激活调用。组装 Flow 时请阅读此文档。reference/field-types.md— 输入约定:规范中的fieldType→ 运行时组件 + JSON 属性。reference/post-screen-automation.md— 可选postScreen块的输入约定。examples/sample-spec.json、examples/inventory-transfer-spec.json— 标准规范示例。
相关技能
fs-data-capture-reference(同级参考库技能)— 手动编写模式、禁止使用的模式及对应的确切部署错误、视觉润色 HTML,以及辅助 CustomObject/PermissionSet/CustomTab 部署的参考手册。诊断部署错误或扩展 JSON 字段映射时请阅读。fs-data-capture-form-designer— 生成此技能使用的规范(基于文本或图片/PDF)。fs-data-capture-form-editor— 修补组织中已部署的 Flow。它使用与此技能创建 Flow 时相同的 ToolingFlowJSON 往返流程(GET Metadata → 编辑 → PATCH)。