Skip to content

Latest commit

 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FlowPulse — Workflow Automation Platform

A multi-tenant workflow automation platform built on nhost (Postgres + Hasura + Auth + Serverless Functions) with a Next.js frontend. Supports real-time execution tracking, LLM-powered steps, cross-org isolation, and approval gates.

Architecture

┌─────────────────────────────────────────────────────────┐
│                   Next.js Frontend                      │
│   (React + Apollo Client + nhost Auth + Subscriptions)  │
└─────────────┬───────────────────────────┬───────────────┘
              │ queries/mutations         │ subscriptions (WSS)
              ▼                           ▼
┌─────────────────────────────────────────────────────────┐
│                 Hasura GraphQL Engine                   │
│    ┌──────────────────────┐  ┌────────────────────┐     │
│    │ Layer 1 Permissions  │  │  Actions (→ Funcs) │     │
│    │ (org-scoped RLS)     │  │  Event Triggers    │     │
│    └──────────────────────┘  └────────────────────┘     │
└─────────────┬───────────────────────────┬───────────────┘
              │                           │
              ▼                           ▼
┌──────────────────────┐    ┌──────────────────────────────┐
│     PostgreSQL       │    │   nhost Serverless Functions │
│  (9 tables + view)   │    │  ┌─ trigger-workflow-run.js  │
│                      │    │  ├─ approve-step.js          │
│                      │    │  ├─ webhook-trigger.js       │
│                      │    │  └─ utils/ (shared code)     │
└──────────────────────┘    │        │                     │
                            │        ├─→ Groq API (LLM)    │
                            │        ├─→ Open-Meteo (HTTP) │
                            │        └─→ ntfy.sh (Notify)  │
                            └──────────────────────────────┘

Key Concepts

  • nhost: An open-source backend-as-a-service bundling Postgres, Hasura, Auth, and Serverless Functions. Locally runs via Docker with nhost up.
  • Hasura: A GraphQL engine that auto-generates a GraphQL API from your Postgres schema. We use it for queries, mutations, subscriptions, permissions, Actions (custom business logic endpoints), and Event Triggers.
  • Hasura Actions: Custom GraphQL mutations backed by serverless functions. When you call triggerWorkflowRun() in GraphQL, Hasura forwards the request to our function handler, which does the actual work.
  • Subscriptions: Real-time WebSocket connections. When our handler updates a step_run status, Hasura pushes the change to all subscribed clients automatically — no page refresh needed.
  • Computed Field/View: org_monthly_usage is a Postgres VIEW (not a table) that aggregates workflow run stats per org. Hasura tracks it as a read-only table so it's queryable via GraphQL.

Prerequisites

Tool Version Install
Docker & Docker Compose Latest docker.com
Node.js 18+ nodejs.org
nhost CLI 1.50+ curl -L https://raw.githubusercontent.com/nhost/cli/main/get.sh | bash
Git Latest pre-installed on most systems

Environment Variables

Variable Purpose Where to Get Free? Required?
HASURA_GRAPHQL_ADMIN_SECRET Admin access to Hasura Auto-generated by nhost init (in .secrets) N/A Yes (auto)
GROQ_API_KEY LLM calls via Groq API console.groq.com — sign up, create API key ✅ Free, no card Optional*
NEXT_PUBLIC_NHOST_SUBDOMAIN Frontend → nhost connection local for dev, your project subdomain for prod N/A Yes
NEXT_PUBLIC_NHOST_REGION nhost region Empty for local, e.g. us-east-1 for prod N/A Yes

*If GROQ_API_KEY is not set, LLM calls use a stubbed response with an artificial delay. This is intentional — see "Stubbed Services" below.


Local Setup (Step by Step)

1. Clone and install dependencies

git clone <repo-url>
cd flowpulse

# Install function dependencies
cd functions && npm install && cd ..

# Install frontend dependencies
cd frontend && npm install --legacy-peer-deps && cd ..

2. Configure environment

# (Optional) Add your Groq API key for real LLM calls
# Add this line to the .secrets file in the project root:
# GROQ_API_KEY = 'your-key-here'

# Frontend is pre-configured for local dev
# frontend/.env.local already contains:
# NEXT_PUBLIC_NHOST_SUBDOMAIN=local

3. Start nhost (Postgres + Hasura + Auth + Functions)

# This starts the entire backend stack via Docker
nhost up

# First run will:
# 1. Pull Docker images
# 2. Apply migrations (create tables)
# 3. Apply metadata (permissions, relationships, actions)
# 4. Apply seed data (demo orgs + workflows)
# 5. Start serverless functions

Wait for "ready" output. The following services will be available:

4. Seed demo users

# Users must be created via Auth API (not raw SQL) for proper password hashing
node functions/seed-users.js

This creates 6 users across 2 orgs:

Email Password Org Role
owner_a@demo.com password123 Acme Corp owner
editor_a@demo.com password123 Acme Corp editor
viewer_a@demo.com password123 Acme Corp viewer
owner_b@demo.com password123 Beta Inc owner
editor_b@demo.com password123 Beta Inc editor
viewer_b@demo.com password123 Beta Inc viewer

5. Start the frontend

cd frontend
npm run dev
# → http://localhost:3000

6. Verify it works

  1. Open http://localhost:3000
  2. Log in as owner_a@demo.com / password123
  3. You should see the "Acme Corp" dashboard with the "Weather Analysis Pipeline" workflow
  4. Click "▶ Run" on the workflow
  5. Watch step statuses update in real-time on the run viewer page

External Services

Service What It Does Open Source? Cost Notes
Groq API LLM inference (Llama 3.3 70B) Models are open-weight; API service is proprietary Free tier, no card required ~30 RPM limit. Falls back to stub if unavailable.
Open-Meteo Weather data for HTTP request demo ✅ Fully open source Free, no API key No signup needed.
ntfy.sh Push notifications ✅ Open source (self-hostable) Free public instance, no signup Messages are public; use unique topic names.

Stubbed Services

If GROQ_API_KEY is not set, the llm_call step uses a stubbed response with a 1.5-second artificial delay. This is intentional and disclosed:

  • The stub returns { classification: "NORMAL", summary: "Stubbed response" }
  • The workflow still exercises the full execution pipeline (status updates, subscriptions, conditional branching)
  • Set the env var for real LLM calls

Project Structure

flowpulse/
├── nhost/
│   ├── nhost.toml                  # nhost service configuration
│   ├── migrations/default/1_init/  # SQL schema (all tables)
│   ├── metadata/                   # Hasura metadata
│   │   ├── actions.yaml            # Action definitions (triggerWorkflowRun, approveStep, webhookTrigger)
│   │   ├── actions.graphql         # Action type definitions
│   │   └── databases/default/tables/  # Table tracking, relationships, permissions
│   └── seeds/default/1_seed.sql    # Demo data (orgs, workflows, steps, triggers)
├── functions/
│   ├── trigger-workflow-run.js     # ⭐ Core: workflow execution engine
│   ├── approve-step.js             # ⭐ Approval gate handler
│   ├── webhook-trigger.js          # Inbound webhook endpoint
│   ├── seed-users.js               # Demo user creation script
│   └── _utils/
│       ├── graphql.js              # Admin GraphQL client
│       └── step-executors.js       # All 6 step type implementations
├── frontend/
│   └── src/
│       ├── app/
│       │   ├── page.js             # Login/signup
│       │   ├── dashboard/page.js   # Workflow list + run controls
│       │   ├── workflow/[id]/page.js        # Workflow builder
│       │   └── workflow/[id]/run/[runId]/page.js  # ⭐ Live run viewer
│       ├── components/Navbar.js    # Nav with org selector + quota
│       └── lib/
│           ├── nhost.js            # nhost client config
│           ├── apollo.js           # Apollo Client with WebSocket subscriptions
│           └── graphql.js          # All GraphQL operations
├── README.md          # ← You are here
├── DEPLOYMENT.md      # Deployment guide
├── WRITEUP.md         # Schema & permission reasoning
└── DEMO.md            # Final Task walkthrough script

Two-Layer Permission System

Layer 1 — Hasura Row-Level Permissions

Every table has permission rules that scope access via the org_members relationship. Even if an Org B user guesses an Org A workflow ID and queries it directly, Hasura will return empty results.

Example (from public_workflows.yaml):

filter:
  organization:
    org_members:
      user_id:
        _eq: X-Hasura-User-Id

Layer 2 — Handler Code Checks

Some restrictions can't be expressed as row-level permissions:

  • Step-type gating: Only owners can add db_write or notify steps (checked in trigger-workflow-run.js)
  • Approval role check: Only owners/editors can approve paused steps (checked in approve-step.js)
  • Quota enforcement: Org quota is checked before allowing a new run

See WRITEUP.md for detailed reasoning.

About

A multi-tenant workflow automation platform built on nhost (Postgres + Hasura + Auth + Serverless Functions) with a Next.js frontend. Supports real-time execution tracking, LLM-powered steps, cross-org isolation, and approval gates.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages