Skip to content

Mock Workflow Trigger

devtools/mock-integrations/mock-workflow-trigger.mjs simulates the async-automation-handler — the Lambda that writes CRM-triggered workflow execution records to the DB and then calls the Flask /process endpoint. Use it to test workflow processing logic without running the full async infrastructure.

What it does

  1. Looks up the Ramp by UUID and its active workflow.
  2. Creates an or_ramp_executions record (status CREATED) and an or_object_entity_id record with mock CRM object data.
  3. POSTs to /api/ramps/<ramp_uuid>/executions/<execution_uuid>/process.
  4. The Flask endpoint processes the workflow steps (creates a project, maps fields, etc.) and returns 200 "Execution processed successfully.".

The /process endpoint is require_login=False, so no auth token is needed.

Prerequisites

@onramptech/onramp-database-js (one-time install)

The mock writes directly to the DB via this package. It's published to GitHub Packages and must be ghost-installed (it won't touch package.json):

bash
# 1. Add read:packages scope to your GitHub CLI token (one-time):
gh auth refresh -s read:packages

# 2. Ghost-install the package:
bun add @onramptech/onramp-database-js --no-save && rm -f bun.lock

Requires the GitHub CLI — run gh auth login first if needed.

A Ramp with an active workflow

You need the UUID of a Ramp that has active_workflow_id set (i.e. a published workflow, or a draft that was saved after setting up a trigger). Find it in the UI URL:

http://localhost:3000/ramps/<ramp-uuid>/workflows

Or query the DB directly:

sql
SELECT uuid, name FROM or_ramps WHERE active_workflow_id IS NOT NULL LIMIT 10;

Local usage

Interactive mode (first-time setup)

bash
bun run mock:workflow

The interactive mode walks you through:

  • Flask API base URL (default http://localhost:5000)
  • Database URL (default postgres://postgres:onramp_local@localhost:5432/onramp_local)
  • Selecting a Ramp from the DB (or entering a UUID manually)
  • CRM service type, object type, event type, and mock field data

Configuration is saved to devtools/mock-integrations/.mock-config.json (gitignored) for future runs. Run interactively once, then use headless mode for all subsequent runs.

Headless mode (for scripts and agents)

bash
bun run mock:workflow <ramp-uuid>

Reads the existing .mock-config.json and overrides just the ramp UUID. Outputs a __JSON_RESULT__ marker followed by structured JSON on stdout:

json
{
  "success": true,
  "rampUuid": "014d1e07-0392-46a1-922a-90d38c266ca4",
  "executionUuid": "bc05a267-de52-4298-bd10-75dfcdaf0ab8",
  "objectEntityUuid": "90921593-cff0-4c7d-8efe-d687f92fe44a",
  "response": { "message": "Execution processed successfully.", "status": 200 }
}

Exit codes: 0 = success, 1 = failure.

PR preview usage

Preview environments run on a Neon branch DB and a CloudFront-fronted Lambda. The mock's preview mode automates the two differences from local: resolving the branch DB connection and adding the required CloudFront OAC header.

Prerequisites

  • dev01 AWS credentials active — the script queries the Lambda env to resolve the Neon branch DB connection.
  • A Ramp with an active workflow in the preview DB — preview DBs start from the golden seed, which has no workflows. Create one via the Workflows UI in the preview SPA before running the mock. Log in with admin@onramp.us / OnRampLocal!23.
  • Integration User is pre-seeded — the golden seed includes an Integration User (role INTEGRATION_USER) for vendor 0, which the async-automation /process flow runs as. Every fresh preview gets it automatically; no manual step.
  • HubSpot is pre-seeded — the golden seed includes a seed-hubspot integration record for vendor 0 with a fully cached CRM schema. HubSpot Deal workflows work without a live OAuth connection.

Running against a preview

bash
bun run mock:workflow:preview -- <pr-key> <ramp-uuid>

Example:

bash
bun run mock:workflow:preview -- pr-9452 014d1e07-0392-46a1-922a-90d38c266ca4

What this does under the hood:

  1. Calls aws lambda get-function-configuration --function-name pr-preview-<pr-key> to read ONRAMP_DATABASE_* from the Lambda env and assembles the Neon branch DB URL.
  2. Connects to the branch DB over SSL (Neon requires TLS; the local default turns SSL off).
  3. Creates the or_ramp_executions and or_object_entity_id records in the branch DB.
  4. POSTs to https://<pr-key>.preview.onrampapps.com/api/ramps/.../process with the x-amz-content-sha256 header set to the SHA-256 of the empty string (e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855). CloudFront OAC requires this header on every non-GET request; without it the request returns 403.
  5. Outputs the same __JSON_RESULT__ JSON as headless mode, plus previewKey and previewUrl fields.

If CloudFront's KVS routing table hasn't registered the preview yet (can happen in the first few minutes after a deploy), the script retries up to 5 times with 6-second delays before giving up.

Finding the ramp UUID in a preview

After creating a workflow via the preview UI, grab the UUID from the URL:

https://<pr-key>.preview.onrampapps.com/dashboard/workflows/<ramp-uuid>/versions/<version-uuid>

Or query the branch DB directly using the connection details from the Lambda env:

bash
VARS=$(aws lambda get-function-configuration --function-name pr-preview-<pr-key> \
  --region us-west-2 --query 'Environment.Variables' --output json)

# Then connect with:
# postgresql://$(echo $VARS | jq -r .ONRAMP_DATABASE_USER):$(echo $VARS | jq -r .ONRAMP_DATABASE_PASSWORD)@$(echo $VARS | jq -r .ONRAMP_DATABASE_HOST):5432/neondb?sslmode=require

Configuration file

devtools/mock-integrations/.mock-config.json (gitignored):

json
{
  "baseUrl": "http://localhost:5000",
  "dbUrl": "postgres://postgres:onramp_local@localhost:5432/onramp_local",
  "defaultRampUuid": "<your-ramp-uuid>",
  "serviceType": "hubspot",
  "objectType": "deals",
  "eventType": "create",
  "objectId": "mock-1234567890",
  "objectDetails": [
    { "name": "dealname", "value": "Mock Deal", "type": "string" },
    { "name": "amount", "value": 10000, "type": "number" }
  ]
}

In preview mode this config is used only for serviceType, objectType, eventType, and objectDetails. The baseUrl and dbUrl are always overridden by the preview-mode logic (Lambda env lookup + CloudFront URL). If no .mock-config.json exists, preview mode falls back to sensible HubSpot Deal defaults.

Limitations

Inbound trigger path works end-to-end. The mock exercises the full inbound flow: DB write → /process → project creation.

Outbound CRM write-back requires a live connection. If the workflow has steps that write data back to HubSpot or Salesforce (e.g. updating a Deal field from a project data field), those steps call the Prismatic integration layer. In previews, Prismatic config is seeded from a shared dev-tier config (injected at reseed). If a workflow step tries to perform a live CRM write and that write fails (e.g. a stale OAuth token or a missing object ID), the /process endpoint will return a step-level error, but the mock tool reports the HTTP status correctly — look at the response body in the JSON output to see step-level failures.

Internal documentation — gated behind Cloudflare Access.