jaganpro/sf-skills/sf-industry-commoncore-callable-apex

Claude Code and agent skill by jaganpro/sf-skills

Trust tier 2
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Salesforce Industries Common Core (OmniStudio/Vlocity) Apex callable generation and review with 120-point scoring. TRIGGER when: user creates or reviews System.Callable classes, migrates `VlocityOpenInterface` / `VlocityOpenInterface2`, or builds Industries callable extensions used by OmniStudio, Integration Procedures, or DataRaptors. DO NOT TRIGGER when: generic Apex classes/triggers (use sf-apex), building Integration Procedures (use sf-industry-commoncore-integration-procedure), authoring OmniScripts (use sf-industry-commoncore-omniscript), configuring Data Mappers (use sf-industry-commoncore-datamapper), or analyzing namespace/dependency issues (use sf-industry-commoncore-omnistudio-analyze).

Install

npx vskill@latest install jaganpro/sf-skills/sf-industry-commoncore-callable-apex

SKILL.md

sf-industry-commoncore-callable-apex: 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.

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 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:

{
"success": true|false,
"data": {...},
"errors": [ { "code": "...", "message": "..." } ]
}

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:

invokeMethod(String methodName, Map<String, Object> inputMap, Map<String, Object> outputMap, Map<String, Object> options)
ParameterRoleCallable equivalent
methodNameAction selector (same semantics as action)action in call(action, args)
inputMapPrimary input data (required keys, types)args.get('inputMap')
outputMapMutable map where results are written (out-by-reference)Return value; Callable returns envelope instead
optionsAdditional 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):

apex
public with sharing class Industries_OrderCallable implements System.Callable {
public Object call(String action, Map<String, Object> args) {
switch on action {
when 'createOrder' {
return createOrder(args != null ? args : new Map<String, Object>());
}
when else {
throw new IndustriesCallableException('Unsupported action: ' + action);
}
}
}
private Map<String, Object> createOrder(Map<String, Object> args) {
// Validate input (e.g. args.get('orderId')), run business logic, return response envelope
return new Map<String, Object>{ 'success' => true };
}
}

Use the vanilla pattern when callers pass flat args and no VlocityOpenInterface integration is required.

Callable skeleton (same inputs as VlocityOpenInterface):

Use inputMap and options keys in args when integrating with Open Interface or when callers pass that structure:

apex
public with sharing class Industries_OrderCallable implements System.Callable {
public Object call(String action, Map<String, Object> args) {
Map<String, Object> inputMap = (args != null && args.containsKey('inputMap'))
? (Map<String, Object>) args.get('inputMap') : (args != null ? args : new Map<String, Object>());
Map<String, Object> options = (args != null && args.containsKey('options'))
? (Map<String, Object>) args.get('options') : new Map<String, Object>();
if (inputMap == null) { inputMap = new Map<String, Object>(); }
if (options == null) { options = new Map<String, Object>(); }
switch on action {
when 'createOrder' {
return createOrder(inputMap, options);
}
when else {
throw new IndustriesCallableException('Unsupported action: ' + action);
}
}
}
private Map<String, Object> createOrder(Map<String, Object> inputMap, Map<String, Object> options) {
// Validate input, run business logic, return response envelope
return new Map<String, Object>{ 'success' => true };
}
}

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 and sharing (with sharing, Security.stripInaccessible())
  4. Bulkify when args include record collections
  5. Use WITH USER_MODE for SOQL when appropriate

VlocityOpenInterface / VlocityOpenInterface2 implementation:

When implementing omnistudio.VlocityOpenInterface or omnistudio.VlocityOpenInterface2, use the signature:

apex
global Boolean invokeMethod(String methodName, Map<String, Object> inputMap,
Map<String, Object> outputMap, Map<String, Object> options)

Open Interface skeleton:

apex
global with sharing class Industries_OrderOpenInterface implements omnistudio.VlocityOpenInterface2 {
global Boolean invokeMethod(String methodName, Map<String, Object> inputMap,
Map<String, Object> outputMap, Map<String, Object> options) {
switch on methodName {
when 'createOrder' {
Map<String, Object> result = createOrder(inputMap, options);
outputMap.putAll(result);
return true;
}
when else {
outputMap.put('success', false);
outputMap.put('errors', new List<Map<String, Object>>{
new Map<String, Object>{ 'code' => 'UNSUPPORTED_ACTION', 'message' => 'Unsupported action: ' + methodName }
});
return false;
}
}
}
private Map<String, Object> createOrder(Map<String, Object> inputMap, Map<String, Object> options) {
// Validate input, run business logic, return response envelope
return new Map<String, Object>{ 'success' => true, 'data' => new Map<String, Object>() };
}
}

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

Example test class:

apex
@IsTest
private class Industries_OrderCallableTest {
@IsTest
static void testCreateOrder() {
System.Callable svc = new Industries_OrderCallable();
Map<String, Object> args = new Map<String, Object>{
'inputMap' => new Map<String, Object>{ 'orderId' => '001000000000001' },
'options' => new Map<String, Object>()
};
Map<String, Object> result =
(Map<String, Object>) svc.call('createOrder', args);
Assert.isTrue((Boolean) result.get('success'));
}
@IsTest
static void testUnsupportedAction() {
try {
System.Callable svc = new Industries_OrderCallable();
svc.call('unknownAction', new Map<String, Object>());
Assert.fail('Expected IndustriesCallableException');
} catch (IndustriesCallableException e) {
Assert.isTrue(e.getMessage().contains('Unsupported action'));
}
}
}

Migration: VlocityOpenInterface to System.Callable

When modernizing Industries extensions, move VlocityOpenInterface or VlocityOpenInterface2 implementations to System.Callable and keep the action contract stable. Use the Salesforce guidance as the source of truth. Salesforce Help

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

Example migration (pattern):

apex
// BEFORE: VlocityOpenInterface2
global class OrderOpenInterface implements omnistudio.VlocityOpenInterface2 {
global Boolean invokeMethod(String methodName, Map<String, Object> input,
Map<String, Object> output,
Map<String, Object> options) {
if (methodName == 'createOrder') {
output.putAll(createOrder(input, options));
return true;
}
return false;
}
}
// AFTER: System.Callable (same inputs: inputMap, options)
public with sharing class OrderCallable implements System.Callable {
public Object call(String action, Map<String, Object> args) {
Map<String, Object> inputMap = args != null ? (Map<String, Object>) args.get('inputMap') : new Map<String, Object>();
Map<String, Object> options = args != null ? (Map<String, Object>) args.get('options') : new Map<String, Object>();
if (inputMap == null) { inputMap = new Map<String, Object>(); }
if (options == null) { options = new Map<String, Object>(); }
switch on action {
when 'createOrder' {
return createOrder(inputMap, options);
}
when else {
throw new IndustriesCallableException('Unsupported action: ' + action);
}
}
}
}

Best Practices (120-Point Scoring)

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
401
Repository forks
88
7-day trend score
30

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 29 Apr 2026, 6 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/jaganpro/sf-skills/sf-industry-commoncore-callable-apex/badge)](https://verified-skill.com/skills/jaganpro/sf-skills/sf-industry-commoncore-callable-apex)

Something wrong with this skill or its page? Tell us.