mcpField
G
generating-custom-field

generating-custom-field

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

关于 generating-custom-field

用于生成和校验 Salesforce 自定义字段元数据的技能,提供避免 Metadata API 部署错误的规则,涵盖常见及计算字段,并重点处理主从关系和汇总字段约束。

主要功能

  1. 01字段元数据生成与校验
  2. 02常见字段类型规则
  3. 03主从关系约束
  4. 04汇总字段要求
  5. 05公式字段校验
  6. 06查找过滤器限制

适用场景

  1. 01创建 Salesforce 自定义字段
  2. 02设置 Lookup 或主从关系
  3. 03生成公式或汇总字段
  4. 04部署前检查字段元数据

安装

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

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

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

详细介绍

何时使用此技能

在需要以下操作时使用此技能:

  • 在任意对象上创建自定义字段
  • 为任意字段类型生成字段元数据
  • 设置关系字段(查找关系或主从关系)
  • 创建公式字段或汇总汇总字段
  • 排查与自定义字段相关的部署错误

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

概述

生成并验证 Salesforce 自定义字段元数据,并应用强制约束以防止部署错误。此技能特别关注失败率最高的字段类型:汇总汇总和主从关系。

规范

1. 目的

本文档定义了生成 CustomField 元数据 XML 时必须遵守的约束。Agent 必须在输出 XML 之前验证这些约束,以防止 Metadata API 部署错误。

重点关注领域:

  • 汇总汇总字段格式错误
  • 主从字段属性限制
  • 查找过滤器限制

2. 通用必需属性

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

属性要求说明
<fullName>必需根据 <label> 推导:每个单词首字母大写,将空格替换为 _,并追加 __c。必须以字母开头。例如,标签 Total Contract Value → Total_Contract_Value__c
<label>必需UI 名称(标题式大小写)
<description>必需说明字段背后的业务“原因”
<inlineHelpText>必需为最终用户提供可操作的指导。内容必须比标签更有价值(例如,使用“输入含税的 USD 金额”,而不只是“金额”)
外部 ID 配置

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

适用类型: Text、Number、Email


3. 技术交互:精度、小数位数和长度

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

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

对于标准 TextArea 类型,Metadata API 要求 <length>255</length>,即使此值无法在 UI 中配置。

可见行数

长文本/富文本和多选列表框必需设置此项,以控制 UI 高度。


4. 字段数据类型

4.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统一电话号码格式
选项列表Picklist包含 valueSetDefinition 和 restricted 的 valueSet
文本Textlength(最大 255)
文本区域TextArea<length>255</length>
长文本LongTextArealength、visibleLines(默认 3)
富文本Htmllength、visibleLines(默认 25)
时间Time仅存储时间(不含日期)
URLUrl验证协议和格式
4.2 计算类型与多值类型
类型<type> 值必需属性
公式结果类型(例如,Number)formula、formulaTreatBlanksAs
汇总汇总Summary完整要求请参见第 6 节
多选列表MultiselectPicklistvalueSet、visibleLines(默认值为 4)
4.3 专用类型
类型<type> 值必需属性
地理位置Locationscale、displayLocationInDecimal
选项列表的 restricted 规则

<valueSet> 中的 <restricted> 布尔值用于控制是否仅允许管理员定义的值。

  • 如果用户未指定 → 默认设置为 <restricted>true</restricted>(受限,可避免选项列表值集过大导致的性能问题)
  • 如果用户明确表示选项列表应允许自定义/新值,或提到“不受限”或“开放” → 设置为 <restricted>false</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>

5. 主从关系规则 ⭐ 至关重要

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

主从字段中禁止使用的属性

绝不可在主从字段中包含以下属性:

禁止的属性原因结果
<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>
  <label>Account</label>
  <type>MasterDetail</type>
  <referenceTo>Account</referenceTo>
  <relationshipName>Contacts</relationshipName>
  <relationshipOrder>0</relationshipOrder>
  <required>true</required>           
  <deleteConstraint>Cascade</deleteConstraint>  
  <lookupFilter>                       
    <active>true</active>
    <filterItems>
      <field>Account.Type</field>
      <operation>equals</operation>
      <value>Customer</value>
    </filterItems>
  </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 个主从关系。更多关系请使用查找关系。

6. 汇总字段规则 ⭐ 至关重要

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

汇总字段的必需元素
元素要求格式
<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 操作):
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
  <fullName>Line_Item_Count__c</fullName>
  <label>Line Item Count</label>
  <description>Count of related line items</description>
  <inlineHelpText>Automatically calculated from child records</inlineHelpText>
  <type>Summary</type>
  <summaryOperation>count</summaryOperation>
  <summaryForeignKey>Order_Line_Item__c.Order__c</summaryForeignKey>
  
  
</CustomField>
✅ 正确 — 汇总汇总字段(MIN 操作):
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
  <fullName>Earliest_Due_Date__c</fullName>
  <label>Earliest Due Date</label>
  <description>Earliest due date among all line items</description>
  <inlineHelpText>Shows the soonest deadline</inlineHelpText>
  <type>Summary</type>
  <summaryOperation>min</summaryOperation>
  <summarizedField>Order_Line_Item__c.Due_Date__c</summarizedField>
  <summaryForeignKey>Order_Line_Item__c.Order__c</summaryForeignKey>
</CustomField>
✅ 正确 — 汇总汇总字段(MAX 操作):
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
  <fullName>Highest_Price__c</fullName>
  <label>Highest Price</label>
  <description>Maximum unit price among all line items</description>
  <inlineHelpText>Shows the most expensive item</inlineHelpText>
  <type>Summary</type>
  <summaryOperation>max</summaryOperation>
  <summarizedField>Order_Line_Item__c.Unit_Price__c</summarizedField>
  <summaryForeignKey>Order_Line_Item__c.Order__c</summaryForeignKey>
</CustomField>
汇总汇总字段速查
操作是否需要 summarizedField?用途
count否统计子记录数量
sum是累加数值
min是查找最小值
max是查找最大值
汇总汇总字段的前提条件
  • 汇总汇总字段只能在主从关系中的父对象上创建
  • 子对象必须具有指向此父对象的主从字段
  • 汇总字段必须存在于子对象上

7. 公式字段规则

公式结果类型

公式本身不是一种类型。<formula> 标签会添加到 <type> 设置为结果数据类型的字段中:

  • Checkbox、Currency、Date、DateTime、Number、Percent、Text
公式 XML 生成规则
  • <formula> 标签中的内容必须使用 <![CDATA[ ... ]]> 部分包裹。这样可以防止 XML 解析器将公式运算符(如 &、<、>)解释为 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>
公式字段依赖项

引用其他字段的公式字段,如果所引用的字段不存在或尚未部署,部署就会失败。请确保在部署公式字段之前,已部署所有被引用的字段。

特定函数指南
函数规则
TEXT()绝不能用于 Text 字段。如果字段本身已是 Text 类型,请移除 TEXT() 包装。
CASE()最后一个参数始终为默认值。参数总数必须为偶数(值-结果对 + 默认值)。
VALUE()只能用于 Text 字段。如果传入的参数是 Number,请移除 VALUE() 包装。
DAY()只能用于 Date 字段。如果使用 DateTime 字段,请先将其转换为 Date(例如,DAY(DATEVALUE(DateTimeField__c)))。
MONTH()只能用于 Date 字段。如果使用 DateTime 字段,请先将其转换为 Date(例如,MONTH(DATEVALUE(DateTimeField__c)))。
DATEVALUE()只能用于 DateTime 字段。如果使用 Date 字段,请移除 DATEVALUE() 包装。
ISPICKVAL()检查 Picklist 字段是否相等时必须使用此函数。绝不能对 Picklist 字段使用 ==。
ISCHANGED()使用 ISCHANGED() 检查字段值是否已更改。不要手动使用 PRIORVALUE() 进行比较。

8. 常见部署错误

错误消息原因修复方法
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 等

9. 验证清单

生成 CustomField XML 之前,请确认:

通用检查
  • <fullName> 是否采用有效格式并以 __c 结尾?
  • <description> 和 <inlineHelpText> 是否都已填写且内容有意义?
  • <label> 是否采用标题大小写?
  • 根 <CustomField> 元素之前是否没有 XML 注释(``)?(根元素之前的注释会导致 SDR 解析器出错)
主从关系字段检查 ⭐ 关键
  • 是否未设置 <required> 属性?(主从关系字段始终必填)
  • 是否未设置 <deleteConstraint> 属性?(主从关系始终级联删除)
  • 是否未设置 <lookupFilter> 块?(仅用于查找关系字段)
  • <relationshipOrder> 是否设为 0 或 1?
  • 父对象的 <sharingModel> 是否设为 ControlledByParent?
查找关系字段检查
  • <deleteConstraint> 是否设为 SetNull、Restrict 或 Cascade?
  • <relationshipName> 是否采用复数 PascalCase?
汇总汇总字段检查 ⭐ 关键
  • 是否未设置 <precision> 属性?
  • 是否未设置 <scale> 属性?
  • <summaryForeignKey> 是否采用 ChildObject__c.MasterDetailField__c 格式?
  • 对于 SUM/MIN/MAX:<summarizedField> 是否采用 ChildObject__c.FieldName__c 格式?
  • 对于 COUNT:是否未设置 <summarizedField>?
  • 子对象是否具有指向此父对象的主从关系字段?
公式字段检查
  • <type> 是否设为结果类型(而非“Formula”)?
  • <formula> 内容是否用 <![CDATA[ ... ]]> 包裹?
  • 是否未设置 <returnType> 属性?(Metadata API 中不存在该属性)
  • 对于数值结果,<formulaTreatBlanksAs> 是否设为 BlankAsZero;对于文本或日期结果,是否设为 BlankAsBlank?
  • 所有引用的字段是否都存在,并且在此字段之前已部署?
数值字段检查
  • scale ≤ precision 是否成立?
  • precision ≤ 18 是否成立?
文本区域检查
  • 对于 TextArea:是否明确包含 <length>255</length>?
  • 对于 LongTextArea/Html:是否设置了 <visibleLines>?
关系数量限制检查
  • 对象上的主从关系是否不超过 2 个?
  • 对象上的查找关系是否不超过 15 个?
命名检查
  • API 名称是否未使用保留字(Order、Group、Select 等)?
  • API 名称在此对象上是否唯一?

评论

支持 Markdown