FlowForge is a full-stack automation platform where you build workflows visually drag nodes onto a canvas, wire them together, and watch them execute in real time with WebSocket-driven animations.
Every node type has a dedicated configuration panel. Every run is logged with per-node input/output and duration. Every execution step pushes state to the canvas live.
Think n8n meets a custom Python backend built from scratch to demonstrate full-stack engineering depth.
flowchart TB
subgraph Browser["Browser"]
Canvas["React Canvas\ndrag & drop · SVG edges · auto-save"]
WsClient["WebSocket client\nuseWorkflowRun hook"]
end
subgraph Server["Django — Daphne / ASGI"]
API["REST API\nDjango REST Framework\n\n/execute/ · /validate/ · /webhook/\n/stats/ · /templates/ · /dry-run/"]
Consumer["WorkflowRunConsumer\nDjango Channels"]
end
subgraph Workers["Celery Worker"]
Executor["WorkflowExecutor\nKahn's Algorithm\n→ topological order\n→ 8 node handlers"]
end
Redis[("Redis\nchannel layer\n+ broker")]
DB[("PostgreSQL\nWorkflow · Node · Edge\nRun · NodeExecution")]
Canvas -->|"PUT /save_graph/\nPOST /execute/"| API
WsClient <-->|"ws:// live state"| Consumer
API -->|"task.delay()"| Redis
Consumer <-->|"group_send / receive"| Redis
Redis --> Workers
Workers --> DB
API --> DB
|
Dashboard & Template Gallery |
Canvas Editor |
git clone <repo> && cd flowforge
./flowforge.sh start # Docker Compose up + health checks for backend + frontend
# Seed demo data
docker compose exec backend python manage.py seed_workflows # 3 demo workflows
docker compose exec backend python manage.py seed_templates # 3 gallery templates
docker compose exec backend python manage.py seed_daily_briefing # Daily Briefing + cron 09:00 BRT
# Services:
# UI: http://localhost:5106
# API: http://localhost:8006/api/
# Admin: http://localhost:8006/admin/
# WebSocket: ws://localhost:8006/ws/| Layer | Technology | Role |
|---|---|---|
| Backend | Django 5.x + Django REST Framework | ORM, serializers, ViewSets, validation |
| Async tasks | Celery + Redis | Decoupled execution, retry logic |
| Real-time | Django Channels + Daphne (ASGI) | WebSocket — zero polling |
| Database | PostgreSQL | JSONB for node config, run output |
| LLM | Ollama (local) | Self-hosted models — no API key needed |
| Frontend | React 18 | Functional components, hooks, no framework |
| Charts | Recharts | SVG-based stats charts |
| Styling | CSS-in-JS inline | Zero build config, design tokens viavar(--*) |
| Unit tests | pytest + pytest-django | 72 tests, 57% coverage — models/API/engine/tasks |
| E2E tests | Playwright (Chrome + Firefox) | Video recording, trace viewer |
| Containers | Docker Compose (dev) + Nginx (prod) | One-command local stack · prod-ready config |
./flowforge.sh test # Headed — Chrome + Firefox (watch live)
./flowforge.sh test:ci # Headless (CI/CD)
./flowforge.sh demo # Records Luna workflow → test-results/*/video.webm
./flowforge.sh trace # Opens Playwright Trace Viewer
./flowforge.sh report # Opens HTML test report
./flowforge.sh codegen # Record new tests by interacting with the browser
./flowforge.sh ui # Playwright UI Mode (interactive)The demo spec (e2e/demo.spec.js) creates a complete 4-node workflow from scratch, configures each node via its panel, validates the DAG, executes, and captures the full run history — all in ~34 seconds of real time.
flowforge/
├── backend/
│ ├── config/ # Django settings, ASGI, URLs
│ └── flowforge/
│ ├── models.py # Workflow, Node, Edge, Run, NodeExecution, WorkflowTemplate
│ ├── engine/
│ │ ├── dag_engine.py # validate_dag() — DFS cycle detection + unreachable nodes
│ │ ├── executor.py # WorkflowExecutor — Kahn's Algorithm
│ │ └── handlers.py # 9 node handlers (strategy pattern) — http/llm/telegram are real
│ ├── api/
│ │ ├── serializers.py # validate_node_config() per node type
│ │ └── views.py # ViewSets + @actions (execute, validate, stats, templates...)
│ ├── consumers.py # WorkflowRunConsumer (WebSocket + snapshot replay)
│ ├── tasks.py # execute_workflow + trigger_daily_briefing Celery tasks
│ └── management/commands/
│ ├── seed_workflows.py
│ ├── seed_templates.py
│ └── seed_daily_briefing.py # Daily Briefing workflow + CeleryBeat PeriodicTask
├── frontend/
│ └── src/
│ ├── App.jsx # Canvas editor + all views
│ ├── components/
│ │ ├── NodeConfigPanels.jsx # 9 config panels (one per node type, incl. Telegram)
│ │ └── NodeDetailDrawer.jsx # Configure / Execution tabs + inline dry-run
│ ├── hooks/
│ │ ├── useApi.js # Generic fetch hook with loading/error state
│ │ └── useWorkflowRun.js # WebSocket + execution state machine
│ └── utils/formatters.js # NODE_TYPES, RUN_STATUS, WORKFLOW_STATUS
│ └── e2e/
│ ├── demo.spec.js # Portfolio demo — full Luna workflow
│ ├── 01-workflow-list.spec.js
│ ├── 02-create-workflow.spec.js
│ ├── 03-canvas-nodes.spec.js
│ └── 04-execute-workflow.spec.js
├── backend/
│ ├── tests/
│ │ ├── conftest.py # Shared fixtures (workflow, workflow_with_nodes, template)
│ │ ├── test_models.py # 17 tests — Workflow, Node, Edge, Run, WorkflowTemplate
│ │ ├── test_dag_engine.py # 11 tests — cycle detection, unreachable nodes
│ │ ├── test_serializers.py # 17 tests — validate_node_config, NodeSerializer, EdgeSerializer
│ │ ├── test_api.py # 23 tests — all REST endpoints + dry_run + cancel
│ │ └── test_tasks.py # 4 tests — execute_workflow, trigger_daily_briefing
│ ├── pytest.ini # DJANGO_SETTINGS_MODULE + asyncio_mode
│ └── requirements-dev.txt # pytest-django, pytest-mock, pytest-cov, pytest-asyncio
├── nginx/nginx.conf # Reverse proxy: API + WebSocket upgrade + static files
├── docs/assets/ # Screenshots + demo GIF
├── flowforge.sh # Stack control + demo recording
├── docker-compose.yml # Development stack
└── docker-compose.prod.yml # Production: + Postgres + Nginx + healthchecks
timeline
title FlowForge — Build History
Sprint 1 : CRUD Workflow/Node/Edge
: Django Admin
: Canvas drag & drop
: Auto-save (debounce 2s)
Sprint 2 : DAG validation (DFS cycle detection)
: POST /validate/ · POST /webhook/
: Error badges on canvas nodes
Sprint 3 : Django Channels + Daphne
: WebSocket real-time state
: Pulse animations · Flow dots
: Progress bar
Sprint 4 : 8 node config panels
: POST /dry-run/ per node
: validate_node_config() in serializer
E2E : Playwright Chrome + Firefox
: Video recording demo
: flowforge.sh full control
Sprint 5 : GET /stats/ dashboard
: Template gallery (3 templates)
: Undo/Redo 20-level stack
: Keyboard shortcuts
Sprint 6 : 72 pytest tests (57% coverage)
: GitHub Actions CI pipeline
: docker-compose.prod + Nginx
: Delete workflow (with confirm)
: Save as (clone with new name)
Built with Python + React · Dark mode only · No magic — just code

