Metadata Standards¶
TODO(David)
Write this section. The pages below are stubs for structure only; cross-cutting rules (naming, descriptions, hygiene, ownership) that apply to every metadata type belong on this landing page.
A practical set of standards for Salesforce metadata: naming, structure, and governance, with the checks that keep orgs consistent and reviewable. Automation comes first because its framework governs how everything else changes, and Observability follows because every automation layer logs through it; the remaining pages group metadata types by domain. The Principles behind these standards include that code and metadata are governed alike.
- Automation: the Automation Framework that governs all automation in the org, then Flows, approval processes, and the retirement of legacy automation
- Observability: logging, platform monitoring with Salesforce Shield, and the observability platform every company must run
- Permissions and Security: profiles, permission sets and groups, sharing, and high-risk permission elements
- Objects and Fields: the data model, validation rules, record types, and picklists
- Integration: the choice of API, External Client Apps, credentials, external services, and access settings
- Settings: org settings metadata and what belongs in version control
- User Interface: Lightning apps and pages, layouts, and actions
- Data Management: custom metadata types, duplicate and matching rules, and data classification
- Analytics: reports, dashboards, and report types
- Agentforce: agents, topics, actions, and prompt templates
Naming¶
The metadata of an org follows one naming convention for each kind of metadata, and the organisation posts those conventions in an easily accessible place for all involved in org maintenance. A name is read far more often than it is written (Naming), and a reader who knows the convention knows what a component is before opening it. The convention is the organisation's own: these standards state the ones that hold everywhere, such as the case of an Apex class name, and leave the rest to the organisation (Names and Descriptions). The specifics of naming conventions are less important than the need to have one consistent convention.
- Each part of a convention is enforced where it can be read. The Centre of Excellence (CoE) checks items that are decided at design time, such as the name of a new object, Flow, or Named Credential, when it approves the design document, so a design document must name every component it introduces. Static analysis checks the parts of a name that a rule can read, such as case, prefix, suffix, and first letter, on every pull request. Reviewers check the rest: that the name says what the component is, and that it is written the same way as the names of the components beside it.
- Some rules below take a convention through their properties: the stock PMD naming rules take a regular expression for each kind of Apex name, the trigger rule takes the suffixes a trigger name may end with, the {N} capital-letter rules take the metadata types they read from a property, the checkbox field rule takes its two prefixes, and the Flow naming rules take the project, application, or business unit codes, kind codes, verbs, and prefixes from properties, so an organisation that has a related convention enforces the parts a rule can read without writing a new rule.
The conventions these standards state, and the rules that check them:
| Metadata type | Convention | Checked by |
|---|---|---|
| Apex class, interface, enum, method, property, field, parameter, and local variable | Naming on the Apex page: Pascal case, camel case, or upper case by kind, with a table of every kind | ClassNamingConventions, MethodNamingConventions, FieldNamingConventions, FormalParameterNamingConventions, LocalVariableNamingConventions, and PropertyNamingConventions |
| Apex class suffix | Naming on the Apex page: Test, Batch, Sched, SchedBatch, and Constants for the role of a class, and Controller for a class that a Lightning component calls |
AuraEnabledControllerNaming for Controller; reviewers for the other suffixes |
| Trigger | Naming on the Apex page: an org uses one convention for every trigger, such as AccountTrigger |
TriggerNameSuffix, with the suffixes the organisation sets |
| Visualforce controller and controller extension | Controller Names: Controller for a controller, and Extension or Ext for an extension |
VisualforceControllerNaming |
| Custom object, custom field, and Flow | Naming on the Objects and Fields page: the name and the label start with a capital letter, and a field's name is its label with each space as an underscore (Shipping_Status__c) |
MetadataNameStartsWithCapital and MetadataLabelStartsWithCapital for the first letter; reviewers for the rest |
| Checkbox field | Naming on the Objects and Fields page: the name starts with Is and never with IsNot (Is_Active__c) |
CheckboxFieldNamePrefix |
| Flow, Flow element, and Flow resource | Naming on the Automation page: a project, application, or business unit code, the object, a kind code, and the purpose, separated by dashes in the label; an element's label starts with the verb for its type; a Decision's label is a question; a resource's name starts with a prefix for its type | FlowNameConvention, FlowElementVerb, FlowDecisionQuestion, and FlowResourcePrefix; reviewers for the kind code of a trigger action and of a subflow |
API Version¶
Every metadata file that states an API version states a recent one. A component keeps the platform behaviour of the version it is saved at, so a fix, a new feature, or a safer default reaches it only when its version is raised (Apex Versioned Behavior Changes; Component Versioning for Lightning Web Components). An older version blocks the pull request (severity 2). Enforced by BumpApiVersion and AvoidOldSalesforceApiVersions.
Components left at old versions also drift apart. One org then runs the same kind of component under several sets of platform behaviour, which makes it harder to predict and to test, and the step to a current version grows with every release that passes. What a version changes for code is shown by example on the Apex and JavaScript pages.
Each organisation chooses its own floor, and moves it when it chooses. {N} rules can enforce the standard, and replacing AvoidOldSalesforceApiVersions with BumpApiVersion is recommended, because the first sets its floor by itself and the second takes the floor that the organisation gives it.
The standard is checked in the apiVersion element of each metadata file. No rule reads sourceApiVersion in sfdx-project.json, or the version in a package.xml manifest.
Duplicated Metadata¶
- No block of metadata XML is copied by hand from one file to another. Much metadata repeats by nature, because the platform writes the same elements into every file of a kind, so the rule is set to report a long run of identical XML, and a report is read as a question: is this a component that should exist once? A block of XML that appears more than once across the repository is reported at severity 5, for the developer's information (Refactoring Duplicates). Enforced by
DetectCopyPasteForXml.
Rules¶
The rules that this page mentions. The Standard column gives each rule's standard in one line, and the Section column links to the section that mentions the rule; "Not yet written" marks a rule of this page that no section mentions yet. Appendix F.6 holds the full cross-reference.
| Rule | Kind | Severity | Standard | Section |
|---|---|---|---|---|
Class |
Stock PMD | 1 | Class, interface, and enum names are in Pascal case | Naming |
Field |
Stock PMD | 1 | Field names are in camel case, and constant and enum value names in upper snake case | Naming |
Formal |
Stock PMD | 1 | Parameter names are in camel case | Naming |
Local |
Stock PMD | 1 | Local variable names are in camel case | Naming |
Method |
Stock PMD | 1 | Method names are in camel case; underscores are allowed | Naming |
Prohibited |
Custom PMD XPath | 1 | No metadata file of a Tier 0 type is committed to version control | Lightning Web Components and Aura: An Organisation Without Aura User Interface: S-Controls |
Property |
Stock PMD | 1 | Property names are in camel case | Naming |
Avoid |
Stock Code Analyzer Regex | 2 | Every metadata file states a recent API version | API Version |
Bump |
Custom PMD XPath | 2 | Every metadata file is at or above the API version floor Notes on this rule. | API Version |
Metadata |
Custom PMD XPath | 2 | Every API name of a Flow, a custom object, or a custom field starts with a capital letter | Naming |
Checkbox |
Custom PMD XPath | 3 | A checkbox field name starts with Is, never with IsNot |
Naming |
Flow |
Custom PMD XPath | 3 | A Decision's label is the question it answers, and ends with a question mark | Naming |
Flow |
Custom PMD XPath | 3 | A Flow element's name starts with the verb for its type | Naming |
Flow |
Custom PMD XPath | 3 | A Flow's name has four parts: the owner code, the object, the kind code, and the purpose | Naming |
Metadata |
Custom PMD XPath | 3 | Every label of a Flow, a custom object, or a custom field starts with a capital letter | Naming |
No |
Custom PMD XPath | 3 | A web link does not hold the absolute URL of a Salesforce org | User Interface: Web Links |
Trigger |
Custom PMD XPath | 3 | A trigger name ends in Trigger, or in the one suffix the organisation sets Notes on this rule. |
Naming |
Aura |
Custom PMD XPath | 4 | A class that a Lightning component calls ends in Controller |
Naming |
Flow |
Custom PMD XPath | 4 | A Flow resource's name starts with the prefix for its type | Naming |
Visualforce |
Custom PMD XPath | 4 | A custom controller's name ends in Controller, and a controller extension's in Extension or Ext Notes on this rule. |
Naming |
Detect |
Stock Code Analyzer CPD | 5 | No block of metadata XML copied by hand from one file to another | Duplicated Metadata |