mcpField
P
platform-custom-field-generate

platform-custom-field-generate

github.com/forcedotcom开发1.1k6.6k 次安装1 天前更新
代码仓库

关于 platform-custom-field-generate

用于生成和校验 Salesforce CustomField 元数据 XML 的技能,面向需要部署字段的用户。重点处理关系字段、汇总字段、选项列表等容易导致部署错误的约束。

主要功能

  1. 01生成 CustomField 元数据 XML
  2. 02校验字段类型要求
  3. 03应用 Master-Detail 限制
  4. 04处理 Roll-Up Summary 规则
  5. 05支持高级选项列表配置

适用场景

  1. 01创建可部署的自定义字段元数据
  2. 02构建 Master-Detail 关系
  3. 03定义汇总计算字段
  4. 04配置内联或引用选项列表

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/forcedotcom/sf-skills --skill platform-custom-field-generate

安装后在 Claude Code 中输入/platform-custom-field-generate确认已加载。

附带文件references/advanced-picklists.md

详细介绍

Salesforce 自定义字段生成器和验证器

概述

生成并验证 Salesforce CustomField 元数据 XML,并对失败率最高的类型——汇总摘要和主从关系——进行特殊处理。Agent 必须在输出 XML 前验证以下约束,以避免 Metadata API 部署错误。


1. 通用必需属性

每个生成的字段都必须包含以下标签:

属性要求说明
<fullName>必需仅限字段名称:根据 <label> 生成——将每个单词首字母大写,将空格替换为 _,并追加 __c。必须以字母开头。例如,标签 Total Contract Value → Total_Contract_Value__c。此规则适用于字段名称。Picklist 值的 <fullName> 不同——必须完全按用户输入保留,包括空格,不加 __c(例如,Closed Won,而不是 Closed_Won)。参见 references/advanced-picklists.md(参考 §3)。
<label>必需UI 名称(标题式大小写)
<description>始终包含说明此字段存在的业务原因。
<inlineHelpText>始终包含为最终用户提供可操作且超出标签信息的指导(例如,“输入含税的 USD 金额”,而不是“金额”)。

尽管 Metadata API 不强制要求 <description> 和 <inlineHelpText>,但它们仍是必需的——省略会导致元数据质量低下。

文件路径(SFDX 源格式): 将每个字段保存为 force-app/main/default/objects/<Object>/fields/<FieldName>__c.field-meta.xml,其中 <Object> 是对象的 API 名称(Account、Opportunity 或自定义对象 Inventory_Item__c)。XML 正确但路径错误时,Metadata API 将无法找到它。

外部 ID 配置

触发条件: 如果用户提及“集成”“导入数据”“外部系统 ID”或“来自 [System Name] 的唯一键”,则设置 <externalId>true</externalId>。

适用类型: Text、Number、Email


2. 精度、小数位数和长度规则

为确保部署成功,请遵循以下数学约束:

精度与小数位数规则
  • precision 表示总位数;scale 表示小数位数
  • 规则: precision ≤ 18 且 scale ≤ precision
  • 计算: 小数点左侧的位数 = precision - scale
“固定为 255”规则

TextArea:不要包含 <length>——API 会将其隐式固定为 255,并拒绝显式指定的值(“Can not specify 'length' for a CustomField of type TextArea”)。该字段只需要 <fullName>、<label> 和 <type>TextArea</type>。

可见行数

长文本/富文本字段和多选列表必须设置可见行数,以控制 UI 高度。


3. 字段数据类型

3.1 简单属性类型
类型<type> 值必需属性
自动编号AutoNumberdisplayFormat(必须包含 {0})、startingNumber
复选框Checkbox将 defaultValue 默认设为 false
日期Date无需指定精度/长度
日期/时间DateTime无需指定精度/长度
电子邮件Email内置格式验证
查找关系LookupreferenceTo、relationshipName、deleteConstraint
主从关系MasterDetailreferenceTo、relationshipName、relationshipOrder
数字Numberprecision、scale
货币Currency默认精度:18,默认小数位数:2
百分比Percent默认精度:5,默认小数位数:2
电话Phone标准化电话号码格式
选项列表PicklistvalueSet,其中包含 valueSetDefinition(内联)或 valueSetName(引用)二者之一;restricted(参见下文“选项列表 restricted 默认值”;高级情况见 §3.4)
文本Textlength(最多 255)
文本区域TextArea无——不要包含 <length>;API 会将长度隐式固定为 255
长文本LongTextArealength、visibleLines(默认值为 3)
富文本Htmllength、visibleLines(默认值为 25)
时间Time仅存储时间(不含日期)
URLUrl验证协议和格式
3.2 计算类型和多值类型
类型<type> 值必需属性
公式结果类型(例如 Number)formula、formulaTreatBlanksAs
汇总汇总Summary完整要求见第 5 节
多选选项列表MultiselectPicklistvalueSet、visibleLines(默认值为 4)
3.3 专用类型
类型<type> 值必需属性
地理位置Locationscale、displayLocationInDecimal
选项列表 restricted 默认值

除非用户明确说明选项列表应接受管理员定义列表以外的自定义值(例如“非受限”/“开放”),否则始终在 <valueSet> 中设置 <restricted>true</restricted>。受限选项集的总值数量上限为 1,000(包括启用和停用的值)。最简内联结构:

<valueSet>
  <restricted>true</restricted>
  <valueSetDefinition>
    <sorted>false</sorted>
    <value><fullName>Option_A</fullName><default>false</default><label>Option A</label></value>
  </valueSetDefinition>
</valueSet>
3.4 高级选项列表

上面的内联 <valueSetDefinition> 是简单情况。以下所有内容的完整规则以及正确和错误示例,请参阅 references/advanced-picklists.md — 遇到任何 非简单选项列表时都应加载该文件。下文括号中的章节编号(例如“参考 §1”)指向该 参考文件,而非此技能。硬性规则:

  • 选项集引用(参考 §1)。 <valueSet> 只能包含 <valueSetName>(引用)或 <valueSetDefinition>(内联定义)之一——绝不能同时包含两者。引用时使用不带后缀的 开发者名称——标准选项集 Industry、GlobalValueSet Priority_Levels,不要加 __gvs 或 __c(__gvs 后缀仅用于组织存储显示;Metadata API 使用不带后缀的名称)。基于选项集的 字段必须设置为 <restricted>true</restricted>。创建选项集是 platform-value-set-generate 技能的职责;此技能只负责引用。
  • 选项名称须保持原样(参考 §3)。 选项列表值的 <fullName>/<label> 必须保留用户输入的 原文,包括空格(Closed Won,绝不要写成 Closed_Won)。空格转换为 _ 并添加 __c 的规则仅适用于 字段名称。
  • 依赖选项列表(参考 §2)。 使用现代 API 38.0+ 格式:<controllingField> + 每组对应一个 <valueSettings>(包含 <controllingFieldValue>+<valueName>);绝不要使用旧版 <picklist>/<picklistValues>/<controllingFieldValues> 标签。控制字段和依赖字段都必须设置为 <restricted>true</restricted>,即使请求中未提及。
  • 增强选项属性(参考 §3)。 <value> 条目还支持 <color>(十六进制,带前导 #)、<isActive>(false 表示停用该选项)以及选项级别的 <description>。
  • 将选项列表限定到记录类型(参考 §5)。 按记录类型控制选项可见性,要在 RecordType 上设置(使用 <picklistValues>),而非字段上。RecordType 文件包含其自身的 <fullName>(不带后缀的开发者名称)。首先判断对象是否需要 BusinessProcess: 只有 Opportunity / Lead / Case / Solution 需要;缺少 <businessProcess> 时将无法部署 (Required field is missing: businessProcess),即使只筛选了自定义选项列表也一样。对于这些对象,需要输出两个关联文件:businessProcesses/<Name>.businessProcess-meta.xml 文件,以及 <RecordType> 中对应的 <businessProcess><Name></businessProcess>(位于 <active> 之后、<picklistValues> 之前;BP 文件中的 <fullName> 必须不带对象限定名)。自定义对象(*__c)和所有其他标准对象(Account、Contact……) 均不需要 BusinessProcess — 只输出 RecordType;不要自行添加。 范围限制: 仅限按记录类型控制选项值的可见性——不包括常规记录类型编写(紧凑布局、页面布局、品牌设置)。

4. 主从关系规则(重要)

主从字段有严格的属性限制,与查找字段不同。违反这些规则会导致部署失败。

主从字段上的禁止属性

主从字段上绝不能包含以下属性:

禁止的属性原因后果
<required>主从关系按设计始终为必填部署错误
<deleteConstraint>主从关系始终级联删除部署错误
<lookupFilter>仅查找字段支持部署错误
主从关系与查找字段对比
属性主从关系查找
<required>禁止可选
<deleteConstraint>禁止(始终为 CASCADE)必填(SetNull、Restrict、Cascade)
<lookupFilter>禁止可选
<relationshipOrder>必填(0 或 1)不适用
<reparentableMasterDetail>可选不适用
<writeRequiresMasterRead>可选不适用
错误 — 带有禁止属性的主从关系:
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
  <fullName>Account__c</fullName>
  <type>MasterDetail</type>
  <referenceTo>Account</referenceTo>
  <relationshipName>Contacts</relationshipName>
  <relationshipOrder>0</relationshipOrder>
  <required>true</required>                     
  <deleteConstraint>Cascade</deleteConstraint>  
  <lookupFilter>...</lookupFilter>              
</CustomField>

错误: Master-Detail Relationship Fields Cannot be Optional or Required · Can not specify 'deleteConstraint' for a CustomField of type MasterDetail · Lookup filters are only supported on Lookup Relationship Fields

正确 — 主从关系字段:
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
  <fullName>Account__c</fullName>
  <label>Account</label>
  <description>Links this record to its parent Account</description>
  <type>MasterDetail</type>
  <referenceTo>Account</referenceTo>
  <relationshipLabel>Child Records</relationshipLabel>
  <relationshipName>ChildRecords</relationshipName>
  <relationshipOrder>0</relationshipOrder>
  <reparentableMasterDetail>false</reparentableMasterDetail>
  <writeRequiresMasterRead>false</writeRequiresMasterRead>
  
</CustomField>
正确 — 查找字段(含可选属性):
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
  <fullName>Related_Account__c</fullName>
  <label>Related Account</label>
  <description>Optional link to a related Account</description>
  <type>Lookup</type>
  <referenceTo>Account</referenceTo>
  <relationshipLabel>Related Records</relationshipLabel>
  <relationshipName>RelatedRecords</relationshipName>
  <required>false</required>
  <deleteConstraint>SetNull</deleteConstraint>
  <lookupFilter>
    <active>true</active>
    <filterItems>
      <field>Account.Type</field>
      <operation>equals</operation>
      <value>Customer</value>
    </filterItems>
    <isOptional>false</isOptional>
  </lookupFilter>
</CustomField>
其他主从关系规则
  • 关系顺序: 对象上的第一个主从关系 = 0,第二个 = 1
  • 关系名称: 必须是复数形式的 PascalCase 字符串(例如,Travel_Bookings)
  • 连接对象: 对于标准多对多关系,使用两个主从关系字段(可启用汇总)
  • 限制: 每个对象最多有 2 个主从关系。其他关系请使用查找关系。

5. 汇总字段规则(重要)

汇总字段的部署失败率最高。请严格遵循这些规则。

汇总字段的必需元素
元素要求格式
<type>必需始终为 Summary
<summaryOperation>必需count、sum、min 或 max
<summaryForeignKey>必需ChildObject__c.MasterDetailField__c
<summarizedField>有条件必需sum、min、max 时必需。count 时不需要
汇总字段的禁止元素

绝不要在汇总字段上包含以下属性:

禁止的属性原因
<precision>汇总字段继承被汇总字段的属性
<scale>汇总字段继承被汇总字段的属性
<required>不适用于汇总字段
<length>不适用于汇总字段
summaryForeignKey 和 summarizedField 的格式规则

重要: summaryForeignKey 和 summarizedField 都必须使用完全限定格式:

ChildObjectAPIName__c.FieldAPIName__c

判定逻辑:

  • summaryForeignKey = ChildObject__c.MasterDetailFieldOnChild__c
  • summarizedField = ChildObject__c.FieldToSummarize__c
错误 — 含有常见错误的汇总字段:
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
  <fullName>Total_Amount__c</fullName>
  <label>Total Amount</label>
  <type>Summary</type>
  <precision>18</precision>           
  <scale>2</scale>                    
  <summaryOperation>sum</summaryOperation>
  <summaryForeignKey>Order__c</summaryForeignKey>        
  <summarizedField>Amount__c</summarizedField>           
</CustomField>

错误:

  • Can not specify 'precision' for a CustomField of type Summary
  • Must specify the name in the CustomObject.CustomField format (e.g. Account.MyNewCustomField)
正确 — 汇总字段(SUM 操作):
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
  <fullName>Total_Amount__c</fullName>
  <label>Total Amount</label>
  <description>Sum of all line item amounts</description>
  <inlineHelpText>Automatically calculated from child line items</inlineHelpText>
  <type>Summary</type>
  <summaryOperation>sum</summaryOperation>
  <summarizedField>Order_Line_Item__c.Amount__c</summarizedField>
  <summaryForeignKey>Order_Line_Item__c.Order__c</summaryForeignKey>
  
</CustomField>

COUNT: 与 SUM 类似,但省略 <summarizedField>(保留 <summaryForeignKey>)。MIN / MAX: 与 SUM 类似,将 <summaryOperation>min或max` 作为操作。

汇总字段速查表
操作是否需要 summarizedField?用例
count否统计子记录数量
sum是累加数值
min是查找最小值
max是查找最大值
汇总字段的先决条件
  • 汇总字段只能创建在主从关系中的父对象上
  • 子对象必须有一个指向此父对象的主从关系字段
  • 被汇总的字段必须存在于子对象上

6. 公式字段规则

公式结果类型

公式本身不是一种类型。<formula> 标签会添加到 <type> 为结果数据类型(Checkbox、Currency、Date、DateTime、Number、Percent、Text)的字段上。

  • 公式字段绝不包含 <length>——文本结果的公式字段也不例外。API 会拒绝该属性:Can not specify a length for CustomFields that have a formula。
公式 XML 生成规则
  • <formula> 标签的内容必须用 <![CDATA[ ... ]]> 包裹,以免解析器将公式运算符(&、<、>)识别为 XML 标记。
  • 如果公式文本本身包含字面序列 ]]>,请通过拆分 CDATA 块来转义它,例如:<![CDATA[Text_Field__c & "]]]]><![CDATA[>"]]>
  • 绝不要使用名为 returnType 的属性或标签。Metadata API 中不存在此项。<type> 标签用于定义公式结果的返回数据类型。
formulaTreatBlanksAs 规则

决策逻辑:

  • 如果公式结果类型为 Number、Currency 或 Percent → 设置 <formulaTreatBlanksAs>BlankAsZero</formulaTreatBlanksAs>
  • 如果公式结果类型为 Text、Date 或 DateTime → 设置 <formulaTreatBlanksAs>BlankAsBlank</formulaTreatBlanksAs>
错误示例 — 将 Formula 用作类型:
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
  <fullName>Calculated_Value__c</fullName>
  <type>Formula</type>  
  <returnType>Number</returnType>  
  <formula>Field1__c + Field2__c</formula>  
</CustomField>
正确示例 — 公式字段:
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
  <fullName>Calculated_Value__c</fullName>
  <label>Calculated Value</label>
  <description>Sum of Field1 and Field2</description>
  <type>Number</type>  
  <precision>18</precision>
  <scale>2</scale>
  <formula><![CDATA[Field1__c + Field2__c]]></formula>
  <formulaTreatBlanksAs>BlankAsZero</formulaTreatBlanksAs>
</CustomField>
公式字段依赖项和函数
  • 如果公式字段引用了其他字段,而被引用字段不存在或尚未部署,部署就会失败 — 请先部署被引用的字段。
  • 比较选项列表时使用 ISPICKVAL()(而不是 ==)。
  • 完整的公式函数参考(TEXT/VALUE/CASE/DAY/MONTH/DATEVALUE/ISCHANGED 类型规则)请参阅 platform-validation-rule-generate 技能,该技能负责公式函数的正确性。

7. 常见部署错误

错误消息原因修复方法
ConversionError: Invalid XML tags or unable to find matching parent xml file for CustomFieldXML 注释位于根 <CustomField> 元素之前删除 .field-meta.xml 文件中 <CustomField> 之前的 XML 注释(``)
Field [FieldName] does not exist. Check spelling.被引用的字段不存在或尚未部署确认被引用字段存在,并且已在此字段之前部署
DUPLICATE_DEVELOPER_NAME对象上已存在该字段的 fullName使用唯一且符合业务需求的名称
MAX_RELATIONSHIPS_EXCEEDED对象上的主从关系字段超过 2 个,或查找关系字段超过 15 个第 3 个及之后的主从关系字段改用查找关系;检查查找关系字段数量
保留关键字错误使用了 Order__c、Group__c 等重命名为 Status_Order__c 等
Value set must reference a value set name or define a value set, but not both<valueSet> 同时包含 <valueSetName> 和 <valueSetDefinition>只保留其中一个(参见第 3.4 节)
duplicate value found: [X] is defined multiple times两个 <value> 条目的 <fullName> 相同确保每个选项列表值的 <fullName> 都唯一
选项列表值出现 Invalid fullName值的 <fullName> 以数字开头或包含连字符以字母开头;不要使用连字符,也不要以数字开头。允许使用空格 — 不要将空格替换为下划线(参见 §3.4 中的值名称保真要求)
Element ...picklist is not allowed使用了已弃用的 ≤37.0 依赖选项列表语法(<picklist>/<picklistValues>/<controllingFieldValues>)使用新版 valueSettings/controllingFieldValue/valueName 格式(第 3.4 节)

8. 验证清单

生成 CustomField XML 之前,请确认:

通用检查
  • <fullName> 的格式是否有效,并以 __c 结尾?
  • <description> 和 <inlineHelpText> 是否都已填写且内容有意义?
  • <label> 是否采用标题式大小写?
  • 根 <CustomField> 元素之前是否没有 XML 注释(``)?(根元素之前的注释会导致 SDR 解析器出错)
主从关系字段检查(重要)
  • 是否未设置 <required> 属性?(主从关系字段始终必填)
  • 是否未设置 <deleteConstraint> 属性?(主从关系字段始终级联删除)
  • 是否未设置 <lookupFilter> 块?(仅适用于查找关系字段)
  • <relationshipOrder> 是否设置为 0 或 1?
  • 父对象的 <sharingModel> 是否设置为 ControlledByParent?
查找字段检查
  • <deleteConstraint> 是否设为 SetNull、Restrict 或 Cascade?
  • <relationshipName> 是否采用复数形式的 PascalCase?
选项列表字段检查
  • 每个 <valueSet> 是否只包含 <valueSetName> 或 <valueSetDefinition> 其中之一,绝不同时包含两者?
  • 对于值集引用,是否设置了 <restricted>true</restricted>?
  • 对于 StandardValueSet 引用,名称是否为不带 __c 的纯枚举值(例如 Industry)?
  • 对于 GlobalValueSet 引用,名称是否为不带 __gvs 后缀的纯开发者名称?
  • 对于依赖选项列表,是否设置了 <controllingField>,并为每一对值设置一个 <valueSettings>(<controllingFieldValue> + <valueName>)?
  • 对于依赖选项列表,是否未使用已弃用的 <picklist>/<picklistValues>/<controllingFieldValues> 形式?
  • 所有选项列表值的 <fullName> 是否均唯一、以字母开头且不含连字符?(允许包含空格——根据 §3.4 值名称保真规则,不要将空格替换为下划线)
汇总汇总字段检查(关键)
  • 是否不存在 <precision> 属性?
  • 是否不存在 <scale> 属性?
  • <summaryForeignKey> 是否采用 ChildObject__c.MasterDetailField__c 格式?
  • 对于 SUM/MIN/MAX:<summarizedField> 是否采用 ChildObject__c.FieldName__c 格式?
  • 对于 COUNT:是否不存在 <summarizedField>?
  • 子对象是否具有指向此父对象的主从关系字段?
公式字段检查
  • <type> 是否设为结果类型(而非“Formula”)?
  • <formula> 内容是否以 <![CDATA[ ... ]]> 包裹?
  • 是否不存在 <returnType> 属性?(Metadata API 中不存在此属性)
  • 是否不存在 <length>?(公式字段从不包含长度,即使是文本结果公式也不例外)
  • <formulaTreatBlanksAs> 是否根据结果类型设置为 BlankAsZero(数值结果)或 BlankAsBlank(文本/日期结果)?
  • 所有引用的字段是否都存在,并且会在此字段之前部署?
数值字段检查
  • scale ≤ precision 是否成立?
  • precision ≤ 18 是否成立?
文本区域检查
  • 对于 TextArea:是否省略了 <length>?(API 会拒绝在 TextArea 字段上显式设置 <length> 值。)
  • 对于 LongTextArea/Html:是否设置了 <visibleLines>?
关系数量限制检查
  • 对象上的主从关系是否不超过 2 个?
  • 对象上的查找关系是否不超过 15 个?
命名检查
  • API 名称是否不含保留字(如 Order、Group、Select 等)?
  • API 名称在此对象上是否唯一?

评论

支持 Markdown