Selegic CRM Docs
ServerFlows

Persistence & State

Schema architecture, idempotency, and FlowRepo service for database operations.

Schema Architecture

Flow definitions and runtime state are stored in PostgreSQL via Prisma:

ModelPurpose
FlowTop-level container for a workflow
FlowVersionJSON graph (nodes + edges); only ACTIVE version executes
FlowRunSingle execution instance
FlowExecutionNodeDetailed logs per node (input/output/errors)
FlowDeadLetterFailed executions for debugging/retry

Schema Relationships

Flow (no attributes) FlowVersion (no attributes) FlowRun (no attributes) FlowExecutionNode (no attributes) FlowDeadLetter (no attributes) has executes contains has

FlowRepo Service

Located in flow-repo.ts, this service is the only component performing raw DB writes for the engine.

Key Operations

// Create a new execution
const run = await flowRepo.createRun({
  flowId: "flow_123",
  versionId: "version_456",
  idempotencyKey: "req_abc",
  triggerEvent: { userId: "user_789" },
});

// Update node status
await flowRepo.updateNodeStatus({
  nodeId: "node_abc",
  status: "SUCCESS",
  output: { result: "..." },
});

Idempotency

To prevent duplicate executions from network retries:

// Check before creating run
const existing = await flowRepo.findByIdempotencyKey(key, versionId);
if (existing) {
  return existing; // Return existing result
}

// Create new run
const run = await flowRepo.createRun({ ... });

Transaction Management

// Ensure atomicity of run + first node creation
Effect.withTransaction(tx => {
  await flowRepo.createRun(tx, runData);
  await flowRepo.createNode(tx, nodeData);
});

State Enums

enum FlowStatus {
  DRAFT = "DRAFT",
  ACTIVE = "ACTIVE",
  PAUSED = "PAUSED",
  ARCHIVED = "ARCHIVED",
}

enum RunStatus {
  PENDING = "PENDING",
  RUNNING = "RUNNING",
  COMPLETED = "COMPLETED",
  FAILED = "FAILED",
  DEAD_LETTER = "DEAD_LETTER",
}

enum NodeStatus {
  PENDING = "PENDING",
  RUNNING = "RUNNING",
  SUCCESS = "SUCCESS",
  FAILED = "FAILED",
}

Storage Optimization

  • Node logs: Use JSONB for input/output to save storage
  • Version history: Retain last 10 versions for rollback
  • Dead letter: Auto-purge after 30 days

On this page