关于 field-service-data-capture-migrate
此技能用于将 Salesforce Field Service Mobile 屏幕流迁移到 DataCaptureFlow,结合 XML 转换、范围确认、依赖处理、验证指导和迁移摘要生成。
主要功能
- 01自动转换流 XML
- 02转换字段与执行图
- 03按顺序处理子流依赖
- 04标记不支持的元素
- 05生成迁移摘要
适用场景
- 01将旧版 Field Service 表单迁至 Data Capture
- 02转换前检查迁移候选流
- 03为利益相关者准备迁移摘要
MCP 相关
该技能说明可使用 Slack MCP 工具将迁移摘要发布为画布和消息;这是可选步骤,也可改用文件输出。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill field-service-data-capture-migrate安装后在 Claude Code 中输入/field-service-data-capture-migrate确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/sample-legacy-flow.flow-meta.xmlreferences/architecture-notes.mdcomponent-mapping.mdconverter-builder-contract.mddc-platform-rules.mdfsm-dc-capability-catalog.mdknown-deploy-errors.mdmigration-checklist.mdtransformer-rules.mdscripts/analyze_flow.pyconvert_to_dc_spec.pycud_analysis.pydeploy_flow.shdiscover_subflow_tree.pyflow_input.pyflow_xml_utils.pyfsm_dc_catalog.pygenerate_summary.pyjson_to_flow_xml.pymanual_review_flags.pyretrieve_flow_rest.shsubflow_names.pytransform_flow.pyvalidate_flow.shscripts/vendor/build_flow.py详细介绍
将 Field Service 移动端流程迁移到 Data Capture
此技能使用全自动 XML 转换器,将旧版 Field Service 移动端流程(processType='FieldServiceMobile')迁移到 DataCaptureFlow。转换器可处理所有已知的迁移模式,包括字段类型转换、执行图重构、变量去重和平台事件移除。
目标: 让 Field Service 客户不再使用 Mobile Screen Flows,转而使用 Data Capture——这是 Field Service 数字表单的战略方向。
SKILL_ROOT="${SKILL_ROOT:-${PLUGIN_ROOT:-$HOME/.vibe/skills}/field-service-data-capture-migrate}"
SCR="$SKILL_ROOT/scripts"
OUT="${FSM_OUT:-$PWD}" # *_DC files land in cwd; override via FSM_OUT.
迁移原因
| 功能 | Mobile Screen Flow | Data Capture Flow |
|---|---|---|
| 条件可见性 | 否——需通过单独的屏幕变通实现 | 是——内置,且可在单个屏幕内实现 |
| 跨字段验证 | 否——仅在点击“下一步”时验证 | 是——实时验证,立即反馈 |
| 离线 | 是——效果不错(Briefcase 预加载) | 是——更好,离线优先,支持自动保存/暂停 |
| 可重复部分 | 是——用户体验一般(循环 + 屏幕) | 是——用户体验更好(原生 Repeater) |
| 移动端用户体验 | 是——效果不错 | 是——更好,点击更少,支持屏幕内逻辑 |
| 依赖选项列表 | 是——仅限移动端 | 部分支持——仅支持条件筛选(路线图) |
| 后台完成 | 是——支持 | 否——路线图 |
| 提交后编辑表单 | 否——功能有限 | 否——路线图 |
| 面向未来 | 否——旧版路径 | 是——AI、语音转表单、持续投入 |
自动化迁移工作流
步骤 0 — 首先明确迁移范围
查询组织之前,先确定用户的意图。 如果请求含糊(例如“迁移流程”“迁移我组织中的流程”),请明确询问用户指的是某个特定流程、几个指定流程,还是组织中的所有 Field Service Mobile 流程。只有在范围明确后,才能继续执行步骤 1。 除非用户明确要求,否则绝不要查询所有流程。
步骤 1 — 发现流程
REST API 端点: GET /services/data/v67.0/tooling/query,通过 Authorization: Bearer <token> 进行身份验证。使用 curl --config——-H 会通过 ps//proc 泄露。
# All Field Service Mobile flows:
# SOQL: SELECT Id, MasterLabel, ProcessType, Status, VersionNumber FROM Flow
# WHERE ProcessType = 'FieldServiceMobile' AND Status IN ('Active','Draft')
# ORDER BY MasterLabel, VersionNumber DESC
curl -X GET "https://<instance>.my.salesforce.com/services/data/v67.0/tooling/query?q=SELECT+Id%2C+MasterLabel%2C+ProcessType%2C+Status%2C+VersionNumber+FROM+Flow+WHERE+ProcessType+%3D+%27FieldServiceMobile%27+AND+Status+IN+%28%27Active%27%2C%27Draft%27%29+ORDER+BY+MasterLabel%2C+VersionNumber+DESC" \
--config <(printf 'header = "Authorization: Bearer %s"\n' "$TOKEN")
# One or more named flows — add: AND MasterLabel IN ('Work Order Wizard', 'Asset Inspection')
响应格式:
{
"size": 2, "totalSize": 2, "done": true,
"records": [
{"Id": "301xx000000001", "MasterLabel": "Asset Inspection", "ProcessType": "FieldServiceMobile", "Status": "Active", "VersionNumber": 5}
]
}
URL 编码:空格 → +/%20,'→%27,,→%2C,(/)→%28/%29,=→%3D。
向用户展示查询结果(表格或列表)。如果用户指定了特定流程,但有任何流程未找到,请立即报告。
步骤 2 — 获取流程 XML
用户直接提供了流程文件,但没有组织访问权限? 跳过步骤 1–2——对每个文件原地执行步骤 4(先处理子流程,使用 --is-subflow),将 <Name>_DC.flow-meta.xml 写入当前目录,然后跳过步骤 5–6(仅适用于组织)。否则,从组织中获取:
mkdir -p /tmp/fsm-migration/project && cd /tmp/fsm-migration/project
echo '{"packageDirectories":[{"path":"force-app","default":true}],"namespace":"","sourceApiVersion":"67.0"}' > sfdx-project.json
# Single flow:
sf project retrieve start --metadata "Flow:<FlowApiName>" --target-org <alias>
# Multiple (comma-separated, no spaces after commas):
sf project retrieve start --metadata "Flow:<Flow1>,Flow:<Flow2>" --target-org <alias>
# All flows (ONLY if the user explicitly confirmed "all" in Step 0):
sf project retrieve start --metadata "Flow" --target-org <alias>
重要: --metadata 必须与用户在步骤 0 中选择的范围一致——除非用户明确确认,否则绝不要获取所有流程。(此步骤目前还没有等效的 REST 接口——请参阅 references/architecture-notes.md。)
步骤 3 — 验证迁移候选流程
只有同时满足 FieldServiceMobile processType 和至少包含一个 <screens> 元素的流程才是有效候选:
migratable=()
for f in force-app/main/default/flows/*.flow-meta.xml; do
base=$(basename "$f" .flow-meta.xml)
if grep -q "FieldServiceMobile" "$f"; then
if grep -q "<screens>" "$f"; then
echo "[MIGRATABLE] $base"; migratable+=("$f")
else
echo "[NO SCREENS] $base — cannot migrate (pure automation flow)"
fi
else
processType=$(grep -oP '(?<=<processType>)[^<]+' "$f" || echo "unknown")
echo "[NOT FSM] $base — processType is '$processType'"
fi
done | sort
echo "Migratable flows: ${#migratable[@]}"
如果用户指定了特定流程,但有任何流程未通过验证,请停止并报告问题——除非用户确认跳过无效流程,否则不要进行部分迁移。如果用户已确认“全部迁移”,此筛选会保留可迁移的子集——继续之前请报告数量。纯自动化流程(没有 <screens>)应保持原样或改为 AutoLaunched 流程;请标记这些流程,但不要迁移它们。
步骤 3b — 解析子流依赖树(组合流)
调用子流的流程必须从叶节点开始迁移——只有在部署集包含其引用的所有 _DC 子流后,调用方才能通过验证:
python3 "$SCR/discover_subflow_tree.py" \
force-app/main/default/flows \
force-app/main/default/flows/<CallerFlowApiName>.flow-meta.xml \
--json /tmp/fsm-migration/subflow-tree.json
| 退出码 | 含义 | 操作 |
|---|---|---|
0 | 所有节点均可迁移 | 按输出顺序进行转换(步骤 4),然后进行包验证(步骤 5) |
1 | ≥1 个依赖受阻(不是 FSM、没有屏幕、存在循环)或缺失 | 停止——不要部署调用方。 报告阻塞节点。 |
2 | 用法错误 | 传入流程目录和至少一个调用方路径(或 --all) |
使用 JSON order 数组作为步骤 4 的转换顺序,并使用文件列表执行步骤 5。
步骤 4 — 转换每个流程
OUT="${FSM_OUT:-$PWD}"; mkdir -p "$OUT"
# Input: the retrieved project path below, or just <FlowApiName>.flow-meta.xml if handed the file.
python3 "$SCR/transform_flow.py" \
force-app/main/default/flows/<FlowApiName>.flow-meta.xml \
"$OUT/<FlowApiName>_DC.flow-meta.xml"
对步骤 3b 树报告的每个 depth > 0 节点,都要传入 --is-subflow。 DataCaptureFlow 子流不能包含 Create/Update/Delete——--is-subflow 会无条件移除 CUD(而不只是调整其顺序),并通过故障路径切断预处理来处理 CUD 故障路径违规;只有顶层调用方(depth == 0)才应采用普通处理方式。对实际子流跳过此参数,会重现步骤 3b 所避免的部署失败:“You can't use Create, Update, or Delete elements in a Data Capture flow subflow”。
使用 python3 "$SCR/subflow_names.py" <FlowApiName> 生成正确的输出文件名——对于名称被覆盖的流程,简单追加 _DC 后缀无法匹配调用方重写后的引用,包试运行将会失败。
转换器会报告已转换的字段、CUD 修复和警告。不支持的元素(Apex/操作调用、子流、故障路径、自定义组件、未知字段类型)会生成 _incompleteMigration 列表和 `` XML 注释;不支持的字段槽位会变成只读的 DisplayText 占位符,绝不会静默变为 ShortText 输入。
并行批量转换——每个流程的转换彼此独立,因此应使用有界的 xargs -P4,而不是顺序循环。如果步骤 3b 生成了 subflow-tree.json,请在其中查找每个流程的 depth,以确定是否添加 --is-subflow;不在树中的流程(没有组合依赖)始终是顶层调用方:
OUT="${FSM_OUT:-$PWD}"; mkdir -p "$OUT"
TREE=/tmp/fsm-migration/subflow-tree.json
find force-app/main/default/flows -maxdepth 1 -name '*.flow-meta.xml' -print0 \
| while IFS= read -r -d '' f; do
grep -q "FieldServiceMobile" "$f" && grep -q "<screens>" "$f" && printf '%s\0' "$f"
done \
| xargs -0 -I{} -P4 bash -c '
f="{}"; base=$(basename "$f" .flow-meta.xml)
dcname=$(python3 "'"$SCR"'/subflow_names.py" "$base")
subflowFlag=""
if [ -f "'"$TREE"'" ]; then
depth=$(jq -r --arg n "$base" "(.order[] | select(.apiName == \$n) | .depth) // 0" "'"$TREE"'")
[ "$depth" -gt 0 ] 2>/dev/null && subflowFlag="--is-subflow"
fi
python3 "'"$SCR"'/transform_flow.py" "$f" "'"$OUT"'/${dcname}.flow-meta.xml" $subflowFlag 2>&1 \
| grep -E "(Transformed|SKIPPED|CUD|Warning)"
'
即使是组合树,这样做也安全——每次转换都不会读取叶节点输出(一个流程输入,一个流程输出),因此这里无需排序;步骤 3b 中从叶节点开始的顺序仅对步骤 5 的包试运行有影响。
**输出名称冲突:**两个源流程绝不能通过 subflow_names.py 解析为相同的 dcname——使用 -P4 时,这会导致并发写入同一文件。如果批次中有名称覆盖,请在转换后抽查:find "${FSM_OUT:-$PWD}" -maxdepth 1 -name '*_DC.flow-meta.xml' | sort | uniq -d。
步骤 4b — 生成迁移摘要
SUM=/tmp/fsm-migration/summaries; mkdir -p $SUM /tmp/fsm-migration/spec
find force-app/main/default/flows -maxdepth 1 -name '*.flow-meta.xml' -print0 \
| while IFS= read -r -d '' f; do
grep -q "FieldServiceMobile" "$f" && grep -q "<screens>" "$f" && printf '%s\0' "$f"
done \
| xargs -0 -I{} -P4 bash -c '
f="{}"; base=$(basename "$f" .flow-meta.xml)
python3 "'"$SCR"'/convert_to_dc_spec.py" "$f" "/tmp/fsm-migration/spec/${base}.json"
python3 "'"$SCR"'/generate_summary.py" \
"/tmp/fsm-migration/spec/${base}.json" \
"'"$SUM"'/${base}-migration-summary.md"
'
摘要会列出组件映射([OK]/[WARNING]/[ERROR] 前缀)、条件逻辑决策、不支持的组件、行为说明、离线预置警告、手动审核清单,以及明确标注的建议占位内容(AI 生成文本只能放在此处)。generate_summary.py 具有确定性,且始终会写入此 .md 文件——它既是步骤 4c 画布的输入,也是离线备用产物。
步骤 4c — 询问如何交付审核结果,然后发布
如果支持交互,务必明确询问,切勿默认选择:“将迁移摘要发布到 Slack,还是下载为 .md 文件?”无论选择哪种方式,步骤 4b 中都会生成每个流程对应的 .md 文件;这里仅决定是否同时创建 Slack canvas。
- **Slack:**询问目标频道并等待用户提供——没有频道时,绝不创建 canvas(可以提供记住的频道,但需确认)。创建 canvas 使用
slack_create_canvasMCP 工具(Python 无法调用)。对于每个流程:读取${base}-migration-summary.md,去掉开头的# Migration Summary: <formTitle>H1 标题(canvas 会单独设置标题),创建标题为Migration Summary: <formTitle>、内容为其余部分的 canvas,然后使用slack_send_message将其链接发布到频道,并记录 URL 以供步骤 7 使用。记住该频道。 - **下载文件:**提供步骤 4b 中已写入的
.md文件路径——无需执行其他操作。
**回退方案:**没有交互式用户,或 Slack 不可用 / canvas 出错时,跳转到 .md 文件路径;无论如何,本次运行均视为成功。
步骤 5 — 验证(dry-run)
可选的非破坏性部署前检查——仅在有组织别名时执行。运行前先询问(会耗费实际时间,并非输出所必需;离线运行可跳过且仍视为成功):“部署前要针对 <alias> 运行 dry-run 验证吗?(yes/no)” 如果 SE 拒绝,则按下方的退出码 3 处理:仅以 Draft 状态部署(此技能唯一会部署的状态)。
默认对一个 bundle 执行一次 dry-run,而不是对每个流程分别执行——这样部署集中的树内 _DC 子流程引用可以正常解析(单独对每个流程执行 dry-run 时,调用方引用的子流程尚未部署,会导致失败)。仅当 bundle 在多个流程上失败且需要定位问题时,才改用逐流程方式:
OUT="${FSM_OUT:-$PWD}"
set --
while IFS= read -r -d '' f; do set -- "$@" "$f"; done \
< <(find "$OUT" -maxdepth 1 -name '*_DC.flow-meta.xml' -print0)
if [ "$#" -gt 0 ]; then
"$SCR/validate_flow.sh" --bundle "<alias>" "$@"
code=$?
if [ "$code" -eq 1 ] && [ "$#" -gt 1 ]; then
echo "Bundle dry-run failed — re-running per-flow to attribute the failure(s):"
"$SCR/validate_flow.sh" "<alias>" "$@"
code=$?
fi
else
echo "No migrated flows to validate."; code=0
fi
逐流程回退时,即使调用方没有问题,引用 _DC 子流程也会失败(其子流程不在该独立部署集中)——如果已知调用方报错提示 flow doesn't exist,应将其视为这种隔离造成的假象,而非实际缺陷。
| 退出码 | 含义 | 操作 |
|---|---|---|
0 | 所有流程均通过验证 | 继续步骤 6 并部署(Draft) |
1 | 至少一个流程的 dry-run 失败或未找到文件 | 如果需要将输出部署到组织中以便手动修复,可按 Draft 状态部署;否则修复转换器缺陷并重新验证。 |
2 | 用法错误(零个参数) | 上方的存在性检查应可避免此情况 |
3 | 没有目标组织——已跳过验证 | 离线情况下属预期结果;输出有效,验证延后 |
无论 dry-run 结果如何,deploy_flow.sh 始终以 Draft 状态部署——dry-run 失败只意味着目前不值得执行部署。
可选的线上冒烟测试(手动——不在 CI 中)。 bundle dry-run 可验证脚本符合约定;在真实组织中运行一次,则可确认输出确实能够部署:
"$SCR/validate_flow.sh" <org-alias> "${FSM_OUT:-$PWD}/<FlowApiName>_DC.flow-meta.xml"
# Expected: exit 0, "PASS <FlowApiName>_DC.flow-meta.xml"
第 6 步 — 部署(启动 + 回滚快照)
OUT="${FSM_OUT:-$PWD}"
set --
while IFS= read -r -d '' f; do set -- "$@" "$f"; done \
< <(find "$OUT" -maxdepth 1 -name '*_DC.flow-meta.xml' -print0)
"$SCR/deploy_flow.sh" <alias> "$@"
deploy_flow.sh 会在写入任何内容之前,捕获每个目标流程此前组织状态的部署前回滚快照,然后仅在明确获得 SE 确认后才部署(Proceed? [y/N];无人值守演示可传入 --yes 跳过确认)。每次部署都仅为草稿——部署副本的 <status> 会被强制改写为 Draft,无论源内容如何,因此这里无法部署为 Active。激活是第 8 步的手动操作。
| 退出码 | 含义 | 操作 |
|---|---|---|
0 | 部署成功 | 继续第 7 步。会打印快照路径,以供回滚。 |
1 | 部署失败、快照查询失败,或缺少流程文件 | **停止。**查看 Status: 下的组件错误。 |
2 | 用法错误(没有流程文件) | find 未匹配到任何内容——检查输出目录 |
3 | 没有目标组织——跳过部署 | 离线时属预期情况;未写入任何内容 |
4 | SE 拒绝了确认提示 | 未写入任何内容;快照会保留以供参考 |
**回滚快照:**写入至 /tmp/fsm-migration/rollback/<timestamp>/snapshot.json,记录每个流程此前是否存在(existedBeforeDeploy),若存在,还会记录其先前的标签、活动版本和最新版本 ID。要恢复,请重新部署快照中标识的版本——但要先确认在本次部署之后没有人编辑过已部署的 _DC 流程,否则这些编辑会丢失。
**部署顺序:**先部署子流程(叶节点),再部署调用它们的流程——使用第 3b 步中 discover_subflow_tree.py 的 order 顺序。
第 7 步 — 验证并报告
# REST API: GET /services/data/v67.0/tooling/query
# SOQL: SELECT MasterLabel, Status FROM Flow
# WHERE ProcessType = 'DataCaptureFlow' AND Status IN ('Draft','Active') ORDER BY MasterLabel
curl -X GET "https://<instance>.my.salesforce.com/services/data/v67.0/tooling/query?q=SELECT+MasterLabel%2C+Status+FROM+Flow+WHERE+ProcessType+%3D+%27DataCaptureFlow%27+AND+Status+IN+%28%27Draft%27%2C%27Active%27%29+ORDER+BY+MasterLabel" \
--config <(printf 'header = "Authorization: Bearer %s"\n' "$TOKEN")
响应格式:
{
"size": 3, "totalSize": 3, "done": true,
"records": [
{"MasterLabel": "Asset Inspection_DC", "Status": "Active"}
]
}
# Functional equivalence check (runs on the SOURCE FieldServiceMobile flow, not the _DC output):
python3 "$SCR/analyze_flow.py" \
force-app/main/default/flows/<FlowApiName>.flow-meta.xml \
/tmp/fsm-migration/analysis/<FlowApiName>.json
在用户手动激活之前(第 8 步),向其说明所有警告。
批次完成后发布汇总运行报告,并采用第 4c 步中选定的交付方式。报告应包括:已迁移的流程(数量 + 名称)、每个流程的 dry-run/部署结果(按退出码)、汇总 GREEN/YELLOW/RED/SKIP 风险计数、[WARNING]/[ERROR] 组件总数,以及每个流程的报告链接/路径。
- **Slack:**发布一份汇总画布,其中链接到第 4c 步的每份流程画布,并发送至同一目标位置。
- **文件下载:**将第 4b 步中每份流程
.md文件的路径列为汇总报告——无需单独创建文件。
第 8 步 — 激活并停用旧流程
迁移后的流程只有通过以下方式才能上线——这里不会自动激活任何流程。在 Flow Builder 中完成验证并在设备上测试后:打开 DC 流程并点击 Activate,然后停用旧的 Field Service Mobile Flow(保持其非活动状态;在完全验证之前不要删除)。
转换器的工作方式
transform_flow.py 是直接进行 XML 到 XML 转换的转换器,涵盖字段类型转换、必需元素注入、标签放置以及 CUD 置于末尾的图结构重组(4 种模式,最多进行 50 次收敛迭代)——完整的字段类型映射表、自动修复列表,以及迁移后的行为变化(查找执行顺序、平台事件、确认屏幕位置、常量),请参阅 references/transformer-rules.md。
无法自动化的模式(需要在 Flow Builder 中重新设计)
| 模式 | 无法自动化的原因 | 建议的重新设计 |
|---|---|---|
| 无屏幕(纯自动化) | DataCaptureFlow 至少需要一个屏幕 | 保留为 Field Service Mobile Flow,或转换为 AutoLaunchedFlow |
| 循环中包含屏幕 | DC 不支持在循环中使用屏幕(会检测并发出警告) | 将循环 + 屏幕替换为 DC 原生的 Repeater 字段 |
| 查找依赖于刚创建的记录 | Create → Get (by new ID) → Create again 循环;DC 要求所有 CUD 操作都在最后执行 | 在屏幕之前完成所有查找,将结果累积到变量中,并在最后批量创建 |
| CUD 操作后显示确认屏幕 | DC 要求屏幕在 CUD 操作之前 | 将其移至 CUD 操作前的摘要屏幕,或使用 DisplayText 预览将要保存的内容 |
| 需要在后台系统 / 桌面端完成 | DC 表单只能在 FSL Mobile 上完成(已列入路线图) | 在路线图功能发布前,保留为 Field Service Mobile Flow |
| 完整的依赖项选项列表 | DC 目前仅支持条件筛选(已列入路线图) | 使用条件可见性作为替代方案 |
迁移风险分类
| 风险 | 标准 | 是否自动化? |
|---|---|---|
| GREEN | 循环中没有屏幕、没有创建→查找循环、没有平台事件 | 是 — 完全自动化 |
| YELLOW | 平台事件、提升到屏幕后的查找、常量、隐藏字段上的 isRequired,或复杂的 DisplayText 公式 | 是 — 自动化并发出警告,激活前需审核 |
| RED — 可重构 | 图重构器可自动修复的 CUD 违规 | 是 — 自动化,转换器会解决这些问题 |
| RED — 需要重新设计 | 循环中包含屏幕、创建→查找循环、Range 滑块字段 | 否 — 需要在 Flow Builder 中手动重新设计 |
| SKIP | 没有屏幕 — 纯自动化流程 | 否 — 不适用于 DataCaptureFlow |
有关权威的 DataCaptureFlow 平台规则(必需的标头、结构规则、访问器后缀、DisplayText 限制、Repeater 详情、全局变量允许列表),请在调试部署错误或手动验证迁移后的流程时查阅 references/dc-platform-rules.md。有关实际部署错误及其修复方法的表格,请参阅 references/known-deploy-errors.md。有关上述哪些步骤仍需要使用 sf CLI 而非 REST,以及原因,请参阅 references/architecture-notes.md。
激活前的检查事项
部署后,在 Flow Builder 中打开每个 DC 流程并验证:
- 检查转换器警告 — 任何按屏幕字段筛选的提升查找都需要手动处理
- 移除平台事件 — 如果原流程触发了实时调度器事件,请规划替代触发器(Apex 或 AutoLaunched 流程)
- 隐藏字段上的
isRequired— 对于转换器标记的字段,清除isRequired并改用validationRule - DisplayText 公式 — 在 Assignment 中预先计算
IF/CASE/ 日期运算结果,并改为引用简单变量 - 计算时机 — 确认计算元素位于显示屏幕之前的屏幕上,而不是与其位于同一屏幕上
- 屏幕顺序和标签 — 确认调整后的屏幕顺序仍然合理
- 查找显示 — 确认 Lookup 字段显示正确的标签;如有需要,调整 Primary Compact Layout
Range滑块字段 — 手动替换为dcNumeric或dcCounter- 在 FSL Mobile 上测试 — 在设备上端到端完成表单
- 测试离线场景 — 开启飞行模式并完成表单 → 重新连接 → 验证同步
此技能中的文件
scripts/transform_flow.py— 主要迁移工具;直接将 XML 转换为 XML。对每个源流程运行(步骤 4)。scripts/subflow_names.py— 迁移后子流程命名规则的唯一真实来源;由transform_flow.py和discover_subflow_tree.py导入。scripts/discover_subflow_tree.py— 传递式子流程依赖发现工具;生成由叶节点优先的顺序,并将每个节点分类为可迁移/受阻/缺失(步骤 3b)。scripts/analyze_flow.py— 风险评估工具;对源流程运行,生成 JSON,且不会修改源流程(步骤 7)。scripts/convert_to_dc_spec.py— 用于迁移摘要的规范转换器(步骤 4b);其 JSON 输出必须符合scripts/vendor/build_flow.py的输入契约(参见references/converter-builder-contract.md)。scripts/generate_summary.py— 根据规范 JSON 生成易读的migration-summary.md(步骤 4b);结果确定,无需联网。scripts/validate_flow.sh— 封装sf project deploy start --dry-run的试运行验证器;退出码0=全部通过,1=至少一项失败,2=用法错误,3=已跳过(无组织)(步骤 5)。scripts/deploy_flow.sh— 启动部署并创建回滚快照;退出码0=已部署,1=失败,2=用法错误,3=已跳过,4=SE 已拒绝(步骤 6)。scripts/fsm_dc_catalog.py— FSM↔DC 功能对等关系的权威目录;此处的FIELD_TYPE_MAP必须与references/transformer-rules.md中的映射表保持同步。scripts/cud_analysis.py、scripts/flow_input.py、scripts/flow_xml_utils.py、scripts/json_to_flow_xml.py、scripts/manual_review_flags.py— 由上述脚本导入的共享内部模块。scripts/retrieve_flow_rest.sh— 实验性的基于 REST 的流程检索脚本;尚未接入步骤 2(参见references/architecture-notes.md)。scripts/vendor/build_flow.py— 随附的 Data Capture 构建脚本,供convert_to_dc_spec.py按契约调用。references/fsm-dc-capability-catalog.md—fsm_dc_catalog.py的易读版本;是判定支持与否的真实来源。references/component-mapping.md— 组件等效关系表(与上述目录配套)。references/converter-builder-contract.md—convert_to_dc_spec.py与build_flow.py之间的权威 JSON 契约。references/migration-checklist.md— 部署后测试的手动验证清单。assets/sample-legacy-flow.flow-meta.xml— 用于端到端试运行转换器的典型旧版FieldServiceMobile流程。