Selegic CRM Docs
ServerExtensions

Action Runtime

Action definitions, execution context, and built-in actions for the extension system.

The Action Runtime executes pre-defined server-side functions. Actions are used by frontend extensions (via SDK transport) or by the Flow Engine.

Action Definition

Every action implements the ActionDefinition interface with input/output schemas (via Valibot) and a handler:

import { v } from "valibot";

export interface ActionDefinition<I, O> {
  input: v.InferInput<I>;
  output: v.InferOutput<O>;
  handler: (ctx: ActionContext, input: v.InferInput<I>, prisma: TenantPrisma) => Promise<v.InferOutput<O>>;
}

ActionContext

The handler receives an ActionContext with identity and scoping:

interface ActionContext {
  orgId: string;        // Internal database ID
  orgSlug: string;     // e.g., "acme-corp"
  userId: string;      // User performing the action
  extensionId?: string; // ID of extension if invoked via token
}

Built-in Actions

The system provides core actions in services/action-handlers.ts:

find_many / find_one

Query records with full tenant isolation using the Dynamic Objects engine:

// Extension code
const contacts = await actions.find_many({
  entity: "contact",
  filter: { active: true },
  limit: 10,
});

mutate

Create, update, delete, or upsert operations on dynamic entities:

await actions.mutate({
  operation: "create",
  entity: "invoice",
  data: { amount: 1000, customer: "cust_123" },
});

query

SQL-like string query syntax for extensions:

const results = await actions.query({
  sql: "SELECT name, email FROM contact WHERE active = true LIMIT 10",
});

Custom Actions

Additional actions can be registered in the action map:

const actions = {
  my_custom_action: {
    input: MyInputSchema,
    output: MyOutputSchema,
    handler: async (ctx, input, prisma) => {
      // Custom logic
      return result;
    },
  },
};

Execution Flow

POST /api/actions/execute validate token route to action execute with tenant context result JSON response Extension SDK CRM API DispatchService ActionHandler TenantPrisma

Performance & Safety

  • Isolation: Handlers receive TenantPrisma scoped to caller's database
  • Timeout: Execution monitored with configurable timeout
  • Validation: All inputs parsed through schema before handler execution

Developing New Actions

  1. Define Schema: Create input/output Valibot schemas
  2. Implement Handler: Add logic to services/action-handlers.ts
  3. Register: Add action to the actions map
  4. Expose: Update Hono routes if using public API

On this page