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
- Looks up the Ramp by UUID and its active workflow.
- Creates an
or_ramp_executionsrecord (statusCREATED) and anor_object_entity_idrecord with mock CRM object data. POSTs to/api/ramps/<ramp_uuid>/executions/<execution_uuid>/process.- 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):
# 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.lockRequires 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>/workflowsOr query the DB directly:
SELECT uuid, name FROM or_ramps WHERE active_workflow_id IS NOT NULL LIMIT 10;Local usage
Interactive mode (first-time setup)
bun run mock:workflowThe 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)
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:
{
"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/processflow runs as. Every fresh preview gets it automatically; no manual step. - HubSpot is pre-seeded — the golden seed includes a
seed-hubspotintegration record for vendor 0 with a fully cached CRM schema. HubSpot Deal workflows work without a live OAuth connection.
Running against a preview
bun run mock:workflow:preview -- <pr-key> <ramp-uuid>Example:
bun run mock:workflow:preview -- pr-9452 014d1e07-0392-46a1-922a-90d38c266ca4What this does under the hood:
- Calls
aws lambda get-function-configuration --function-name pr-preview-<pr-key>to readONRAMP_DATABASE_*from the Lambda env and assembles the Neon branch DB URL. - Connects to the branch DB over SSL (Neon requires TLS; the local default turns SSL off).
- Creates the
or_ramp_executionsandor_object_entity_idrecords in the branch DB. POSTs tohttps://<pr-key>.preview.onrampapps.com/api/ramps/.../processwith thex-amz-content-sha256header 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.- Outputs the same
__JSON_RESULT__JSON as headless mode, pluspreviewKeyandpreviewUrlfields.
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:
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=requireConfiguration file
devtools/mock-integrations/.mock-config.json (gitignored):
{
"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.