Merge branch 'main' into feat/enhance-using-webapp-salesforce-data
6
.gitignore
vendored
@ -128,10 +128,8 @@ venv.bak/
|
||||
|
||||
# React sample templates: track internal `src/lib` utility modules
|
||||
# These rules override the global `lib/` ignore in the Python section above.
|
||||
!samples/webapp-template-app-react-sample-b2x-experimental/force-app/main/default/webapplications/appreactsampleb2x/src/lib/
|
||||
!samples/webapp-template-app-react-sample-b2x-experimental/force-app/main/default/webapplications/appreactsampleb2x/src/lib/**
|
||||
!samples/webapp-template-app-react-sample-b2e-experimental/force-app/main/default/webapplications/appreactsampleb2e/src/lib/
|
||||
!samples/webapp-template-app-react-sample-b2e-experimental/force-app/main/default/webapplications/appreactsampleb2e/src/lib/**
|
||||
!samples/**/lib/
|
||||
!samples/**/lib/**
|
||||
|
||||
# IDEs and Editors
|
||||
.vscode/
|
||||
|
||||
@ -1,3 +1,12 @@
|
||||
## [1.5.1](https://github.com/forcedotcom/afv-library/compare/1.5.0...1.5.1) (2026-03-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* correct .gitignore to track sample lib/ folders @W-21361802@ ([#119](https://github.com/forcedotcom/afv-library/issues/119)) ([7018d49](https://github.com/forcedotcom/afv-library/commit/7018d49e26aa366962e0073f3e964adab47ccea2))
|
||||
|
||||
|
||||
|
||||
# [1.5.0](https://github.com/forcedotcom/afv-library/compare/1.4.0...1.5.0) (2026-03-24)
|
||||
|
||||
|
||||
|
||||
@ -198,4 +198,4 @@ A maintainer will merge your PR after approval.
|
||||
- Push the branch.
|
||||
- Open a PR.
|
||||
- Respond to feedback.
|
||||
- Keep your fork updated.
|
||||
- Keep your fork updated.
|
||||
427
README.md
@ -1,48 +1,34 @@
|
||||
# Agentforce Vibes Library
|
||||
|
||||
AI prompts and rules library for Agentforce Vibes development, content creation, and workflow automation.
|
||||
AI skills and rules library for Agentforce Vibes development of Salesforce metadata.
|
||||
|
||||
## 📚 About
|
||||
|
||||
This repository curates Salesforce-focused prompts, system rules, and executable skills from the wider developer community to accelerate Agentforce Vibes agentic workflows. Collections are organized by development discipline—Apex, LWC, flows, deployments, testing, investigation, spec-driven delivery, and more—so contributors can share reusable prompts, scaffolds, guardrails, and workflows that other teams can adapt and extend.
|
||||
This repository curates Salesforce-focused skills and system rules from the wider developer community to accelerate Agentforce Vibes agentic workflows.
|
||||
|
||||
## 🗂️ Structure
|
||||
|
||||
```
|
||||
afv-library/
|
||||
├── prompts/ # Single-file instructions for straightforward tasks
|
||||
│ ├── apex-development/
|
||||
│ ├── lwc-development/
|
||||
│ ├── flow-development/
|
||||
│ ├── getting-started/
|
||||
│ └── ...
|
||||
├── rules/ # Single-file guardrails and standards
|
||||
│ ├── apex-development/
|
||||
│ ├── lwc-development/
|
||||
│ ├── spec-driven-dev/
|
||||
│ └── ...
|
||||
├── skills/ # Directory-based executable workflows
|
||||
│ ├── apex-development/
|
||||
│ │ └── trigger-refactor-pipeline/
|
||||
│ │ ├── SKILL.md
|
||||
│ │ ├── scripts/
|
||||
│ │ ├── references/
|
||||
│ │ └── assets/
|
||||
│ ├── metadata-deployments/
|
||||
│ ├── testing-automation/
|
||||
│ ├── generating-apex/
|
||||
│ ├── generating-custom-object/
|
||||
│ ├── generating-flow/
|
||||
│ └── ...
|
||||
├── samples/ # Synced sample apps (e.g. from npm)
|
||||
│ └── webapp-template-app-react-sample-b2e-experimental/
|
||||
│ └── ...
|
||||
├── scripts/
|
||||
│ └── ...
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## 🚀 Quick Start
|
||||
## Manual Usage
|
||||
|
||||
### Manual Usage
|
||||
Browse the repository and copy/paste any rule or skill directly into Agentforce Vibes or your preferred AI tool.
|
||||
|
||||
Browse the repository and copy/paste any prompt, rule, or skill directly into Agentforce Vibes or your preferred AI tool.
|
||||
|
||||
### Samples
|
||||
## Samples
|
||||
|
||||
The `samples/` folder contains synced sample apps. For example, `samples/webapp-template-app-react-sample-b2e-experimental/` is kept in sync with the npm package `@salesforce/webapp-template-app-react-sample-b2e-experimental` (nightly and on manual trigger via GitHub Actions). To run the same sync locally from the repo root:
|
||||
|
||||
@ -53,87 +39,10 @@ npm run sync-react-b2e-sample
|
||||
|
||||
The GitHub Action runs these same commands and opens a PR only when the npm package version has changed. See [samples/README.md](samples/README.md) for details.
|
||||
|
||||
### Connecting Team or Personal Libraries
|
||||
|
||||
You can register additional repos with the extension as long as they mirror this structure:
|
||||
## 🛠️ Agent Skills
|
||||
|
||||
- Root folders named `prompts/`, `rules/`, and `skills/`, each containing category subfolders (e.g., `prompts/apex-development/`).
|
||||
- Each prompt or rule stored in its own Markdown file with YAML frontmatter (`name`, `description`, `tags`, optional setup metadata).
|
||||
- Each skill stored in its own directory containing a `SKILL.md` file with required frontmatter, plus optional `scripts/`, `references/`, and `assets/` subdirectories.
|
||||
- Category folders may include a `README.md` describing their focus; empty folders are allowed for future content.
|
||||
|
||||
When you add a new library:
|
||||
|
||||
1. **Structure your repository** with the same folder layout shown in `## 🗂️ Structure`:
|
||||
- `prompts/` folder with category subfolders containing `.md` files
|
||||
- `rules/` folder with category subfolders containing `.md` files
|
||||
- `skills/` folder with category subfolders, each containing skill directories with `SKILL.md`
|
||||
2. **Follow format requirements**:
|
||||
- Prompts and rules: YAML frontmatter (`name`, `description`, `tags`) + markdown body
|
||||
- Skills: Directory with `SKILL.md` + optional `scripts/`, `references/`, `assets/` subdirectories
|
||||
3. **Ensure script executability** for skills: Mark Python/Bash scripts as executable (`chmod +x`)
|
||||
4. **Register the repository** with `Agentforce Vibes: Add Library` in VS Code
|
||||
5. **Refresh the extension** to index and display the new content
|
||||
|
||||
## 📝 Prompt Format
|
||||
|
||||
Every prompt begins with YAML frontmatter that surfaces key metadata to contributors and tooling:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: Concise Prompt Title
|
||||
description: One-sentence summary of the outcome you want
|
||||
tags: category, use-case, tooling
|
||||
requires_deploy: true # optional – include when pre-work is required
|
||||
setup_summary: Deploy baseline trigger before refactor # optional helper text
|
||||
---
|
||||
```
|
||||
|
||||
- `name`, `description`, and `tags` are required.
|
||||
- Use lowercase, comma-separated tags drawn from the category and focus area (e.g., `apex, refactor, testing`).
|
||||
- Add `requires_deploy` (and an optional `setup_summary`) when the prompt depends on seed metadata or data.
|
||||
|
||||
After the frontmatter, organize the body with clear sections. A common pattern is:
|
||||
|
||||
1. `## Setup` – only when pre-work, sample metadata, or environment configuration is needed.
|
||||
2. `## Context` – summarize the scenario, constraints, personas, or assets involved.
|
||||
3. `## Instructions` – detail the tasks in numbered steps, calling out decision points or checkpoints.
|
||||
4. `## Testing & Reporting` – define verification steps, coverage expectations, or deliverables.
|
||||
5. `## Follow-ups` – optional space for stretch goals, review questions, or iteration loops.
|
||||
|
||||
### Example Prompt
|
||||
|
||||
**File:** `prompts/apex-development/trigger-refactoring.md`
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: Trigger Refactor Helper
|
||||
description: Refactor the Opportunity trigger into a handler pattern with tests
|
||||
tags: apex, refactor, testing
|
||||
requires_deploy: true
|
||||
setup_summary: Deploy baseline trigger to target org before running instructions
|
||||
---
|
||||
|
||||
## Setup
|
||||
1. Deploy the baseline trigger shown below to your default or scratch org.
|
||||
2. Confirm the trigger compiles successfully before continuing.
|
||||
|
||||
```apex
|
||||
// ... baseline trigger omitted for brevity ...
|
||||
```
|
||||
|
||||
## Instructions
|
||||
Refactor `OpportunityTrigger` into a handler class (or classes) that handles the same behavior using bulk-safe patterns. Ensure the trigger itself delegates and remains behaviorally identical.
|
||||
|
||||
## Testing & Reporting
|
||||
- Create unit tests covering positive and negative paths for each handler method.
|
||||
- Include a bulk test that updates 50 `Opportunity` records where only half qualify for the `after update` logic.
|
||||
- Deploy the refactored code and run the tests, then report coverage and key observations.
|
||||
```
|
||||
|
||||
## 🛠️ Agent Skills Format
|
||||
|
||||
Agent Skills extend prompts and rules by bundling executable workflows, scripts, and reference materials into self-contained directories. Skills follow the open [Agent Skills specification](https://agentskills.io/) and are portable across many agent tools (Cursor, Claude Code, VS Code extensions, etc.).
|
||||
Agent Skills extend rules by bundling executable workflows, scripts, and reference materials into self-contained directories. Skills follow the open [Agent Skills specification](https://agentskills.io/) and are portable across many agent tools (Cursor, Claude Code, VS Code extensions, etc.).
|
||||
|
||||
### Directory Structure
|
||||
|
||||
@ -143,324 +52,16 @@ Each skill is a folder containing:
|
||||
- `references/` (optional) - additional documentation
|
||||
- `assets/` (optional) - templates, schemas, lookup data
|
||||
|
||||
### Required Frontmatter
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: skill-name-here # lowercase, hyphens, matches folder name
|
||||
description: What this skill does and when to use it (1-1024 chars)
|
||||
license: Apache-2.0 # optional
|
||||
compatibility: Requires... # optional
|
||||
metadata: # optional
|
||||
author: your-org
|
||||
version: "1.0"
|
||||
allowed-tools: Bash Read Write # optional, space-delimited
|
||||
---
|
||||
```
|
||||
|
||||
The `name` must:
|
||||
- Be 1-64 characters
|
||||
- Use only lowercase letters, numbers, and hyphens
|
||||
- Match the parent directory name
|
||||
- Not start or end with hyphens
|
||||
|
||||
The `description` should explain both what the skill does and when to use it, including keywords that help agents identify relevant tasks.
|
||||
|
||||
### Progressive Disclosure
|
||||
|
||||
Skills are designed for efficient context use:
|
||||
|
||||
1. **Discovery** - agents load only name + description at startup
|
||||
2. **Activation** - full SKILL.md loaded when needed
|
||||
3. **Execution** - scripts/references loaded on-demand
|
||||
|
||||
Keep your main `SKILL.md` under 500 lines and move detailed reference material to separate files.
|
||||
|
||||
### Example Skill Structure
|
||||
|
||||
**File:** `skills/apex-development/trigger-refactor-pipeline/SKILL.md`
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: trigger-refactor-pipeline
|
||||
description: Refactor Salesforce triggers into handler patterns with automated test generation and deployment. Use when modernizing legacy triggers with DML/SOQL in loops.
|
||||
license: Apache-2.0
|
||||
compatibility: Requires Salesforce CLI, Python 3.9+, jq
|
||||
metadata:
|
||||
author: afv-library
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use when you need to modernize legacy triggers with DML/SOQL in loops or inconsistent patterns.
|
||||
|
||||
## Step 1: Analyze Trigger
|
||||
|
||||
Run `scripts/analyze_trigger.py <TriggerName>` to identify anti-patterns:
|
||||
- DML operations inside loops
|
||||
- SOQL queries inside loops
|
||||
- Missing bulkification
|
||||
|
||||
The script outputs a report showing:
|
||||
- Line numbers with issues
|
||||
- Recommended refactoring approach
|
||||
- Complexity score
|
||||
|
||||
## Step 2: Generate Handler
|
||||
|
||||
See [handler patterns reference](references/handler_patterns.md) for templates that match your trigger context:
|
||||
- Before insert/update patterns
|
||||
- After insert/update/delete patterns
|
||||
- Bulk collection strategies
|
||||
|
||||
Copy the appropriate template from `assets/` and customize.
|
||||
|
||||
## Step 3: Create Tests
|
||||
|
||||
Use `assets/test_template.apex` as a scaffold. Ensure coverage includes:
|
||||
- Single record operations
|
||||
- Bulk operations (200+ records)
|
||||
- Mixed scenarios
|
||||
- Negative cases
|
||||
|
||||
## Step 4: Deploy and Validate
|
||||
|
||||
Deploy using Salesforce CLI and run all tests. Verify:
|
||||
- All tests pass with 100% coverage
|
||||
- No new governor limit issues
|
||||
- Behavior matches original trigger
|
||||
```
|
||||
|
||||
### Validation
|
||||
|
||||
Skills can be validated using the [skills-ref](https://github.com/agentskills/agentskills/tree/main/skills-ref) tool:
|
||||
|
||||
```bash
|
||||
skills-ref validate ./skills/apex-development/trigger-refactor-pipeline
|
||||
```
|
||||
|
||||
This checks that your `SKILL.md` frontmatter is valid and follows all naming conventions.
|
||||
|
||||
## 📂 Categories Guide
|
||||
|
||||
These starter categories reflect the current repository layout. Contributors are welcome to propose new ones or reorganize as long as the structure stays consistent for the VS Code extension.
|
||||
|
||||
### When to Use Each Format
|
||||
|
||||
| Format | Use When | Example |
|
||||
|--------|----------|---------|
|
||||
| **Prompt** | Single-shot instruction for a straightforward task | "Create a validation rule on Account that prevents blank NumberOfEmployees" |
|
||||
| **Rule** | Ongoing guardrail or standard to enforce | "Apex triggers must delegate to handler classes with bulk-safe patterns" |
|
||||
| **Skill** | Multi-step workflow requiring scripts, templates, or reference docs | "Refactor trigger → analyze anti-patterns → generate handler → create tests → deploy" |
|
||||
|
||||
### Prompts
|
||||
|
||||
| Category | Purpose | Example Topics |
|
||||
|----------|---------|----------------|
|
||||
| **apex-development** | Build and optimize Apex codebases | Trigger frameworks, async patterns, governor limit tuning |
|
||||
| **lwc-development** | Craft Lightning Web Components | Component architecture, reactive data, UI patterns |
|
||||
| **metadata-deployments** | Plan and execute releases | Packaging, Git branching, rollback prep |
|
||||
| **vibe-coding** | Agentforce Vibes coding workflows | Apex/LWC scaffolds, prompt-to-code translation |
|
||||
| **testing-automation** | Validate platform behavior | Apex tests, Flow scenarios, regression suites |
|
||||
| **investigation-triage** | Diagnose and resolve issues | Incident response, log analysis, performance forensics |
|
||||
| **data-operations** | Manage data pipelines | ETL prompts, bulk operations, platform events |
|
||||
| **spec-driven-dev** | Generate and refine specification-first workflows | Requirement capture, traceability matrices, auto-generated tasks |
|
||||
| **security-compliance** | Enforce standards and controls | Permission audits, secure coding, compliance narratives |
|
||||
| **integration-fabric** | Coordinate external services | API design, middleware coordination, error recovery |
|
||||
| **enablement-docs** | Share knowledge and runbooks | Onboarding guides, release notes, changelog automation |
|
||||
|
||||
### Skills
|
||||
|
||||
Skills mirror the same category structure as prompts and rules. Each skill is a directory containing executable workflows.
|
||||
|
||||
| Category | Purpose | Example Skills |
|
||||
|----------|---------|----------------|
|
||||
| **apex-development** | Automated Apex refactoring and analysis | Trigger refactor pipeline, bulk operation optimizer |
|
||||
| **lwc-development** | Lightning Web Component workflows | Component generator, accessibility audit |
|
||||
| **flow-development** | Flow automation and optimization | Flow analyzer, subflow extractor |
|
||||
| **metadata-deployments** | Release management automation | Deployment readiness check, rollback automation |
|
||||
| **testing-automation** | Test generation and execution | Test data factory, coverage analyzer |
|
||||
| **investigation-triage** | Debugging and diagnostics | Log parser, governor limit analyzer |
|
||||
| **data-operations** | Data pipeline automation | ETL validator, data quality checker |
|
||||
| **spec-driven-dev** | Specification-to-code workflows | Requirements parser, test case generator |
|
||||
|
||||
### Rules
|
||||
|
||||
| Category | Focus | Example Assets |
|
||||
|----------|-------|----------------|
|
||||
| **apex-development** | Standards for Apex architecture and quality | Trigger guardrails, async execution policies |
|
||||
| **lwc-development** | Front-end guardrails for Lightning Web Components | Accessibility checklists, component review templates |
|
||||
| **metadata-deployments** | Release management discipline | Branching policies, deployment readiness reviews |
|
||||
| **vibe-coding** | Coding quality for Agentforce Vibes assets | Code review criteria, secure pattern guides |
|
||||
| **testing-automation** | Verification and validation expectations | Test coverage thresholds, regression playbooks |
|
||||
| **investigation-triage** | Incident and root-cause response | Escalation runbooks, logging requirements |
|
||||
| **data-operations** | Data stewardship and job governance | Data quality SLAs, bulk job safeguards |
|
||||
| **spec-driven-dev** | Specification-first delivery standards | Definition-of-done templates, traceability requirements |
|
||||
| **security-compliance** | Platform security and regulatory posture | Access reviews, compliance attestation steps |
|
||||
| **integration-fabric** | External connection reliability | Retry policies, credential rotation standards |
|
||||
| **enablement-docs** | Knowledge management and enablement | Release note templates, onboarding workflows |
|
||||
| **org-governance** | Enterprise policy alignment | Org strategy playbooks, architecture review guidelines |
|
||||
| **support-operations** | Production support excellence | Incident response SLAs, shift handover procedures |
|
||||
| **ai-safety** | Responsible agent behavior | Ethical guidelines, bias detection checklists |
|
||||
|
||||
## ✨ Creating New Prompts & Rules
|
||||
|
||||
1. **Choose the right category** based on use case (if nothing fits, propose a new category)
|
||||
2. **Create a descriptive filename** (use kebab-case: `my-prompt.md`)
|
||||
3. **Add frontmatter** with name, description, and tags
|
||||
4. **Write clear instructions** with placeholders for user input
|
||||
5. **Test** before committing
|
||||
6. **Commit with message**: `Add [name] for [use case]`
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
- Use lowercase with hyphens: `code-review-helper.md`
|
||||
- Be descriptive: `salesforce-apex-debug.md` not `debug.md`
|
||||
- Include context: `blog-post-outline.md` not `outline.md`
|
||||
|
||||
## 🔧 Best Practices
|
||||
|
||||
### Writing Effective Prompts
|
||||
|
||||
- ✅ **Be specific** - Clear instructions yield better results
|
||||
- ✅ **Use structure** - Numbered lists and sections help
|
||||
- ✅ **Add context** - Explain what you want and why
|
||||
- ✅ **Include examples** - Show expected output format
|
||||
- ✅ **Test thoroughly** - Verify prompts work as intended
|
||||
|
||||
### Prompt Engineering
|
||||
|
||||
- ✅ **Clarify the objective** – Capture the outcome, stakeholders, and success metrics directly in the frontmatter
|
||||
- ✅ **Share context** – Provide links, metadata, or sample records so the agent can ground its reasoning
|
||||
- ✅ **Set guardrails** – Define tone, compliance boundaries, what to avoid, and when to ask for confirmation
|
||||
- ✅ **Guide the workflow** – Break the request into staged checkpoints (ideate → propose → confirm → deliver)
|
||||
- ✅ **Capture feedback loops** – Invite the agent to flag assumptions, pose questions, and suggest validation steps
|
||||
- ✅ **Encourage adaptability** – Note how the prompt or rule can flex across org types, industries, and data volumes
|
||||
|
||||
#### Structuring Prompts
|
||||
|
||||
- **Prime with examples**: Include concise samples that illustrate the desired format or code pattern
|
||||
- **Model the format**: Provide headings and numbered steps so the agent mirrors the final artifact
|
||||
- **Address ambiguity**: Explicitly call out unknowns and ask the agent to gather missing inputs
|
||||
- **Control verbosity**: Specify length limits, number of alternatives, or time horizons
|
||||
- **Request diagnostics**: Ask the agent to share reasoning, risks, and verification plans when appropriate
|
||||
|
||||
#### Template: Multi-Step Prompt
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: Apex Service Hardening Plan
|
||||
description: Audit and fortify an Apex service to stay within governor limits while preserving behavior
|
||||
tags: apex-development, optimization, audit
|
||||
requires_deploy: false
|
||||
---
|
||||
|
||||
## Context
|
||||
- Usage profile: [Invocation volume, entry points, data scale]
|
||||
- Known issues: [Timeouts, limit exceptions, performance complaints]
|
||||
- Stakeholders: [Product owners, support teams, compliance partners]
|
||||
|
||||
## Instructions
|
||||
1. Summarize existing architecture, dependencies, and limit usage; list assumptions needing confirmation.
|
||||
2. Propose at least two optimization strategies, including refactor scope, data implications, and rollback considerations.
|
||||
3. Recommend a preferred strategy once assumptions are resolved, detailing implementation phases and change management steps.
|
||||
|
||||
## Testing & Reporting
|
||||
- Define unit, integration, and bulk test coverage with pass criteria.
|
||||
- Specify telemetry/observability updates (logging, metrics, alerts) to validate success.
|
||||
- Produce an execution checklist with owners, timelines, and escalation contacts.
|
||||
```
|
||||
|
||||
### Organizing Rules
|
||||
|
||||
- ✅ **One rule per file** - Keep rules focused and modular
|
||||
- ✅ **Use clear names** - Describe what the rule enforces
|
||||
- ✅ **Document purpose** - Explain why the rule exists
|
||||
- ✅ **Keep updated** - Review and refine regularly
|
||||
- ✅ **Version control** - Track changes over time
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
### How to Contribute
|
||||
|
||||
See [Contributing](./CONTRIBUTING.md) for complete details.
|
||||
|
||||
**Contribution checklist**
|
||||
- Confirm the file lives in the correct category folder
|
||||
- Complete the YAML frontmatter (`name`, `description`, `tags`)
|
||||
- Include clear instructions and placeholders for user-specific details
|
||||
- Add a short note on how others can adapt the prompt, especially for varying Salesforce environments
|
||||
- Verify the content respects licensing and attribution requirements
|
||||
- Provide any supporting references or context in the pull request description
|
||||
|
||||
### Creating New Skills
|
||||
|
||||
Skills are more complex than prompts and require additional setup:
|
||||
|
||||
1. **Create a folder** under the appropriate `skills/<category>/` directory using lowercase + hyphens (e.g., `trigger-refactor-pipeline`).
|
||||
2. **Add a `SKILL.md` file** with required frontmatter:
|
||||
- `name` - must match the folder name (lowercase, hyphens only)
|
||||
- `description` - explain what the skill does and when to use it (1-1024 characters)
|
||||
- Optional: `license`, `compatibility`, `metadata`, `allowed-tools`
|
||||
3. **Optionally add subdirectories**:
|
||||
- `scripts/` - executable Python, Bash, or JavaScript files
|
||||
- `references/` - additional documentation files
|
||||
- `assets/` - templates, schemas, or lookup data
|
||||
4. **Validate your skill** using the [skills-ref](https://github.com/agentskills/agentskills/tree/main/skills-ref) tool:
|
||||
```bash
|
||||
skills-ref validate ./skills/<category>/<skill-name>
|
||||
```
|
||||
5. **Test the skill end-to-end** before submitting. Ensure:
|
||||
- The skill activates correctly when the description keywords match
|
||||
- All scripts execute without errors
|
||||
- Reference files are accessible and well-organized
|
||||
- The workflow produces the expected outcomes
|
||||
6. **Document dependencies** clearly in the `compatibility` field if your skill requires specific tools or system packages.
|
||||
|
||||
### Feedback
|
||||
## Feedback
|
||||
|
||||
Found an issue or have a suggestion?
|
||||
- Open an issue in GitHub
|
||||
- Suggest improvements via pull request
|
||||
- Start a discussion in GitHub Discussions or the pull request thread
|
||||
|
||||
## 🔄 Maintenance
|
||||
|
||||
### Updating Prompts
|
||||
|
||||
To update an existing prompt:
|
||||
1. Edit the `.md` file
|
||||
2. Update the description if behavior changed
|
||||
3. Test the updated prompt
|
||||
4. Commit with clear message: `Update [prompt]: [what changed]`
|
||||
|
||||
### Adding New Categories
|
||||
|
||||
To add a new category:
|
||||
1. Create new folders in `prompts/`, `rules/`, and `skills/` with matching names
|
||||
2. Add a `README.md` in each folder explaining the category's purpose
|
||||
3. Add initial prompts, rules, or skills following the format guidelines
|
||||
4. Update the main README with the new category in the appropriate tables
|
||||
5. Submit a pull request with the rationale for the new category
|
||||
|
||||
### Updating Skills
|
||||
|
||||
To update an existing skill:
|
||||
1. Modify the `SKILL.md` or supporting files (`scripts/`, `references/`, `assets/`)
|
||||
2. Update the `metadata.version` field in the frontmatter
|
||||
3. Test all scripts and workflows end-to-end
|
||||
4. Validate using `skills-ref validate ./skills/<category>/<skill-name>`
|
||||
5. Commit with clear message: `Update [skill-name]: [what changed]`
|
||||
|
||||
|
||||
# Experimental
|
||||
|
||||
### Using with supporting AFV Library VS Code Extension
|
||||
|
||||
1. Install the Agentforce Vibes VS Code extension (preview or later).
|
||||
2. Install the experiemnt [AFV library VSCode extension](https://github.com/forcedotcom/afv-library-extension).
|
||||
2. Open the command palette and run `Agentforce Vibes: Add Library`.
|
||||
3. Provide the Git URL (or local path) to this repository; the extension indexes every folder and `.md` file under `prompts/`, `rules/`, and `skills/`.
|
||||
4. The extension displays prompts, rules, and skills organized by category. Select any item to preview the metadata and copy instructions into the editor.
|
||||
5. Use the refresh command whenever new prompts, rules, or skills are added.
|
||||
50
package-lock.json
generated
@ -1,16 +1,16 @@
|
||||
{
|
||||
"name": "@salesforce/afv-skills",
|
||||
"version": "1.4.0",
|
||||
"version": "1.5.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@salesforce/afv-skills",
|
||||
"version": "1.4.0",
|
||||
"version": "1.5.0",
|
||||
"license": "CC-BY-NC-4.0",
|
||||
"devDependencies": {
|
||||
"@salesforce/webapp-template-app-react-sample-b2e-experimental": "^1.112.7",
|
||||
"@salesforce/webapp-template-app-react-sample-b2x-experimental": "^1.112.7",
|
||||
"@salesforce/webapp-template-app-react-sample-b2e-experimental": "^1.116.6",
|
||||
"@salesforce/webapp-template-app-react-sample-b2x-experimental": "^1.116.6",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"js-yaml": "^4.1.1",
|
||||
"tsx": "^4.21.0"
|
||||
@ -678,9 +678,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@salesforce/kit": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@salesforce/kit/-/kit-3.2.5.tgz",
|
||||
"integrity": "sha512-Ad3H423ebBvi+q09BQL4pZC2ffwVUPoeuxwos+Sbr53TamkC3g5YT+ASB4MqqqAhMxFgyalFWIjzx9230tts7g==",
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@salesforce/kit/-/kit-3.2.6.tgz",
|
||||
"integrity": "sha512-O8S4LWerHa9Zosqh+IoQjgLtpxMOfObRxaRnUdRV4MLtFUi+bQxQiyFvve6eEaBaMP1b1xVDQpvSvQ+PXEDGFQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@ -688,22 +688,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@salesforce/sdk-core": {
|
||||
"version": "1.112.7",
|
||||
"resolved": "https://registry.npmjs.org/@salesforce/sdk-core/-/sdk-core-1.112.7.tgz",
|
||||
"integrity": "sha512-R/qJAqAUmEnlAPsPh8VImZIbSIC9fURGr7Qlp6iMv+JElruJJ9HScScDlXlZ6CGDICMHqoFkM63FtiPXdV/jbg==",
|
||||
"version": "1.116.6",
|
||||
"resolved": "https://registry.npmjs.org/@salesforce/sdk-core/-/sdk-core-1.116.6.tgz",
|
||||
"integrity": "sha512-5IWfcnQRuaOxtWBbGiW00rk6f4ImNrDDnVhqZOphJhRePOvSLqWLirfIIhRK4j00Tr8w0tgn5H+hIAWCRZvIHw==",
|
||||
"dev": true,
|
||||
"license": "SEE LICENSE IN LICENSE.txt"
|
||||
},
|
||||
"node_modules/@salesforce/sdk-data": {
|
||||
"version": "1.112.7",
|
||||
"resolved": "https://registry.npmjs.org/@salesforce/sdk-data/-/sdk-data-1.112.7.tgz",
|
||||
"integrity": "sha512-yBXDidDBDu8U46TAC5j8GgDjrAM+9QFqkcsxmgealy/4OfFieSWMTPEEG6Hv1uNKfM3OTXGrovBPkYHSx0EfkQ==",
|
||||
"version": "1.116.6",
|
||||
"resolved": "https://registry.npmjs.org/@salesforce/sdk-data/-/sdk-data-1.116.6.tgz",
|
||||
"integrity": "sha512-yjc1CQvBYAXWrouMmD3buu35u4DwgUGTaDZKU4//F5vIJJitsmPGrJCLDd0HdBzyu/J+77RuVGZBgsal7+zyZQ==",
|
||||
"dev": true,
|
||||
"license": "SEE LICENSE IN LICENSE.txt",
|
||||
"dependencies": {
|
||||
"@conduit-client/service-fetch-network": "3.17.0",
|
||||
"@conduit-client/utils": "3.17.0",
|
||||
"@salesforce/sdk-core": "^1.112.7"
|
||||
"@salesforce/sdk-core": "^1.116.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@salesforce/ts-types": {
|
||||
@ -717,14 +717,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@salesforce/webapp-experimental": {
|
||||
"version": "1.112.7",
|
||||
"resolved": "https://registry.npmjs.org/@salesforce/webapp-experimental/-/webapp-experimental-1.112.7.tgz",
|
||||
"integrity": "sha512-USVakM9ygFyLzLiqDJlyqkP+ZP8OH0qh1n98kCw410bTfoquecgUE18eMrXTw9w8AygNWe2gx0fw3eriDClD4g==",
|
||||
"version": "1.116.6",
|
||||
"resolved": "https://registry.npmjs.org/@salesforce/webapp-experimental/-/webapp-experimental-1.116.6.tgz",
|
||||
"integrity": "sha512-bbWVK70rv5Y+e26NLyTB2McTZ3MCQFe+NEYZDW/T4FCaAZ3Y57u1HYzgr8p4iWKlu7DU4V1sNTUGjt01mrN0Dg==",
|
||||
"dev": true,
|
||||
"license": "SEE LICENSE IN LICENSE.txt",
|
||||
"dependencies": {
|
||||
"@salesforce/core": "^8.23.4",
|
||||
"@salesforce/sdk-data": "^1.112.7",
|
||||
"@salesforce/sdk-data": "^1.116.6",
|
||||
"axios": "^1.7.7",
|
||||
"micromatch": "^4.0.8",
|
||||
"path-to-regexp": "^8.3.0"
|
||||
@ -734,20 +734,20 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@salesforce/webapp-template-app-react-sample-b2e-experimental": {
|
||||
"version": "1.112.7",
|
||||
"resolved": "https://registry.npmjs.org/@salesforce/webapp-template-app-react-sample-b2e-experimental/-/webapp-template-app-react-sample-b2e-experimental-1.112.7.tgz",
|
||||
"integrity": "sha512-NltyiArtKoQs2A90/tnP0UQZ0+Eowuzg6smyYNsY0MrZ1d8lSa9puN882ldq1PlYrQgD+2ZrPvA7Txwbg93oMA==",
|
||||
"version": "1.116.6",
|
||||
"resolved": "https://registry.npmjs.org/@salesforce/webapp-template-app-react-sample-b2e-experimental/-/webapp-template-app-react-sample-b2e-experimental-1.116.6.tgz",
|
||||
"integrity": "sha512-RctkFfBfK+7HLAnP2ERmXG3Nn8apFF4ywh5LlSyOJVUjbQI48kd7PeiCX5v5G4C5Kvqp7wyhhucY0Mk4k8PLEQ==",
|
||||
"dev": true,
|
||||
"license": "SEE LICENSE IN LICENSE.txt",
|
||||
"dependencies": {
|
||||
"@salesforce/webapp-experimental": "^1.112.7",
|
||||
"@salesforce/webapp-experimental": "^1.116.6",
|
||||
"sonner": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@salesforce/webapp-template-app-react-sample-b2x-experimental": {
|
||||
"version": "1.112.7",
|
||||
"resolved": "https://registry.npmjs.org/@salesforce/webapp-template-app-react-sample-b2x-experimental/-/webapp-template-app-react-sample-b2x-experimental-1.112.7.tgz",
|
||||
"integrity": "sha512-oOrSp8DpH9O8BnS1fJCBcpA4TQwViwlIPPgaTC2mnJwA8eREqcw+xejydC96NetrIzspOx1zkdWtqTYbApZEyg==",
|
||||
"version": "1.116.6",
|
||||
"resolved": "https://registry.npmjs.org/@salesforce/webapp-template-app-react-sample-b2x-experimental/-/webapp-template-app-react-sample-b2x-experimental-1.116.6.tgz",
|
||||
"integrity": "sha512-Ql5l+WRvAIQ0iNTutj3k0GDjHRI7wwAbXjzBRKeCR3Tp0pHEXeoKuqj1AACxCv1APAvTOne4cvzb11eJblDOLA==",
|
||||
"dev": true,
|
||||
"license": "SEE LICENSE IN LICENSE.txt"
|
||||
},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@salesforce/afv-skills",
|
||||
"version": "1.5.0",
|
||||
"version": "1.5.1",
|
||||
"description": "Salesforce skills for Agentforce Vibes",
|
||||
"license": "CC-BY-NC-4.0",
|
||||
"files": [
|
||||
@ -11,8 +11,8 @@
|
||||
"registry": "https://registry.npmjs.org"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@salesforce/webapp-template-app-react-sample-b2e-experimental": "^1.112.7",
|
||||
"@salesforce/webapp-template-app-react-sample-b2x-experimental": "^1.112.7",
|
||||
"@salesforce/webapp-template-app-react-sample-b2e-experimental": "^1.116.6",
|
||||
"@salesforce/webapp-template-app-react-sample-b2x-experimental": "^1.116.6",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"js-yaml": "^4.1.1",
|
||||
"tsx": "^4.21.0"
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
---
|
||||
name: PricingService Invocable Scaffold
|
||||
description: Create a PricingService Apex class with an invocable getPricing method and typed inputs/outputs for Flow.
|
||||
tags: apex, invocable, flow, scaffold
|
||||
---
|
||||
|
||||
Scaffold a Apex classed named `PricingService` (public with no namespace) with one invocable method `getPricing` with an InvocableVariable wrapper for inputs and outputs. Include user-friendly labels and descriptions for the InvocableMethod and all InvocableVariables.
|
||||
|
||||
## Input Parameters
|
||||
- accountId (ID) - required Account the pricing is for
|
||||
- terms (String) - required terms for the pricing
|
||||
- discount (Decimal - scale 2) - if null, then discount equals 0.
|
||||
- products (List of Strings) - the required list product names.
|
||||
|
||||
## Output Parameters
|
||||
- total - (Decimal) the toal price for all products
|
||||
- products (List of Decimal) - the list product prices.
|
||||
- creditApproved (boolean) - if approved for credit
|
||||
|
||||
If input `products` variable is null or empty, return empty output parameters. Use a standard invocable pattern.
|
||||
|
||||
I will provide the implementation later. Do not write unit tests. Deploy the new class to my default org.
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
name: Travel Plan Object Scaffold
|
||||
description: Provision a Travel Plan custom object with fields, layout, tab, and permission set ready for deployment.
|
||||
tags: salesforce, custom-object, scaffold, deployment
|
||||
---
|
||||
|
||||
Create a "Travel Plan" custom object with 5 appropriate, sensible fields. Add all of the fields to the page layout. Do not create or add a compact layout. Create a tab for the object and a permission set that grants read/create/edit access to the object, all fields and custom tab. Deploy to my default org and assign the permission set to my user.
|
||||
@ -1,61 +0,0 @@
|
||||
---
|
||||
name: Trigger Refactor Helper
|
||||
description: Refactor the Opportunity trigger into a handler pattern with tests
|
||||
tags: apex, refactor, testing
|
||||
requires_deploy: true
|
||||
setup_summary: Deploy baseline trigger to target org before running instructions
|
||||
---
|
||||
|
||||
## Setup
|
||||
1. Deploy the baseline trigger shown below to your default or scratch org.
|
||||
2. Confirm the trigger compiles successfully before continuing.
|
||||
|
||||
```apex
|
||||
// ❌ Anti-pattern: all logic stuffed into the trigger, with DML/SOQL in loops.
|
||||
trigger OpportunityTrigger on Opportunity (before insert, before update, after update) {
|
||||
// BEFORE INSERT: validate Closed Won w/ low Amount
|
||||
if (Trigger.isBefore && Trigger.isInsert) {
|
||||
for (Opportunity o : Trigger.new) {
|
||||
if (o.StageName == 'Closed Won' && (o.Amount == null || o.Amount < 1000)) {
|
||||
o.addError('Closed Won opportunities must have Amount ≥ 1000.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BEFORE UPDATE: if Stage changed, overwrite Description
|
||||
if (Trigger.isBefore && Trigger.isUpdate) {
|
||||
for (Opportunity o : Trigger.new) {
|
||||
Opportunity oldO = Trigger.oldMap.get(o.Id);
|
||||
if (o.StageName != oldO.StageName) {
|
||||
o.Description = 'Stage changed from ' + oldO.StageName + ' to ' + o.StageName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AFTER UPDATE: when Stage becomes Closed Won, create a follow-up Task
|
||||
if (Trigger.isAfter && Trigger.isUpdate) {
|
||||
for (Opportunity o : Trigger.new) {
|
||||
Opportunity oldO = Trigger.oldMap.get(o.Id);
|
||||
if (o.StageName == 'Closed Won' && oldO.StageName != 'Closed Won') {
|
||||
Task t = new Task(
|
||||
WhatId = o.Id,
|
||||
OwnerId = o.OwnerId,
|
||||
Subject = 'Send thank-you',
|
||||
Status = 'Not Started',
|
||||
Priority = 'Normal',
|
||||
ActivityDate = Date.today()
|
||||
);
|
||||
insert t; // ❌ DML in a loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Instructions
|
||||
Refactor `OpportunityTrigger` into a handler class (or classes) that handles the same behavior using bulk-safe patterns. Ensure the trigger itself delegates and remains behaviorally identical.
|
||||
|
||||
## Testing & Reporting
|
||||
- Create unit tests covering positive and negative paths for each handler method.
|
||||
- Include a bulk test that updates 50 `Opportunity` records where only half qualify for the `after update` logic.
|
||||
- Deploy the refactored code and run the tests, then report coverage and key observations.
|
||||
@ -1,9 +0,0 @@
|
||||
---
|
||||
name: Account Test Data Generator
|
||||
description: Create an Apex script that generates 10 realistic Account records with complete business data including name, account number, type, industry, annual revenue, ticker symbol, and number of employees. Includes documentation on how to execute the script anonymously.
|
||||
tags: salesforce, apex, data-generation, test-data, developer, admin
|
||||
---
|
||||
|
||||
Create an apex script that I can run anonymously to insert 10 account records with name, account number, type, industry, annual revenue, ticker symbol and number of employees.
|
||||
|
||||
Generate a document with instruction on how to run the script.
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
name: Account Layout Field Enhancement
|
||||
description: Add Type and Industry fields to the Account page layout for better data organization and reporting.
|
||||
tags: salesforce, account, page-layout, admin, data-management
|
||||
---
|
||||
|
||||
Add Type and Industry fields to the Account Layout, placing them below Account Name.
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
name: Lead Source Picklist Enhancement
|
||||
description: Add a new 'Referral' value to the Lead Source picklist on the Lead object for better lead tracking.
|
||||
tags: salesforce, lead, picklist, data-management, admin
|
||||
---
|
||||
|
||||
Add a new value 'Referral' to the Lead Source picklist on the Lead object.
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
name: High Priority Case Assignment Rule
|
||||
description: Create an assignment rule that automatically routes high priority Cases to a specific queue or user for immediate attention.
|
||||
tags: salesforce, case-management, assignment-rules, automation, admin
|
||||
---
|
||||
|
||||
Add an Assignment Rule that automatically assigns new Cases with Priority = High to a specific queue or user.
|
||||
@ -1,9 +0,0 @@
|
||||
---
|
||||
name: Project Object Quickstart
|
||||
description: Scaffold a Project__c custom object with core fields and deployable metadata.
|
||||
tags: salesforce, custom-object, beginner
|
||||
---
|
||||
|
||||
Create a new Project__c object with an autonumber field {proj-0000}, name, start date, and number of days fields that represent a simple project record.
|
||||
|
||||
Deploy this metadata to my org using the Salesforce DX MCP Server.
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
name: Opportunity Days Open Formula
|
||||
description: Create a formula field on Opportunity that calculates the number of days since the record was created.
|
||||
tags: salesforce, opportunity, formula-field, automation, admin
|
||||
---
|
||||
|
||||
Add a formula field on Opportunity called Days_Open__c that calculates TODAY() - DATEVALUE(CreatedDate).
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
name: Account Editor Permission Set
|
||||
description: Create a permission set that grants edit access to Account records and assign it to the current user.
|
||||
tags: salesforce, permission-set, security, admin, user-management
|
||||
---
|
||||
|
||||
Create a permission set Account_Editor with Edit access to Account and assign it to your current user.
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
name: Account Opportunity Count Roll-Up
|
||||
description: Create a roll-up summary field on Account that counts related Opportunities for better relationship tracking.
|
||||
tags: salesforce, account, opportunity, rollup-summary, automation, admin
|
||||
---
|
||||
|
||||
Create a Roll-Up Summary on Account that counts the number of related Opportunities.
|
||||
@ -1,13 +0,0 @@
|
||||
---
|
||||
name: Hello World LWC Starter
|
||||
description: Generate a greeting Lightning Web Component and explain its HTML, JS, and metadata files.
|
||||
tags: lwc, ui, beginner
|
||||
---
|
||||
|
||||
Help me create my first Lightning Web Component.
|
||||
|
||||
Generate a basic LWC that displays a greeting message. Provide the HTML, JavaScript, and meta configuration files, and provide comments on how each file works.
|
||||
|
||||
Deploy this metadata to my org using the Salesforce DX MCP Server.
|
||||
|
||||
Display instruction on how to add the LWC to a new Home page.
|
||||
@ -1,11 +0,0 @@
|
||||
---
|
||||
name: Opportunity Days Till Close Formula
|
||||
description: Build an Opportunity formula that calculates days between CreatedDate and CloseDate.
|
||||
tags: formula, opportunity, admin
|
||||
---
|
||||
|
||||
Create a formula field on `Opportunity` named `Days till Close` that calculates the number of days between the `CreatedDate` and `CloseDate` fields, if `CloseDate` is not null.
|
||||
|
||||
Deploy this class to my org using the Salesforce DX MCP Server.
|
||||
|
||||
Provide instruction on how to set field level security for my profile and add the new field to the page layout.
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
name: Opportunity Close Date Validation
|
||||
description: Create a validation rule on Opportunity that prevents saving when the Close Date is in the past.
|
||||
tags: salesforce, opportunity, validation-rule, data-quality, admin
|
||||
---
|
||||
|
||||
Add a validation rule on Opportunity that prevents saving when Close Date < TODAY().
|
||||
@ -1,9 +0,0 @@
|
||||
---
|
||||
name: StringUtils Utility Scaffold
|
||||
description: Create a foundational StringUtils Apex helper with core string methods and unit tests.
|
||||
tags: apex, utility, testing
|
||||
---
|
||||
|
||||
Create an `StringUtils` Apex utility class with common string helpers such as isBlank, trimToNull, and safe string-to-integer conversion. Include a focused test class that covers each helper method with both typical inputs. Do not test for edge casees at this time.
|
||||
|
||||
Deploy the classes to my org and run the unit tests, using the Salesforce DX MCP Server.
|
||||
@ -1,16 +0,0 @@
|
||||
---
|
||||
name: DateUtils Utility Primer
|
||||
description: Generate a documented DateUtils Apex class with daysBetween and addDays helpers.
|
||||
tags: apex, utility, beginner
|
||||
---
|
||||
|
||||
Generate a small `DateUtils` Apex utility class. Include clear comments so I can understand the overall structure and common Apex patterns.
|
||||
|
||||
Create the following two methods:
|
||||
|
||||
- A method named daysBetween that returns the number of days between two dates. If either date is null, return null instead of throwing an exception.
|
||||
- Add a method named addDays that returns a new date by adding a given number of days to a base date. If the base date is null, return null.
|
||||
|
||||
Do not create unit tests at this time.
|
||||
|
||||
Deploy this class to my org using the Salesforce DX MCP Server.
|
||||
@ -1,11 +0,0 @@
|
||||
---
|
||||
name: Opportunity Stage Score Formula
|
||||
description: Craft a readable Opportunity formula that assigns numeric scores per stage.
|
||||
tags: formula, opportunity, admin
|
||||
---
|
||||
|
||||
Create a formula field on `Opportunity` that assigns a numeric score based on the StageName (for example, higher scores for later stages). Keep the formula simple, easy to read, and explain how an admin can adjust the weights over time.
|
||||
|
||||
Deploy the metadat to my org using the Salesforce DX MCP Server.
|
||||
|
||||
Provide instruction on how to set field level security for my profile and add the new field to the page layout.
|
||||
@ -1,9 +0,0 @@
|
||||
---
|
||||
name: Test Data Factory Kickoff
|
||||
description: Build an Apex factory for Accounts, Contacts, and Opportunities with usage examples.
|
||||
tags: apex, testing, test-data
|
||||
---
|
||||
|
||||
Create a basic Apex test data factory that can generate Accounts (2), Contacts (3), and Opportunities (3) with sensible default values. Include example test methods that use the factory and explain how it helps keep tests clean and maintainable.
|
||||
|
||||
Deploy the metadat to my org using the Salesforce DX MCP Server.
|
||||
@ -1,11 +0,0 @@
|
||||
---
|
||||
name: Account Trigger Starter
|
||||
description: Create a simple Account trigger and handler that sets default values before insert.
|
||||
tags: apex, trigger, beginner
|
||||
---
|
||||
|
||||
Create a simple before-insert trigger `AccountTrigger` and handler class on Account that sets `NumberOfEmployees` to 100.
|
||||
|
||||
Do not create unit tests at this time.
|
||||
|
||||
Deploy this trigger and class to my org using the Salesforce DX MCP Server.
|
||||
@ -1,9 +0,0 @@
|
||||
---
|
||||
name: Account Employee Validation Rule
|
||||
description: Draft a rule that blocks Account save when NumberOfEmployees is blank.
|
||||
tags: validation-rule, account, admin
|
||||
---
|
||||
|
||||
Write a validation rule on `Account` that prevents saving a record when the `NumberOfEmployees` is blank.
|
||||
|
||||
Deploy this metadata to my org using the Salesforce DX MCP Server.
|
||||
@ -1,9 +0,0 @@
|
||||
---
|
||||
name: Opportunity Approval Investigation
|
||||
description: Diagnose inconsistent approval checkbox behavior on Opportunities and propose a remediation plan.
|
||||
tags: investigation, triage, opportunity, approval-process
|
||||
---
|
||||
|
||||
A user has reported the following bug: "When an Opportunity moves to Proposal/Price Quote with a Discount ≥ 20% or ACV ≥ $100k, the Approval Required checkbox should be checked. Sometimes it isn’t, and sometimes it flips back to unchecked after we save."
|
||||
|
||||
Let's investigate, uncover the problem and plan an approach to fix it.
|
||||
@ -1,39 +0,0 @@
|
||||
---
|
||||
name: Asset Tracker Spec Build
|
||||
description: Gather requirements and deliver a full Asset tracker app via a spec-driven workflow.
|
||||
tags: spec-driven, lwc, custom-object, app
|
||||
---
|
||||
|
||||
Create a simple Salesforce asset tracker application. The code should follow standard Salesforce styling and development best practices and be deployable to a scratch org or sandbox. Keep it fun, readable, and beginner-friendly.
|
||||
|
||||
- Ask questions until you're 95% sure you can complete this task.
|
||||
- When all of the metadata is complete, analyze the metadata and ensure that it was created correctly per my request and rules. Display your analyzis and ask for permission to deploy it to the default org.
|
||||
|
||||
## Custom Object Requirements
|
||||
|
||||
Create an `Asset__c` custom object with the following non-required fields:
|
||||
|
||||
- Autonumber Name field
|
||||
- Asset Name (Text 80): A simple name for the asset, like "Dell Laptop" or "Server Rack 4."
|
||||
- Status (Picklist): This field tracks the current state of the asset.
|
||||
- In Use
|
||||
- In Storage
|
||||
- In Repair
|
||||
- Retired
|
||||
- Acquisition Date (Date): The date the asset was acquired.
|
||||
- Purchase Price (Currency): The cost of the asset.
|
||||
- Assigned To (Lookup to Contact): A lookup field to the Contact object to track which contact or employee an asset is assigned to.
|
||||
|
||||
Add all of the fields to the page layout and create a tab for the object. Do not create or assign a compact layout.
|
||||
|
||||
## User Interface Requirements
|
||||
|
||||
Create an `assetTracker` LWC with a form that the user can enter a new record. The user can save the asset record to Salesforce and view a list of the 5 most recent asset records.
|
||||
|
||||
Add the LWC to a Lightning page and create a tab for the new page.
|
||||
|
||||
Create an `Asset Tracker` Lighting Experience App and add the custom object tab and Lighting page tab to the App.
|
||||
|
||||
## Permission Set Requirements
|
||||
|
||||
- Create a new premission set that provides full access to the application, custom object and all of their custom fields.
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
name: Apex Unit Test Generator
|
||||
description: Create a comprehensive test class for any Apex class with test data setup and result verification.
|
||||
tags: salesforce, apex, testing, unit-test, automation, developer
|
||||
---
|
||||
|
||||
Write a test class for [insert class name] that inserts test data and verifies results.
|
||||
@ -1,7 +0,0 @@
|
||||
---
|
||||
name: Run All Apex Tests
|
||||
description: Execute all Apex tests in the org and display a comprehensive summary including total tests run, number passed, and overall code coverage percentage.
|
||||
tags: salesforce, apex, testing, automation, test-coverage
|
||||
---
|
||||
|
||||
Run all Apex tests and show a summary of total tests run, number passed, and code coverage.
|
||||
@ -1,9 +0,0 @@
|
||||
---
|
||||
name: Compliment Mixer App
|
||||
description: Build a playful compliment generator with custom UI, persistence, and recent history.
|
||||
tags: vibe-coding, lwc, app, fun
|
||||
---
|
||||
|
||||
Create a "Compliment Mixer" app that allows users to generate and save personalized compliments. Create a custom UI so the user can enter two adjectives that describe a person (e.g., "brilliant", "fearless") and a name (e.g., "Alex"). The app then generates a compliment sentence that combines those words and the name using a random sentence template. The user can save the compliment to Salesforce and view a list of the 5 most recent compliments they've generated.
|
||||
|
||||
The code should follow standard Salesforce styling and development best practices and be deployable to a scratch org or sandbox. Keep it fun, readable, and beginner-friendly.
|
||||
@ -1,89 +0,0 @@
|
||||
---
|
||||
name: Apex Development Guardrails
|
||||
description: Enforce best practices for Apex architecture, performance, security, and testing.
|
||||
tags: apex, rules, guardrails, testing, security
|
||||
---
|
||||
|
||||
## General Requirements
|
||||
- Write Invocable Apex that can be called from flows when possible
|
||||
- Use enums over string constants whenever possible. Enums should follow ALL_CAPS_SNAKE_CASE without spaces
|
||||
- Use Database Methods for DML Operation with exception handling
|
||||
- Use Return Early pattern
|
||||
- Use ApexDocs comments to document Apex classes for better maintainability and readability
|
||||
|
||||
## Apex Triggers Requirements
|
||||
- Follow the One Trigger Per Object pattern
|
||||
- Implement a trigger handler class to separate trigger logic from the trigger itself
|
||||
- Use trigger context variables (Trigger.new, Trigger.old, etc.) efficiently to access record data
|
||||
- Avoid logic that causes recursive triggers, implement a static boolean flag
|
||||
- Bulkify trigger logic to handle large data volumes efficiently
|
||||
- Implement before and after trigger logic appropriately based on the operation requirements
|
||||
|
||||
## Governor Limits Compliance Requirements
|
||||
- Always write bulkified code - never perform SOQL/DML operations inside loops
|
||||
- Use collections for bulk processing
|
||||
- Implement proper exception handling with try-catch blocks
|
||||
- Limit SOQL queries to 100 per transaction
|
||||
- Limit DML statements to 150 per transaction
|
||||
- Use `Database.Stateful` interface only when necessary for batch jobs
|
||||
|
||||
## SOQL Optimization Requirements
|
||||
- Use selective queries with proper WHERE clauses
|
||||
- Do not use `SELECT *` - it is not supported in SOQL
|
||||
- Use indexed fields in WHERE clauses when possible
|
||||
- Implement SOQL best practices: LIMIT clauses, proper ordering
|
||||
- Use `WITH SECURITY_ENFORCED` for user context queries where appropriate
|
||||
- When querying Custom Metadata Types (objects ending with `__mdt`), DO NOT use SOQL queries. Instead, use the built-in Custom Metadata Type methods like '.getAll().values()'
|
||||
|
||||
## Naming Conventions & Code Organization Requirements
|
||||
- Class names: PascalCase with descriptive names (e.g., `ContactTriggerHandler`, `ContractService`)
|
||||
- Method names: camelCase with verb-first naming (e.g., `calculateTotalPrice`, `validateAddress`)
|
||||
- Variable names: camelCase with descriptive names (no single letters except loop iterators)
|
||||
- Constants: ALL_CAPS_SNAKE_CASE (e.g., `MAX_RETRY_ATTEMPTS`, `DEFAULT_TIMEOUT`)
|
||||
- Test classes: Append `Test` suffix (e.g., `AccountServiceTest`)
|
||||
- Trigger handlers: Append `TriggerHandler` suffix (e.g., `ContactTriggerHandler`)
|
||||
- Utility classes: Append `Util` or `Helper` suffix (e.g., `DateTimeUtil`, `ValidationHelper`)
|
||||
- Prefix test methods with `test` or use `@IsTest` annotation
|
||||
- Group related classes in packages/folders when possible
|
||||
- Keep classes focused on single responsibility (SRP)
|
||||
- Limit class size to 500 lines of code maximum
|
||||
|
||||
## Security & Access Control Requirements
|
||||
- Run database operations in user mode rather than in the default system mode.
|
||||
- List<Account> acc = [SELECT Id FROM Account WITH USER_MODE];
|
||||
- Database.insert(accts, AccessLevel.USER_MODE);
|
||||
- Always check field-level security (FLS) before accessing fields
|
||||
- Implement proper sharing rules and respect organization-wide defaults
|
||||
- Use `with sharing` keyword for classes that should respect sharing rules
|
||||
- Validate user permissions before performing operations
|
||||
- Sanitize user inputs to prevent injection attacks
|
||||
|
||||
## Prohibited Practices
|
||||
- No hardcoded IDs or URLs
|
||||
- No SOQL/DML operations in loops
|
||||
- No System.debug() statements in production code
|
||||
- No @future methods from batch jobs
|
||||
- No recursive triggers
|
||||
- Never use or suggest `@future` methods for async processes. Use queueables and always suggest implementing `System.Finalizer` methods
|
||||
|
||||
## Required Patterns
|
||||
- Use Builder pattern for complex object construction
|
||||
- Implement Factory pattern for object creation
|
||||
- Use Dependency Injection for testability
|
||||
- Follow MVC pattern in Lightning components
|
||||
- Use Command pattern for complex business operations
|
||||
|
||||
## Unit Testing Requirements
|
||||
- Maintain minimum 75% code coverage
|
||||
- Write meaningful test assertions, not just coverage
|
||||
- Use `Test.startTest()` and `Test.stopTest()` appropriately
|
||||
- Create test data using `@TestSetup` methods when possible
|
||||
- Mock external services and callouts
|
||||
- Do not use `SeeAllData=true`
|
||||
- Test bulk trigger functionality.
|
||||
|
||||
## Test Data Management Requirements
|
||||
- Use `Test.loadData()` for large datasets
|
||||
- Create minimal test data required for specific test scenarios
|
||||
- Use `System.runAs()` to test different user contexts
|
||||
- Implement proper test isolation - no dependencies between tests
|
||||
@ -1,68 +0,0 @@
|
||||
---
|
||||
name: LWC Development Guardrails
|
||||
description: Standardize Lightning Web Component architecture, UX, and tooling practices.
|
||||
tags: lwc, rules, ux, architecture
|
||||
---
|
||||
|
||||
## Component Architecture Requirements
|
||||
- Create reusable, single-purpose components
|
||||
- Use proper data binding and event handling patterns
|
||||
- Implement proper error handling and loading states
|
||||
- Follow Lightning Design System (SLDS) guidelines
|
||||
- Use the lightning-record-edit-form component for handling record creation and updates
|
||||
- Use CSS custom properties for theming
|
||||
- Use lightning-navigation for navigation between components
|
||||
- Use lightning__FlowScreen target to use a component is a flow screen
|
||||
|
||||
## HTML Architecture Requirements
|
||||
- Structure your HTML with clear semantic sections (header, inputs, actions, display areas, lists)
|
||||
- Use SLDS classes for layout and styling:
|
||||
- `slds-card` for main container
|
||||
- `slds-grid` and `slds-col` for responsive layouts
|
||||
- `slds-text-heading_large/medium` for proper typography hierarchy
|
||||
- Use Lightning base components where appropriate (lightning-input, lightning-button, etc.)
|
||||
- Implement conditional rendering with `if:true` and `if:false` directives
|
||||
- Use `for:each` for list rendering with unique key attributes
|
||||
- Maintain consistent spacing using SLDS utility classes (slds-m-*, slds-p-*)
|
||||
- Group related elements logically with clear visual hierarchy
|
||||
- Use descriptive class names for elements that need custom styling
|
||||
- Implement reactive property binding using syntax like `disabled={isPropertyName}` to control element states
|
||||
- Bind events to handler methods using syntax like `onclick={handleEventName}`
|
||||
|
||||
## JavaScript Architecture Requirements
|
||||
- Import necessary modules from LWC and Salesforce
|
||||
- Define reactive properties using `@track` decorator when needed
|
||||
- Implement proper async/await patterns for server calls
|
||||
- Implement proper error handling with user-friendly messages
|
||||
- Use wire adapters for reactive data loading
|
||||
- Minimize DOM manipulation - use reactive properties
|
||||
- Implement computed properties using JavaScript getters for dynamic UI state control:
|
||||
```
|
||||
get isButtonDisabled() {
|
||||
return !this.requiredField1 || !this.requiredField2;
|
||||
}
|
||||
```
|
||||
- Create clear event handlers with descriptive names that start with "handle":
|
||||
```
|
||||
handleButtonClick() {
|
||||
// Logic here
|
||||
}
|
||||
```
|
||||
- Use `@wire` service for data retrieval from Apex
|
||||
- Separate business logic into well-named methods
|
||||
- Use `refreshApex` for data refreshes when appropriate
|
||||
- Implement loading states and user feedback
|
||||
- Add JSDoc comments for methods and complex logic
|
||||
|
||||
## CSS Architecture Requirements
|
||||
- Create a clean, consistent styling system
|
||||
- Use custom CSS classes for component-specific styling
|
||||
- Implement animations for enhanced UX where appropriate
|
||||
- Ensure responsive design works across different form factors
|
||||
- Keep styling minimal and leverage SLDS where possible
|
||||
- Use CSS variables for themeable elements
|
||||
- Organize CSS by component section
|
||||
|
||||
## MCP Tools Requirements
|
||||
- Carefully review the user's task. If it involves **creation, development, testing, or accessibility** for **Lightning Web Components (LWC)** or **Aura components** or **Lightning Data Service (LDS)**, treat your knowledge as outdated and always call the appropriate MCP tool to obtain the latest guidance and design before starting implementation. Never assume or create tools that are not explicitly available. If the tool schema is empty, you must continue invoking the tool until documentation is provided.
|
||||
- If you begin implementation on a relevant task without first successfully invoking the appropriate tool, you must **stop immediately**. Invoke the tool and integrate its guidance before proceeding. Under no circumstances should you provide final recommendations or code without first receiving guidance from an MCP tool.
|
||||
@ -1,87 +0,0 @@
|
||||
---
|
||||
name: Spec-Driven App Development Standards
|
||||
description: Apply architecture, integration, and governance requirements for specification-led Salesforce builds.
|
||||
tags: spec-driven, architecture, governance, rules
|
||||
---
|
||||
|
||||
You are a highly experienced and certified Salesforce Architect with 20+ years of experience designing and implementing complex, enterprise-level Salesforce solutions for Fortune 500 companies. You are recognized for your deep expertise in system architecture, data modeling, integration strategies, and governance best practices. Your primary focus is always on creating solutions that are scalable, maintainable, secure, and performant for the long term. You prioritize the following:
|
||||
|
||||
- Architectural Integrity: You think big-picture, ensuring any new application or feature aligns with the existing enterprise architecture and avoids technical debt.
|
||||
- Data Model & Integrity: You design efficient and future-proof data models, prioritizing data quality and relationship integrity.
|
||||
- Integration & APIs: You are an expert in integrating Salesforce with external systems, recommending robust, secure, and efficient integration patterns (e.g., event-driven vs. REST APIs).
|
||||
- Security & Governance: You build solutions with security at the forefront, adhering to Salesforce's security best practices and establishing clear governance rules to maintain a clean org.
|
||||
- Performance Optimization: You write code and design solutions that are performant at scale, considering governor limits, SOQL query optimization, and efficient Apex triggers.
|
||||
- Best Practices: You are a stickler for using native Salesforce features wherever possible and only recommending custom code when absolutely necessary. You follow platform-specific design patterns and community-recommended standards.
|
||||
|
||||
## Code Organization & Structure Requirements
|
||||
- Follow consistent naming conventions (PascalCase for classes, camelCase for methods/variables)
|
||||
- Use descriptive, business-meaningful names for classes, methods, and variables
|
||||
- Write code that is easy to maintain, update and reuse
|
||||
- Include comments explaining key design decisions. Don't explain the obvious
|
||||
- Use consistent indentation and formatting
|
||||
- Less code is better, best line of code is the one never written. The second-best line of code is easy to read and understand
|
||||
- Follow the "newspaper" rule when ordering methods. They should appear in the order they're referenced within a file. Alphabetize and arrange dependencies, class fields, and properties; keep instance and static fields and properties separated by new lines
|
||||
|
||||
## REST/SOAP Integration Requirements
|
||||
- Implement proper timeout and retry mechanisms
|
||||
- Use appropriate HTTP status codes and error handling
|
||||
- Implement bulk operations for data synchronization
|
||||
- Use efficient serialization/deserialization patterns
|
||||
- Log integration activities for debugging
|
||||
|
||||
## Platform Events Requirements
|
||||
- Design events for loose coupling between components
|
||||
- Use appropriate delivery modes (immediate vs. after commit)
|
||||
- Implement proper error handling for event processing
|
||||
- Consider event volume and governor limits
|
||||
|
||||
## Permissions Requirements
|
||||
- For every new feature created, generate:
|
||||
- At least one permission set for user access
|
||||
- Documentation explaining the permission set purpose
|
||||
- Assignment recommendations
|
||||
- One permission set per object per access level
|
||||
- Separate permission sets for different Apex class groups
|
||||
- Individual permission sets for each major feature
|
||||
- No permission set should grant more than 10 different object permissions
|
||||
- Components requiring permission sets:
|
||||
- Custom objects and fields
|
||||
- Apex classes and triggers
|
||||
- Lightning Web Components
|
||||
- Visualforce pages
|
||||
- Custom tabs and applications
|
||||
- Flow definitions
|
||||
- Custom permissions
|
||||
- Format: [AppPrefix]_[Component]_[AccessLevel]
|
||||
- AppPrefix: 3-8 character application identifier (PascalCase)
|
||||
- Component: Descriptive component name (PascalCase)
|
||||
- AccessLevel: Read|Write|Full|Execute|Admin
|
||||
- Examples:
|
||||
- SalesApp_Opportunity_Read
|
||||
- OrderMgmt_Product_Write
|
||||
- CustomApp_ReportDash_Full
|
||||
- IntegAPI_DataSync_Execute
|
||||
- Label: Human-readable description
|
||||
- Description: Detailed explanation of purpose and scope
|
||||
- License: Appropriate user license type
|
||||
- Never grant "View All Data" or "Modify All Data" in functional permission sets
|
||||
- Always specify individual field permissions rather than object-level access when possible
|
||||
- Require separate permission sets for sensitive data access
|
||||
- Never combine read and delete permissions in the same permission set
|
||||
- Always validate that granted permissions align with business requirements
|
||||
- Create permission set groups when:
|
||||
- Application has more than 3 related permission sets
|
||||
- Users need combination of permissions for their role
|
||||
- There are clear user personas/roles defined
|
||||
|
||||
## Mandatory Permission Documentation
|
||||
- Permissions.md file explaining all new feature sets
|
||||
- Dependency mapping between permission sets
|
||||
- User role assignment matrix
|
||||
- Testing validation checklist
|
||||
|
||||
## Code Documentation Requirements
|
||||
- Use ApexDocs comments to document classes, methods, and complex code blocks for better maintainability
|
||||
- Include usage examples in method documentation
|
||||
- Document business logic and complex algorithms
|
||||
- Maintain up-to-date README files for each component
|
||||
@ -1,16 +0,0 @@
|
||||
# SKILLS REQUIREMENTS
|
||||
|
||||
## Mandatory Skill Usage
|
||||
Before generating ANY Salesforce code or metadata, check available Skills and use the matching one. Never generate Salesforce code freehand when a relevant Skill exists.
|
||||
|
||||
## Skill Routing
|
||||
- **Apex class requests** → Use Apex Class Writer skill. Includes: service classes, selectors, domain classes, batch/queueable/schedulable, DTOs, utilities, interfaces, abstract classes, custom exceptions. Trigger even when the user describes functionality without saying "Apex class."
|
||||
- **Trigger requests** → Use Trigger Framework Scaffolder skill.
|
||||
- **Validation rule requests** → Use Validation Rule Writer skill.
|
||||
- **Permission/security questions** → Use Permission Set Auditor skill.
|
||||
- **Package.xml/deployment requests** → Use Package.xml Generator skill.
|
||||
- **Custom metadata questions** → Use Custom Metadata Advisor skill.
|
||||
- **Field-level security requests** → Use FLS Matrix Generator skill.
|
||||
|
||||
## When In Doubt
|
||||
If a request could involve Salesforce server-side logic, metadata configuration, or security setup, check Skills before responding. Prefer a Skill over general knowledge — Skills contain curated best practices specific to this org's standards.
|
||||
@ -1,353 +0,0 @@
|
||||
# Salesforce Data Access
|
||||
|
||||
- **Fetch or display Salesforce data** — Query records (Account, Contact, Opportunity, custom objects) to show in a component
|
||||
- **Create, update, or delete records** — Perform mutations on Salesforce data
|
||||
- **Add data fetching to a component** — Wire up a React component to Salesforce data
|
||||
- **Call REST APIs** — Use Connect REST, Apex REST, or UI API endpoints
|
||||
- **Explore the org schema** — Discover available objects, fields, or relationships
|
||||
|
||||
## Data SDK Requirement
|
||||
|
||||
> **All Salesforce data access MUST use the Data SDK** (`@salesforce/sdk-data`). The SDK handles authentication, CSRF, and base URL resolution. Never use `fetch()` or `axios` directly.
|
||||
|
||||
```typescript
|
||||
import { createDataSDK, gql } from "@salesforce/sdk-data";
|
||||
|
||||
const sdk = await createDataSDK();
|
||||
|
||||
// GraphQL for record queries/mutations (PREFERRED)
|
||||
const response = await sdk.graphql?.<ResponseType>(query, variables);
|
||||
|
||||
// REST for Connect REST, Apex REST, UI API (when GraphQL insufficient)
|
||||
const res = await sdk.fetch?.("/services/apexrest/my-resource");
|
||||
```
|
||||
|
||||
**Always use optional chaining** (`sdk.graphql?.()`, `sdk.fetch?.()`) — these methods may be undefined in some surfaces.
|
||||
|
||||
## Supported APIs
|
||||
|
||||
**Only the following APIs are permitted.** Any endpoint not listed here must not be used.
|
||||
|
||||
| API | Method | Endpoints / Use Case |
|
||||
|-----|--------|----------------------|
|
||||
| GraphQL | `sdk.graphql` | All record queries and mutations via `uiapi { }` namespace |
|
||||
| UI API REST | `sdk.fetch` | `/services/data/v{ver}/ui-api/records/{id}` — record metadata when GraphQL is insufficient |
|
||||
| Apex REST | `sdk.fetch` | `/services/apexrest/{resource}` — custom server-side logic, aggregates, multi-step transactions |
|
||||
| Connect REST | `sdk.fetch` | `/services/data/v{ver}/connect/file/upload/config` — file upload config |
|
||||
| Einstein LLM | `sdk.fetch` | `/services/data/v{ver}/einstein/llm/prompt/generations` — AI text generation |
|
||||
|
||||
**Not supported:**
|
||||
|
||||
- **Enterprise REST query endpoint** (`/services/data/v*/query` with SOQL) — blocked at the proxy level. Use GraphQL for record reads; use Apex REST if server-side SOQL aggregates are required.
|
||||
- **Aura-enabled Apex** (`@AuraEnabled`) — an LWC/Aura pattern with no invocation path from React webapps.
|
||||
- **Chatter API** (`/chatter/users/me`) — use `uiapi { currentUser { ... } }` in a GraphQL query instead.
|
||||
- **Any other Salesforce REST endpoint** not listed in the supported table above.
|
||||
|
||||
## Decision: GraphQL vs REST
|
||||
|
||||
| Need | Method | Example |
|
||||
|------|--------|---------|
|
||||
| Query/mutate records | `sdk.graphql` | Account, Contact, custom objects |
|
||||
| Current user info | `sdk.graphql` | `uiapi { currentUser { Id Name { value } } }` |
|
||||
| UI API record metadata | `sdk.fetch` | `/ui-api/records/{id}` |
|
||||
| Connect REST | `sdk.fetch` | `/connect/file/upload/config` |
|
||||
| Apex REST | `sdk.fetch` | `/services/apexrest/auth/login` |
|
||||
| Einstein LLM | `sdk.fetch` | `/einstein/llm/prompt/generations` |
|
||||
|
||||
**GraphQL is preferred** for record operations. Use REST only when GraphQL doesn't cover the use case.
|
||||
|
||||
---
|
||||
|
||||
## GraphQL Workflow
|
||||
|
||||
### Step 1: Acquire Schema
|
||||
|
||||
The `schema.graphql` file (265K+ lines) is the source of truth. **Never open or parse it directly.**
|
||||
|
||||
1. Check if `schema.graphql` exists at the SFDX project root
|
||||
2. If missing, run from the **webapp dir**: `npm run graphql:schema`
|
||||
3. Custom objects appear only after metadata is deployed
|
||||
|
||||
### Step 2: Look Up Entity Schema
|
||||
|
||||
Map user intent to PascalCase names ("accounts" → `Account`), then **run the search script from the project root**:
|
||||
|
||||
```bash
|
||||
# From project root — look up all relevant schema info for one or more entities
|
||||
bash scripts/graphql-search.sh Account
|
||||
|
||||
# Multiple entities at once
|
||||
bash scripts/graphql-search.sh Account Contact Opportunity
|
||||
```
|
||||
|
||||
The script outputs five sections per entity:
|
||||
1. **Type definition** — all queryable fields and relationships
|
||||
2. **Filter options** — available fields for `where:` conditions
|
||||
3. **Sort options** — available fields for `orderBy:`
|
||||
4. **Create input** — fields accepted by create mutations
|
||||
5. **Update input** — fields accepted by update mutations
|
||||
|
||||
Use this output to determine exact field names before writing any query or mutation. **Maximum 2 script runs.** If the entity still can't be found, ask the user — the object may not be deployed.
|
||||
|
||||
### Step 3: Generate Query
|
||||
|
||||
Use the templates below. Every field name **must** be verified from the script output in Step 2.
|
||||
|
||||
#### Read Query Template
|
||||
|
||||
```graphql
|
||||
query GetAccounts {
|
||||
uiapi {
|
||||
query {
|
||||
Account(where: { Industry: { eq: "Technology" } }, first: 10) {
|
||||
edges {
|
||||
node {
|
||||
Id
|
||||
Name @optional { value }
|
||||
Industry @optional { value }
|
||||
# Parent relationship
|
||||
Owner @optional { Name { value } }
|
||||
# Child relationship
|
||||
Contacts @optional {
|
||||
edges { node { Name @optional { value } } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**FLS Resilience**: Apply `@optional` to all record fields. The server omits inaccessible fields instead of failing. Consuming code must use optional chaining:
|
||||
|
||||
```typescript
|
||||
const name = node.Name?.value ?? "";
|
||||
```
|
||||
|
||||
#### Mutation Template
|
||||
|
||||
```graphql
|
||||
mutation CreateAccount($input: AccountCreateInput!) {
|
||||
uiapi {
|
||||
AccountCreate(input: $input) {
|
||||
Record { Id Name { value } }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Mutation constraints:**
|
||||
- Create: Include required fields, only `createable` fields, no child relationships
|
||||
- Update: Include `Id`, only `updateable` fields
|
||||
- Delete: Include `Id` only
|
||||
|
||||
#### Object Metadata & Picklist Values
|
||||
|
||||
Use `uiapi { objectInfos(...) }` to fetch field metadata or picklist values. Pass **either** `apiNames` or `objectInfoInputs` — never both in the same query.
|
||||
|
||||
**Object metadata** (field labels, data types, CRUD flags):
|
||||
|
||||
```typescript
|
||||
const GET_OBJECT_INFO = gql`
|
||||
query GetObjectInfo($apiNames: [String!]!) {
|
||||
uiapi {
|
||||
objectInfos(apiNames: $apiNames) {
|
||||
ApiName
|
||||
label
|
||||
labelPlural
|
||||
fields {
|
||||
ApiName
|
||||
label
|
||||
dataType
|
||||
updateable
|
||||
createable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const sdk = await createDataSDK();
|
||||
const response = await sdk.graphql?.(GET_OBJECT_INFO, { apiNames: ["Account"] });
|
||||
const objectInfos = response?.data?.uiapi?.objectInfos ?? [];
|
||||
```
|
||||
|
||||
**Picklist values** (use `objectInfoInputs` + `... on PicklistField` inline fragment):
|
||||
|
||||
```typescript
|
||||
const GET_PICKLIST_VALUES = gql`
|
||||
query GetPicklistValues($objectInfoInputs: [ObjectInfoInput!]!) {
|
||||
uiapi {
|
||||
objectInfos(objectInfoInputs: $objectInfoInputs) {
|
||||
ApiName
|
||||
fields {
|
||||
ApiName
|
||||
... on PicklistField {
|
||||
picklistValuesByRecordTypeIDs {
|
||||
recordTypeID
|
||||
picklistValues {
|
||||
label
|
||||
value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const response = await sdk.graphql?.(GET_PICKLIST_VALUES, {
|
||||
objectInfoInputs: [{ objectApiName: "Account" }],
|
||||
});
|
||||
const fields = response?.data?.uiapi?.objectInfos?.[0]?.fields ?? [];
|
||||
```
|
||||
|
||||
### Step 4: Validate & Test
|
||||
|
||||
1. **Lint**: `npx eslint <file>` from webapp dir
|
||||
2. **Test**: Ask user before testing. For mutations, request input values — never fabricate data.
|
||||
|
||||
**If ESLint reports a GraphQL error** (e.g. `Cannot query field`, `Unknown type`, `Unknown argument`), the field or type name is wrong. Re-run the schema search script to find the correct name — do not guess:
|
||||
|
||||
```bash
|
||||
# From project root — re-check the entity that caused the error
|
||||
bash scripts/graphql-search.sh <EntityName>
|
||||
```
|
||||
|
||||
Then fix the query using the exact names from the script output.
|
||||
|
||||
---
|
||||
|
||||
## Webapp Integration (React)
|
||||
|
||||
```typescript
|
||||
import { createDataSDK, gql } from "@salesforce/sdk-data";
|
||||
|
||||
const GET_ACCOUNTS = gql`
|
||||
query GetAccounts {
|
||||
uiapi {
|
||||
query {
|
||||
Account(first: 10) {
|
||||
edges {
|
||||
node {
|
||||
Id
|
||||
Name @optional { value }
|
||||
Industry @optional { value }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const sdk = await createDataSDK();
|
||||
const response = await sdk.graphql?.(GET_ACCOUNTS);
|
||||
|
||||
if (response?.errors?.length) {
|
||||
throw new Error(response.errors.map(e => e.message).join("; "));
|
||||
}
|
||||
|
||||
const accounts = response?.data?.uiapi?.query?.Account?.edges?.map(e => e.node) ?? [];
|
||||
|
||||
---
|
||||
|
||||
## REST API Patterns
|
||||
|
||||
Use `sdk.fetch` when GraphQL is insufficient. See the [Supported APIs](#supported-apis) table for the full allowlist.
|
||||
|
||||
```typescript
|
||||
declare const __SF_API_VERSION__: string;
|
||||
const API_VERSION = typeof __SF_API_VERSION__ !== "undefined" ? __SF_API_VERSION__ : "65.0";
|
||||
|
||||
// Connect — file upload config
|
||||
const res = await sdk.fetch?.(`/services/data/v${API_VERSION}/connect/file/upload/config`);
|
||||
|
||||
// Apex REST (no version in path)
|
||||
const res = await sdk.fetch?.("/services/apexrest/auth/login", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ email, password }),
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
|
||||
// UI API — record with metadata (prefer GraphQL for simple reads)
|
||||
const res = await sdk.fetch?.(`/services/data/v${API_VERSION}/ui-api/records/${recordId}`);
|
||||
|
||||
// Einstein LLM
|
||||
const res = await sdk.fetch?.(`/services/data/v${API_VERSION}/einstein/llm/prompt/generations`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ promptTextorId: prompt }),
|
||||
});
|
||||
```
|
||||
|
||||
**Current user**: Do not use Chatter (`/chatter/users/me`). Use GraphQL instead:
|
||||
|
||||
```typescript
|
||||
const GET_CURRENT_USER = gql`
|
||||
query CurrentUser {
|
||||
uiapi { currentUser { Id Name { value } } }
|
||||
}
|
||||
`;
|
||||
const response = await sdk.graphql?.(GET_CURRENT_USER);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
<project-root>/ ← SFDX project root
|
||||
├── schema.graphql ← grep target (lives here)
|
||||
├── sfdx-project.json
|
||||
└── force-app/main/default/webapplications/<app-name>/ ← webapp dir
|
||||
├── package.json ← npm scripts
|
||||
└── src/
|
||||
```
|
||||
|
||||
| Command | Run From | Why |
|
||||
|---------|----------|-----|
|
||||
| `npm run graphql:schema` | webapp dir | Script in webapp's package.json |
|
||||
| `npx eslint <file>` | webapp dir | Reads eslint.config.js |
|
||||
| `bash scripts/graphql-search.sh <Entity>` | project root | Schema lookup |
|
||||
| `sf api request rest` | project root | Needs sfdx-project.json |
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Schema Lookup (from project root)
|
||||
|
||||
Run the search script to get all relevant schema info in one step:
|
||||
|
||||
```bash
|
||||
bash scripts/graphql-search.sh <EntityName>
|
||||
```
|
||||
|
||||
| Script Output Section | Used For |
|
||||
|-----------------------|----------|
|
||||
| Type definition | Field names, parent/child relationships |
|
||||
| Filter options | `where:` conditions |
|
||||
| Sort options | `orderBy:` |
|
||||
| CreateRepresentation | Create mutation field list |
|
||||
| UpdateRepresentation | Update mutation field list |
|
||||
|
||||
### Error Categories
|
||||
|
||||
| Error Contains | Resolution |
|
||||
|----------------|------------|
|
||||
| `Cannot query field` | Field name is wrong — run `graphql-search.sh <Entity>` and use the exact name from the Type definition section |
|
||||
| `Unknown type` | Type name is wrong — run `graphql-search.sh <Entity>` to confirm the correct PascalCase entity name |
|
||||
| `Unknown argument` | Argument name is wrong — run `graphql-search.sh <Entity>` and check Filter or OrderBy sections |
|
||||
| `invalid syntax` | Fix syntax per error message |
|
||||
| `validation error` | Field name is wrong — run `graphql-search.sh <Entity>` to verify |
|
||||
| `VariableTypeMismatch` | Correct argument type from schema |
|
||||
| `invalid cross reference id` | Entity deleted — ask for valid Id |
|
||||
|
||||
### Checklist
|
||||
|
||||
- [ ] All field names verified via search script (Step 2)
|
||||
- [ ] `@optional` applied to record fields (reads)
|
||||
- [ ] Optional chaining in consuming code
|
||||
- [ ] Lint passes: `npx eslint <file>`
|
||||
@ -1,16 +0,0 @@
|
||||
# UI Platform Rule
|
||||
|
||||
**All new UI must be built as a Salesforce Web Application.**
|
||||
|
||||
When any task involves creating a new UI, frontend, page, dashboard, form, or user-facing feature:
|
||||
|
||||
1. Use `sf webapp generate` to scaffold the web app inside the SFDX project — do not use `create-react-app`, standalone Vite, or any other scaffold.
|
||||
2. The app must live under `<sfdx-source>/webapplications/<AppName>/` as a WebApplication bundle.
|
||||
3. Do not build new UIs as LWC components, Aura components, or Visualforce pages.
|
||||
|
||||
For setup from the project root, use `node scripts/setup-cli.mjs --help` and the options documented there.
|
||||
|
||||
## Data Access (MUST FOLLOW)
|
||||
|
||||
- **Never hardcode data in the app.** All data displayed in the UI must come from live Salesforce data fetching — no static arrays, mock objects, or placeholder values in production code.
|
||||
- **Follow `.a4drules/webapp-data.md`** before writing any data access code. All implementation must match those rules (Data SDK, supported APIs, GraphQL workflow).
|
||||
@ -1 +1 @@
|
||||
1.112.7
|
||||
1.116.6
|
||||
|
||||
@ -3,6 +3,116 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.116.6](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.116.5...v1.116.6) (2026-03-26)
|
||||
|
||||
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.116.5](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.116.4...v1.116.5) (2026-03-26)
|
||||
|
||||
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.116.4](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.116.3...v1.116.4) (2026-03-26)
|
||||
|
||||
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.116.3](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.116.2...v1.116.3) (2026-03-26)
|
||||
|
||||
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.116.2](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.116.1...v1.116.2) (2026-03-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* use public npm registry in sf-project-setup @W-21746844@ ([#355](https://github.com/salesforce-experience-platform-emu/webapps/issues/355)) ([4047d1e](https://github.com/salesforce-experience-platform-emu/webapps/commit/4047d1e0b79fcda14badc5a1826da2ae7ef68a68))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.116.1](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.116.0...v1.116.1) (2026-03-25)
|
||||
|
||||
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [1.116.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.115.0...v1.116.0) (2026-03-25)
|
||||
|
||||
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [1.115.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.114.0...v1.115.0) (2026-03-25)
|
||||
|
||||
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [1.114.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.113.0...v1.114.0) (2026-03-25)
|
||||
|
||||
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [1.113.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.112.10...v1.113.0) (2026-03-25)
|
||||
|
||||
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.112.10](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.112.9...v1.112.10) (2026-03-24)
|
||||
|
||||
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.112.9](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.112.8...v1.112.9) (2026-03-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* address PR [#81](https://github.com/salesforce-experience-platform-emu/webapps/issues/81) review feedback on graphql-search.sh ([#345](https://github.com/salesforce-experience-platform-emu/webapps/issues/345)) ([54a6e59](https://github.com/salesforce-experience-platform-emu/webapps/commit/54a6e590afd1923a12f776eba6b6cc147729c697))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.112.8](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.112.7...v1.112.8) (2026-03-24)
|
||||
|
||||
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.112.7](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.112.6...v1.112.7) (2026-03-23)
|
||||
|
||||
**Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
|
||||
|
||||
@ -1,42 +1,42 @@
|
||||
# App React Sample B2E
|
||||
# Property Management App
|
||||
|
||||
A B2E (Business-to-Employee) sample React web app for the Salesforce platform. Demonstrates property management, maintenance requests, tenant applications, a dashboard, and an Agentforce conversation client. Built with React, Vite, TypeScript, and Tailwind/shadcn.
|
||||
A property management sample React web app for the Salesforce platform. Demonstrates property management, maintenance requests, tenant applications, a dashboard, and an Agentforce conversation client. Built with React, Vite, TypeScript, and Tailwind/shadcn.
|
||||
|
||||
## What's included
|
||||
|
||||
| Path | Description |
|
||||
| ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `force-app/main/default/webapplications/appreactsampleb2e/` | React web app (source, config, tests) |
|
||||
| `force-app/main/default/objects/` | 17 custom objects — Agent\_\_c, Application\_\_c, KPI_Snapshot\_\_c, Lease\_\_c, Maintenance_Request\_\_c, Maintenance_Worker\_\_c, Notification\_\_c, Payment\_\_c, Property\_\_c, Property_Cost\_\_c, Property_Feature\_\_c, Property_Image\_\_c, Property_Listing\_\_c, Property_Management_Company\_\_c, Property_Owner\_\_c, Property_Sale\_\_c, Tenant\_\_c |
|
||||
| `force-app/main/default/layouts/` | Page layouts for each custom object |
|
||||
| `force-app/main/default/permissionsets/` | `Property_Management_Access` permission set |
|
||||
| `force-app/main/default/data/` | Sample data (JSON) for all objects, importable via `sf data import tree` |
|
||||
| Path | Description |
|
||||
| --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `force-app/main/default/webapplications/propertymanagementapp/` | React web app (source, config, tests) |
|
||||
| `force-app/main/default/objects/` | 17 custom objects — Agent\_\_c, Application\_\_c, KPI_Snapshot\_\_c, Lease\_\_c, Maintenance_Request\_\_c, Maintenance_Worker\_\_c, Notification\_\_c, Payment\_\_c, Property\_\_c, Property_Cost\_\_c, Property_Feature\_\_c, Property_Image\_\_c, Property_Listing\_\_c, Property_Management_Company\_\_c, Property_Owner\_\_c, Property_Sale\_\_c, Tenant\_\_c |
|
||||
| `force-app/main/default/layouts/` | Page layouts for each custom object |
|
||||
| `force-app/main/default/permissionsets/` | `Property_Management_Access` permission set |
|
||||
| `force-app/main/default/data/` | Sample data (JSON) for all objects, importable via `sf data import tree` |
|
||||
|
||||
## Getting started
|
||||
|
||||
Navigate to the web app and install dependencies:
|
||||
|
||||
```bash
|
||||
cd force-app/main/default/webapplications/appreactsampleb2e
|
||||
cd force-app/main/default/webapplications/propertymanagementapp
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Opens at http://localhost:5173 by default. For build and test instructions, see the [web app README](force-app/main/default/webapplications/appreactsampleb2e/README.md).
|
||||
Opens at http://localhost:5173 by default. For build and test instructions, see the [web app README](force-app/main/default/webapplications/propertymanagementapp/README.md).
|
||||
|
||||
## Deploy
|
||||
|
||||
### Deploy everything (metadata + web app)
|
||||
|
||||
```bash
|
||||
cd force-app/main/default/webapplications/appreactsampleb2e && npm install && npm run build && cd -
|
||||
cd force-app/main/default/webapplications/propertymanagementapp && npm install && npm run build && cd -
|
||||
sf project deploy start --source-dir force-app --target-org <alias>
|
||||
```
|
||||
|
||||
### Deploy the web app only
|
||||
|
||||
```bash
|
||||
cd force-app/main/default/webapplications/appreactsampleb2e && npm install && npm run build && cd -
|
||||
cd force-app/main/default/webapplications/propertymanagementapp && npm install && npm run build && cd -
|
||||
sf project deploy start --source-dir force-app/main/default/webapplications --target-org <alias>
|
||||
```
|
||||
|
||||
|
||||
@ -24,7 +24,9 @@
|
||||
"Description__c": "Modern 2-bedroom apartment with stunning city views. Features include balcony, in-unit washer/dryer, and central AC. Great location near restaurants and shopping.",
|
||||
"Tour_URL__c": "https://example.com/tour/sunset-4b",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?w=800",
|
||||
"Agent__c": "@AgentRef2"
|
||||
"Agent__c": "@AgentRef2",
|
||||
"Coordinates__Latitude__s": 34.1007222,
|
||||
"Coordinates__Longitude__s": -118.329413
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -50,7 +52,9 @@
|
||||
"Description__c": "Spacious downtown loft with high ceilings and modern finishes. Building amenities include gym, pool, and secured parking.",
|
||||
"Tour_URL__c": "https://example.com/tour/downtown-loft",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1554995207-c18c203602cb?w=800",
|
||||
"Agent__c": "@AgentRef2"
|
||||
"Agent__c": "@AgentRef2",
|
||||
"Coordinates__Latitude__s": 34.052235,
|
||||
"Coordinates__Longitude__s": -118.243683
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -76,7 +80,9 @@
|
||||
"Description__c": "Cozy garden studio in quiet neighborhood. Features private balcony and additional storage unit. No pets allowed.",
|
||||
"Tour_URL__c": null,
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1560448204-e02f11c3d0e2?w=800",
|
||||
"Agent__c": "@AgentRef3"
|
||||
"Agent__c": "@AgentRef3",
|
||||
"Coordinates__Latitude__s": 34.18045,
|
||||
"Coordinates__Longitude__s": -118.3101988
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -102,7 +108,9 @@
|
||||
"Description__c": "Elegant 3-bedroom penthouse in gated community with luxury amenities. Currently under maintenance, available mid-December.",
|
||||
"Tour_URL__c": "https://example.com/tour/luxury-penthouse",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1512917774080-9991f1c4c750?w=800",
|
||||
"Agent__c": "@AgentRef4"
|
||||
"Agent__c": "@AgentRef4",
|
||||
"Coordinates__Latitude__s": 33.7777777,
|
||||
"Coordinates__Longitude__s": -84.39
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -128,7 +136,9 @@
|
||||
"Description__c": "Modern high-rise apartment with floor-to-ceiling windows and stunning sunset views. Building features 24/7 doorman.",
|
||||
"Tour_URL__c": "https://example.com/tour/sunset-towers",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1545324418-cc1a3fa10c00?w=800",
|
||||
"Agent__c": "@AgentRef5"
|
||||
"Agent__c": "@AgentRef5",
|
||||
"Coordinates__Latitude__s": 34.0914289,
|
||||
"Coordinates__Longitude__s": -118.3617537
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -154,7 +164,9 @@
|
||||
"Description__c": "Stunning beachfront home with direct ocean access, modern kitchen, panoramic views, and private pool. Premium property.",
|
||||
"Tour_URL__c": "https://example.com/tour/ocean-villa",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1564013799919-ab600027ffc6?w=800",
|
||||
"Agent__c": "@AgentRef3"
|
||||
"Agent__c": "@AgentRef3",
|
||||
"Coordinates__Latitude__s": 34.022352,
|
||||
"Coordinates__Longitude__s": -118.4911912
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -180,7 +192,9 @@
|
||||
"Description__c": "Modern condo in Silicon Valley with smart home features, rooftop deck, and premium amenities. Perfect for tech professionals.",
|
||||
"Tour_URL__c": "https://example.com/tour/tech-hub",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1580587771525-78b9dba3b914?w=800",
|
||||
"Agent__c": "@AgentRef2"
|
||||
"Agent__c": "@AgentRef2",
|
||||
"Coordinates__Latitude__s": 37.4446046,
|
||||
"Coordinates__Longitude__s": -122.1595598
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -206,7 +220,9 @@
|
||||
"Description__c": "Charming historic brownstone with original hardwood floors, exposed brick, and modern updates. Rare Telegraph Hill location.",
|
||||
"Tour_URL__c": "https://example.com/tour/brownstone",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1568605114967-8130f3a36994?w=800",
|
||||
"Agent__c": "@AgentRef3"
|
||||
"Agent__c": "@AgentRef3",
|
||||
"Coordinates__Latitude__s": 37.8022765,
|
||||
"Coordinates__Longitude__s": -122.4062978
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -232,7 +248,9 @@
|
||||
"Description__c": "Bright studio in trendy Marina District with city views and modern amenities. Walking distance to shops and restaurants.",
|
||||
"Tour_URL__c": null,
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1502672023488-70e25813eb80?w=800",
|
||||
"Agent__c": "@AgentRef4"
|
||||
"Agent__c": "@AgentRef4",
|
||||
"Coordinates__Latitude__s": 37.7990915,
|
||||
"Coordinates__Longitude__s": -122.4319382
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -258,7 +276,9 @@
|
||||
"Description__c": "Magnificent estate with pool, tennis court, wine cellar, and breathtaking city views. Ultimate luxury living.",
|
||||
"Tour_URL__c": "https://example.com/tour/beverly-estate",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1613490493576-7fde63acd811?w=800",
|
||||
"Agent__c": "@AgentRef5"
|
||||
"Agent__c": "@AgentRef5",
|
||||
"Coordinates__Latitude__s": 34.0897964,
|
||||
"Coordinates__Longitude__s": -118.392847
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -284,7 +304,9 @@
|
||||
"Description__c": "Modern office space with open floor plan, conference rooms, and panoramic bay views. Premium downtown location.",
|
||||
"Tour_URL__c": "https://example.com/tour/market-office",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1497366216548-37526070297c?w=800",
|
||||
"Agent__c": "@AgentRef2"
|
||||
"Agent__c": "@AgentRef2",
|
||||
"Coordinates__Latitude__s": 37.7886951,
|
||||
"Coordinates__Longitude__s": -122.397125
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -310,7 +332,9 @@
|
||||
"Description__c": "Beautiful wine country home with vineyard views, gourmet kitchen, and outdoor entertainment area. Perfect for wine enthusiasts.",
|
||||
"Tour_URL__c": "https://example.com/tour/napa-retreat",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?w=800",
|
||||
"Agent__c": "@AgentRef4"
|
||||
"Agent__c": "@AgentRef4",
|
||||
"Coordinates__Latitude__s": 38.3134748,
|
||||
"Coordinates__Longitude__s": -122.2863822
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -336,7 +360,9 @@
|
||||
"Description__c": "Contemporary townhome near tech companies with private garage and community amenities. Ideal for families.",
|
||||
"Tour_URL__c": null,
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1600585154340-be6161a56a0c?w=800",
|
||||
"Agent__c": "@AgentRef5"
|
||||
"Agent__c": "@AgentRef5",
|
||||
"Coordinates__Latitude__s": 37.407126,
|
||||
"Coordinates__Longitude__s": -122.0883981
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -362,7 +388,9 @@
|
||||
"Description__c": "Converted warehouse loft with soaring ceilings, exposed beams, and artistic neighborhood vibe.",
|
||||
"Tour_URL__c": "https://example.com/tour/artistic-loft",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1600607687939-ce8a6c25118c?w=800",
|
||||
"Agent__c": "@AgentRef1"
|
||||
"Agent__c": "@AgentRef1",
|
||||
"Coordinates__Latitude__s": 37.8034013,
|
||||
"Coordinates__Longitude__s": -122.2798006
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -388,7 +416,9 @@
|
||||
"Description__c": "Ultra-luxury penthouse with concierge service, gym, and incredible bay and city views. Currently under maintenance.",
|
||||
"Tour_URL__c": "https://example.com/tour/luxury-highrise",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1737898378296-94dc316cd443?w=800",
|
||||
"Agent__c": "@AgentRef2"
|
||||
"Agent__c": "@AgentRef2",
|
||||
"Coordinates__Latitude__s": 37.7886951,
|
||||
"Coordinates__Longitude__s": -122.397125
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -414,7 +444,9 @@
|
||||
"Description__c": "Charming family home with large backyard, updated kitchen, and excellent school district. Perfect for families.",
|
||||
"Tour_URL__c": null,
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1600566753190-17f0baa2a6c3?w=800",
|
||||
"Agent__c": "@AgentRef3"
|
||||
"Agent__c": "@AgentRef3",
|
||||
"Coordinates__Latitude__s": 37.4863302,
|
||||
"Coordinates__Longitude__s": -122.2247151
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -440,7 +472,9 @@
|
||||
"Description__c": "Brand new studio with smart home features, in-unit laundry, and rooftop terrace access. Modern living at its best.",
|
||||
"Tour_URL__c": "https://example.com/tour/modern-studio",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1600585154084-4e5fe7c39198?w=800",
|
||||
"Agent__c": "@AgentRef4"
|
||||
"Agent__c": "@AgentRef4",
|
||||
"Coordinates__Latitude__s": 37.7873686,
|
||||
"Coordinates__Longitude__s": -122.4055017
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -466,7 +500,9 @@
|
||||
"Description__c": "Sophisticated executive condo with marble finishes, city views, and luxury building amenities. Premium Nob Hill location.",
|
||||
"Tour_URL__c": "https://example.com/tour/executive-suite",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1600607687920-4e2a09cf159d?w=800",
|
||||
"Agent__c": "@AgentRef5"
|
||||
"Agent__c": "@AgentRef5",
|
||||
"Coordinates__Latitude__s": 37.7907054,
|
||||
"Coordinates__Longitude__s": -122.406344
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -492,7 +528,9 @@
|
||||
"Description__c": "Fully restored Victorian mansion with period details, modern conveniences, and beautiful garden. Rare Pacific Heights gem.",
|
||||
"Tour_URL__c": "https://example.com/tour/victorian",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1600566753151-384129cf4e3e?w=800",
|
||||
"Agent__c": "@AgentRef1"
|
||||
"Agent__c": "@AgentRef1",
|
||||
"Coordinates__Latitude__s": 37.7933344,
|
||||
"Coordinates__Longitude__s": -122.4200908
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -518,7 +556,9 @@
|
||||
"Description__c": "Bright apartment with bay views, hardwood floors, and walking distance to Marina Green. Great neighborhood.",
|
||||
"Tour_URL__c": null,
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1600585154526-990dced4db0d?w=800",
|
||||
"Agent__c": "@AgentRef2"
|
||||
"Agent__c": "@AgentRef2",
|
||||
"Coordinates__Latitude__s": 37.7990915,
|
||||
"Coordinates__Longitude__s": -122.4319382
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -544,7 +584,9 @@
|
||||
"Description__c": "Comfortable townhouse with private patio, attached garage, and close to UC Berkeley. Great for students or faculty.",
|
||||
"Tour_URL__c": null,
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1603661764782-a3c9812afada?w=800",
|
||||
"Agent__c": "@AgentRef3"
|
||||
"Agent__c": "@AgentRef3",
|
||||
"Coordinates__Latitude__s": 37.8774835,
|
||||
"Coordinates__Longitude__s": -122.2660899
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -570,7 +612,9 @@
|
||||
"Description__c": "Modern open office space perfect for tech startups with high-speed internet and flexible layout. Prime SOMA location.",
|
||||
"Tour_URL__c": "https://example.com/tour/startup-hub",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1497366811353-6870744d04b2?w=800",
|
||||
"Agent__c": "@AgentRef4"
|
||||
"Agent__c": "@AgentRef4",
|
||||
"Coordinates__Latitude__s": 37.7751904,
|
||||
"Coordinates__Longitude__s": -122.4107713
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -596,7 +640,9 @@
|
||||
"Description__c": "Spacious family home with modern kitchen, large basement, and proximity to Golden Gate Park. Perfect for families.",
|
||||
"Tour_URL__c": null,
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1600566753086-00f18fb6b3ea?w=800",
|
||||
"Agent__c": "@AgentRef5"
|
||||
"Agent__c": "@AgentRef5",
|
||||
"Coordinates__Latitude__s": 37.7463285,
|
||||
"Coordinates__Longitude__s": -122.4732595
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -622,7 +668,9 @@
|
||||
"Description__c": "Contemporary loft in vibrant Mission Bay with waterfront access and modern amenities. Great location near ballpark.",
|
||||
"Tour_URL__c": "https://example.com/tour/mission-loft",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1600607687920-4e2a09cf159d?w=800",
|
||||
"Agent__c": "@AgentRef1"
|
||||
"Agent__c": "@AgentRef1",
|
||||
"Coordinates__Latitude__s": 37.7433669,
|
||||
"Coordinates__Longitude__s": -122.4666667
|
||||
},
|
||||
{
|
||||
"attributes": {
|
||||
@ -648,7 +696,9 @@
|
||||
"Description__c": "Elegant apartment in prestigious Pacific Heights with hardwood floors, in-unit laundry, and 24/7 doorman service.",
|
||||
"Tour_URL__c": "https://example.com/tour/pac-heights",
|
||||
"Hero_Image__c": "https://images.unsplash.com/photo-1600585152220-90363fe7e115?w=800",
|
||||
"Agent__c": "@AgentRef2"
|
||||
"Agent__c": "@AgentRef2",
|
||||
"Coordinates__Latitude__s": 37.7851601,
|
||||
"Coordinates__Longitude__s": -122.4351546
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<fullName>Coordinates__c</fullName>
|
||||
<description>Location coordinates</description>
|
||||
<displayLocationInDecimal>true</displayLocationInDecimal>
|
||||
<label>Coordinates</label>
|
||||
<required>false</required>
|
||||
<scale>6</scale>
|
||||
<trackHistory>false</trackHistory>
|
||||
<trackTrending>false</trackTrending>
|
||||
<type>Location</type>
|
||||
</CustomField>
|
||||
@ -416,6 +416,11 @@
|
||||
<field>Property__c.Address__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<fieldPermissions>
|
||||
<editable>true</editable>
|
||||
<field>Property__c.Coordinates__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<fieldPermissions>
|
||||
<editable>true</editable>
|
||||
<field>Property__c.Type__c</field>
|
||||
|
||||
@ -97,6 +97,11 @@
|
||||
<field>Property__c.Address__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
<fieldPermissions>
|
||||
<editable>false</editable>
|
||||
<field>Property__c.Coordinates__c</field>
|
||||
<readable>true</readable>
|
||||
</fieldPermissions>
|
||||
|
||||
<!-- Field Permissions: Tenant__c -->
|
||||
<fieldPermissions>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# App React Sample B2E
|
||||
# Property Management App
|
||||
|
||||
A sample B2E (Business-to-Employee) React web app on the Salesforce platform. Includes property management, maintenance requests, tenant applications, a dashboard, and an Agentforce conversation client. Built with React, Vite, TypeScript, and Tailwind/shadcn.
|
||||
Property management sample React web app on the Salesforce platform. Includes property management, maintenance requests, tenant applications, a dashboard, and an Agentforce conversation client. Built with React, Vite, TypeScript, and Tailwind/shadcn.
|
||||
|
||||
For project-level details (metadata, deploy, sample data), see the [project README](../../../../../../README.md).
|
||||
|
||||
@ -15,8 +15,8 @@
|
||||
"graphql:schema": "node scripts/get-graphql-schema.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@salesforce/sdk-data": "^1.112.7",
|
||||
"@salesforce/webapp-experimental": "^1.112.7",
|
||||
"@salesforce/sdk-data": "^1.116.6",
|
||||
"@salesforce/webapp-experimental": "^1.116.6",
|
||||
"@tailwindcss/vite": "^4.1.17",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
@ -43,7 +43,7 @@
|
||||
"@graphql-eslint/eslint-plugin": "^4.1.0",
|
||||
"@graphql-tools/utils": "^11.0.0",
|
||||
"@playwright/test": "^1.49.0",
|
||||
"@salesforce/vite-plugin-webapp-experimental": "^1.112.7",
|
||||
"@salesforce/vite-plugin-webapp-experimental": "^1.116.6",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/react": "^16.1.0",
|
||||
"@testing-library/user-event": "^14.5.2",
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<WebApplication xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||
<masterLabel>appreactsampleb2x</masterLabel>
|
||||
<masterLabel>propertymanagementapp</masterLabel>
|
||||
<description>A Salesforce web application.</description>
|
||||
<isActive>true</isActive>
|
||||
<version>1</version>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 873 B After Width: | Height: | Size: 873 B |
|
Before Width: | Height: | Size: 408 B After Width: | Height: | Size: 408 B |
|
Before Width: | Height: | Size: 857 B After Width: | Height: | Size: 857 B |
|
Before Width: | Height: | Size: 853 B After Width: | Height: | Size: 853 B |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 906 B After Width: | Height: | Size: 906 B |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |