From 808127c03add7a0ff219588d0d78391acba9d23e Mon Sep 17 00:00:00 2001 From: ysachdeva-sfdc Date: Tue, 5 May 2026 13:13:46 +0530 Subject: [PATCH] @W-22335628 add generating-eval-seed-data skill (#237) * feat: add generating-eval-seed-data skill New skill that generates minimal seed-data stubs (custom fields, objects, Apex class stubs) for evaluation datasets in the afv-library. Adapted from the adk-eval-seed-data-generator with afv-library conventions and all PR #194 review feedback addressed (scoped allowed-tools, no hardcoded paths, progressive disclosure, skills referenced by name). * fix: replace stub eval data with real adk-core datasets Replace fabricated eval stubs with actual gold files and seed-data from adk-core: payment_overdue (formula field), AssetFedexValidationRule (validation rule with lookup deps), QueueableWithCalloutRecipes (Apex with class dependencies). * fix: remove related-skills from generating-eval-seed-data frontmatter * fix: use detailed allowed-tools command signatures * fix: scope allowed-tools to sf project deploy start only * fix: change stage from Draft to Pilot --- skills/generating-eval-seed-data/SKILL.md | 162 ++++++++++++++++++ .../examples/stub-examples.md | 132 ++++++++++++++ .../references/stub-rules.md | 147 ++++++++++++++++ .../gold/classes/RestClient.cls | 20 +++ .../gold/classes/RestClient.cls-meta.xml | 5 + .../gold/classes/TestFactory.cls | 6 + .../gold/classes/TestFactory.cls-meta.xml | 5 + .../prompt.md | 1 + .../classes/QueueableWithCalloutRecipes.cls | 70 ++++++++ .../fields/Payment_Due_Date__c.field-meta.xml | 6 + .../fields/Payment_Status__c.field-meta.xml | 22 +++ .../prompt.md | 1 + .../fields/Payment_Overdue__c.field-meta.xml | 21 +++ .../fields/AssetProvided__c.field-meta.xml | 8 + .../fields/AssetServicedBy__c.field-meta.xml | 8 + .../prompt.md | 1 + ...setFedexValidation.validationRule-meta.xml | 20 +++ 17 files changed, 635 insertions(+) create mode 100644 skills/generating-eval-seed-data/SKILL.md create mode 100644 skills/generating-eval-seed-data/examples/stub-examples.md create mode 100644 skills/generating-eval-seed-data/references/stub-rules.md create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/RestClient.cls create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/RestClient.cls-meta.xml create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/TestFactory.cls create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/TestFactory.cls-meta.xml create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/prompt.md create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/seed-data/classes/QueueableWithCalloutRecipes.cls create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/gold/objects/Contract/fields/Payment_Due_Date__c.field-meta.xml create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/gold/objects/Contract/fields/Payment_Status__c.field-meta.xml create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/prompt.md create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/seed-data/objects/Contract/fields/Payment_Overdue__c.field-meta.xml create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/gold/objects/Asset/fields/AssetProvided__c.field-meta.xml create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/gold/objects/Asset/fields/AssetServicedBy__c.field-meta.xml create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/prompt.md create mode 100644 skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/seed-data/objects/Asset/validationRules/AssetFedexValidation.validationRule-meta.xml diff --git a/skills/generating-eval-seed-data/SKILL.md b/skills/generating-eval-seed-data/SKILL.md new file mode 100644 index 0000000..bf1699f --- /dev/null +++ b/skills/generating-eval-seed-data/SKILL.md @@ -0,0 +1,162 @@ +--- +name: generating-eval-seed-data +description: "Generate minimal seed-data stubs for Salesforce metadata evaluation datasets in the afv-library. Use this skill to create seed-data directories containing lightweight dependency declarations (custom fields, objects, Apex class stubs) that a dataset's gold file references. TRIGGER when: user says generate seed data, create seed-data stubs, populate seed-data, dataset dependencies, gold file dependencies, add supporting metadata for eval, or wants to set up prerequisite objects/fields for a test dataset. Also use when the user mentions seed-data, eval fixtures, stub generation, or asks to fill in the seed-data directory for any skill's tests/evals/ dataset. SKIP when: user wants to generate the gold file itself (use the domain-specific generating skill), wants to run evals (use eval runner tooling), or wants to create a new skill from scratch (use creating-sf-skill)." +license: LICENSE.txt has complete terms +metadata: + version: "1.0" + stage: Pilot +allowed-tools: Bash(sf project deploy start) Read Write +--- + +# Generating Eval Seed Data + +Generate seed-data **stubs** — minimal supporting metadata dependencies — for evaluation datasets in the afv-library. Stubs declare the bare-minimum custom objects, fields, relationships, and Apex classes that a dataset's gold file references, just enough so the gold file can be validated in isolation. + +## Scope + +- **In scope**: Analyzing gold files to identify custom dependencies, generating minimal stub XML/Apex for those dependencies, validating stubs deploy successfully via dry-run, and populating the `seed-data/` directory. +- **Out of scope**: Generating the gold file itself (delegate to the domain-specific skill), creating new eval datasets or prompt.md files (delegate to `creating-sf-skill`), deploying metadata to production orgs. + +--- + +## Required Inputs + +Gather before proceeding: + +- **Dataset path**: Path to a single dataset (`skills//tests/evals//`) or a domain path containing multiple datasets. Always ask if not provided. +- **Target org alias**: The Salesforce org alias for dry-run validation (e.g., `myDevOrg`). Ask if not provided. + +Defaults unless specified: +- API version: `62.0` +- Stub style: absolute minimum elements per metadata type (see `references/stub-rules.md`) + +--- + +## Workflow + +All steps are sequential. Do not skip or reorder. + +### Phase 1 — Identify and Read + +1. **Identify the dataset(s)** + - If the path contains `tests/evals/` (or has `prompt.md` / `gold/` directly inside), treat as a single dataset. + - Otherwise, look for `tests/evals/` subdirectory. If it exists, list all subdirectories — each is a dataset. Process them all. + - If neither pattern matches, ask the user to clarify. + +2. **Read the gold file(s)** + - Look for gold files in `{dataset_path}/gold/`. These are Salesforce metadata XML or Apex files. + - If gold files exist, proceed to step 3. + - If gold files do NOT exist, ask: "This dataset has no gold file. Would you like me to generate one from `prompt.md`?" If yes, read `prompt.md` and generate a plausible gold file, then proceed. + +3. **Read stub generation rules** — load `references/stub-rules.md` before analyzing. + +### Phase 2 — Analyze and Generate + +4. **Analyze dependencies** + - Read all gold files and identify every custom dependency. Look for: + - **Custom fields** (`__c`): referenced in formulas, conditions, assignments, or relationship traversals (`__r.Name` implies a lookup `__c`) + - **Custom objects** (`__c`): any custom object the gold metadata lives on or references via lookups + - **Apex classes**: parent classes, interfaces, or utility classes referenced by gold code + - For each dependency, determine: metadata type, correct API name, minimum required attributes. + - Standard Salesforce objects (Account, Contact, Case, etc.) and their standard fields do NOT need stubs. + +5. **Generate stubs** + - Create the `seed-data/` directory structure following the rules in `references/stub-rules.md`. + - Include ONLY the minimum elements per metadata type — no optional attributes. + - For picklists: only include values explicitly referenced in the gold file. + +6. **Compare against example** — verify output matches patterns in `examples/stub-examples.md`. + +### Phase 3 — Validate + +7. **Validate with dry-run deployment** + - Create a temporary SFDX project: + ```bash + cd /tmp && sf project generate --name seed-data-validation-$(date +%s) --template empty + ``` + - Read the temp project's `sfdx-project.json` to resolve the deploy path — do not hardcode `force-app/main/default/`. Extract `packageDirectories[].path` (use the entry with `"default": true`; if none, use the first entry). + - Copy seed-data and gold files into the resolved deploy path: + ```bash + cp -r {dataset_path}/seed-data/* {temp_project}/{resolved_path}/ + cp -r {dataset_path}/gold/* {temp_project}/{resolved_path}/ + ``` + - Run dry-run: + ```bash + sf project deploy start --dry-run -d "{resolved_path}" --target-org {target_org} --test-level NoTestRun --wait 10 --json + ``` + +8. **Auto-fix on failure** + - Parse JSON error output and fix issues (missing fields, invalid types, missing relationships). + - Re-run dry-run after each fix. Max 3 retries. + - If still failing after 3 retries, report remaining errors and ask for guidance. + +9. **Copy validated stubs back** + - Replace `{dataset_path}/seed-data/` with the validated versions. + - Only copy back stub files you generated — do NOT copy gold file content into seed-data. + +10. **Clean up and report** + - Delete the temporary SFDX project. + - Report: files generated, validation status, any fixes applied. + - For multiple datasets, print a summary table: + + | # | Dataset | Stubs Generated | Validation | Notes | + |---|---------|----------------|------------|-------| + | 1 | … | … | … | … | + +--- + +## Rules / Constraints + +| Constraint | Rationale | +|-----------|-----------| +| Stubs include ONLY minimum required elements | Optional attributes add noise and can cause unexpected deployment errors | +| Never invent picklist values beyond what gold references | Extra values create false dependencies and mislead evaluators | +| Standard objects/fields never get stubs | They exist in every org; stubs would be redundant and can conflict | +| Always validate via dry-run before finalizing | Catches missing dependencies and malformed XML before the contributor sees them | +| API version defaults to 62.0 | Matches current afv-library convention; override only if gold file specifies otherwise | +| Copy back only stub files, not gold files | Mixing gold content into seed-data corrupts the dataset structure | +| Never hardcode `force-app/main/default/` — always read `sfdx-project.json` | Customers customize the package directory path; hardcoding breaks non-default projects | +| Reference cross-skills by name, never by filesystem path | Skill catalog layout varies across AFV installations; hardcoded paths break portability | + +--- + +## Gotchas + +| Issue | Resolution | +|-------|------------| +| Relationship traversal (`__r.Name`) implies a lookup field | Generate a Lookup stub for the corresponding `__c` field | +| Gold file references a field on a standard object | Only generate the custom field stub, not the standard object definition | +| Multiple gold files reference the same custom object | Generate the object stub once; place field stubs under the same object directory | +| Picklist referenced in formula via `ISPICKVAL` | Extract only the specific value string from the formula; do not add other values | +| Gold file has no custom dependencies | Skip stub generation; report "no seed-data needed" | +| Dry-run fails with `DUPLICATE_DEVELOPER_NAME` | A stub conflicts with an existing org object — rename or skip | + +--- + +## Output Expectations + +Deliverables: +- Stub metadata files: `{dataset_path}/seed-data/objects/{ObjectName}/fields/{FieldName}.field-meta.xml` +- Stub object definitions: `{dataset_path}/seed-data/objects/{ObjectName}/{ObjectName}.object-meta.xml` +- Stub Apex classes: `{dataset_path}/seed-data/classes/{ClassName}.cls` + `.cls-meta.xml` +- Console report: list of generated files, validation status, fixes applied + +--- + +## Cross-Skill Integration + +| Need | Delegate to | +|------|-------------| +| Generate the gold file for a dataset | Domain-specific skill (`generating-validation-rule`, `generating-apex`, etc.) | +| Create a new skill with eval datasets | `creating-sf-skill` | +| Generate a complete custom field (not a stub) | `generating-custom-field` | +| Generate a complete custom object (not a stub) | `generating-custom-object` | + +--- + +## Reference File Index + +| File | When to read | +|------|-------------| +| `references/stub-rules.md` | Phase 2, step 3 — before generating any stubs | +| `examples/stub-examples.md` | Phase 2, step 6 — to verify generated output matches expected patterns | diff --git a/skills/generating-eval-seed-data/examples/stub-examples.md b/skills/generating-eval-seed-data/examples/stub-examples.md new file mode 100644 index 0000000..9d4f624 --- /dev/null +++ b/skills/generating-eval-seed-data/examples/stub-examples.md @@ -0,0 +1,132 @@ +# Seed-Data Stub Examples + +Input/output examples showing gold file analysis and the resulting seed-data stubs. + +--- + +## Example 1: Formula Field with Date and Picklist Dependencies + +**Gold file**: `gold/objects/Contract/fields/Payment_Overdue__c.field-meta.xml` + +```xml + + + Payment_Overdue__c + + Text + IF(AND(Payment_Due_Date__c < TODAY(), ISPICKVAL(Payment_Status__c, "UNPAID")), "PAYMENT OVERDUE", null) + BlankAsZero + 20 + +``` + +**Analysis**: Formula references `Payment_Due_Date__c` (Date) and `Payment_Status__c` +(Picklist with value `UNPAID`). + +**Generated stubs**: + +`seed-data/objects/Contract/fields/Payment_Due_Date__c.field-meta.xml`: +```xml + + + Payment_Due_Date__c + + Date + +``` + +`seed-data/objects/Contract/fields/Payment_Status__c.field-meta.xml`: +```xml + + + Payment_Status__c + + Picklist + + + + UNPAID + + + + + +``` + +Only `UNPAID` is included — no other values. + +--- + +## Example 2: Flow Referencing Custom Objects + +**Gold file**: A Flow XML that triggers on `Adoption__c` record creation and references +a Lookup to `Animal__c`. + +**Generated stubs**: + +`seed-data/objects/Adoption__c/Adoption__c.object-meta.xml`: +```xml + + + Deployed + + + + Text + + Adoptions + ReadWrite + +``` + +`seed-data/objects/Animal__c/Animal__c.object-meta.xml`: +```xml + + + Deployed + + + + Text + + Animals + ReadWrite + +``` + +`seed-data/objects/Adoption__c/fields/Animal__c.field-meta.xml`: +```xml + + + Animal__c + + Lookup + Animal__c + Adoptions + +``` + +--- + +## Example 3: Apex Class with Parent Class Dependency + +**Gold file**: `gold/classes/OrderProcessor.cls` extends `BaseProcessor`. + +**Generated stubs**: + +`seed-data/classes/BaseProcessor.cls`: +```java +public abstract class BaseProcessor { +} +``` + +`seed-data/classes/BaseProcessor.cls-meta.xml`: +```xml + + + 62.0 + Active + +``` + +Empty stub — no method bodies or implementations. diff --git a/skills/generating-eval-seed-data/references/stub-rules.md b/skills/generating-eval-seed-data/references/stub-rules.md new file mode 100644 index 0000000..db7ac16 --- /dev/null +++ b/skills/generating-eval-seed-data/references/stub-rules.md @@ -0,0 +1,147 @@ +# Stub Generation Rules + +Rules for generating minimal seed-data stubs. Stubs declare what exists and what type +it is — nothing more. + +--- + +## General Principles + +- **Stubs, not full metadata**: generate the absolute minimum XML to declare a field, + object, or class. No optional attributes, no invented values. +- **Only what gold references**: for picklists, include ONLY values explicitly named in + the gold file. For objects, do not add fields beyond what gold uses. +- **No optional attributes**: omit `description`, `trackHistory`, `trackTrending`, + `required`, `externalId`, `inlineHelpText`, `restricted`, `sorted`, `default`, + `relationshipLabel`, and any other non-essential element. +- **Standard objects don't need definitions**: Account, Contact, Opportunity, Case, Lead, + User, and other standard objects already exist. Only stub their custom fields (`__c`). +- **API version**: use `62.0` unless gold specifies otherwise. + +--- + +## Custom Field Stubs + +**Path**: `seed-data/objects/{ObjectName}/fields/{FieldApiName}.field-meta.xml` + +Include ONLY these elements per field type: + +| Field Type | Required Elements | +|-----------|------------------| +| Lookup | `fullName`, `label`, `type`, `referenceTo`, `relationshipName` | +| Master-Detail | `fullName`, `label`, `type`, `referenceTo`, `relationshipName` | +| Picklist | `fullName`, `label`, `type`, `valueSet` (only referenced values) | +| Text | `fullName`, `label`, `type`, `length` | +| Number | `fullName`, `label`, `type`, `precision`, `scale` | +| Currency | `fullName`, `label`, `type`, `precision`, `scale` | +| Percent | `fullName`, `label`, `type`, `precision`, `scale` | +| Date | `fullName`, `label`, `type` | +| DateTime | `fullName`, `label`, `type` | +| Checkbox | `fullName`, `label`, `type`, `defaultValue` | +| Email | `fullName`, `label`, `type` | +| Phone | `fullName`, `label`, `type` | +| Url | `fullName`, `label`, `type` | +| TextArea | `fullName`, `label`, `type` | +| LongTextArea | `fullName`, `label`, `type`, `length`, `visibleLines` | + +### Picklist Value Rules + +Only include picklist values that appear explicitly in the gold file. Common patterns: + +| Gold Pattern | Extract | +|-------------|---------| +| `ISPICKVAL(Status__c, "UNPAID")` | `UNPAID` only | +| `IF(Stage__c = "Closed Won", ...)` | `Closed Won` only | +| `Active...` | `Active` only | + +Do NOT add values "for completeness." If the gold formula checks for `"UNPAID"`, do not +add `PAID`, `PARTIALLY_PAID`, or any other values. + +--- + +## Custom Object Stubs + +**Path**: `seed-data/objects/{ObjectApiName}/{ObjectApiName}.object-meta.xml` + +Include ONLY these elements: + +```xml + + + Deployed + + + + Text + + {Object Plural Label} + ReadWrite + +``` + +Do NOT add `description`, `enableActivities`, `enableBulkApi`, `enableHistory`, +`enableReports`, `enableSearch`, or any other optional element. + +--- + +## Apex Class Stubs + +**Path**: `seed-data/classes/{ClassName}.cls` + `seed-data/classes/{ClassName}.cls-meta.xml` + +The `.cls` file is an empty stub — class signature only: + +```java +public class MyUtilClass { +} +``` + +For interfaces: +```java +public interface MyInterface { +} +``` + +For abstract classes: +```java +public abstract class MyBaseClass { +} +``` + +The `.cls-meta.xml`: +```xml + + + 62.0 + Active + +``` + +Do NOT generate method bodies, business logic, or implementations. + +--- + +## Dependency Detection Patterns + +| Gold Pattern | Dependency Type | Stub Needed | +|-------------|----------------|-------------| +| `Payment_Due_Date__c` in formula | Custom field | Date field stub | +| `AssetProvided__r.Name` in formula | Lookup relationship | Lookup field stub for `AssetProvided__c` | +| `ISPICKVAL(Status__c, "X")` | Picklist field | Picklist stub with value `X` | +| `Animal__c` | Custom object | Object stub for `Animal__c` | +| `extends BaseHandler` | Apex parent class | Class stub for `BaseHandler` | +| `implements Queueable` | Standard interface | No stub needed (standard) | +| `Account.Name` | Standard object + field | No stub needed | +| `CustomObj__c.Custom_Field__c` | Custom field on custom object | Both object and field stubs | + +--- + +## Common Validation Errors and Fixes + +| Error Pattern | Fix | +|--------------|-----| +| `Field does not exist: FieldName__c` | Add the missing field stub | +| `Invalid type: ObjectName__c` | Add the custom object stub | +| `Missing required field: X` | Add the required XML element | +| `Invalid picklist value` | Add the missing value to the picklist stub | +| `Relationship not found` | Add the lookup field that defines the relationship | +| `apiVersion is required` | Add `62.0` | diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/RestClient.cls b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/RestClient.cls new file mode 100644 index 0000000..38be2a5 --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/RestClient.cls @@ -0,0 +1,20 @@ +public with sharing class RestClient { + public enum HttpVerb { + GET, + POST, + PUT, + PATCH, + DEL + } + + public static HttpResponse makeApiCall( + String namedCredential, + HttpVerb method, + String path + ) { + HttpRequest request = new HttpRequest(); + request.setEndpoint('callout:' + namedCredential + '/' + path); + request.setMethod(method.name()); + return new Http().send(request); + } +} diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/RestClient.cls-meta.xml b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/RestClient.cls-meta.xml new file mode 100644 index 0000000..998805a --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/RestClient.cls-meta.xml @@ -0,0 +1,5 @@ + + + 62.0 + Active + diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/TestFactory.cls b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/TestFactory.cls new file mode 100644 index 0000000..cb3fbce --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/TestFactory.cls @@ -0,0 +1,6 @@ +@isTest +public class TestFactory { + public static List invalidateSObjectList(List records) { + return records; + } +} diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/TestFactory.cls-meta.xml b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/TestFactory.cls-meta.xml new file mode 100644 index 0000000..998805a --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/gold/classes/TestFactory.cls-meta.xml @@ -0,0 +1,5 @@ + + + 62.0 + Active + diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/prompt.md b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/prompt.md new file mode 100644 index 0000000..bc26f39 --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/prompt.md @@ -0,0 +1 @@ +Generate seed-data for an Apex dataset. The gold file is a QueueableWithCalloutRecipes class that implements Queueable and Database.AllowsCallouts. It references RestClient.makeApiCall() and TestFactory.invalidateSObjectList(). The dataset path is domains/apex/datasets/QueueableWithCalloutRecipes/. My target org is myDevOrg. \ No newline at end of file diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/seed-data/classes/QueueableWithCalloutRecipes.cls b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/seed-data/classes/QueueableWithCalloutRecipes.cls new file mode 100644 index 0000000..c39451e --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-apex-callout/seed-data/classes/QueueableWithCalloutRecipes.cls @@ -0,0 +1,70 @@ +/** + * @description Demmonstrates the use of the Queueable interface to make + * callouts. The methods in this class are called by the system at run time. + * To enqueue this job and see it's results, use `System.enqueueJob(new QueueableWithCalloutRecipes());` + * + * More on the Queable interface: + * https://sfdc.co/queueable-apex + * + * @group Async Apex Recipes + * @see RestClient + */ +public with sharing class QueueableWithCalloutRecipes implements Queueable, Database.AllowsCallouts { + // This allows us to cause a DML failure in execute batch, enabling testing. + @testVisible + private static Boolean throwError = false; + @testVisible + private static Boolean circuitBreakerThrown = false; + + /** + * @description Internal custom exception class + */ + public class QueueableWithCalloutRecipesException extends Exception { + } + + /** + * @description This is the only required method to implement Queueable. + * Queueable classes that also implement Database.allowsCallouts can make + * HTTP requests to external services. In this recipe we make a GET request + * to developer.salesforce.com + * @param qc dependency injected by the system + * @example + * ``` + * System.enqueueJob(new QueueableWithCalloutRecipes()); + * ``` + */ + public static void execute(QueueableContext qc) { + HttpResponse response = RestClient.makeApiCall( + 'GoogleBooksAPI', + RestClient.HttpVerb.GET, + 'volumes?q=salesforce' + ); + List accounts = [ + SELECT Id + FROM Account + ORDER BY Id + LIMIT 1000 + ]; + for (Account acct : accounts) { + acct.Description = String.valueOf(response.getStatusCode()); + } + if (Test.isRunningTest() && throwError) { + accounts = (List) TestFactory.invalidateSObjectList( + accounts + ); + } + + try { + update accounts; + } catch (DmlException dmle) { + System.debug( + LoggingLevel.INFO, + 'real life use cases should do something more than just logging the error: ' + + dmle.getMessage() + ); + if (Test.isRunningTest()) { + QueueableWithCalloutRecipes.circuitBreakerThrown = true; + } + } + } +} diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/gold/objects/Contract/fields/Payment_Due_Date__c.field-meta.xml b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/gold/objects/Contract/fields/Payment_Due_Date__c.field-meta.xml new file mode 100644 index 0000000..529519e --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/gold/objects/Contract/fields/Payment_Due_Date__c.field-meta.xml @@ -0,0 +1,6 @@ + + + Payment_Due_Date__c + + Date + diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/gold/objects/Contract/fields/Payment_Status__c.field-meta.xml b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/gold/objects/Contract/fields/Payment_Status__c.field-meta.xml new file mode 100644 index 0000000..0cc9719 --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/gold/objects/Contract/fields/Payment_Status__c.field-meta.xml @@ -0,0 +1,22 @@ + + + Payment_Status__c + + Picklist + + false + + false + + UNPAID + false + + + + PAID + false + + + + + diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/prompt.md b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/prompt.md new file mode 100644 index 0000000..0239a01 --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/prompt.md @@ -0,0 +1 @@ +Generate seed-data for a CustomFormulaField dataset. The gold file is a formula field on Contract that checks if a payment is overdue — it references Payment_Due_Date__c and ISPICKVAL(Payment_Status__c, "UNPAID"). The dataset path is domains/CustomFormulaField/datasets/payment_overdue/. My target org is myDevOrg. \ No newline at end of file diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/seed-data/objects/Contract/fields/Payment_Overdue__c.field-meta.xml b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/seed-data/objects/Contract/fields/Payment_Overdue__c.field-meta.xml new file mode 100644 index 0000000..0aa951b --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-formula-field/seed-data/objects/Contract/fields/Payment_Overdue__c.field-meta.xml @@ -0,0 +1,21 @@ + + + Payment_Overdue__c + + Text + + BlankAsZero + Returns 'PAYMENT OVERDUE' when Payment_Due_Date__c is before today and Payment_Status__c is UNPAID; otherwise null. + false + false + false + false + false + diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/gold/objects/Asset/fields/AssetProvided__c.field-meta.xml b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/gold/objects/Asset/fields/AssetProvided__c.field-meta.xml new file mode 100644 index 0000000..1d2ad30 --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/gold/objects/Asset/fields/AssetProvided__c.field-meta.xml @@ -0,0 +1,8 @@ + + + AssetProvided__c + + Account + AssetProvided + Lookup + diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/gold/objects/Asset/fields/AssetServicedBy__c.field-meta.xml b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/gold/objects/Asset/fields/AssetServicedBy__c.field-meta.xml new file mode 100644 index 0000000..754ac23 --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/gold/objects/Asset/fields/AssetServicedBy__c.field-meta.xml @@ -0,0 +1,8 @@ + + + AssetServicedBy__c + + Account + AssetServicedBy + Lookup + diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/prompt.md b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/prompt.md new file mode 100644 index 0000000..3404461 --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/prompt.md @@ -0,0 +1 @@ +Generate seed-data for a ValidationRule dataset. The gold file is a validation rule on Asset that blocks insert/update when AssetProvided Name contains FedEx, AssetServicedBy Owner CompanyName contains FedEx, and Asset was modified within last 3 months. The dataset path is domains/ValidationRule/datasets/AssetFedexValidationRule/. My target org is myDevOrg. \ No newline at end of file diff --git a/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/seed-data/objects/Asset/validationRules/AssetFedexValidation.validationRule-meta.xml b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/seed-data/objects/Asset/validationRules/AssetFedexValidation.validationRule-meta.xml new file mode 100644 index 0000000..96f77a9 --- /dev/null +++ b/skills/generating-eval-seed-data/tests/evals/generating-eval-seed-data-validation-rule/seed-data/objects/Asset/validationRules/AssetFedexValidation.validationRule-meta.xml @@ -0,0 +1,20 @@ + + + AssetFedExValidation + true + Block insert/update if AssetProvided Name contains 'FedEx', AssetServicedBy Owner CompanyName contains 'FedEx', and Asset LastModified is not more than last 3 months + += ADDMONTHS(TODAY(), -3) + )]]> + + Cannot insert/update: Asset conditions not met. +