omnistudio-callable-apex-generate
Salesforce Industries Common Core (OmniStudio/Vlocity) Apex callable generation and review skill with 120-point scoring. Use when creating, reviewing, or migrating Industries callable Apex implementations. TRIGGER when: user creates or reviews System.Callable classes, migrates VlocityOpenInterface o
By forcedotcom · 4,641 installs
npx skills add forcedotcom/sf-skills --skill omnistudio-callable-apex-generate
Source repository · Upstream listing
omnistudio callable apex generate: Callable Apex for Salesforce Industries Common Core
Specialist for Salesforce Industries Common Core callable Apex implementations. Produce secure,
deterministic, and configurable Apex that cleanly integrates with OmniStudio and Industries
extension points.
Scope
In scope : Creating System.Callable classes for Industries extension points; reviewing callable implementations for correctness and risks; migrating VlocityOpenInterface / VlocityOpenInterface2 to System.Callable ; 120 point scoring and validation
Out of scope : Generic Apex classes without callable interface (use platform apex generate ); building Integration Procedures (use omnistudio integration procedure generate ); authoring OmniScripts (use omnistudio omniscript generate ); deploying Apex classes (use platform metadata deploy )
Core Responsibilities
1. Callable Generation : Build System.Callable classes with safe action dispatch
2. Callable Review : Audit existing callable implementations for correctness and risks
3. Validation & Scoring : Evaluate against the 120 point rubric
4. Industries Fit : Ensure compatibility with OmniStudio/Industries extension points
Workflow (4 Phase Pattern)
Phase 1: Requirements Gathering
Ask for:
Entry point (OmniScript, Integration Procedure, DataRaptor, or other Industries hook)
Action names (strings passed into call )
Input/output contract (required keys, types, and response shape)
Data access needs (objects/fields, CRUD/FLS (Create/Read/Update/Delete and Field Level Security) rules)
Side effects (DML, callouts, async requirements)
Then:
1. Scan for existing callable classes: Glob: / Callable .cls
2. Identify shared utilities or base classes used for Industries extensions
3. Create a task list
Phase 2: Design & Contract Definition
Define the callable contract :
Action list (explicit, versioned strings)
Input schema (required keys + types)
Output schema (consistent response envelope)
Recommended response envelope :
Action dispatch rules :
Use switch on action
Default case throws a typed exception
No dynamic method invocation or reflection
VlocityOpenInterface / VlocityOpenInterface2 contract mapping :
When designing for legacy Open Interface extensions (or dual Callable + Open Interface support), map the signature:
Parameter Role Callable equivalent
methodName Action selector (same semantics as action ) action in call(action, args)
inputMap Primary input data (required keys, types) args.get('inputMap')
outputMap Mutable map where results are written (out by reference) Return value; Callable returns envelope instead
options Additional context (parent DataRaptor/OmniScript context, invocation metadata) args.get('options')
Design rules for Open Interface contracts:
Treat inputMap and options as the combined input schema
Define what keys must be written to outputMap per action (success and error cases)
Preserve methodName strings so they align with Callable action strings
Document whether options is required, optional, or unused for each action
Phase 3: Implementation Pattern
Vanilla System.Callable (flat args, no Open Interface coupling):
Read assets/pattern callable vanilla.cls before generating — use when callers pass flat args and no VlocityOpenInterface integration is required.
Callable skeleton (same inputs as VlocityOpenInterface):
Read assets/pattern callable openinterface.cls before generating — use inputMap and options keys in args when integrating with Open Interface or when callers pass that structure.
Input format : Callers pass args as { 'inputMap' = Map<String, Object , 'options' = Map<String, Object } . For backward compatibility with flat callers, if args lacks 'inputMap' , treat args itself as inputMap and use an empty map for options .
Implementation rules :
1. Keep call() thin; delegate to private methods or service classes
2. Validate and coerce input types early (null safe)
3. Enforce CRUD/FLS (Create/Read/Update/Delete and Field Level Security) and sharing ( with sharing , Security.stripInaccessible() )
4. Bulkify when args include record collections
5. Use WITH USER MODE for SOQL when appropriate
6. Namespace handling : System.Callable is a standard interface (no namespace prefix required); omnistudio.VlocityOpenInterface2 uses the managed omnistudio package namespace — always qualify it. If the callable class will be deployed into a namespaced managed package, ask the user for the namespace prefix and apply it to custom class names (e.g., myns Industries XxxCallable )
VlocityOpenInterface / VlocityOpenInterface2 implementation :
When implementing omnistudio.VlocityOpenInterface or omnistudio.VlocityOpenInterface2 , use the signature:
Read assets/pattern openinterface.cls before generating — complete VlocityOpenInterface2 skeleton with switch on dispatch and outputMap contract.
Open Interface implementation rules:
Write results into outputMap via putAll() or individual put() calls; do not return the envelope from invokeMethod
Return true for success, false for unsupported or failed actions
Use the same internal private methods as the Callable (same inputMap and options parameters); only the entry point differs
Populate outputMap with the same envelope shape ( success , data , errors ) for consistency
Both Callable and Open Interface accept the same inputs ( inputMap , options ) and delegate to identical private method signatures for shared logic.
Phase 4: Testing & Validation
Minimum tests:
Positive : Supported action executes successfully
Negative : Unsupported action throws expected exception
Contract : Missing/invalid inputs return error envelope
Bulk : Handles list inputs without hitting limits
Read assets/pattern test class.cls — complete test class skeleton (positive, negative, contract, bulk, and null args cases) before generating tests.
Migration: VlocityOpenInterface to System.Callable
When modernizing Industries extensions, move VlocityOpenInterface or
VlocityOpenInterface2 implementations to System.Callable and keep the
action contract stable.
Guidance :
Preserve action names ( methodName ) as action strings in call()
Pass inputMap and options as keys in args : { 'inputMap' = inputMap, 'options' = options }
Return a consistent response envelope instead of mutating outMap
Keep call() thin; delegate to the same internal methods with (inputMap, options) signature
Add tests for each action and unsupported action
Read assets/pattern migration.cls — annotated before/after migration example (VlocityOpenInterface2 → System.Callable) before starting migration work.
Best Practices (120 Point Scoring)
Category Points Key Rules
Contract & Dispatch 20 Explicit action list; switch on ; versioned action strings
Input Validation 20 Required keys validated; types coerced safely; null guards
Security 20 with sharing ; CRUD/FLS checks; Security.stripInaccessible()
Error Handling 15 Typed exceptions; consistent error envelope; no empty catch
Bulkification & Limits 20 No SOQL/DML in loops; supports list inputs
Testing 15 Positive/negative/contract/bulk tests
Documentation 10 ApexDoc ( / ... / block comments — Salesforce Apex documentation standard) for class and action methods
Thresholds : [PASS] 90+ (Ready) [REVIEW] 70 89 (Review) [BLOCK] <70 (Block)
Guardrails (Mandatory)
Stop and ask the user if any of these would be introduced:
Dynamic method execution based on user input (no reflection)
SOQL/DML inside loops
without sharing on callable classes
Silent failures (empty catch, swallowed exceptions)
Inconsistent response shapes across actions
Gotchas
Issue Resolution
Caller passes flat args but code expects inputMap key Guard defensively: if args lacks 'inputMap' key, treat args itself as the input map
call() receives null for args Always null check args before accessing keys; initialize to empty map if null
Test class uses (Map<String, Object ) svc.call(...) but call returns a wrong type Ensure every action returns the same envelope type ( Map<String, Object ) — mixed return types break callers
VlocityOpenInterface2 migration breaks callers that read outputMap by reference After migrating to Callable, callers must read the return value instead of reading outputMap — update all callers
IndustriesCallableException class missing in project This custom exception must be deployed alongside the callable class — include it in every deployment package
Org has both legacy Open Interface and new Callable wired to same action Only one entry point should be active at a time; disable the old interface after confirming the callable works
Common Anti Patterns
call() contains business logic instead of delegating
Action names are unversioned or not documented
Input maps assumed to have keys without checks
Mixed response types (sometimes Map, sometimes String)
No tests for unsupported actions
Cross Skill Integration
Skill When to Use Example
platform apex generate General Apex work beyond callable implementations "Create trigger for Account"
platform custom object generate / platform custom field generate Verify object/field availability before coding "Describe Product2 fields"
platform metadata deploy Validate/deploy callable classes "Deploy to sandbox"
Reference Skill
Use the core Apex standards, testing patterns, and guardrails in:
[skills/platform apex generate/SKILL.md](../platform apex generate/SKILL.md)
Bundled Examples
[examples/Test QuoteByProductCallable/](examples/Test QuoteByProductCallable/) — read only query example with WITH USER MODE
[examples/Test VlocityOpenInterfaceConversion/](examples/Test VlocityOpenInterfaceConversion/) — migration from legacy VlocityOpenInterface
[examples/Test VlocityOpenInterface2Conversion/](examples/Test VlocityOpenInterface2Conversion/) — migration from VlocityOpenInterface2
Output Expectations
Deliverables produced by this skill:
<ClassName .cls — Callable class implementing System.Callable with switch on action dispatch
<ClassName Test.cls — Test class with positive, negative, contract, and bulk test methods
IndustriesCallableException.cls — Custom exception class (if not already present in the project)
Notes
Prefer deterministic, side effect aware callable actions
Keep action contracts stable; introduce new actions for breaking changes
Avoid long running work in synchronous callables; use async when needed
Reference File Index
File When to read
assets/pattern callable vanilla.cls Phase 3 — vanilla System.Callable skeleton (flat args, no Open Interface coupling)
assets/pattern callable openinterface.cls Phase 3 — System.Callable skeleton with inputMap / options args (Open Interface compatible)
assets/pattern openinterface.cls Phase 3 — VlocityOpenInterface2 skeleton with switch on dispatch and outputMap contract
assets/pattern test class.cls Phase 4 — test class skeleton (positive, negative, contract, bulk, and null args cases)
assets/pattern migration.cls Migration — annotated before/after migration pattern (VlocityOpenInterface2 → System.Callable)
examples/Test QuoteByProductCallable/Industries QuoteByProductCallable.cls Phase 3 — complete callable implementation with WITH USER MODE SOQL and error envelope
examples/Test QuoteByProductCallable/Industries QuoteByProductCallableTest.cls Phase 4 — full test class covering positive, contract, and unsupported ac