# Development Workflow

This guide walks through the complete development workflow using sfp in a modular Salesforce project following the Flxbl framework.

## Overview

The development workflow in an sfp-powered project follows an iterative approach where developers work in isolated environments, make changes using source-driven development, and submit their work through pull requests that trigger automated validation and review environments.

{% @mermaid/diagram content="graph LR A\[Fetch Environment] --> B\[Pull Latest] B --> C\[Make Changes] C --> D\[Push Changes] D --> E\[Test Locally] E --> F\[Create PR] F --> G\[CI/CD Validation] G --> H\[Review Environment] H --> I\[Merge]" %}

## Prerequisites

### DevHub Access Required

Before starting development with sfp, ensure you have:

1. **DevHub access** - Required for:
   * Building packages (all types)
   * Creating scratch orgs
   * Managing unlocked packages
2. **DevHub user setup**:

   * Your user must be added to the DevHub org
   * Follow Salesforce's guide: [Add DevHub License Users](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_setup_add_free_license_users.htm)
   * Authenticate to your DevHub:

   ```bash
   sf org login web --alias mydevhub --set-default-dev-hub
   ```
3. **Verify DevHub connection**:

   ```bash
   # Check your DevHub connection
   sf org display --target-dev-hub
   ```

## 1. Starting a New Feature

### Fetch a Development Environment

Every feature or story begins with a developer fetching a fresh environment from a pre-prepared pool. The frequency depends on your team's practice:

* **Scratch Orgs**: Can be fetched for every story or feature
* **Sandboxes**: Typically fetched at the start of an iteration or sprint

#### Fetch from Server-Managed Pools

```bash
# List available instances (works for both scratch orgs and sandboxes)
sfp pool list \
  --tag dev-pool

# Fetch an org from the pool (scratch or sandbox)
sfp pool fetch \
  --tag dev-pool

# Extend org expiration if needed
sfp pool extend \
  --tag dev-pool

# Unassign and return to pool when done
sfp pool unassign \
  --tag dev-pool
```

#### Create a New Sandbox (if needed)

```bash
# Create a new sandbox directly
sfp sandbox create --name feature-sandbox \
  --type Developer \
  --source-org production \
  --alias my-feature-sandbox
```

### Authenticate to Your Environment

Once you have your environment:

```bash
# Open the org to verify access
sfp org open --targetusername my-feature-org

# Open in a specific browser
sfp org open --targetusername my-feature-org --browser chrome

# Set as default for convenience
sfp config set target-org my-feature-org

# Set globally
sfp config set target-org my-feature-org --global
```

## 2. Development Cycle

### Pull Latest Metadata

Before making changes, ensure you have the latest metadata from your org:

```bash
# Pull all changes from the org (using aliases: pull, source:pull, project:pull)
sfp pull --targetusername my-feature-org

# Pull with conflict resolution
sfp pull --targetusername my-feature-org --ignore-conflicts

# Pull a specific package
sfp pull --targetusername my-feature-org --package my-package

# Pull and see what replacements were reversed
sfp pull --targetusername my-feature-org --json
```

The pull command will:

* Retrieve metadata changes from your org
* Apply reverse text replacements to convert environment-specific values back to placeholders
* Update your local source files

### Make Your Changes

Now you can work on your feature using your preferred IDE:

1. **Modify existing metadata** in package directories
2. **Create new components** using SF CLI or your IDE
3. **Add new packages** if needed:

```bash
# Create a new source package
sfp package create source -n "feature-payment" \
  -r "src/payment-processing" \
  --domain

# Create an unlocked package
sfp package create unlocked -n "feature-payment" \
  -r "src/payment-processing" \
  -v mydevhub

# Create a data package
sfp package create data -n "reference-data" \
  -r "data/reference-data"
```

4. **Organize packages** into logical groups using release configs (domains are conceptual, not explicit commands)

### Push Changes to Your Org

Deploy your local changes to the development org:

```bash
# Push all changes (using aliases: push, source:push, project:push)
sfp push --targetusername my-feature-org

# Push a specific package
sfp push --targetusername my-feature-org --package my-package

# Push ignoring conflicts
sfp push --targetusername my-feature-org --ignore-conflicts

# Push and see what replacements were applied
sfp push --targetusername my-feature-org --json
```

The push command will:

* Apply text replacements for environment-specific values
* Deploy metadata to your org
* Run tests if specified

### Build and Test Locally

#### Build Artifacts

Test that your packages can be built successfully:

```bash
# Build all packages (DevHub required)
sfp build --devhubalias mydevhub

# Build a specific domain
sfp build --devhubalias mydevhub --domain sales

# Build a specific package
sfp build --devhubalias mydevhub --package payment-processing

# Build with different options
sfp build --devhubalias mydevhub \
  --branch feature/payment \
  --buildnumber 123 \
  --diffcheck

# Note: DevHub is required even for source packages to resolve dependencies
```

#### Run Apex Tests

Execute tests in your development org to validate your changes. sfp follows a package-centric testing approach:

```bash
# Test a specific package (recommended)
sfp apextests trigger -o my-feature-org -l RunAllTestsInPackage -n sales-core

# Test all packages in a domain
sfp apextests trigger -o my-feature-org -l RunAllTestsInDomain \
  -r config/release-config.yaml

# Quick test during development
sfp apextests trigger -o my-feature-org -l RunSpecifiedTests \
  --specifiedtests PaymentProcessorTest

# Test with code coverage validation
sfp apextests trigger -o my-feature-org -l RunAllTestsInPackage \
  -n sales-core -c -p 80
```

For detailed information on test levels, coverage validation, output formats, and CI/CD integration, see [Running Apex Tests](/flxbl/sfp/development/running-apex-tests.md).

#### Install to Your Org (Optional)

While developers rarely need to install built artifacts to their own orgs, you can test the installation:

```bash
# Install a single package
sfp install --target-org my-feature-org \
  --artifacts artifacts \
  --package payment-processing

# Install with skip testing for faster deployment
sfp install --target-org my-feature-org \
  --artifacts artifacts \
  --skipifalreadyinstalled
```

## 3. Dependency Management

As you develop, you may need to manage package dependencies:

### Analyze Dependencies

```bash
# Understand package dependencies
sfp dependency explain --package payment-processing

# Expand all transitive dependencies (for troubleshooting)
sfp dependency expand --target-devhub mydevhub

# Clean up redundant dependencies
sfp dependency shrink --target-devhub mydevhub
```

## 4. Submitting Your Work

### Create a Pull Request

Once your feature is complete:

```bash
# Commit your changes
git add .
git commit -m "feat: implement payment processing module"

# Push to your feature branch
git push origin feature/payment-processing

# Create PR using GitHub CLI (optional)
gh pr create --title "Payment Processing Module" \
  --body "Implements new payment gateway integration"
```

### CI/CD Pipeline Takes Over

When you create a PR, the automated pipeline will:

1. **Run sfp validate** to verify your changes:

```bash
# This runs automatically in CI/CD
sfp validate org --target-org validation-org \
  --mode thorough \
  --coverageThreshold 75
```

2. **Create a review environment** for acceptance testing:

```bash
# CI/CD creates an ephemeral environment
sfp pool scratch fetch --pool review-pool \
  --alias pr-123-review

# Install the changes
sfp install --target-org pr-123-review \
  --artifacts artifacts
```

3. **Run quality checks**:
   * Code coverage validation
   * Dependency validation
   * Package structure verification

### Review Environment Testing

The review environment URL is posted to your PR for stakeholders to test:

* Product owners can validate functionality
* QA can run acceptance tests
* Other developers can review the implementation

## 5. Post-Merge

After your PR is approved and merged:

1. **Artifacts are built** from the main branch
2. **Published to artifact repository**
3. **Ready for release** to higher environments

```bash
# This happens automatically in CI/CD
sfp build --branch main
sfp publish --artifacts artifacts \
  --npm-registry https://your-registry.com
```

## Common Workflows

### Working with Aliasified Packages

When working with environment-specific metadata:

```bash
# Pull from a specific environment
sfp pull --targetusername dev-sandbox

# The correct variant is automatically selected
# src-env-specific/main/dev/* contents are used
```

### Using Text Replacements

For configuration values that change per environment:

```yaml
# Create preDeploy/replacements.yml in your package
replacements:
  - name: "API Endpoint"
    glob: "**/*.cls"
    pattern: "%%API_URL%%"
    environments:
      default: "https://api.dev.example.com"
      prod: "https://api.example.com"
```

Then push/pull will automatically handle replacements:

```bash
# Push replaces placeholders with environment values
sfp push --targetusername my-feature-org

# Pull reverses replacements back to placeholders
sfp pull --targetusername my-feature-org
```

### Handling Destructive Changes

When you need to delete metadata:

1. Move components to `pre-destructive/` or `post-destructive/` folders
2. Push changes normally:

```bash
sfp push --targetusername my-feature-org
```

The destructive changes are automatically processed.

## Troubleshooting

### Pool is Empty

```bash
# Check pool status
sfp pool list --tag dev-pool

# Replenish the pool
sfp pool probe --tag dev-pool
```

{% hint style="info" %}
Pool provisioning and replenishment is managed by the sfp server. If pools are consistently empty, contact your administrator to adjust pool configuration via `sfp server pool config update`.
{% endhint %}

### Push/Pull Conflicts

```bash
# Ignore conflicts during pull
sfp pull --targetusername my-feature-org --ignore-conflicts

# Ignore conflicts during push
sfp push --targetusername my-feature-org --ignore-conflicts
```

### Build Failures

```bash
# Check for issues in specific package
sfp build --devhubalias mydevhub \
  --package problematic-package \
  --loglevel DEBUG

# Validate dependencies
sfp dependency explain --package problematic-package
```

### DevHub Connection Issues

```bash
# Re-authenticate to DevHub
sf org login web --alias mydevhub --set-default-dev-hub

# Verify DevHub is enabled
sf org display --target-dev-hub

# Check DevHub limits
sf limits api display --target-org mydevhub
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flxbl.io/flxbl/sfp/development/development-workflow.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
