关于 consumer-goods-accruals-datakit-deploy
此 Skill 引导将 TPM Liability Accruals 端到端部署到 Salesforce 组织,涵盖就绪检查、部署验证和任务调度。它通过内置脚本执行流程,并要求所有退出路径都生成 Phase 6 报告。
主要功能
- 01Salesforce 组织就绪检查
- 02验证 Data Cloud 连接
- 03部署数据套件和元数据
- 04验证部署日志
- 05安排导出与应计计算
- 06所有结果均生成 Phase 6 报告
适用场景
- 01向组织部署 TPM Liability Accruals
- 02检查部署状态并报告失败
- 03部署前执行试运行
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill consumer-goods-accruals-datakit-deploy安装后在 Claude Code 中输入/consumer-goods-accruals-datakit-deploy确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
scripts/setup.jsscripts/steps/00-check-prerequisites.js01-download-static-resource.js02-replace-org-id.js03-deploy-metadata.js04-deploy-engine.js05-deploy-tpm-accruals.js06-create-dataspace.js07-deploy-accruals-reports.js08-deploy-ui.js09-completion.jsutils.js详细介绍
强制要求:始终编写 Phase 6 报告
完成所有阶段后——包括提前停止、阶段受阻或出现错误的情况——你都必须将 Phase 6 报告写入磁盘。未能写入报告始终属于测试失败,无论你对场景的处理有多好。
这适用于所有退出路径,无一例外:
- 正常完成(运行了所有阶段)
- Phase 1 停止(预检失败、未找到销售组织、缺少 CGCloudAddons、未启用 Data Cloud)
- Phase 3 错误(设置脚本以非零状态退出)
- Phase 4 检测到失败(DataKitDeploymentLog 中存在失败)
- 计划冲突(触发 Phase 5 守卫)
- 任何其他阻塞条件(缺少输入、组织无法访问等)
将报告写入 ${outputDir}/report.md(任务中 generatedFileLocationDirective 指定的路径)。不要只将报告作为聊天消息输出——它必须作为文件存在于磁盘上。如果你正确处理了场景,却没有写入文件,评估将记录为 no_output,得分为零。
部署 Accrual Data Kit
将 TPM Liability Accruals 解决方案端到端安装到 Salesforce 组织中。
运行 scripts/ 中打包的完整设置工具链:检查组织是否就绪、
验证 Data Cloud 连接、下载 CGCloudAddons 静态资源、
部署数据工具包、确认部署,并安排 Data Cloud 导出
和应计计算链。
专为无头交付设计:指定一个组织,即可运行完整安装流程。
命名空间因构建版本而异:cgcloud(已发布)、cgcloud_dev(开发版/测试版),或无前缀(仅源代码)。设置脚本会在运行时通过查询 DataCloudExportScheduler Apex 类自动检测前缀。切勿硬编码 cgcloud. 或 cgcloud_dev.。
参考:TPM 应计引擎概念
从技能根目录运行设置脚本:
node scripts/setup.js --org <alias> [options]
收集输入
运行任何 Phase 1 检查之前,先收集并验证所有必需输入。 在确认组织别名和销售组织名称之前,不要开始 Phase 1。如果询问后仍有任一项缺失,立即停止并编写 Phase 6 报告。
开始前先询问——不要猜测。
| 输入 | 默认值 | 备注 |
|---|---|---|
| 组织别名/用户名 | — | 目标组织的 sf 别名。必需。 |
| 销售组织名称 | — | 用于命名 Data Space(DataSpace_<salesOrg>)、其前缀(DS<lastChar>_)以及 UI 控制器映射键。必需。必须恰好为 4 个字母或数字(例如 0001、AB12)。如果用户尚未提供且无法提供,请勿猜测或使用任何默认值——立即停止,编写 Phase 6 报告,并将 Phase 1 标记为受阻(“未提供销售组织名称”),然后结束会话。没有该名称时,不得运行任何 Phase 1 检查。 |
| 跳过 Data Space? | 否 | 仅当组织没有 Data Space 时选择“是”(某些演示组织属于这种情况)。 |
| 试运行? | 否 | 准备文件;跳过所有部署和计划安排。优先提供此选项。 |
| 命名空间覆盖值 | 自动检测 | 仅在自动检测失败时传入。值末尾不得带 __。 |
| 导出 cron | 0 0 2 * * ? | 仅当用户要求不同的计划时才询问。 |
| 应计链 cron | 0 0 3 * * ? | 仅当用户要求不同的计划时才询问。 |
试运行标记在此处收集一次,并在所有阶段中遵循——不要重复询问。
Phase 1 — 预检
首次失败时立即停止。检查失败后不得继续。
1.1 本地工具
- 已安装 Salesforce CLI:
sf --version - Node 22:
node --version
1.2 组织可访问
sf org display --target-org <alias> --json
确认 status 为 Active。记录 id(组织 ID)、instanceUrl、apiVersion。
命令以非零状态退出或状态非活动 → 停止,并请用户登录。
1.3 确认 Data Cloud Data Kit 框架已存在
sf data query --target-org <alias> \
--query "SELECT Id FROM DataKitDeploymentLog LIMIT 1"
INVALID_TYPE 或 NOT_FOUND → 立即停止:此组织未启用 Data Cloud Data Kit 框架。告知用户必须先启用 Data Cloud 和 Data Kit 功能,才能继续此技能。立即编写 Phase 6 报告,并将 Phase 1 标记为受阻,同时注明确切的查询错误。不要运行任何后续查询、下载或部署。
零行结果正常——框架已存在,继续执行 Phase 1.4。
1.4 确认 CGCloudAddons 静态资源已存在
sf data query --target-org <alias> \
--query "SELECT Id FROM StaticResource WHERE Name='CGCloudAddons'"
零行结果 → 立即停止:未安装托管软件包(或此版本未包含 CGCloudAddons)。告知用户必须先安装该软件包才能继续。立即编写 Phase 6 报告,并将 Phase 1 标记为受阻:CGCloudAddons not found。此失败后,不要尝试下载、部署或安排任何任务。
1.5 验证销售组织
sf data query --target-org <alias> --json \
--query "SELECT Id, Name FROM Sales_Organization__c WHERE Name = '<salesOrg>'"
零行结果 → 立即停止:用户提供的销售组织名称在此组织中不存在。向用户展示查询和零行结果。不要继续部署或安排任务。
将 Phase 1 记录为受阻:Sales org '<salesOrg>' not found。
1.6 部署基线
sf data query --target-org <alias> --json \
--query "SELECT MAX(CreatedDate) maxCreated FROM DataKitDeploymentLog"
聚合查询始终恰好返回一行。表为空(首次部署)时,maxCreated 为 null。存储 DEPLOY_BASELINE_TIME = maxCreated ?? ''(将 null 视为空字符串)。仅当 DEPLOY_BASELINE_TIME 非空时,Phase 4 才使用 WHERE CreatedDate > DEPLOY_BASELINE_TIME;为空时,完全省略 WHERE 子句——在 Salesforce SOQL 中,WHERE CreatedDate > null 会导致 INVALID_QUERY_FILTER_OPERATOR 错误,并中止查询。
1.7 组织端手动前置条件
如果用户的提示词已确认这些前置条件,则视为已确认——不要再次询问。只询问用户尚未说明的项目:
- 已启用 Data Cloud 和 Analytics Studio(Setup → Data Cloud Setup)
- 已启用 Connectors 功能(Data Cloud Setup → Feature Manager)
- 在 Processing Services Pairing 中分配给 Accrual Ingestion Process,且拥有 Data Cloud Architect 权限集的用户
- TPM Offcore 已连接应用的 OAuth 范围
cdp_ingest_api - 许可证:
AccrualsProcessingAddOn、AccrualsProcessingUserAddOn、TpmAccrualsAddOn、TpmAccrualsUserAddOn(仅供参考——记录用户确认的内容)
Phase 2 — 验证 Data Cloud 连接(尽力而为)
尝试通过查询验证 cdp_ingest_api——将“无法验证”视为 WARN,而非 STOP:
sf data query --target-org <alias> \
--query "SELECT Id, Name FROM ConnectedApplication WHERE Name LIKE '%TPM%'"
如果查询因权限而出错,请用户确认 cdp_ingest_api 是否位于 Setup → App Manager →(编辑 TPM Offcore 已连接应用)→ OAuth Policies → Selected OAuth Scopes 中。仅在用户确认后继续。
第 3 阶段 — 运行设置脚本
从技能自身的根目录运行端到端设置脚本。在试运行模式下,传入 --dry-run。
node scripts/setup.js --org <alias> --sales-org <salesOrg> [--skip-dataspace] [--dry-run] [--namespace <ns>]
如果当前工作目录中无法访问 scripts/setup.js,请在第 6 阶段报告中将第 3 阶段记录为
not run — script path not accessible in this environment,并直接继续第 4 阶段(查询 DataKitDeploymentLog 中 DEPLOY_BASELINE_TIME 之后的所有行)。
脚本按以下顺序执行这些步骤:
- 步骤 0 — 确认先决条件(交互式提示,试运行时跳过)
- 步骤 1 — 下载
CGCloudAddons静态资源 - 步骤 2 — 替换数据工具包元数据中的
__SF_ORG_ID__占位符 - 步骤 3 — 部署 TPM Accruals 数据工具包元数据(
sf project deploy start) - 步骤 4 — 通过
sfdatakit__DeployDataKitComponents部署 Liability Accruals Engine 数据工具包 (跳过已部署的组件;等待完成最多 30 分钟) - 步骤 5 — 通过
sfdatakit__DeployDataKitComponents部署 TPM Accruals 数据工具包 (同样的模式;也会等待完成) - 步骤 6 — 创建 Data Space(手动提示 — 见下文;使用
--skip-dataspace时跳过) - 步骤 7 — 部署 Accruals Reports 元数据并替换 Data Space 占位符(两次传递)
- 步骤 8 — 部署
TPMAccrualTacticSummaryUI 组件并替换命名空间和 Data Space - 步骤 9 — 打印计划安排说明
脚本会在步骤 0(确认先决条件)和步骤 6(创建 Data Space)暂停。暂停时,捕获从 === Step N: 开始的 stdout 区块,并原样转达给用户。等待用户完成该步骤后再继续。
将 TPMAccrualTacticSummary UI 组件添加到 Promotion 页面是运行后的手动步骤 — 脚本只会打印相关说明。在第 6 阶段将其跟踪为待处理事项。
退出代码非零时 → 停止并展示 stdout 的最后 50 行。脚本失败时不要继续第 4 阶段。
第 4 阶段 — 验证部署
试运行模式下跳过整个阶段。 在报告中将其记录为 pending — not run (dry-run)。
sf data query --target-org <alias> --json \
--query "SELECT ComponentName, DeploymentStatus, DeploymentError, CreatedDate
FROM DataKitDeploymentLog
WHERE CreatedDate > ${DEPLOY_BASELINE_TIME}
ORDER BY CreatedDate ASC
LIMIT 200"
(如果 DEPLOY_BASELINE_TIME 为空,则省略 WHERE 子句。始终包含 LIMIT 200。)
评估这些行:
- 任何
DeploymentStatus = 'Failure'或非空的DeploymentError→ 停止,列出每个失败组件的名称及其DeploymentError值。不要继续第 5 阶段。 在第 6 阶段报告中将第 5 阶段记录为not run — deployment failures unresolved。 - 任何
InProgress行 → 等待 60 秒后重新查询。在所有行都处于终止状态(Successful或Failure)之前,不要进入第 5 阶段。如果 30 分钟后仍有任何行处于InProgress,则停止并报告实时计数。 - 零行 → 部署尚未生成日志条目;每隔 60 秒重新查询,最多 30 分钟。若持续返回零行,则视为部署问题 — 停止并报告。
- 所有行均为
Successful→ 继续第 5 阶段。 - 在任何行处于
InProgress、Failure状态时,或在轮询时限内返回零行时,绝不要进入第 5 阶段。
第 5 阶段 — 计划安排
试运行模式下:仍然执行步骤 5.1(检测命名空间 — 只读)和 5.2(检查 cron 作业 — 只读),打印替换完整的 Apex 代码,但不要执行 sf apex run。在报告中将第 5 阶段记录为 pending — not run (dry-run)。
5.1 检测命名空间前缀
查询已安装的类(使用与 scripts/steps/utils.js 相同的探测方法):
sf data query --target-org <alias> --json \
--query "SELECT NamespacePrefix FROM ApexClass WHERE Name='DataCloudExportScheduler'"
| 查询结果 | NS_PREFIX | 含义 |
|---|---|---|
| 0 行 | — | Scheduler 类未部署 → 停止:第 3 阶段未完成 |
| 1 行,值为 null | "" | 未托管源代码部署 |
| 1 行,任意值 | 该值 | 使用查询返回的任何命名空间 |
| >1 行 | — | 存在歧义 → 停止,打印所有行 |
组合点分隔的前缀:
NS="${NS_PREFIX:+${NS_PREFIX}.}" # yields "cgcloud.", "cgcloud_dev.", or ""
以下每个 Apex 标识符都写作 ${NS}ClassName。
5.2 防止重复的 cron 作业
sf data query --target-org <alias> --json \
--query "SELECT Id, State, CronJobDetail.Name FROM CronTrigger
WHERE CronJobDetail.Name IN
('DataCloud Export Daily','TPM Accrual Process Chain')"
如果存在匹配的作业:
- 向用户展示每个冲突作业现有的
Id和State。 - 明确询问:中止现有作业并重新安排,还是跳过安排?
- 不要静默覆盖——在调用
System.schedule前等待用户回答。 - 如果用户选择中止并重新安排:对每个冲突作业运行
System.abortJob('<id>'),然后继续执行 5.3/5.4,并验证新的CronTrigger显示State = 'WAITING'且NextFireTime非空。 - 在 Phase 6 报告中记录冲突及其处理结果。
**Cron 顺序要求:**导出作业(5.3)必须先于应计链作业(5.4)触发,以便链运行时 Data Cloud 数据已就绪。默认值(exportCron = 0 0 2 * * ?,accrualCron = 0 0 3 * * ?)确保间隔 1 小时。用户提供自定义表达式时,请验证导出 cron 先于应计 cron——建议间隔至少 1 小时。如果两个表达式冲突或顺序颠倒,请警告用户;未经用户确认,不要安排作业。
5.3 安排 Data Cloud Connector 导出
将以下 Apex 写入临时文件(例如 /tmp/dc-export.apex),运行后删除该文件:
${NS}DataCloudExportScheduler scheduler = new ${NS}DataCloudExportScheduler(
new List<String>{ 'promotionmeasures', 'paymenttacticmeasures', 'dailymeasurereal' }
);
System.schedule('DataCloud Export Daily', '<exportCron>', scheduler);
# Write to temp file, run, clean up
cat > /tmp/dc-export.apex << 'EOF'
<filled-in Apex from above>
EOF
sf apex run --target-org <alias> --file /tmp/dc-export.apex
rm /tmp/dc-export.apex
验证:CronTrigger WHERE CronJobDetail.Name = 'DataCloud Export Daily' → 恰好一行,State = 'WAITING',且 NextFireTime 非空。
5.4 安排应计计算链
将以下 Apex 写入临时文件(例如 /tmp/accrual-chain.apex),运行后删除该文件(参见 Rules — ingestionMode 仅允许使用 'partial' 或 'full'):
${NS}ScheduleTPMAccrualProcessChain scheduler =
new ${NS}ScheduleTPMAccrualProcessChain();
System.schedule('TPM Accrual Process Chain', '<accrualCron>', scheduler);
# Write to temp file, run, clean up
cat > /tmp/accrual-chain.apex << 'EOF'
<filled-in Apex from above>
EOF
sf apex run --target-org <alias> --file /tmp/accrual-chain.apex
rm /tmp/accrual-chain.apex
使用与 5.3 相同的 CronTrigger 模式进行验证。
参考:
Phase 6 — 报告
**每次运行后都要撰写此报告,包括提前停止的情况。**如果执行在 Phase 1 受阻(缺少输入、预检失败、未启用 Data Cloud、未找到销售组织),请在确认停止条件后立即撰写报告——不要跳过。如果正确处理提前停止,却没有生成 report.md 文件,将被判定为失败。如果你处于带有文件输出指令的 Agent 评估环境中,该指令的意思是“完成后写入文件”,而不是“写入文件而不执行任务”。
使用 shell 命令将报告写入磁盘(例如,使用 Write 工具或 cat > <path>)。不要只将其作为聊天消息输出——报告必须作为文件存在于任务指令指定的路径。
**提前停止的报告应简短。**如果执行在 Phase 3 开始前受阻(缺少输入、预检失败),报告只需涵盖实际发生的情况:受阻原因、未执行的内容,以及用户重试时必须提供的信息。不要用从未执行的阶段的套话充斥提前停止报告(详细的 DataKit 部署行、计划冲突处理、许可证警告、手动步骤)。只有执行了相应阶段时,这些部分才相关。Phase 1 受阻时,3–5 行的报告即可。
Deployment report — <org alias, or "not provided">
Sales org: <salesOrg, or "not provided">
Dry run: <yes|no>
Namespace prefix: <detected value, or "(not detected — execution blocked)">
Phase 1 preflight: <passed | blocked: <exact check that failed>>
DataKit deployments: <X succeeded / Y failed / Z in progress, or "not run — Phase 1 blocked">
Data Space: <created | skipped | not run — Phase 1 blocked>
Data Cloud Export: <scheduled | dry-run | not run — Phase 1 blocked>
Accrual Chain: <scheduled | dry-run | not run — Phase 1 blocked>
Pending manual steps: <list, or "none — execution did not complete">
License warnings: <unconfirmed licenses, or "none — not checked">
规则
- 始终先执行,再报告。 完成所有阶段(或达到有记录的停止条件)后,才能撰写第 6 阶段报告。绝不能用报告代替执行此技能——文件输出指令的意思是“完成后再写”,而不是“写报告代替实际操作”。
- 重新运行就意味着重新运行。 当用户要求重新运行或验证现有部署时,始终重新执行
node scripts/setup.js,并在此之前捕获新的DataKitDeploymentLog基线。不要将之前成功的运行视为充分依据——必须根据本次运行产生的新日志行重新验证。 - 如果本次运行的任何
DataKitDeploymentLog行满足DeploymentStatus = 'Failure'或DeploymentError非空,绝不能宣称成功。 - 只有当
CronTrigger显示State = 'WAITING'且NextFireTime不为 null 时,才能宣称计划任务成功。 - 首个预检失败时立即停止;报告确切的失败原因。
- 必须逐字转达设置脚本标准输出中的手动操作说明,并等待用户回应。
- 输出的 Apex 中绝不能硬编码命名空间前缀——始终使用
${NS}组合。 ingestionMode仅接受'partial'或'full';'initial'会抛出异常。