mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-07-30 03:09:50 +08:00
feat: add skills from 260
This commit is contained in:
parent
00ad869c7b
commit
65947b1550
@ -0,0 +1,212 @@
|
||||
---
|
||||
name: salesforce-custom-application
|
||||
description: Generate CustomApplication (Lightning App) metadata with proper navigation types, branding, and action overrides. Use when creating Lightning applications for specific user workflows.
|
||||
---
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when you need to:
|
||||
- Create Lightning applications
|
||||
- Organize tabs and features into focused apps
|
||||
- Configure application navigation and branding
|
||||
- Set up custom page layouts for objects
|
||||
- Troubleshoot deployment errors related to custom applications
|
||||
|
||||
## Specification
|
||||
|
||||
# CustomApplication (Lightning App) Metadata Specification
|
||||
|
||||
## 📋 Overview
|
||||
Custom applications (Lightning Apps) that group tabs and functionality to provide a focused user experience for specific business processes. Always configured for Lightning Experience.
|
||||
|
||||
## 🎯 Purpose
|
||||
- Organize related functionality into focused applications
|
||||
- Group tabs and components for specific user roles
|
||||
- Provide tailored user experiences
|
||||
- Control access to specific features and data
|
||||
- Use Standard navigation for general business applications or Console navigation for specialized service/support workflows requiring multi-tab workspaces
|
||||
- Create professional, branded application identity with custom colors and branding
|
||||
- Override standard actions with custom Lightning pages for enhanced user experience
|
||||
- Enable profile-specific experiences through profile action overrides
|
||||
|
||||
## ⚙️ Required Properties
|
||||
|
||||
### Core Application Properties
|
||||
- **fullName**: API name of the application
|
||||
- **label**: Display name of the application
|
||||
- **uiType**: Always "Lightning" for modern apps
|
||||
- **navType**: CRITICAL - Choose based on user requirements and workflow patterns
|
||||
- "Standard": DEFAULT for general business applications (e.g., sales, marketing, operations)
|
||||
- "Console": ONLY when workflow requires managing multiple records simultaneously with split-view or multi-tab workspace (e.g., customer service, call centers, support operations)
|
||||
- **formFactors**: Array of form factors (["LARGE"] for desktop, ["SMALL"] for mobile, or both)
|
||||
|
||||
### Optional Properties
|
||||
- **description**: Brief description of the application's purpose
|
||||
- **tabs**: Array of tab names to include
|
||||
- **utilityBar**: API name of the Utility Bar configuration
|
||||
- **brand**: ⚠️ HIGHLY RECOMMENDED - Branding configuration object (headerColor, shouldOverrideOrgTheme, footerColor, primaryTabColor)
|
||||
- **actionOverrides**: ⚠️ REQUIRED when custom record pages exist - Action override configuration (actionName, content, formFactor, type, pageOrSobjectType)
|
||||
- **profileActionOverrides**: Profile-specific action overrides (actionName, content, formFactor, pageOrSobjectType, type, profile)
|
||||
- **isNavAutoTempTabsDisabled**: Navigation behavior setting (default: false)
|
||||
- **isNavPersonalizationDisabled**: Personalization setting (default: false)
|
||||
- **isNavTabPersistenceDisabled**: Tab persistence setting (default: false)
|
||||
|
||||
## 🔧 Application Configuration
|
||||
|
||||
### Navigation Type Selection (CRITICAL)
|
||||
**Decision Criteria for navType:**
|
||||
|
||||
**Choose "Standard" (DEFAULT) for:**
|
||||
- General business applications and most workflows
|
||||
- Single-record focus or linear navigation patterns
|
||||
- Standard tab-based navigation is sufficient
|
||||
|
||||
**Choose "Console" ONLY when workflow requires:**
|
||||
- Managing multiple related records simultaneously in split-view
|
||||
- Multi-tab workspace for handling complex, interconnected data
|
||||
- Contextual information from multiple sources visible at once
|
||||
- Examples: customer service operations, support desks, call centers
|
||||
|
||||
**When in doubt:** Default to "Standard" for most general business use cases
|
||||
|
||||
### Navigation Settings
|
||||
- **isNavAutoTempTabsDisabled**: Controls automatic temporary tab creation
|
||||
- **isNavPersonalizationDisabled**: Controls user personalization features
|
||||
- **isNavTabPersistenceDisabled**: Controls tab persistence across sessions
|
||||
|
||||
### Tab Management
|
||||
- **tabs**: Array of tab names to include in the application
|
||||
- **formFactors**: Device-specific configurations (Large for desktop, Small for mobile)
|
||||
|
||||
### Utility Bar
|
||||
- **utilityBar**: Reference to Lightning utility bar (appears at bottom of Lightning Experience)
|
||||
|
||||
### Branding (HIGHLY RECOMMENDED - DO NOT SKIP)
|
||||
**IMPORTANT**: Provide branding configuration to create a professional, visually distinct application identity.
|
||||
|
||||
- **brand.headerColor**: Header bar color in hex format (e.g., "#0070D2") - RECOMMENDED
|
||||
- **brand.shouldOverrideOrgTheme**: Override organization theme (true/false) - Default: false
|
||||
- **brand.footerColor**: Footer color in hex format
|
||||
- **brand.primaryTabColor**: Primary tab color in hex format
|
||||
|
||||
### Action Overrides (CRITICAL - DO NOT SKIP)
|
||||
**IMPORTANT**: Action overrides MUST be created for every custom object tab that has a record page generated by flexipage expert.
|
||||
|
||||
- **actionOverrides.actionName**: Action to override ("View" or "Tab")
|
||||
- **actionOverrides.content**: Page/component name (FlexiPage, Visualforce, Lightning component)
|
||||
- For "View" action: Reference record pages generated by flexipage expert
|
||||
- For "Tab" action: Reference home/app pages generated by flexipage expert
|
||||
- **actionOverrides.formFactor**: Device type ("Large" or "Small")
|
||||
- **actionOverrides.type**: Override type ("Default", "Visualforce", "Flexipage", "LightningComponent", "Scontrol")
|
||||
- Recommended: Use "Flexipage" for Lightning record/home pages generated by flexipage expert
|
||||
- **actionOverrides.pageOrSobjectType**: Object API name the override applies to
|
||||
- **actionOverrides.comment**: Optional description (max 1000 characters)
|
||||
- Auto-generated comment: "Action override created by Lightning App Builder during activation."
|
||||
- **actionOverrides.skipRecordTypeSelect**: Skip record type selection (default: false)
|
||||
|
||||
### Profile Action Overrides
|
||||
- **profileActionOverrides.actionName**: Action to override ("View" or "Tab")
|
||||
- **profileActionOverrides.content**: Page/component name
|
||||
- For "View" action: Reference profile-specific record pages generated by flexipage expert
|
||||
- For "Tab" action: Reference profile-specific home pages generated by flexipage expert
|
||||
- Can reference same or different FlexiPages than actionOverrides for profile-specific experiences
|
||||
- **profileActionOverrides.formFactor**: Device type ("Large" or "Small")
|
||||
- **profileActionOverrides.pageOrSobjectType**: Object API name
|
||||
- **profileActionOverrides.type**: Override type
|
||||
- Recommended: Use "Flexipage" for Lightning pages generated by flexipage expert
|
||||
- **profileActionOverrides.profile**: Profile API name (e.g., "Admin", "Standard User")
|
||||
- Enables different page layouts for different user profiles
|
||||
|
||||
## 📱 Device Support
|
||||
|
||||
### Desktop Configuration
|
||||
- **formFactor**: "Large"
|
||||
- **tabs**: Full list of application tabs
|
||||
|
||||
### Phone Configuration
|
||||
- **formFactor**: "Small"
|
||||
- **tabs**: Mobile-optimized tab selection
|
||||
|
||||
### Tablet Configuration
|
||||
- **formFactor**: "Medium"
|
||||
- **tabs**: Tablet-appropriate tab selection
|
||||
|
||||
## 🎨 User Experience Features
|
||||
|
||||
### Navigation Behavior
|
||||
- **Auto Temporary Tabs**: Can be enabled/disabled
|
||||
- **Personalization**: User customization options
|
||||
- **Tab Persistence**: Remember user's tab selections
|
||||
|
||||
### Accessibility
|
||||
- **Keyboard Navigation**: Full keyboard support
|
||||
- **Screen Reader**: Compatible with assistive technologies
|
||||
- **High Contrast**: Support for high contrast modes
|
||||
|
||||
## 🔗 Integration Points
|
||||
- **Custom Tabs**: Include custom object and web tabs
|
||||
- **Standard Tabs**: Include standard Salesforce tabs
|
||||
- **Lightning Pages**: Integrate with Lightning page layouts
|
||||
- **Components**: Include custom Lightning components
|
||||
## ✅ Best Practices
|
||||
- **Always use Lightning UI**: Set `uiType` to "Lightning" for modern apps
|
||||
- **Choose appropriate navigation**: CRITICAL - Analyze requirements carefully for `navType` selection
|
||||
- Use "Standard" (DEFAULT) for general business applications
|
||||
- Use "Console" ONLY when workflow requires multi-tab workspace, split-view, or managing multiple related records simultaneously
|
||||
- Examples for Console: customer service, call centers, support operations
|
||||
- Default to "Standard" for most general business use cases
|
||||
- **Include Standard Tabs**: Add common Salesforce tabs (Home, Accounts, Contacts, etc.)
|
||||
- **Use clear, descriptive application names**
|
||||
- **Group related functionality logically**
|
||||
- **Consider different user roles and needs**
|
||||
- **Test across different device types**
|
||||
- **Ensure proper permissions and access control**
|
||||
- **Provide meaningful descriptions for users**
|
||||
- **Follow consistent naming conventions**
|
||||
- **Always configure branding**: Set headerColor to create professional application identity
|
||||
- **Use accessible brand colors**: Ensure hex colors have sufficient contrast (WCAG AA compliant)
|
||||
- **Configure utility bars**: Add useful quick-access tools for users
|
||||
- **Leverage action overrides**: Customize page layouts for specific objects using FlexiPages from flexipage expert
|
||||
- **Use profile overrides**: Provide role-specific experiences by referencing different flexipage expert generated pages per profile
|
||||
|
||||
## 🎯 Enhancement Rules
|
||||
- **uiType**: Always set to "Lightning" for modern app experience
|
||||
- **navType**: CRITICAL DECISION - Analyze user requirements carefully
|
||||
- Set to "Standard" (DEFAULT) for general business applications
|
||||
- Set to "Console" ONLY when workflow requires:
|
||||
- Managing multiple related records simultaneously with split-view capability
|
||||
- Multi-tab workspace for handling complex, interconnected data
|
||||
- Contextual information from multiple sources visible at once
|
||||
- Console examples: customer service operations, call centers, support desks
|
||||
- When in doubt between Standard and Console, choose "Standard" for most business use cases
|
||||
- **formFactors**: Always set to ["LARGE"] for desktop Lightning Experience
|
||||
- **Standard Tabs**: Automatically add Home, Accounts, Contacts, Opportunities, Leads, Cases
|
||||
- **Navigation Settings**: Set all navigation flags to false for best user experience
|
||||
- **Branding**: ALWAYS include brand configuration for professional application identity
|
||||
- MANDATORY: Set brand.headerColor to appropriate color (e.g., "#0070D2" for Salesforce Blue)
|
||||
- Set brand.shouldOverrideOrgTheme based on requirements
|
||||
- **Action Overrides**: ALWAYS create action overrides when custom record pages exist
|
||||
- MANDATORY: Add actionOverrides for "View" action pointing to flexipage expert generated record pages
|
||||
- Use "Flexipage" type and reference the exact FlexiPage name
|
||||
- Set formFactor to "Large" for desktop
|
||||
- Include pageOrSobjectType with the object API name
|
||||
- **Profile Action Overrides**: Reference flexipage expert generated pages for role-based customization
|
||||
- **Form Factors**: Use "Large" for desktop, "Small" for mobile in overrides
|
||||
|
||||
## ⚠️ CRITICAL Verification Checklist (MUST VERIFY)
|
||||
- [ ] All tabs are included in the application
|
||||
- [ ] **navType IS CORRECTLY SET** - Verify Console vs Standard selection
|
||||
- [ ] Default to "Standard" for most general business applications
|
||||
- [ ] Set to "Console" ONLY if workflow requires managing multiple records simultaneously, split-view, or multi-tab workspace
|
||||
- [ ] If requirements are general/ambiguous → navType should be "Standard"
|
||||
- [ ] **BRANDING IS CONFIGURED** - This is HIGHLY RECOMMENDED for professional applications
|
||||
- [ ] brand.headerColor is set with valid hex color (e.g., "#0070D2")
|
||||
- [ ] brand.shouldOverrideOrgTheme is set (default: false)
|
||||
- [ ] **ACTION OVERRIDES ARE CREATED** - This is MANDATORY for every custom object with a record page
|
||||
- [ ] Action overrides are defined for EACH custom object tab pointing to the correct record page
|
||||
- [ ] actionOverrides.content matches the exact FlexiPage name generated by flexipage expert
|
||||
- [ ] actionOverrides.pageOrSobjectType is set to the correct object API name
|
||||
- [ ] actionOverrides.type is set to "Flexipage"
|
||||
- [ ] actionOverrides.actionName is set to "View"
|
||||
- [ ] actionOverrides.formFactor is set to "Large"
|
||||
- [ ] All required fields are populated (fullName, label, uiType, navType, formFactors)
|
||||
@ -0,0 +1,493 @@
|
||||
---
|
||||
name: salesforce-custom-field
|
||||
description: Generate CustomField metadata XML with proper type handling, relationship rules, and formula syntax. Handles Master-Detail, Lookup, Roll-Up Summary, and Formula fields correctly. Use when creating or modifying custom fields.
|
||||
---
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when you need to:
|
||||
- Create custom fields on any object
|
||||
- Generate field metadata for any field type
|
||||
- Set up relationship fields (Lookup or Master-Detail)
|
||||
- Create formula or roll-up summary fields
|
||||
- Troubleshoot deployment errors related to custom fields
|
||||
|
||||
## Specification
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This document defines the mandatory constraints for generating CustomField metadata XML. The agent must verify these constraints before outputting XML to prevent Metadata API deployment errors.
|
||||
|
||||
**Critical Focus Areas:**
|
||||
- Roll-up Summary field format errors
|
||||
- Master-Detail field attribute restrictions
|
||||
- Lookup Filter restrictions
|
||||
|
||||
---
|
||||
|
||||
## 2. Universal Mandatory Attributes
|
||||
|
||||
Every generated field must include these tags:
|
||||
|
||||
| Attribute | Requirement | Notes |
|
||||
|-----------|-------------|-------|
|
||||
| `<fullName>` | Required | Derive from `<label>`: capitalize each word, replace spaces with `_`, append `__c`. Must start with a letter. E.g., label `Total Contract Value` → `Total_Contract_Value__c` |
|
||||
| `<label>` | Required | The UI name (Title Case) |
|
||||
| `<description>` | Mandatory | State the business "why" behind the field |
|
||||
| `<inlineHelpText>` | Mandatory | Provide actionable guidance for the end-user. Must add value beyond the label (e.g., "Enter the value in USD including tax" instead of just "The amount") |
|
||||
|
||||
### External ID Configuration
|
||||
|
||||
**Trigger:** If the user mentions "integration," "importing data," "external system ID," or "unique key from [System Name]," set `<externalId>true</externalId>`.
|
||||
|
||||
**Applicable Types:** Text, Number, Email
|
||||
|
||||
---
|
||||
|
||||
## 3. Technical Interplay: Precision, Scale, and Length
|
||||
|
||||
To ensure deployment success, follow these mathematical constraints:
|
||||
|
||||
### Precision vs. Scale Rules
|
||||
|
||||
- `precision` is the total digits; `scale` is the decimal digits
|
||||
- **Rule:** `precision ≤ 18` AND `scale ≤ precision`
|
||||
- **Calculation:** Digits to the left of decimal = `precision - scale`
|
||||
|
||||
### The "Fixed 255" Rule
|
||||
|
||||
For standard TextArea types, the Metadata API requires `<length>255</length>`, even though it isn't configurable in the UI.
|
||||
|
||||
### Visible Lines
|
||||
|
||||
Mandatory for Long/Rich text and Multi-select picklists to control UI height.
|
||||
|
||||
---
|
||||
|
||||
## 4. Field Data Types
|
||||
|
||||
### 4.1 Simple Attribute Types
|
||||
|
||||
| Type | `<type>` Value | Required Attributes |
|
||||
|------|----------------|---------------------|
|
||||
| Auto Number | `AutoNumber` | `displayFormat` (must include `{0}`), `startingNumber` |
|
||||
| Checkbox | `Checkbox` | Default `defaultValue` to `false` |
|
||||
| Date | `Date` | No precision/length required |
|
||||
| Date/Time | `DateTime` | No precision/length required |
|
||||
| Email | `Email` | Built-in format validation |
|
||||
| Lookup Relationship | `Lookup` | `referenceTo`, `relationshipName`, `deleteConstraint` |
|
||||
| Master-Detail Relationship | `MasterDetail` | `referenceTo`, `relationshipName`, `relationshipOrder` |
|
||||
| Number | `Number` | `precision`, `scale` |
|
||||
| Currency | `Currency` | Default precision: 18, scale: 2 |
|
||||
| Percent | `Percent` | Default precision: 5, scale: 2 |
|
||||
| Phone | `Phone` | Standardizes phone number formatting |
|
||||
| Picklist | `Picklist` | `valueSet` with `valueSetDefinition` and `restricted` |
|
||||
| Text | `Text` | `length` (Max 255) |
|
||||
| Text Area | `TextArea` | `<length>255</length>` |
|
||||
| Text (Long) | `LongTextArea` | `length`, `visibleLines` (default 3) |
|
||||
| Text (Rich) | `Html` | `length`, `visibleLines` (default 25) |
|
||||
| Time | `Time` | Stores time only (no date) |
|
||||
| URL | `Url` | Validates for protocol and format |
|
||||
|
||||
### 4.2 Computed & Multi-Value Types
|
||||
|
||||
| Type | `<type>` Value | Required Attributes |
|
||||
|------|----------------|---------------------|
|
||||
| Formula | Result type (e.g., `Number`) | `formula`, `formulaTreatBlanksAs` |
|
||||
| Roll-Up Summary | `Summary` | See Section 6 for complete requirements |
|
||||
| Multi-Select Picklist | `MultiselectPicklist` | `valueSet`, `visibleLines` (default 4) |
|
||||
|
||||
### 4.3 Specialized Types
|
||||
|
||||
| Type | `<type>` Value | Required Attributes |
|
||||
|------|----------------|---------------------|
|
||||
| Geolocation | `Location` | `scale`, `displayLocationInDecimal` |
|
||||
|
||||
### Picklist `restricted` Rule
|
||||
|
||||
The `<restricted>` boolean inside `<valueSet>` controls whether only admin-defined values are allowed.
|
||||
|
||||
- IF user does not specify → default to `<restricted>true</restricted>` (restricted, avoids performance issues with large picklist value sets)
|
||||
- IF user explicitly says the picklist should allow custom/new values, or mentions "unrestricted" or "open" → set `<restricted>false</restricted>`
|
||||
- Restricted picklists are limited to 1,000 total values (active + inactive)
|
||||
|
||||
```xml
|
||||
<valueSet>
|
||||
<restricted>true</restricted>
|
||||
<valueSetDefinition>
|
||||
<sorted>false</sorted>
|
||||
<value>
|
||||
<fullName>Option_A</fullName>
|
||||
<default>false</default>
|
||||
<label>Option A</label>
|
||||
</value>
|
||||
</valueSetDefinition>
|
||||
</valueSet>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Master-Detail Relationship Rules ⭐ CRITICAL
|
||||
|
||||
Master-Detail fields have **strict attribute restrictions** that differ from Lookup fields. Violating these rules causes deployment failures.
|
||||
|
||||
### Forbidden Attributes on Master-Detail Fields
|
||||
|
||||
**NEVER include these attributes on Master-Detail fields:**
|
||||
|
||||
| Forbidden Attribute | Why | What Happens |
|
||||
|---------------------|-----|--------------|
|
||||
| `<required>` | Master-Detail is ALWAYS required by design | Deployment error |
|
||||
| `<deleteConstraint>` | Master-Detail ALWAYS cascades deletes | Deployment error |
|
||||
| `<lookupFilter>` | Only supported on Lookup fields | Deployment error |
|
||||
|
||||
### Master-Detail vs Lookup Comparison
|
||||
|
||||
| Attribute | Master-Detail | Lookup |
|
||||
|-----------|---------------|--------|
|
||||
| `<required>` | ❌ FORBIDDEN | ✅ Optional |
|
||||
| `<deleteConstraint>` | ❌ FORBIDDEN (always CASCADE) | ✅ Required (`SetNull`, `Restrict`, `Cascade`) |
|
||||
| `<lookupFilter>` | ❌ FORBIDDEN | ✅ Optional |
|
||||
| `<relationshipOrder>` | ✅ Required (0 or 1) | ❌ Not applicable |
|
||||
| `<reparentableMasterDetail>` | ✅ Optional | ❌ Not applicable |
|
||||
| `<writeRequiresMasterRead>` | ✅ Optional | ❌ Not applicable |
|
||||
|
||||
### ❌ INCORRECT — Master-Detail with forbidden attributes:
|
||||
|
||||
```xml
|
||||
<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> <!-- WRONG: Remove this -->
|
||||
<deleteConstraint>Cascade</deleteConstraint> <!-- WRONG: Remove this -->
|
||||
<lookupFilter> <!-- WRONG: Remove this entire block -->
|
||||
<active>true</active>
|
||||
<filterItems>
|
||||
<field>Account.Type</field>
|
||||
<operation>equals</operation>
|
||||
<value>Customer</value>
|
||||
</filterItems>
|
||||
</lookupFilter>
|
||||
</CustomField>
|
||||
```
|
||||
|
||||
**Errors:**
|
||||
- `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`
|
||||
|
||||
### ✅ CORRECT — Master-Detail field:
|
||||
|
||||
```xml
|
||||
<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>
|
||||
<!-- NO required, deleteConstraint, or lookupFilter -->
|
||||
</CustomField>
|
||||
```
|
||||
|
||||
### ✅ CORRECT — Lookup field (with optional attributes):
|
||||
|
||||
```xml
|
||||
<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>
|
||||
```
|
||||
|
||||
### Additional Master-Detail Rules
|
||||
|
||||
- **Relationship Order:** First Master-Detail on object = `0`, second = `1`
|
||||
- **Relationship Name:** Must be a plural PascalCase string (e.g., `Travel_Bookings`)
|
||||
- **Junction Objects:** Use two Master-Detail fields for standard many-to-many (enables Roll-ups)
|
||||
- **Limit:** Maximum 2 Master-Detail relationships per object. Use Lookup for additional relationships.
|
||||
|
||||
---
|
||||
|
||||
## 6. Roll-Up Summary Field Rules ⭐ CRITICAL
|
||||
|
||||
Roll-up Summary fields have the **highest deployment failure rate**. Follow these rules exactly.
|
||||
|
||||
### Required Elements for Roll-Up Summary
|
||||
|
||||
| Element | Requirement | Format |
|
||||
|---------|-------------|--------|
|
||||
| `<type>` | Required | Always `Summary` |
|
||||
| `<summaryOperation>` | Required | `count`, `sum`, `min`, or `max` |
|
||||
| `<summaryForeignKey>` | Required | `ChildObject__c.MasterDetailField__c` |
|
||||
| `<summarizedField>` | Conditional | Required for `sum`, `min`, `max`. NOT for `count` |
|
||||
|
||||
### Forbidden Elements on Roll-Up Summary
|
||||
|
||||
**NEVER include these attributes on Roll-Up Summary fields:**
|
||||
|
||||
| Forbidden Attribute | Why |
|
||||
|---------------------|-----|
|
||||
| `<precision>` | Summary inherits from summarized field |
|
||||
| `<scale>` | Summary inherits from summarized field |
|
||||
| `<required>` | Not applicable to Summary fields |
|
||||
| `<length>` | Not applicable to Summary fields |
|
||||
|
||||
### Format Rules for summaryForeignKey and summarizedField
|
||||
|
||||
**CRITICAL:** Both `summaryForeignKey` and `summarizedField` MUST use the fully qualified format:
|
||||
|
||||
```
|
||||
ChildObjectAPIName__c.FieldAPIName__c
|
||||
```
|
||||
|
||||
**Decision Logic:**
|
||||
- `summaryForeignKey` = `ChildObject__c.MasterDetailFieldOnChild__c`
|
||||
- `summarizedField` = `ChildObject__c.FieldToSummarize__c`
|
||||
|
||||
### ❌ INCORRECT — Roll-Up Summary with common errors:
|
||||
|
||||
```xml
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Total_Amount__c</fullName>
|
||||
<label>Total Amount</label>
|
||||
<type>Summary</type>
|
||||
<precision>18</precision> <!-- WRONG: Remove - inherited from source -->
|
||||
<scale>2</scale> <!-- WRONG: Remove - inherited from source -->
|
||||
<summaryOperation>sum</summaryOperation>
|
||||
<summaryForeignKey>Order__c</summaryForeignKey> <!-- WRONG: Missing field name -->
|
||||
<summarizedField>Amount__c</summarizedField> <!-- WRONG: Missing object name -->
|
||||
</CustomField>
|
||||
```
|
||||
|
||||
**Errors:**
|
||||
- `Can not specify 'precision' for a CustomField of type Summary`
|
||||
- `Must specify the name in the CustomObject.CustomField format (e.g. Account.MyNewCustomField)`
|
||||
|
||||
### ✅ CORRECT — Roll-Up Summary (SUM operation):
|
||||
|
||||
```xml
|
||||
<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>
|
||||
<!-- NO precision, scale, required, or length -->
|
||||
</CustomField>
|
||||
```
|
||||
|
||||
### ✅ CORRECT — Roll-Up Summary (COUNT operation):
|
||||
|
||||
```xml
|
||||
<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>
|
||||
<!-- NO summarizedField needed for COUNT -->
|
||||
<!-- NO precision, scale, required, or length -->
|
||||
</CustomField>
|
||||
```
|
||||
|
||||
### ✅ CORRECT — Roll-Up Summary (MIN operation):
|
||||
|
||||
```xml
|
||||
<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>
|
||||
```
|
||||
|
||||
### ✅ CORRECT — Roll-Up Summary (MAX operation):
|
||||
|
||||
```xml
|
||||
<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>
|
||||
```
|
||||
|
||||
### Roll-Up Summary Quick Reference
|
||||
|
||||
| Operation | summarizedField Required? | Use Case |
|
||||
|-----------|---------------------------|----------|
|
||||
| `count` | NO | Count number of child records |
|
||||
| `sum` | YES | Add up numeric values |
|
||||
| `min` | YES | Find smallest value |
|
||||
| `max` | YES | Find largest value |
|
||||
|
||||
### Roll-Up Summary Prerequisites
|
||||
|
||||
- Roll-Up Summary fields can ONLY be created on the **parent** object in a Master-Detail relationship
|
||||
- The child object MUST have a Master-Detail field pointing to this parent
|
||||
- The summarized field must exist on the child object
|
||||
|
||||
---
|
||||
|
||||
## 7. Formula Field Rules
|
||||
|
||||
### Formula Result Types
|
||||
|
||||
A Formula is not a type itself. The `<formula>` tag is added to a field whose `<type>` is set to the **result data type**:
|
||||
- `Checkbox`, `Currency`, `Date`, `DateTime`, `Number`, `Percent`, `Text`
|
||||
|
||||
### Formula XML Generation Rules
|
||||
|
||||
- The contents of the `<formula>` tag MUST be wrapped in a `<![CDATA[ ... ]]>` section. This prevents the XML parser from interpreting formula operators (like `&`, `<`, `>`) as XML markup.
|
||||
- If the formula text itself contains the literal sequence `]]>`, escape it by breaking the CDATA block: e.g., `<![CDATA[Text_Field__c & "]]]]><![CDATA[>"]]>`
|
||||
- NEVER use an attribute or tag named `returnType`. This does not exist in the Metadata API. The `<type>` tag defines the return data type of the formula result.
|
||||
|
||||
### formulaTreatBlanksAs Rule
|
||||
|
||||
**Decision Logic:**
|
||||
- IF formula result type = `Number`, `Currency`, or `Percent` → set `<formulaTreatBlanksAs>BlankAsZero</formulaTreatBlanksAs>`
|
||||
- IF formula result type = `Text`, `Date`, or `DateTime` → set `<formulaTreatBlanksAs>BlankAsBlank</formulaTreatBlanksAs>`
|
||||
|
||||
### ❌ INCORRECT — Using Formula as type:
|
||||
|
||||
```xml
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Calculated_Value__c</fullName>
|
||||
<type>Formula</type> <!-- WRONG: Formula is not a valid type -->
|
||||
<returnType>Number</returnType> <!-- WRONG: returnType does not exist in Metadata API -->
|
||||
<formula>Field1__c + Field2__c</formula> <!-- WRONG: Missing CDATA wrapper -->
|
||||
</CustomField>
|
||||
```
|
||||
|
||||
### ✅ CORRECT — Formula field:
|
||||
|
||||
```xml
|
||||
<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> <!-- Result type, not "Formula" -->
|
||||
<precision>18</precision>
|
||||
<scale>2</scale>
|
||||
<formula><![CDATA[Field1__c + Field2__c]]></formula>
|
||||
<formulaTreatBlanksAs>BlankAsZero</formulaTreatBlanksAs>
|
||||
</CustomField>
|
||||
```
|
||||
|
||||
### Formula Field Dependencies
|
||||
|
||||
Formula fields that reference other fields will fail deployment if the referenced field does not exist or has not been deployed yet. Ensure all referenced fields are deployed before the formula field.
|
||||
|
||||
### Specific Function Guidelines
|
||||
|
||||
| Function | Rule |
|
||||
|----------|------|
|
||||
| `TEXT()` | MUST NOT be used with Text fields. If the field is already Text, remove the `TEXT()` wrapper. |
|
||||
| `CASE()` | Last parameter is always the default value. Total parameter count MUST be even (value-result pairs + default). |
|
||||
| `VALUE()` | MUST only be used with Text fields. If a Number is passed as parameter, remove the `VALUE()` wrapper. |
|
||||
| `DAY()` | MUST only be used with Date fields. If a DateTime field is used, convert it to Date first (e.g., `DAY(DATEVALUE(DateTimeField__c))`). |
|
||||
| `MONTH()` | MUST only be used with Date fields. If a DateTime field is used, convert it to Date first (e.g., `MONTH(DATEVALUE(DateTimeField__c))`). |
|
||||
| `DATEVALUE()` | MUST only be used with DateTime fields. If a Date field is used, remove the `DATEVALUE()` wrapper. |
|
||||
| `ISPICKVAL()` | MUST be used when checking equality of a Picklist field. NEVER use `==` with Picklist fields. |
|
||||
| `ISCHANGED()` | Use `ISCHANGED()` to check if a field value has changed. Do not manually compare with `PRIORVALUE()`. |
|
||||
|
||||
---
|
||||
|
||||
## 8. Common Deployment Errors
|
||||
|
||||
| Error Message | Cause | Fix |
|
||||
|---------------|-------|-----|
|
||||
| `Field [FieldName] does not exist. Check spelling.` | Referenced field does not exist or has not been deployed yet | Verify the referenced field exists and is deployed before this field |
|
||||
| `DUPLICATE_DEVELOPER_NAME` | Field fullName already exists on the object | Use a unique business-driven name |
|
||||
| `MAX_RELATIONSHIPS_EXCEEDED` | More than 2 Master-Detail or 15 Lookup fields on the object | Use Lookup for 3rd+ Master-Detail; review Lookup count |
|
||||
| Reserved keyword error | Using `Order__c`, `Group__c`, etc. | Rename to `Status_Order__c`, etc. |
|
||||
|
||||
---
|
||||
|
||||
## 9. Verification Checklist
|
||||
|
||||
Before generating CustomField XML, verify:
|
||||
|
||||
### Universal Checks
|
||||
- [ ] Does `<fullName>` use valid format and end in `__c`?
|
||||
- [ ] Are `<description>` and `<inlineHelpText>` both populated and meaningful?
|
||||
- [ ] Is `<label>` in Title Case?
|
||||
|
||||
### Master-Detail Field Checks ⭐ CRITICAL
|
||||
- [ ] Is `<required>` attribute ABSENT? (Master-Detail is always required)
|
||||
- [ ] Is `<deleteConstraint>` attribute ABSENT? (Master-Detail always cascades)
|
||||
- [ ] Is `<lookupFilter>` block ABSENT? (Only for Lookup fields)
|
||||
- [ ] Is `<relationshipOrder>` set to `0` or `1`?
|
||||
- [ ] Is parent object's `<sharingModel>` set to `ControlledByParent`?
|
||||
|
||||
### Lookup Field Checks
|
||||
- [ ] Is `<deleteConstraint>` set to `SetNull`, `Restrict`, or `Cascade`?
|
||||
- [ ] Is `<relationshipName>` in plural PascalCase?
|
||||
|
||||
### Roll-Up Summary Field Checks ⭐ CRITICAL
|
||||
- [ ] Is `<precision>` attribute ABSENT?
|
||||
- [ ] Is `<scale>` attribute ABSENT?
|
||||
- [ ] Is `<summaryForeignKey>` in format `ChildObject__c.MasterDetailField__c`?
|
||||
- [ ] For SUM/MIN/MAX: Is `<summarizedField>` in format `ChildObject__c.FieldName__c`?
|
||||
- [ ] For COUNT: Is `<summarizedField>` ABSENT?
|
||||
- [ ] Does the child object have a Master-Detail field to this parent?
|
||||
|
||||
### Formula Field Checks
|
||||
- [ ] Is `<type>` set to result type (NOT "Formula")?
|
||||
- [ ] Is `<formula>` content wrapped in `<![CDATA[ ... ]]>`?
|
||||
- [ ] Is `<returnType>` attribute ABSENT? (does not exist in Metadata API)
|
||||
- [ ] Is `<formulaTreatBlanksAs>` set to `BlankAsZero` for numeric results or `BlankAsBlank` for text/date results?
|
||||
- [ ] Do all referenced fields exist and deploy before this field?
|
||||
|
||||
### Numeric Field Checks
|
||||
- [ ] Is `scale ≤ precision`?
|
||||
- [ ] Is `precision ≤ 18`?
|
||||
|
||||
### Text Area Checks
|
||||
- [ ] For TextArea: Is `<length>255</length>` explicitly included?
|
||||
- [ ] For LongTextArea/Html: Is `<visibleLines>` set?
|
||||
|
||||
### Relationship Limit Checks
|
||||
- [ ] Are there 2 or fewer Master-Detail relationships on the object?
|
||||
- [ ] Are there 15 or fewer Lookup relationships on the object?
|
||||
|
||||
### Naming Checks
|
||||
- [ ] Is the API name free of reserved words (`Order`, `Group`, `Select`, etc.)?
|
||||
- [ ] Is the API name unique on this object?
|
||||
@ -0,0 +1,236 @@
|
||||
---
|
||||
name: salesforce-custom-object
|
||||
description: Generate CustomObject metadata XML following Salesforce best practices. Ensures correct sharing models, name fields, and required elements. Use when creating new custom objects or modifying existing object metadata.
|
||||
---
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when you need to:
|
||||
- Create new custom objects
|
||||
- Generate custom object metadata XML
|
||||
- Configure object sharing and security settings
|
||||
- Set up object features and capabilities
|
||||
- Troubleshoot deployment errors related to custom objects
|
||||
|
||||
## Specification
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This document defines the mandatory constraints for generating CustomObject metadata XML (`.object` file). The agent must verify these constraints before outputting XML to prevent Metadata API deployment errors.
|
||||
|
||||
---
|
||||
|
||||
## 2. Syntactic Essentials (Tier 1)
|
||||
|
||||
The following constraints must be true for the XML body to deploy successfully.
|
||||
|
||||
**Note:** The API Name (fullName) is NOT a tag; it is the filename (e.g., `Vehicle__c.object`).
|
||||
|
||||
### Required Elements
|
||||
|
||||
| Element | Requirement | Notes |
|
||||
|---------|-------------|-------|
|
||||
| `<label>` | Required | Singular UI name |
|
||||
| `<pluralLabel>` | Required | Plural UI name |
|
||||
| `<sharingModel>` | Required | See Sharing Model Rules below |
|
||||
| `<deploymentStatus>` | Required | Always set to `Deployed` |
|
||||
| `<nameField>` | Required | Primary record identifier (requires `<label>` and `<type>`) |
|
||||
| `<visibility>` | Required | Always set to `Public` |
|
||||
|
||||
### Sharing Model Rules
|
||||
|
||||
**Default:** Set `<sharingModel>` to `ReadWrite`.
|
||||
|
||||
**Exception:** If this object contains a Master-Detail relationship field, `<sharingModel>` MUST be `ControlledByParent`.
|
||||
|
||||
**Decision Logic:**
|
||||
- IF object has NO Master-Detail field → use `ReadWrite`
|
||||
- IF object has Master-Detail field → use `ControlledByParent`
|
||||
- IF a Master-Detail field is being added to an existing child object → that existing object's `<sharingModel>` must also be updated to `ControlledByParent`
|
||||
|
||||
**❌ INCORRECT** — Will cause error: `Cannot set sharingModel to ReadWrite on a CustomObject with a MasterDetail relationship field`
|
||||
```xml
|
||||
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<label>Order Line Item</label>
|
||||
<pluralLabel>Order Line Items</pluralLabel>
|
||||
<sharingModel>ReadWrite</sharingModel> <!-- WRONG: Object has a M-D field -->
|
||||
<deploymentStatus>Deployed</deploymentStatus>
|
||||
</CustomObject>
|
||||
```
|
||||
|
||||
**✅ CORRECT:**
|
||||
```xml
|
||||
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<label>Order Line Item</label>
|
||||
<pluralLabel>Order Line Items</pluralLabel>
|
||||
<sharingModel>ControlledByParent</sharingModel> <!-- CORRECT -->
|
||||
<deploymentStatus>Deployed</deploymentStatus>
|
||||
</CustomObject>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Smart Defaults & Decision Logic (Tier 2)
|
||||
|
||||
The agent must choose which features to enable based on the object's intended use case.
|
||||
|
||||
### A. The Name Field Decision
|
||||
|
||||
| Type | When to Use | Additional Requirements |
|
||||
|------|-------------|------------------------|
|
||||
| **Text** | Default for human-named entities (Projects, Locations, Teams) | None |
|
||||
| **AutoNumber** | Use for transactions, logs, or IDs (Invoices, Requests, Tickets) | Must include `<displayFormat>` (e.g., `INV-{0000}`) and `<startingNumber>1</startingNumber>` |
|
||||
|
||||
**Text Name Field Example:**
|
||||
```xml
|
||||
<nameField>
|
||||
<label>Project Name</label>
|
||||
<type>Text</type>
|
||||
</nameField>
|
||||
```
|
||||
|
||||
**AutoNumber Name Field Example:**
|
||||
```xml
|
||||
<nameField>
|
||||
<label>Invoice Number</label>
|
||||
<type>AutoNumber</type>
|
||||
<displayFormat>INV-{0000}</displayFormat>
|
||||
<startingNumber>1</startingNumber>
|
||||
</nameField>
|
||||
```
|
||||
|
||||
### B. Object Description
|
||||
|
||||
**`<description>`**: Mandatory. Every object must contain a professional summary.
|
||||
|
||||
If the intent is vague, generate a summary:
|
||||
> "Object used to track and manage [Intent] within the organization."
|
||||
### C. Junction Object Naming
|
||||
|
||||
If the object is a many-to-many link between two parents, name the object by combining the two parent entities to ensure the schema remains intuitive.
|
||||
|
||||
**Examples:**
|
||||
- `Position_Candidate__c` (links Position and Candidate)
|
||||
- `Job_Application__c` (links Job and Application)
|
||||
|
||||
### D. Feature Enablement (Clean XML)
|
||||
|
||||
To maintain "Clean XML," only include optional tags when deviating from the Salesforce platform default of `false`.
|
||||
|
||||
**Scenario A: User-Facing Objects (Apps, Trackers, Business Entities)**
|
||||
- Trigger: The object is intended for direct user interaction
|
||||
- Action: Set `<enableSearch>`, `<enableReports>`, `<enableActivities>`, and `<enableHistory>` to `true`
|
||||
|
||||
**Scenario B: System-Facing Objects (Junctions, Background Logs)**
|
||||
- Trigger: The object exists for technical associations or background data
|
||||
- Action: Omit these tags to keep the UI clean and the XML lean
|
||||
|
||||
---
|
||||
|
||||
## 4. Critical Constraints & Common Failures
|
||||
|
||||
### Reserved Words
|
||||
|
||||
Never use reserved words as API names for Custom Objects or Custom Fields:
|
||||
|
||||
| Category | Reserved Words (Do Not Use as API Names) |
|
||||
|----------|------------------------------------------|
|
||||
| SOQL/SQL | `Select`, `From`, `Where`, `Limit`, `Order`, `Group` |
|
||||
| System | `User`, `External`, `View`, `Type` |
|
||||
| Temporal | `Date`, `Number` |
|
||||
|
||||
### Relationship Cap
|
||||
|
||||
Do not create more than **2 Master-Detail relationships** for a single object. If a third relationship is required, use a Lookup instead.
|
||||
|
||||
### XML Root Element
|
||||
|
||||
Do NOT include the `<fullName>` tag at the root of the `.object` XML file. The API name is derived from the filename.
|
||||
|
||||
**❌ INCORRECT:**
|
||||
```xml
|
||||
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Vehicle__c</fullName> <!-- WRONG: Remove this -->
|
||||
<label>Vehicle</label>
|
||||
</CustomObject>
|
||||
```
|
||||
|
||||
**✅ CORRECT:**
|
||||
```xml
|
||||
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<label>Vehicle</label>
|
||||
<!-- fullName comes from filename: Vehicle__c.object -->
|
||||
</CustomObject>
|
||||
```
|
||||
|
||||
### Validation Rule Naming Convention
|
||||
|
||||
Validation rule names follow different conventions than custom fields.
|
||||
|
||||
**Rules:**
|
||||
- Must contain only alphanumeric characters and underscores
|
||||
- Must begin with a letter
|
||||
- Cannot end with an underscore
|
||||
- Cannot contain two consecutive underscores
|
||||
- **Must NOT end with `__c`** (unlike custom fields)
|
||||
|
||||
**❌ INCORRECT:**
|
||||
```xml
|
||||
<validationRules>
|
||||
<fullName>Require_Start_Date__c</fullName> <!-- WRONG: Has __c suffix -->
|
||||
<active>true</active>
|
||||
<errorMessage>Start Date is required.</errorMessage>
|
||||
<formula>ISBLANK(Start_Date__c)</formula>
|
||||
</validationRules>
|
||||
```
|
||||
**Error:** `The validation name can only contain alphanumeric characters, must begin with a letter, cannot end with an underscore...`
|
||||
|
||||
**✅ CORRECT:**
|
||||
```xml
|
||||
<validationRules>
|
||||
<fullName>Require_Start_Date</fullName> <!-- CORRECT: No __c suffix -->
|
||||
<active>true</active>
|
||||
<errorMessage>Start Date is required.</errorMessage>
|
||||
<formula>ISBLANK(Start_Date__c)</formula>
|
||||
</validationRules>
|
||||
```
|
||||
|
||||
**Naming Pattern Reference:**
|
||||
|
||||
| Metadata Type | Naming Pattern | Example |
|
||||
|---------------|----------------|---------|
|
||||
| Custom Fields | Ends with `__c` | `Start_Date__c` |
|
||||
| Validation Rules | No suffix | `Require_Start_Date` |
|
||||
| Custom Objects | Ends with `__c` | `Vehicle__c` |
|
||||
|
||||
---
|
||||
|
||||
## 5. Verification Checklist
|
||||
|
||||
Before generating the Custom Object XML, verify:
|
||||
|
||||
### Syntactic Checks
|
||||
- [ ] Are both `<label>` and `<pluralLabel>` present?
|
||||
- [ ] Is `<deploymentStatus>` set to `Deployed`?
|
||||
- [ ] Is `<visibility>` set to `Public`?
|
||||
- [ ] Does `<nameField>` include both `<label>` and `<type>`?
|
||||
- [ ] If `<type>` is `AutoNumber`, are `<displayFormat>` and `<startingNumber>` included?
|
||||
|
||||
### Sharing Model Check (Critical)
|
||||
- [ ] Does this object have a Master-Detail relationship field?
|
||||
- If YES → `<sharingModel>` MUST be `ControlledByParent`
|
||||
- If NO → `<sharingModel>` should be `ReadWrite`
|
||||
|
||||
### Constraint Checks
|
||||
- [ ] Is the API name free of reserved words?
|
||||
- [ ] Are there 2 or fewer Master-Detail relationships?
|
||||
- [ ] Is `<fullName>` absent from the XML root?
|
||||
|
||||
### Validation Rule Checks (if applicable)
|
||||
- [ ] Do validation rule names NOT end with `__c`?
|
||||
- [ ] Do validation rule names follow alphanumeric + underscore pattern?
|
||||
|
||||
### Architectural Checks
|
||||
- [ ] Is `<description>` present with a meaningful summary?
|
||||
- [ ] Are `<enableSearch>` and `<enableReports>` set to `true` if user-facing?
|
||||
- [ ] Does the filename match the intended API name?
|
||||
@ -0,0 +1,78 @@
|
||||
---
|
||||
name: salesforce-custom-tab
|
||||
description: Generate CustomTab metadata XML for object tabs, web tabs, or Visualforce tabs. Use when adding navigation tabs to Salesforce applications.
|
||||
---
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when you need to:
|
||||
- Create tabs for objects, web pages, or Visualforce pages
|
||||
- Add navigation tabs to applications
|
||||
- Configure tab visibility and access
|
||||
- Troubleshoot deployment errors related to custom tabs
|
||||
|
||||
## Specification
|
||||
|
||||
# CustomTab Metadata Specification
|
||||
|
||||
## 📋 Overview
|
||||
Custom tabs for navigating to objects, web content, or Visualforce pages within Salesforce applications.
|
||||
|
||||
## 🎯 Purpose
|
||||
- Provide navigation to custom objects
|
||||
- Link to external web content
|
||||
- Access Visualforce pages
|
||||
- Organize application navigation
|
||||
|
||||
## ⚙️ Required Properties
|
||||
|
||||
### Core Tab Properties
|
||||
- **label**: Display name of the tab
|
||||
- **fullName**: API name of the object (for object tabs)
|
||||
- **url**: Web URL (for web tabs)
|
||||
- **page**: Visualforce page name (for Visualforce tabs)
|
||||
|
||||
## 🔧 Tab Types
|
||||
|
||||
### Object Tabs
|
||||
- **Purpose**: Navigate to custom or standard objects
|
||||
- **Required**: `fullName` property (set to object API name)
|
||||
- **Example**: `<fullName>CustomObject__c</fullName>`
|
||||
|
||||
### Web Tabs
|
||||
- **Purpose**: Link to external websites or web applications
|
||||
- **Required**: `url` property
|
||||
- **Example**: `<url>https://example.com</url>`
|
||||
|
||||
### Visualforce Tabs
|
||||
- **Purpose**: Access custom Visualforce pages
|
||||
- **Required**: `page` property
|
||||
- **Example**: `<page>CustomPage</page>`
|
||||
|
||||
## 🎨 Tab Configuration
|
||||
|
||||
### Tab Style
|
||||
- **Default**: Use standard tab styling
|
||||
- **Custom**: Can specify custom tab styles if needed
|
||||
|
||||
### Tab Visibility
|
||||
- **Default**: Visible to all users with access
|
||||
- **Custom**: Can be configured for specific user profiles
|
||||
|
||||
## 📱 Supported Applications
|
||||
- **Standard Apps**: Available in standard Salesforce applications
|
||||
- **Custom Apps**: Can be included in custom applications
|
||||
- **Community Apps**: Available in community applications
|
||||
|
||||
## 🔗 Integration Points
|
||||
- **Object Relationships**: Links to related object records
|
||||
- **Web Content**: External website integration
|
||||
- **Visualforce Pages**: Custom page functionality
|
||||
- **Lightning Components**: Modern component integration
|
||||
## ✅ Best Practices
|
||||
- Use clear, descriptive tab labels
|
||||
- Choose appropriate tab types for functionality
|
||||
- Consider user experience and navigation flow
|
||||
- Test tab functionality across different applications
|
||||
- Ensure proper permissions and visibility settings
|
||||
- Follow consistent naming conventions
|
||||
@ -0,0 +1,186 @@
|
||||
---
|
||||
name: salesforce-experience-site
|
||||
description: Generate Digital Experience Site metadata including Network, CustomSite, and DigitalExperienceBundle configurations. Use when creating Experience Cloud sites or web apps.
|
||||
---
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when you need to:
|
||||
- Create Experience Cloud sites or communities
|
||||
- Build customer-facing portals
|
||||
- Set up site configuration and settings
|
||||
- Generate Experience Site metadata
|
||||
- Troubleshoot deployment errors related to Experience Sites
|
||||
|
||||
## Specification
|
||||
|
||||
# Digital Experience Site Metadata Specification
|
||||
|
||||
## 📋 Overview
|
||||
Digital Experience Sites for building and hosting websites backed by either Salesforce or web app (React) metadata.
|
||||
|
||||
## 🎯 Purpose
|
||||
- Provide a website for retail and customer services.
|
||||
- Use either Salesforce Experience metadata or something else like React or Angular.
|
||||
- Configure site, network, and app settings for the website.
|
||||
|
||||
## ⚙️ Required Properties
|
||||
### Core Site Properties
|
||||
- **siteName**: You must determine the name of the site. You must make the name `UpperCamelCase` (e.g., `'MyCommunity'`).
|
||||
- **siteUrlPathPrefix**. You must determine the url path prefix of the site. You must make the url path prefix `kebab-case`. You must convert the site name to the url prefix if an explicit prefix is not provided (e.g., `'my-community'`).
|
||||
- **templateType**: You must determine what type of template is being used for the site. Default to `OneRuntime`.
|
||||
|
||||
## 🔧 Site Template Types
|
||||
### OneRuntime
|
||||
- **Purpose**: Support a site or web app backed by a non-Salesforce metadata framework like React or Angular
|
||||
|
||||
## 🔄 Generation Workflow
|
||||
You must follow the steps below to generate insertable Digital Experience Site metadata.
|
||||
|
||||
### Step 1: Determine the Template Type
|
||||
- You must first determine the template type of the Experience Site using the Site Template Types section.
|
||||
|
||||
### Step 2: Use Template Type to Get Metadata Configurations for Project Structure and Fields
|
||||
- You must determine the project structure and fields for the chosen template type.
|
||||
- You must resolve all properties and fields.
|
||||
- You must use the following configurations for OneRuntime template type:
|
||||
|
||||
#### OneRuntime Template Type Configuration
|
||||
#### Project Structure
|
||||
#### Additional Instructions
|
||||
- You must construct the project folders to match the provided paths.
|
||||
- You must use the `get_metadata_api_context` MCP tool to get the schemas for `DigitalExperienceConfig`, `DigitalExperienceBundle`, `Network`, and `CustomSite`.
|
||||
|
||||
#### Configuration
|
||||
- DigitalExperienceConfig
|
||||
- Path: `digitalExperienceConfigs/{siteName}1.digitalExperienceConfig`
|
||||
- DigitalExperienceBundle
|
||||
- Path: `digitalExperiences/site/{siteName}1/{siteName}1.digitalExperience-meta.xml`
|
||||
- Network
|
||||
- Path: `networks/{siteName}.network`
|
||||
- CustomSite
|
||||
- Path: `sites/{siteName}.site`
|
||||
- DigitalExperience
|
||||
- Path: `digitalExperiences/site/{siteName}1/{contentType}/{apiName}/*`
|
||||
- Description: These are the content component directories defining site and language information. Each directory must have a `_meta.json` and `content.json` file.
|
||||
- Required component content types (`contentType`):
|
||||
- `sfdc_cms__site`
|
||||
|
||||
#### Fields
|
||||
#### Additional Site Properties
|
||||
- **namespace**: You must determine the namespace of the React app. Default to empty.
|
||||
- **appDevName**. You must determine the developer name of the React app. Default to empty.
|
||||
|
||||
#### Configuration
|
||||
- `DigitalExperienceConfig`
|
||||
- label: {siteName}
|
||||
- urlPathPrefix: {siteUrlPathPrefix}
|
||||
- space: site/{siteName}1
|
||||
|
||||
- `DigitalExperienceBundle`
|
||||
- label: {siteName}1
|
||||
|
||||
- `Network`
|
||||
- allowInternalUserLogin: false
|
||||
- allowMembersToFlag: false
|
||||
- changePasswordTemplate: unfiled$public/CommunityChangePasswordEmailTemplate
|
||||
- disableReputationRecordConversations: true
|
||||
- emailSenderAddress: admin@company.com
|
||||
- emailSenderName: {siteName}
|
||||
- embeddedLoginEnabled: false
|
||||
- enableApexCDNCaching: true
|
||||
- enableCustomVFErrorPageOverrides: false
|
||||
- enableDirectMessages: true
|
||||
- enableExpFriendlyUrlsAsDefault: false
|
||||
- enableExperienceBundleBasedSnaOverrideEnabled: true
|
||||
- enableGuestChatter: false
|
||||
- enableGuestFileAccess: false
|
||||
- enableGuestMemberVisibility: false
|
||||
- enableImageOptimizationCDN: true
|
||||
- enableInvitation: false
|
||||
- enableKnowledgeable: false
|
||||
- enableLWRExperienceConnectedApp: true
|
||||
- enableMemberVisibility: false
|
||||
- enableNicknameDisplay: true
|
||||
- enablePrivateMessages: false
|
||||
- enableReputation: false
|
||||
- enableShowAllNetworkSettings: false
|
||||
- enableSiteAsContainer: true
|
||||
- enableTalkingAboutStats: true
|
||||
- enableTopicAssignmentRules: true
|
||||
- enableTopicSuggestions: false
|
||||
- enableUpDownVote: false
|
||||
- forgotPasswordTemplate: unfiled$public/CommunityForgotPasswordEmailTemplate
|
||||
- gatherCustomerSentimentData: false
|
||||
- headlessForgotPasswordTemplate: unfiled$public/CommunityHeadlessForgotPasswordTemplate
|
||||
- headlessRegistrationTemplate: unfiled$public/CommunityHeadlessRegistrationTemplate
|
||||
- networkMemberGroups:
|
||||
- profile: admin
|
||||
- networkPageOverrides:
|
||||
- changePasswordPageOverrideSetting: Standard
|
||||
- forgotPasswordPageOverrideSetting: Designer
|
||||
- homePageOverrideSetting: Designer
|
||||
- loginPageOverrideSetting: Designer
|
||||
- selfRegProfilePageOverrideSetting: Designer
|
||||
- newSenderAddress: admin@company.com
|
||||
- picassoSite: {siteName}1
|
||||
- selfRegistration: false
|
||||
- sendWelcomeEmail: true
|
||||
- site: {siteName}
|
||||
- siteArchiveStatus: NotArchived
|
||||
- status: UnderConstruction
|
||||
- tabs:
|
||||
- defaultTab: home
|
||||
- standardTab: Chatter
|
||||
- urlPathPrefix: {siteUrlPathPrefix}vforcesite
|
||||
- welcomeTemplate: unfiled$public/CommunityWelcomeEmailTemplate
|
||||
|
||||
- `CustomSite`
|
||||
- active: true
|
||||
- allowGuestPaymentsApi: false
|
||||
- allowHomePage: false
|
||||
- allowStandardAnswersPages: false
|
||||
- allowStandardIdeasPages: false
|
||||
- allowStandardLookups: false
|
||||
- allowStandardPortalPages: true
|
||||
- allowStandardSearch: false
|
||||
- authorizationRequiredPage: CommunitiesLogin
|
||||
- bandwidthExceededPage: BandwidthExceeded
|
||||
- browserXssProtection: true
|
||||
- cachePublicVisualforcePagesInProxyServers: true
|
||||
- clickjackProtectionLevel: SameOriginOnly
|
||||
- contentSniffingProtection: true
|
||||
- enableAuraRequests: true
|
||||
- fileNotFoundPage: FileNotFound
|
||||
- genericErrorPage: Exception
|
||||
- inMaintenancePage: InMaintenance
|
||||
- indexPage: CommunitiesLanding
|
||||
- masterLabel: {siteName}
|
||||
- redirectToCustomDomain: false
|
||||
- referrerPolicyOriginWhenCrossOrigin: true
|
||||
- selfRegPage: CommunitiesSelfReg
|
||||
- siteType: ChatterNetwork
|
||||
- urlPathPrefix: {siteUrlPathPrefix}vforcesite
|
||||
|
||||
- `DigitalExperience`
|
||||
1. sfdc_cms__site
|
||||
- apiName: {siteName}1
|
||||
- type: sfdc_cms__site
|
||||
- title: {siteName}
|
||||
- urlName: {siteUrlPathPrefix}
|
||||
- contentBody:
|
||||
- authenticationType: AUTHENTICATED_WITH_PUBLIC_ACCESS_ENABLED
|
||||
- appContainer: true
|
||||
- appSpace: {namespace}__{appDevName}
|
||||
|
||||
### Step 3: Create a Project Structure for the Chosen Template Type
|
||||
You must construct a metadata project folder using the knowledge from Step 2.
|
||||
|
||||
### Step 4: Resolve All Required Fields for the Chosen Template Type
|
||||
You must determine values for all required metadata fields using the knowledge from Step 2.
|
||||
|
||||
## ✅ Verification Checklist
|
||||
- [ ] All properties are resolved.
|
||||
- [ ] All metadata directories and files are created based on the template type configurations.
|
||||
- [ ] All metadata fields are populated based on the template type configurations.
|
||||
- [ ] All metadata is validated by running CLI command `sf project deploy validate --metadata DigitalExperienceBundle DigitalExperience DigitalExperienceConfig Network CustomSite --target-org ${usernameOrAlias}`
|
||||
472
skills/salesforce-metadata-experts/salesforce-flexipage/SKILL.md
Normal file
472
skills/salesforce-metadata-experts/salesforce-flexipage/SKILL.md
Normal file
@ -0,0 +1,472 @@
|
||||
---
|
||||
name: salesforce-flexipage
|
||||
description: Generate FlexiPage metadata using CLI bootstrapping and MCP actions for component discovery. Use when creating Record Pages, App Pages, or Home Pages in Lightning Experience.
|
||||
---
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when you need to:
|
||||
- Create Lightning pages (Record, App, or Home pages)
|
||||
- Build custom page layouts in Lightning Experience
|
||||
- Add components to Lightning pages
|
||||
- Configure page structure and components
|
||||
- Troubleshoot deployment errors related to FlexiPages
|
||||
|
||||
## Specification
|
||||
|
||||
# FlexiPage Generation Guide
|
||||
|
||||
## Overview
|
||||
Generate Lightning pages (RecordPage, AppPage, HomePage) using CLI bootstrapping + MCP actions for component discovery and configuration.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start Workflow
|
||||
|
||||
### Step 1: Bootstrap with CLI
|
||||
|
||||
```bash
|
||||
sf template generate flexipage \
|
||||
--name <PageName> \
|
||||
--template <RecordPage|AppPage|HomePage> \
|
||||
--sobject <SObject> \
|
||||
--primary-field <Field1> \
|
||||
--secondary-fields <Field2,Field3> \
|
||||
--detail-fields <Field4,Field5,Field6,Field7> \
|
||||
--output-dir force-app/main/default/flexipages
|
||||
```
|
||||
|
||||
**Template-specific requirements:**
|
||||
- **RecordPage**: Requires `--sobject` (e.g., Account, Custom_Object__c)
|
||||
- **RecordPage**: Requires `--primary-field` and `--secondary-fields` for dynamic highlights, `--detail-fields` for full record details. Use the most important identifying field as primary, e.g. Name. Use the secondary fields (max 12, recommended 4-6) to show a summary of the record. Use Use detail fields to show the full details of the record.
|
||||
- **AppPage**: No additional requirements
|
||||
- **HomePage**: No additional requirements
|
||||
|
||||
**What you get:**
|
||||
- Valid FlexiPage XML with correct structure
|
||||
- Pre-configured regions and basic components
|
||||
- Proper field references and facet structure
|
||||
- Ready to deploy as-is or enhance further
|
||||
|
||||
### Step 2: Deploy Base Page
|
||||
|
||||
```bash
|
||||
sf project deploy start --source-dir force-app/main/default/flexipages
|
||||
```
|
||||
|
||||
**Deploy early, deploy often.** Start with the bootstrapped page, validate it works, then enhance.
|
||||
|
||||
### Step 3: Enhance with MCP Actions (Optional)
|
||||
|
||||
If you need to add more components or customize:
|
||||
|
||||
#### A. Discover Available Components
|
||||
```
|
||||
DISCOVER_UI_COMPONENTS
|
||||
```
|
||||
Returns: List of components available for this page type with descriptions.
|
||||
|
||||
#### B. Get Component Schemas
|
||||
```
|
||||
GET_UI_COMPONENT_SCHEMAS
|
||||
```
|
||||
Returns: JSON schemas showing required/optional properties, types, data sources. Also includes instructions specific to each component.
|
||||
|
||||
#### C. Get Data Source Values
|
||||
```
|
||||
GET_DATA_SOURCE_VALUES
|
||||
```
|
||||
Returns: Valid values for properties with data sources.
|
||||
|
||||
### Step 4: Update and Redeploy
|
||||
|
||||
Modify the generated XML, adding components discovered via MCP. Deploy incrementally.
|
||||
|
||||
---
|
||||
|
||||
## Critical XML Rules
|
||||
|
||||
### 1. Property Value Encoding (MOST COMMON ERROR)
|
||||
|
||||
**Any property value with HTML/XML characters MUST be manually encoded in the following order** (wrong order causes double-encoding corruption):
|
||||
|
||||
```
|
||||
1. & → & (FIRST! Encode this before others)
|
||||
2. < → <
|
||||
3. > → >
|
||||
4. " → "
|
||||
5. ' → '
|
||||
```
|
||||
|
||||
**Wrong:**
|
||||
```xml
|
||||
<value><b>Important</b> text</value>
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
```xml
|
||||
<value><b>Important</b> text</value>
|
||||
```
|
||||
|
||||
**Check your XML:** Search for `<value>` tags - they should never contain raw `<` or `>` characters.
|
||||
|
||||
### 2. Field References
|
||||
|
||||
**ALWAYS:** `Record.{FieldApiName}`
|
||||
**NEVER:** `{ObjectName}.{FieldApiName}`
|
||||
|
||||
```xml
|
||||
<!-- Correct -->
|
||||
<fieldItem>Record.Name</fieldItem>
|
||||
|
||||
<!-- Wrong -->
|
||||
<fieldItem>Account.Name</fieldItem>
|
||||
```
|
||||
|
||||
### 3. Region vs Facet Types
|
||||
|
||||
**Template Regions** (header, main, sidebar):
|
||||
```xml
|
||||
<name>header</name>
|
||||
<type>Region</type>
|
||||
```
|
||||
|
||||
**Component Facets** (internal slots like fieldSection columns):
|
||||
```xml
|
||||
<name>Facet-12345</name>
|
||||
<type>Facet</type>
|
||||
```
|
||||
|
||||
**Rule:** If it's a template region name → `Region`. If it's a component slot → `Facet`.
|
||||
|
||||
### 4. fieldInstance Structure
|
||||
|
||||
Every fieldInstance requires:
|
||||
```xml
|
||||
<itemInstances>
|
||||
<fieldInstance>
|
||||
<fieldInstanceProperties>
|
||||
<name>uiBehavior</name>
|
||||
<value>none</value> <!-- none|readonly|required -->
|
||||
</fieldInstanceProperties>
|
||||
<fieldItem>Record.FieldName__c</fieldItem>
|
||||
<identifier>RecordFieldName_cField</identifier>
|
||||
</fieldInstance>
|
||||
</itemInstances>
|
||||
```
|
||||
|
||||
**Rules:**
|
||||
- Each fieldInstance in its own `<itemInstances>` wrapper
|
||||
- Must have `fieldInstanceProperties` with `uiBehavior`
|
||||
- Use `Record.{Field}` format
|
||||
|
||||
---
|
||||
|
||||
## Using MCP Actions
|
||||
|
||||
### When to Use Each Action
|
||||
|
||||
#### DISCOVER_UI_COMPONENTS
|
||||
**When:** You want to see what components are available for your page type.
|
||||
|
||||
**Returns:** Component list with names, namespaces, descriptions.
|
||||
|
||||
**Use for:** Finding components to add to your bootstrapped page.
|
||||
|
||||
#### GET_UI_COMPONENT_SCHEMAS
|
||||
**When:** You know which components you want but need to understand their properties. If you have issues configuring a component and need more detailed instructions or knowledge.
|
||||
|
||||
**Returns:** JSON schemas with:
|
||||
- Required vs optional properties
|
||||
- Property types (string, boolean, array, etc.)
|
||||
- Data source references
|
||||
- Descriptions
|
||||
- Additional component-specific instructions or knowledge, often useful for more complex components.
|
||||
|
||||
**Use for:** Understanding how to configure components before adding to XML.
|
||||
|
||||
#### GET_DATA_SOURCE_VALUES
|
||||
**When:** A component property references a data source and you need valid values.
|
||||
|
||||
**Returns:** Valid values (e.g., "1", "2", "3" for column count).
|
||||
|
||||
**Use for:** Ensuring property values match allowed options.
|
||||
|
||||
---
|
||||
|
||||
## Common Deployment Errors
|
||||
|
||||
### "Invalid field reference"
|
||||
**Cause:** Used `ObjectName.Field` instead of `Record.Field`
|
||||
**Fix:** Change to `Record.{FieldApiName}`
|
||||
|
||||
### "Element fieldInstance is duplicated"
|
||||
**Cause:** Multiple fieldInstances in one itemInstances
|
||||
**Fix:** Each fieldInstance needs its own `<itemInstances>` wrapper
|
||||
|
||||
### "Missing fieldInstanceProperties"
|
||||
**Cause:** No uiBehavior specified
|
||||
**Fix:** Add `fieldInstanceProperties` with `uiBehavior`
|
||||
|
||||
### "Invalid component property"
|
||||
**Cause:** Wrong property name or format
|
||||
**Fix:** Use `GET_UI_COMPONENT_SCHEMAS` to see exact property names and types, or to find additional documentation.
|
||||
|
||||
### "Unused Facet"
|
||||
**Cause:** Facet defined but not referenced by any component
|
||||
**Fix:** Remove Facet or reference it in a component property
|
||||
|
||||
### "XML parsing error"
|
||||
**Cause:** Unencoded HTML/XML in property values
|
||||
**Fix:** Manually encode `<`, `>`, `&`, `"`, `'` in all `<value>` tags
|
||||
|
||||
### "Cannot create component with namespace"
|
||||
**Cause:** Invalid page name (don't use `__c` suffix in page names)
|
||||
**Fix:** Use "Volunteer_Record_Page" not "Volunteer__c_Record_Page"
|
||||
|
||||
### "Region specifies mode that parent doesn't support"
|
||||
**Cause:** Added `<mode>` tag to region
|
||||
**Fix:** Remove `<mode>` tags - they're not needed for standard regions
|
||||
|
||||
---
|
||||
|
||||
## Component-Specific Tips
|
||||
|
||||
### dynamicHighlights (RecordPage Header)
|
||||
|
||||
**Location:** Must be in `header` region.
|
||||
**Explicit Fields** (via CLI): Use the most important fields to show a summary of the record. The single primary field is used to identify the record, like a name. The secondary fields (max 12, recommended 6) are used as a summary of the record.
|
||||
```bash
|
||||
--primary-field Name
|
||||
--secondary-fields Phone,Industry,AnnualRevenue
|
||||
```
|
||||
CLI generates Facets with field references automatically.
|
||||
|
||||
### fieldSection
|
||||
|
||||
**Use for:** Displaying fields in columns.
|
||||
|
||||
**Structure:** Three-level nesting:
|
||||
1. Template Region (Region type)
|
||||
2. Column Facets (Facet type)
|
||||
3. Field Facets (Facet type)
|
||||
|
||||
**Referenced in component property:**
|
||||
```xml
|
||||
<componentInstanceProperties>
|
||||
<name>columns</name>
|
||||
<value>Facet-{uuid}</value>
|
||||
</componentInstanceProperties>
|
||||
```
|
||||
---
|
||||
|
||||
## Incremental Development Pattern
|
||||
|
||||
**Philosophy:** Deploy small, working increments. Don't build entire complex page at once.
|
||||
|
||||
**Process:**
|
||||
1. **CLI bootstrap** → Deploy base page
|
||||
2. **Add one component** → Deploy
|
||||
3. **Add another component** → Deploy
|
||||
4. **Repeat** until complete
|
||||
|
||||
**Benefits:**
|
||||
- Isolated errors (know exactly what broke)
|
||||
- Faster debugging
|
||||
- Build confidence with each success
|
||||
- Get user feedback early
|
||||
|
||||
**Anti-pattern:** Building entire complex page → one giant error cascade.
|
||||
|
||||
---
|
||||
|
||||
## Adding Components to Existing FlexiPages
|
||||
|
||||
### Workflow
|
||||
|
||||
When user provides an existing FlexiPage file path:
|
||||
|
||||
1. **Read the file** using native file I/O
|
||||
2. **Parse XML** to extract:
|
||||
- Existing component identifiers
|
||||
- Available regions (parse from file, don't assume names)
|
||||
- Existing facets
|
||||
3. **Use MCP actions** for discovery:
|
||||
- DISCOVER_UI_COMPONENTS (find available components)
|
||||
- GET_UI_COMPONENT_SCHEMAS (understand properties and get additional documentation)
|
||||
- GET_DATA_SOURCE_VALUES (validate data source values)
|
||||
4. **Generate component XML** (apply all rules from "Critical XML Rules" section)
|
||||
5. **Insert** into appropriate region
|
||||
6. **Write** modified XML back to file
|
||||
7. **Deploy**: `sf project deploy start --source-dir force-app/...`
|
||||
|
||||
---
|
||||
|
||||
### Generating Unique Identifiers
|
||||
|
||||
**Algorithm**:
|
||||
```
|
||||
1. Extract all existing <identifier> values from XML
|
||||
2. Generate base name: {componentType}_{context}
|
||||
Examples: "relatedList_contacts", "richText_header", "tabs_main"
|
||||
3. Find first available number:
|
||||
- Try "{base}_1"
|
||||
- If exists, try "{base}_2", "{base}_3", etc.
|
||||
- Use first available
|
||||
```
|
||||
|
||||
**Examples**:
|
||||
- First contacts related list: `relatedList_contacts_1`
|
||||
- Second contacts related list: `relatedList_contacts_2`
|
||||
- Rich text in header: `richText_header_1`
|
||||
- Field section: `fieldSection_details_1`
|
||||
|
||||
**Facet Naming - Two Patterns**:
|
||||
|
||||
1. **Named facets** (for major content areas):
|
||||
- `detailTabContent` (detail tab content)
|
||||
- `maintabs` (main tab container)
|
||||
- `sidebartabs` (sidebar tab container)
|
||||
- Use when facet represents meaningful content area
|
||||
|
||||
2. **UUID facets** (for internal structure):
|
||||
- Format: `Facet-{8hex}-{4hex}-{4hex}-{4hex}-{12hex}`
|
||||
- Example: `Facet-66d5a4b3-bf14-4665-ba75-1ceaa71b2cde`
|
||||
- Use for field section columns, nested containers, anonymous slots
|
||||
|
||||
---
|
||||
|
||||
### Region Selection
|
||||
|
||||
**Parse regions from file** - don't hardcode names. Templates vary:
|
||||
- `flexipage:recordHomeTemplateDesktop` → `header`, `main`, `sidebar`
|
||||
- `runtime_service_fieldservice:...` → `header`, `main`, `footer`
|
||||
- Others may have different region names
|
||||
|
||||
**Default placement**: End of target region (after last `<itemInstances>`)
|
||||
|
||||
**Insertion pattern**:
|
||||
```xml
|
||||
<flexiPageRegions>
|
||||
<name>main</name> <!-- or whatever region name exists -->
|
||||
<type>Region</type>
|
||||
<itemInstances><!-- Existing component 1 --></itemInstances>
|
||||
<itemInstances><!-- Existing component 2 --></itemInstances>
|
||||
<itemInstances>
|
||||
<!-- INSERT NEW COMPONENT HERE -->
|
||||
</itemInstances>
|
||||
</flexiPageRegions>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Container Components with Facets
|
||||
|
||||
Components like tabs, accordions, field sections require facets.
|
||||
|
||||
**Pattern**:
|
||||
```xml
|
||||
<!-- 1. Component in region -->
|
||||
<flexiPageRegions>
|
||||
<itemInstances>
|
||||
<componentInstance>
|
||||
<componentName>flexipage:tabset2</componentName>
|
||||
<identifier>tabs_main_1</identifier>
|
||||
<componentInstanceProperties>
|
||||
<name>tabs</name>
|
||||
<value>tab1_content</value>
|
||||
<value>tab2_content</value>
|
||||
</componentInstanceProperties>
|
||||
</componentInstance>
|
||||
</itemInstances>
|
||||
<name>main</name>
|
||||
<type>Region</type>
|
||||
</flexiPageRegions>
|
||||
|
||||
<!-- 2. Facets (siblings of region, NOT nested inside) -->
|
||||
<flexiPageRegions>
|
||||
<itemInstances><!-- Tab 1 content --></itemInstances>
|
||||
<name>tab1_content</name>
|
||||
<type>Facet</type>
|
||||
</flexiPageRegions>
|
||||
|
||||
<flexiPageRegions>
|
||||
<itemInstances><!-- Tab 2 content --></itemInstances>
|
||||
<name>tab2_content</name>
|
||||
<type>Facet</type>
|
||||
</flexiPageRegions>
|
||||
```
|
||||
|
||||
**Critical**: Facet regions are siblings of template regions at the same level, not nested inside them.
|
||||
|
||||
---
|
||||
|
||||
## Required Metadata Structure
|
||||
|
||||
```xml
|
||||
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<flexiPageRegions>
|
||||
<!-- Regions and components here -->
|
||||
</flexiPageRegions>
|
||||
<masterLabel>Page Label</masterLabel>
|
||||
<template>
|
||||
<name>flexipage:recordHomeTemplateDesktop</name>
|
||||
</template>
|
||||
<type>RecordPage</type>
|
||||
<sobjectType>Object__c</sobjectType> <!-- RecordPage only -->
|
||||
</FlexiPage>
|
||||
```
|
||||
|
||||
**Page Types:**
|
||||
- `RecordPage` - requires `<sobjectType>`
|
||||
- `AppPage` - no sobjectType
|
||||
- `HomePage` - no sobjectType
|
||||
|
||||
---
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
Before deploying:
|
||||
- [ ] Used CLI to bootstrap (don't start from scratch)
|
||||
- [ ] All field references use `Record.{Field}` format
|
||||
- [ ] Each fieldInstance has `fieldInstanceProperties` with `uiBehavior`
|
||||
- [ ] Each fieldInstance in own `<itemInstances>` wrapper
|
||||
- [ ] Template regions use `<type>Region</type>`
|
||||
- [ ] Component facets use `<type>Facet</type>`
|
||||
- [ ] Property values with HTML/XML are manually encoded
|
||||
- [ ] No `<mode>` tags in regions
|
||||
- [ ] No `__c` suffix in page names
|
||||
- [ ] Each Facet referenced by exactly one component property
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference: CLI Command
|
||||
|
||||
```bash
|
||||
# RecordPage with fields
|
||||
sf template generate flexipage \
|
||||
--name Account_Custom_Page \
|
||||
--template RecordPage \
|
||||
--sobject Account \
|
||||
--primary-field Name \
|
||||
--secondary-fields Phone,Industry,AnnualRevenue \
|
||||
--detail-fields Street,City,State,Name,Phone,Email
|
||||
|
||||
# AppPage
|
||||
sf template generate flexipage \
|
||||
--name Sales_Dashboard \
|
||||
--template AppPage \
|
||||
--label "Sales Dashboard"
|
||||
|
||||
# HomePage
|
||||
sf template generate flexipage \
|
||||
--name Custom_Home \
|
||||
--template HomePage \
|
||||
--description "Custom home for sales team"
|
||||
```
|
||||
|
||||
**All templates support:**
|
||||
- `--output-dir` (default: current directory)
|
||||
- `--api-version` (default: latest)
|
||||
- `--label` (default: page name)
|
||||
- `--description`
|
||||
339
skills/salesforce-metadata-experts/salesforce-flow/SKILL.md
Normal file
339
skills/salesforce-metadata-experts/salesforce-flow/SKILL.md
Normal file
@ -0,0 +1,339 @@
|
||||
---
|
||||
name: salesforce-flow
|
||||
description: Generate Flow metadata using the mandatory 3-step pipeline (fetchGroundedObjectMetadata → flowElementSelection → flowElementGeneration). Use when creating Screen Flows, Autolaunched Flows, Record-Triggered Flows, or Scheduled Flows.
|
||||
---
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when you need to:
|
||||
- Create any type of Flow (Screen, Autolaunched, Record-Triggered, Scheduled)
|
||||
- Generate Flow metadata XML
|
||||
- Automate business processes without code
|
||||
- Build user-guided workflows or background automation
|
||||
- Troubleshoot deployment errors related to Flows
|
||||
|
||||
## Specification
|
||||
|
||||
# Flow Metadata Specification
|
||||
|
||||
## 📋 Overview
|
||||
Salesforce Flows are powerful automation tools that enable complex business process automation without code. Flows can collect and process data through interactive screens, execute logic and calculations, manipulate records, call external services, and trigger based on various events. Flow types include Screen Flows (user-guided), Autolaunched Flows (background processing), Record-Triggered Flows (database events), Scheduled Flows (time-based), and Platform Event-Triggered Flows (event-driven).
|
||||
|
||||
## 🎯 Purpose
|
||||
- Automate complex business processes with declarative logic and branching
|
||||
- Guide users through multi-step data collection and decision workflows via Screen Flows
|
||||
- Perform CRUD operations on Salesforce records automatically
|
||||
- Execute background processing and integrations via Autolaunched Flows
|
||||
- React to record changes in real-time with Record-Triggered Flows
|
||||
- Schedule recurring tasks and batch operations with Scheduled Flows
|
||||
- Create reusable, maintainable automation that admins can modify without code
|
||||
|
||||
## ⚙️ Flow Generation Pipeline
|
||||
|
||||
**🚨 MANDATORY: You MUST follow this exact 3-step pipeline. No exceptions. No shortcuts. No skipping steps. Do NOT manually create flow metadata XML or attempt to generate flow metadata outside of this pipeline. Do NOT attempt to use any other tool, API, or method to generate flow metadata. This pipeline is the ONLY supported way to generate flows. Any deviation will produce invalid or broken metadata.**
|
||||
|
||||
Flow generation is a **strict 3-step pipeline**. ALL steps must be called in order. Every step is required. **There is no alternative approach — this is the only way to generate flow metadata:**
|
||||
|
||||
### Step 1 (REQUIRED): Fetch Grounded Object Metadata (`fetchGroundedObjectMetadata`)
|
||||
Fetches org schema metadata relevant to the flow generation request. This step is **mandatory** and must always be called first.
|
||||
|
||||
**Inputs (all required):**
|
||||
- **userPrompt** (STRING, REQUIRED): The user's natural language request
|
||||
- **inflightMetadata** (ARRAY, REQUIRED): Custom objects/fields from local sfdx project. Use empty array `[]` if none needed.
|
||||
|
||||
**Outputs:**
|
||||
- **groundingMetadata** (STRING): Grounded object metadata for org schema relevant to the request, returned as a JSON string. **You must pass this directly to Step 2 — it is already a string and does not need to be serialized again.**
|
||||
|
||||
### Step 2 (REQUIRED): Flow Element Selection (`flowElementSelection`)
|
||||
Selects flow elements (assignments, decisions, record ops, etc.) and their connections based on the user prompt and grounded metadata. This step is **mandatory** and must be called after Step 1.
|
||||
|
||||
**Inputs (all required):**
|
||||
- **userPrompt** (STRING, REQUIRED): The user's natural language request (**must be the same value as Step 1**)
|
||||
- **groundingMetadata** (STRING, REQUIRED): Org schema metadata (**must be the exact string returned from Step 1 output** — pass it directly, do NOT serialize it again)
|
||||
- **operationId** (STRING, REQUIRED): Operation ID (use empty string `""` for first call)
|
||||
|
||||
**Outputs:**
|
||||
- **operationId** (STRING): Operation ID. **You must pass this to Step 3.**
|
||||
- **userOutput** (STRING): Reasoning for next steps. You can show this to the user.
|
||||
|
||||
### Step 3 (REQUIRED): Flow Element Generation (`flowElementGeneration`)
|
||||
Generates flow metadata element by element. This step is **mandatory** and must be called after Step 2. **Must be called repeatedly in a loop until `isComplete` is `true`.**
|
||||
|
||||
**Inputs (all required):**
|
||||
- **operationId** (STRING, REQUIRED): Operation ID **from Step 2 output**
|
||||
- **requestSource** (STRING, REQUIRED): The source of the request. Use **`"A4V"`** to get flow metadata in XML format.
|
||||
|
||||
**Outputs:**
|
||||
- **isComplete** (BOOLEAN): Indicates if the flow generation is complete. **You must check this value.**
|
||||
- **result** (STRING): Result of the flow element generation. Contains the final flow metadata **only when `isComplete` is `true`**.
|
||||
|
||||
**🚨 MANDATORY: Loop until complete.**
|
||||
- Call `flowElementGeneration` with the `operationId` from Step 2 and `requestSource` (use `"A4V"` for XML output, empty string or other value for JSON).
|
||||
- Check the `isComplete` output after each call.
|
||||
- If `isComplete` is `false`, you **MUST** call `flowElementGeneration` again with the **same `operationId`** from Step 2.
|
||||
- **Do NOT stop** until `isComplete` is `true`.
|
||||
- When `isComplete` is `true`, extract the flow metadata from the `result` field.
|
||||
|
||||
## 📦 inflightMetadata Format
|
||||
**DATA TYPE: ARRAY (not string)**
|
||||
|
||||
**⚠️ STRICT NAMING CONVENTION - MUST FOLLOW EXACTLY:**
|
||||
| Property | Correct Name | ❌ Do NOT Use |
|
||||
|----------|-------------|---------------|
|
||||
| Object API name | `apiName` | `objectApiName`, `name`, `objectName` |
|
||||
| Field API name | `apiName` | `fieldApiName`, `name`, `fieldName` |
|
||||
| Field type | `type` | `fieldType`, `dataType` |
|
||||
| Lookup target | `referenceTo` | `relatedTo`, `lookupTo`, `reference` |
|
||||
|
||||
When custom objects are needed (sample format showing multiple field data types):
|
||||
```json
|
||||
[
|
||||
{
|
||||
"type": "CustomObject",
|
||||
"apiName": "CustomerRequest__c",
|
||||
"label": "Customer Request",
|
||||
"fields": [
|
||||
{
|
||||
"apiName": "Status__c",
|
||||
"type": "Picklist",
|
||||
"label": "Status",
|
||||
"values": ["New", "In Progress", "Completed"]
|
||||
},
|
||||
{
|
||||
"apiName": "Priority__c",
|
||||
"type": "Number",
|
||||
"label": "Priority"
|
||||
},
|
||||
{
|
||||
"apiName": "AssignedTo__c",
|
||||
"type": "Lookup",
|
||||
"label": "Assigned To",
|
||||
"referenceTo": "User"
|
||||
},
|
||||
{
|
||||
"apiName": "Description__c",
|
||||
"type": "Textarea",
|
||||
"label": "Description"
|
||||
},
|
||||
{
|
||||
"apiName": "Email__c",
|
||||
"type": "Email",
|
||||
"label": "Contact Email"
|
||||
},
|
||||
{
|
||||
"apiName": "DueDate__c",
|
||||
"type": "Date",
|
||||
"label": "Due Date"
|
||||
},
|
||||
{
|
||||
"apiName": "IsUrgent__c",
|
||||
"type": "Boolean",
|
||||
"label": "Is Urgent"
|
||||
},
|
||||
{
|
||||
"apiName": "Amount__c",
|
||||
"type": "Currency",
|
||||
"label": "Amount"
|
||||
}
|
||||
],
|
||||
"relationships": []
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
**Supported field types**: Text, Textarea, Number, Picklist, Lookup, Email, Phone, URL, Date, Datetime, Boolean, Checkbox, Currency, Percent
|
||||
|
||||
When no custom objects needed:
|
||||
```json
|
||||
[]
|
||||
```
|
||||
|
||||
### ⚠️ MANDATORY Decision Logic for inflightMetadata (DATA TYPE: ARRAY)
|
||||
|
||||
1. **REQUIRED - First**: Scan the local sfdx project for custom objects and fields that are relevant to the user's flow request.
|
||||
2. **If relevant custom objects ARE found**: You MUST extract and pass them as an array of structured objects (see format above)
|
||||
3. **If NO relevant custom objects found**: You MUST pass an empty array `[]` (NOT the string `"[]"`)
|
||||
4. **NEVER**: Pass text descriptions, instructions, or string representations in inflightMetadata
|
||||
5. **MANDATORY**: The data type MUST be ARRAY, not STRING
|
||||
|
||||
**Instructions for Cline when custom objects ARE relevant:**
|
||||
- Extract the object metadata and map to JSON properties:
|
||||
- `apiName`: The object's API name (with `__c` suffix for custom objects)
|
||||
- `label`: The object's display label
|
||||
- `type`: Set to `"CustomObject"`
|
||||
- `fields`: Array of field objects, each containing:
|
||||
- `apiName`: The field's API name (with `__c` suffix for custom fields)
|
||||
- `type`: The field type (Text, Number, Picklist, Lookup, etc.)
|
||||
- `label`: The field's display label
|
||||
- `values`: (Picklist only) Array of picklist values
|
||||
- `referenceTo`: (Lookup only) The target object API name
|
||||
- Include only objects and fields that are relevant to the flow being generated
|
||||
|
||||
## 🎯 Mandatory Enhancement Rules
|
||||
- **userPrompt**: REQUIRED. Always use the exact user prompt without modification.
|
||||
- **inflightMetadata**: REQUIRED. Always use ARRAY data type.
|
||||
- MUST use `[]` (empty array) when no custom objects needed
|
||||
- MUST use structured array of objects when custom objects are relevant
|
||||
- NEVER use string `"[]"` - this is incorrect
|
||||
- NEVER use text descriptions - only structured object metadata
|
||||
|
||||
### 🚨 MANDATORY: Multiple Flows = Multiple Separate Pipelines
|
||||
|
||||
**❌ NEVER club multiple flow prompts into a single `userPrompt` field.**
|
||||
|
||||
When the user requests multiple flows (e.g., for an app with several flows), each flow MUST be generated with a **separate 3-step pipeline** and a **separate payload**. This is mandatory and non-negotiable.
|
||||
|
||||
**❌ WRONG - Multiple flows clubbed into one userPrompt:**
|
||||
```json
|
||||
{
|
||||
"userPrompt": "Generate the following flows: 1) Screen Flow - Tenant Onboarding... 2) Autolaunched Flow - Generate Checklist... 3) Record-Triggered Flow - Sync Unit...",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
**✅ CORRECT - Separate call for EACH flow:**
|
||||
|
||||
**Flow 1 - Step 1 (fetchGroundedObjectMetadata):**
|
||||
```json
|
||||
{
|
||||
"userPrompt": "Create a Screen Flow named Tenant_Onboarding that captures tenant details, selects a Unit__c with Status__c = 'Vacant', creates Lease__c...",
|
||||
"inflightMetadata": [...]
|
||||
}
|
||||
```
|
||||
Then call Step 2 (`flowElementSelection`) with the `groundingMetadata` from Step 1, then Step 3 (`flowElementGeneration`) with the `operationId` from Step 2.
|
||||
|
||||
**Flow 2 - Step 1 (fetchGroundedObjectMetadata):**
|
||||
```json
|
||||
{
|
||||
"userPrompt": "Create an Autolaunched Flow named Generate_Onboarding_Checklist that given a Lease__c Id input, queries OnboardingTask__c...",
|
||||
"inflightMetadata": [...]
|
||||
}
|
||||
```
|
||||
Then call Step 2 and Step 3 for this flow.
|
||||
|
||||
**Flow 3 - Step 1 (fetchGroundedObjectMetadata):**
|
||||
```json
|
||||
{
|
||||
"userPrompt": "Create a Record-Triggered Flow named Sync_Unit_On_Lease_Changes that on insert and update of Lease__c...",
|
||||
"inflightMetadata": [...]
|
||||
}
|
||||
```
|
||||
Then call Step 2 and Step 3 for this flow.
|
||||
|
||||
**Mandatory Rules:**
|
||||
- If there are N flows to generate, there MUST be N separate 3-step pipelines. No exceptions.
|
||||
- For each flow, you MUST scan the local sfdx project to populate `inflightMetadata` with custom objects/fields **specific to that flow prompt**.
|
||||
- Each flow pipeline MUST have its own `inflightMetadata` containing only the objects/fields relevant to that particular flow.
|
||||
|
||||
## 🔧 Example Tool Calls
|
||||
|
||||
**Example 1: Standard objects only (no custom objects)**
|
||||
|
||||
**Step 1 - fetchGroundedObjectMetadata:**
|
||||
```json
|
||||
{
|
||||
"userPrompt": "Create a scheduled-triggered Flow named Daily_Good_Morning that runs daily at 6:00 AM and sends an email to the running user saying good morning.",
|
||||
"inflightMetadata": []
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2 - flowElementSelection:**
|
||||
```json
|
||||
{
|
||||
"userPrompt": "Create a scheduled-triggered Flow named Daily_Good_Morning that runs daily at 6:00 AM and sends an email to the running user saying good morning.",
|
||||
"groundingMetadata": "<groundingMetadata string from Step 1 — pass directly, do not serialize again>",
|
||||
"operationId": ""
|
||||
}
|
||||
```
|
||||
|
||||
**Step 3 - flowElementGeneration (call in a loop):**
|
||||
```json
|
||||
{
|
||||
"operationId": "<operationId from Step 2>",
|
||||
"requestSource": "A4V"
|
||||
}
|
||||
```
|
||||
Call repeatedly with the same `operationId` until `isComplete` is `true`. When `isComplete` is `true`, extract the flow metadata from the `result` field. Use `"requestSource": "A4V"` to get flow metadata in XML format.
|
||||
|
||||
**Example 2: With custom objects from local sfdx project**
|
||||
|
||||
**Step 1 - fetchGroundedObjectMetadata:**
|
||||
```json
|
||||
{
|
||||
"userPrompt": "Create a flow that updates the status of a Customer Request when it's assigned",
|
||||
"inflightMetadata": [
|
||||
{
|
||||
"type": "CustomObject",
|
||||
"apiName": "CustomerRequest__c",
|
||||
"label": "Customer Request",
|
||||
"fields": [
|
||||
{
|
||||
"apiName": "Status__c",
|
||||
"type": "Picklist",
|
||||
"label": "Status",
|
||||
"values": ["New", "In Progress", "Completed"]
|
||||
},
|
||||
{
|
||||
"apiName": "AssignedTo__c",
|
||||
"type": "Lookup",
|
||||
"label": "Assigned To",
|
||||
"referenceTo": "User"
|
||||
}
|
||||
],
|
||||
"relationships": []
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2 - flowElementSelection:**
|
||||
```json
|
||||
{
|
||||
"userPrompt": "Create a flow that updates the status of a Customer Request when it's assigned",
|
||||
"groundingMetadata": "<groundingMetadata string from Step 1 — pass directly, do not serialize again>",
|
||||
"operationId": ""
|
||||
}
|
||||
```
|
||||
|
||||
**Step 3 - flowElementGeneration (call in a loop):**
|
||||
```json
|
||||
{
|
||||
"operationId": "<operationId from Step 2>",
|
||||
"requestSource": "A4V"
|
||||
}
|
||||
```
|
||||
Call repeatedly with the same `operationId` until `isComplete` is `true`. When `isComplete` is `true`, extract the flow metadata from the `result` field. Use `"requestSource": "A4V"` to get flow metadata in XML format
|
||||
|
||||
## ✅ Mandatory Best Practices
|
||||
- **ALWAYS** follow the 3-step pipeline: fetchGroundedObjectMetadata → flowElementSelection → flowElementGeneration. This is the ONLY way to generate flow metadata. There are no alternatives.
|
||||
- Do NOT manually create flow metadata XML, JSON, or any other format outside of this pipeline.
|
||||
- Do NOT attempt to "optimize" by skipping steps or combining steps. Each step is atomic and required.
|
||||
- **NEVER** skip any step in the pipeline. All 3 steps are required.
|
||||
- **NEVER** try to generate flow metadata without calling all 3 steps.
|
||||
- **NEVER** deviate from this pipeline under any circumstance — even if you think you know the flow structure.
|
||||
- For single flow requests: you MUST use the user prompt as `userPrompt`.
|
||||
- For multiple flow requests: you MUST run a separate 3-step pipeline for each flow.
|
||||
- You MUST put flow requirements in `userPrompt`, NOT in `inflightMetadata`.
|
||||
- `inflightMetadata` is ONLY for custom object/field metadata from local project (see above). No exceptions.
|
||||
- Step 3 MUST be called in a loop with the same `operationId` from Step 2 until `isComplete` is `true`. Do NOT stop early.
|
||||
- You MUST only extract the flow metadata from the `result` field when `isComplete` is `true`.
|
||||
|
||||
## 🚨 CRITICAL Verification Checklist (MUST VERIFY BEFORE AND AFTER EVERY FLOW GENERATION)
|
||||
|
||||
**Failure to follow this checklist exactly will result in broken or missing flow metadata.**
|
||||
|
||||
- [ ] **Pipeline**: ALL 3 steps are called in strict order (fetchGroundedObjectMetadata → flowElementSelection → flowElementGeneration). No step is skipped.
|
||||
- [ ] **No manual metadata**: Flow metadata is NOT manually created, modified, or generated outside of this pipeline by any means
|
||||
- [ ] **No deviation**: No alternative tools, APIs, or methods were used instead of or alongside this pipeline
|
||||
- [ ] **userPrompt** contains a single flow prompt (split if user requested multiple flows)
|
||||
- [ ] **userPrompt** is passed consistently to both Step 1 and Step 2 (same value)
|
||||
- [ ] **inflightMetadata** is ARRAY data type (NOT string)
|
||||
- [ ] **inflightMetadata** is `[]` when no custom objects needed
|
||||
- [ ] **inflightMetadata** contains structured objects extracted by scanning the local sfdx project for relevant custom objects/fields
|
||||
- [ ] **inflightMetadata** does NOT contain `"[]"` (string) - must be `[]` (array)
|
||||
- [ ] **inflightMetadata** does NOT contain text descriptions or instructions
|
||||
- [ ] **groundingMetadata** from Step 1 output is passed directly to Step 2 input (it is already a string — do NOT serialize it again)
|
||||
- [ ] **operationId** from Step 2 output is passed to Step 3 input
|
||||
- [ ] **requestSource** should be set to `"A4V"` always
|
||||
- [ ] **Step 3** is called in a loop with the same `operationId` from Step 2 until `isComplete` is `true`
|
||||
- [ ] **result** field is used to extract the XML flow metadata only when `isComplete` is `true`
|
||||
@ -0,0 +1,69 @@
|
||||
---
|
||||
name: salesforce-validation-rule
|
||||
description: Generate ValidationRule metadata XML with proper formula syntax, CDATA handling, and error messages. Use when creating validation rules to enforce business logic at the data layer.
|
||||
---
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when you need to:
|
||||
- Create validation rules to enforce data quality
|
||||
- Prevent invalid records from being saved
|
||||
- Generate validation rule metadata with formulas
|
||||
- Add business logic validation to objects
|
||||
- Troubleshoot deployment errors related to validation rules
|
||||
|
||||
## Specification
|
||||
|
||||
# ValidationRule Metadata Specification
|
||||
|
||||
### 📋 Overview
|
||||
Validation Rules are declarative metadata components used to enforce data quality and business logic in Salesforce. They evaluate a formula expression when a record is saved and prevent the save operation if the expression returns TRUE.
|
||||
|
||||
### 🎯 Purpose
|
||||
-Enforce business rules at the data layer
|
||||
-Prevent invalid or incomplete records from being saved
|
||||
-Display meaningful error messages to guide users
|
||||
|
||||
### ⚙️ Required Properties
|
||||
|
||||
#### Core Validation Rule Properties
|
||||
|
||||
- **fullName**
|
||||
- The unique API name of the validation rule
|
||||
- Must start with a letter
|
||||
- Can contain letters, numbers, and underscores
|
||||
- Cannot end with an underscore
|
||||
- Cannot contain consecutive underscores
|
||||
- Cannot exceed 40 character.
|
||||
|
||||
- **active**
|
||||
-Indicates whether the validation rule is enabled
|
||||
true → Rule is enforced
|
||||
false → Rule is inactive
|
||||
|
||||
- **errorConditionFormula**
|
||||
- The logical formula that evaluates record data
|
||||
- Must return TRUE or FALSE
|
||||
- If TRUE, the validation rule triggers an error
|
||||
|
||||
- **errorMessage**
|
||||
- The message displayed to the user when validation fails
|
||||
- Maximum length: 255 characters
|
||||
|
||||
### Specific Function Guidelines
|
||||
- TEXT - TEXT() function MUST NOT be used with Text fields, to fix this you can just remove the TEXT() function.
|
||||
- CASE - In salesforce CASE() function, last parameter is the default value. Admins often miss to provide this and number of parameters to CASE() function are always even.
|
||||
- VALUE - VALUE() function should only be used with Text fields. If a number is being used as a parameter to the VALUE() function, remove the VALUE() function.
|
||||
- DAY - DAY() function should only be used with Date fields. If a Datetime field is being used as a parameter to the DAY() function, convert it into a Date first.
|
||||
- MONTH - MONTH() function should only be used with Date fields. If a Datetime field is being used as a parameter to the MONTH() function, convert it into a Date first.
|
||||
- DATEVALUE - DATEVALUE() function should only be used with DateTime fields. If a Date is being used as a parameter to the DATEVALUE() function, remove the DATEVALUE() function.
|
||||
- ISPICKVAL - If checking equality of a picklist type field, the function ISPICKVAL() MUST be used.
|
||||
- ISCHANGE - Use ISCHANGE() function to check the value of a record has changed.
|
||||
|
||||
### Critical Rules
|
||||
1. Formula XML Handling(MOST COMMON ERROR)
|
||||
- ANY errorConditionFormula containing XML tags MUST be inside a CDATA section in the metadata XML.
|
||||
|
||||
2. Interpretation of "Update" Instructions. When receiving instructions to modify a formula, distinguish between a replacement and an addition:
|
||||
- "Update the formula to [Action]": Completely replace the existing formula logic with the new requirement.
|
||||
- "Update the formula to also [Action]": Keep the existing logic and append the new requirement (usually by wrapping the logic in an AND() or OR() function).
|
||||
67
skills/solution/lex-app-solution/SKILL.md
Normal file
67
skills/solution/lex-app-solution/SKILL.md
Normal file
@ -0,0 +1,67 @@
|
||||
---
|
||||
name: lex-app-solution
|
||||
description: Build complete Lightning Applications using Application-First Development Model. Creates CustomObject, CustomField, CustomTab, FlexiPage, and CustomApplication metadata in sequence. Optionally creates ValidationRule and Flow metadata when requested. Use when user requests a complete application, system, or solution (not individual components).
|
||||
---
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when you need to:
|
||||
- Build or enhance a complete Lightning Application from scratch
|
||||
- Create end-to-end solutions requiring multiple metadata types working together
|
||||
- Guide users through full application development workflows
|
||||
- Ensure proper sequencing of metadata creation (objects → fields → tabs → pages → app)
|
||||
- Make context-aware decisions about which objects need tabs and pages
|
||||
- Orchestrate CustomObject, CustomField, CustomTab, FlexiPage, and CustomApplication metadata
|
||||
- Optionally create ValidationRule and Flow metadata when requested
|
||||
|
||||
**Do not use this skill for:**
|
||||
- Creating individual metadata components (use specific metadata expert skills instead)
|
||||
- Modifying existing metadata without building a full application
|
||||
- Troubleshooting or fixing deployment errors for single components
|
||||
|
||||
## Specification
|
||||
|
||||
# Salesforce Application Development Requirements
|
||||
|
||||
You are a highly experienced and certified Salesforce Architect. Your purpose is to assist developers in generating high-quality, secure, and maintainable Salesforce metadata. You must adhere to the principles of architectural integrity, data integrity, security, and performance.
|
||||
|
||||
## The Application-First Development Model
|
||||
|
||||
**When to Use:** User requests a complete application, system, or solution (not just individual components).
|
||||
|
||||
Your approach for full applications is to build or enhance a complete Lightning Application. You must guide the user through the following logical sequence to ensure a complete and user-ready result.
|
||||
|
||||
**The Guided Application Workflow (Step-by-Step with Context):**
|
||||
|
||||
1. **App Scoping & Vision:** Define the application's purpose. Ask: "What is the name of the application we are building (e.g., 'Project Management')?
|
||||
What is its primary goal?"
|
||||
|
||||
2. **Data Foundation (Objects & Fields):** Create ALL `CustomObjects` and their `CustomFields` first. This gives you the complete data model context.
|
||||
|
||||
3. **Validation Rules (OPTIONAL):** Create `ValidationRule` metadata only if explicitly requested in the prompt. Skip this step if validation rules are not mentioned.
|
||||
|
||||
4. **Flow Automation (OPTIONAL):** Create `Flow` metadata only if explicitly requested in the prompt. Skip this step if flows are not mentioned. Flows depend on CustomObject and CustomField metadata being created first.
|
||||
|
||||
5. **Object Analysis & Tab Decision Phase (MANDATORY):**
|
||||
- **STOP and analyze each object before creating any tabs**
|
||||
- **For each object, explicitly state:** "Do users need direct access to this object?"
|
||||
- **Consider:** Is this a primary business entity, junction object, lookup-only object, or system object?
|
||||
- **Make intelligent decisions** about which objects need tabs
|
||||
- **List which objects will get tabs and which will be skipped**
|
||||
- **DO NOT proceed to tab creation until this analysis is complete**
|
||||
|
||||
6. **User Accessibility (Tabs):** Create `CustomTab` metadata **only for objects that passed the decision phase** (primary business objects that
|
||||
users need direct access to).
|
||||
|
||||
7. **User Experience (Record Pages):** Create `FlexiPage` metadata **only for objects that have tabs** (following the tab decision from step 5).
|
||||
**CRITICAL:** Follow the FlexiPage rules to generate the complete structure including field instances from the start:
|
||||
- Use the simple structure example from the rules
|
||||
- Include primaryField and secondaryFields facet regions
|
||||
- Select intelligent fields based on the object's field types
|
||||
- This ensures the highlights panel displays meaningful, relevant fields
|
||||
|
||||
8. **Application Assembly (The App):** Create the `CustomApplication` (Lightning App) itself, adding **only the tabs that were created in
|
||||
step 6** to its navigation.
|
||||
|
||||
|
||||
**Key Principle:** Always create objects first, then make context-aware decisions about tabs, then create tabs and pages only for selected objects.
|
||||
Loading…
Reference in New Issue
Block a user