Skip to content

Latest commit

 

History

History
291 lines (196 loc) · 5.66 KB

File metadata and controls

291 lines (196 loc) · 5.66 KB

Workflow Engine – Requirements

This document captures the complete and final set of requirements for the Workflow Engine project.


1. Goal

Build a full-stack workflow automation application (similar in spirit to Zapier) that allows users to:

  • Define workflows as JSON
  • Trigger workflows via unique HTTP endpoints
  • Execute workflow steps sequentially
  • Integrate with external systems such as Slack or Discord via HTTP webhooks

2. Tech Stack (Required)

Backend

  • Node.js
  • TypeScript
  • HTTP framework of choice (Express is acceptable)

Frontend

  • React
  • TypeScript
  • Can use any framework (Next.js is acceptable)

Database

  • Relational database (PostgreSQL, MySQL, etc.)

3. Application Scope

  • The application is single-tenant
  • No authentication or user identity
  • All workflows are globally visible and editable

4. Workflow Model

Each workflow must have:

  • id (generated by backend)
  • name (string)
  • enabled (boolean)
  • trigger (exactly one HTTP trigger)
  • steps (ordered list, must not be empty)

Trigger

  • Only HTTP triggers are supported
  • Backend generates a unique, publicly accessible URL path for each workflow
  • Triggered via HTTP POST

Example:

{
  "type": "http",
  "path": "/t/<random-id>"
}

5. Backend API Requirements

The backend must expose the following endpoints:

  • POST /workflows – create a workflow
  • GET /workflows – list all workflows
  • GET /workflows/:id – fetch a single workflow
  • PUT /workflows/:id or PATCH /workflows/:id – update a workflow
  • DELETE /workflows/:id – delete a workflow

6. Workflow Validation Rules

  • Workflow must contain at least one step
  • Unsupported step types must result in a validation error
  • Unsupported transform operations must result in a validation error
  • Invalid workflow payloads must return clear 4xx errors

7. Workflow Execution

Triggering

  • A POST request to the workflow’s trigger URL starts a workflow run
  • If the workflow is disabled, the trigger endpoint must return 403 or 404
  • Each trigger request creates a new workflow run
  • No idempotency or “exactly once” guarantees are required

Trigger Response

  • The trigger endpoint must return a synchronous HTTP response
  • The response must include the workflow run status:
    • success
    • skipped
    • failed

Execution Rules

  • Steps execute sequentially, in the order defined
  • Execution stops on:
    • First failed step → failed
    • Failed filter condition → skipped

8. Workflow Run Persistence

A workflow run record must be created when execution starts and updated when execution completes.

Each workflow run must persist:

  • Workflow ID
  • Status (success, skipped, failed)
  • Start timestamp
  • End timestamp
  • Error details (if any)

For failed HTTP request steps, additionally persist:

  • HTTP status code
  • Response headers
  • Response body

9. Workflow Run Statuses

Valid statuses are:

  • success – all steps executed successfully
  • skipped – execution stopped by a filter step
  • failed – execution stopped due to an error

10. Context (ctx)

  • ctx is initialized using the inbound HTTP request body
  • ctx is passed to each step
  • Steps may read and/or mutate ctx
  • Missing fields accessed via dot-paths resolve to null

11. Step Types

11.1 Filter Step

Purpose: Gate execution based on values in ctx.

Shape:

{
  "type": "filter",
  "conditions": [{ "path": "field", "op": "eq", "value": "x" }]
}

Rules:

  • Supported ops: eq, neq

  • Operates on ctx using dot-paths

  • All conditions must pass

  • If any condition fails:

    • Execution stops
    • Run status = skipped
  • Filter steps do not modify ctx


11.2 Transform Step

Purpose: Modify ctx for downstream steps.

Supported operations:

  • default
  • template
  • pick

Rules:

  • Transform steps only modify ctx
  • No side effects
  • Operations execute in order
  • Dot-paths behave similar to lodash.get/set
  • Template operations replace missing values with an empty string

pick operation:

  • Retains only the specified fields
  • Removes all other fields from ctx
  • Can operate on root or nested objects

Example:

{
  "type": "transform",
  "ops": [
    { "op": "default", "path": "actor_name", "value": "Unknown" },
    { "op": "template", "to": "title", "template": "Event {{type}}" }
  ]
}

11.3 HTTP Request Step

Purpose: Call external systems.

Shape:

{
  "type": "http_request",
  "method": "POST",
  "url": "https://example.com/webhook",
  "headers": { "Content-Type": "application/json" },
  "body": { "mode": "custom", "value": { "text": "{{title}}" } },
  "timeoutMs": 2000,
  "retries": 3
}

Rules:

  • HTTP retries are handled synchronously

  • Retries must occur on:

    • Network errors
    • HTTP 5xx responses
  • No need to support chaining or dependency handling between HTTP steps

  • Supported body modes:

    • ctx: send the entire ctx as JSON
    • custom: send a custom JSON object with templates

On failure:

  • Stop execution
  • Mark run as failed
  • Persist HTTP failure details

12. Frontend Requirements

The frontend must support:

  • List workflows
  • Create workflows
  • Edit workflows
  • Delete workflows
  • View a workflow’s generated trigger URL
  • Edit workflow steps as raw JSON using a code editor (e.g., Monaco)

UI design is not graded, but the UI must be usable.


13. Minimum Functional Check

The system must demonstrate:

  • Workflow creation
  • Triggering via HTTP
  • Sequential execution of steps
  • Posting a message to Slack or Discord via webhook