<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Benchouia Ahmed Abdelhakim</title>
    <description>The latest articles on DEV Community by Benchouia Ahmed Abdelhakim (@benchouia_ahmedabdelhaki).</description>
    <link>https://dev.to/benchouia_ahmedabdelhaki</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3973116%2F3bc4696d-cfae-4bf6-be61-b00ea91c4915.png</url>
      <title>DEV Community: Benchouia Ahmed Abdelhakim</title>
      <link>https://dev.to/benchouia_ahmedabdelhaki</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/benchouia_ahmedabdelhaki"/>
    <language>en</language>
    <item>
      <title>Oumma from Zero: Installing the Engine, the Web App and Keycloak (A Guide for Absolute Beginners)</title>
      <dc:creator>Benchouia Ahmed Abdelhakim</dc:creator>
      <pubDate>Sat, 24 Oct 2026 10:04:58 +0000</pubDate>
      <link>https://dev.to/benchouia_ahmedabdelhaki/oumma-from-zero-installing-the-engine-the-web-app-and-keycloak-a-guide-for-absolute-beginners-14kb</link>
      <guid>https://dev.to/benchouia_ahmedabdelhaki/oumma-from-zero-installing-the-engine-the-web-app-and-keycloak-a-guide-for-absolute-beginners-14kb</guid>
      <description>&lt;h1&gt;
  
  
  Oumma from Zero: Installing the Engine, the Web App and Keycloak
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;This is the "make it run on my machine" episode of the Oumma series. If you've read the previous articles you know what Oumma does: a platform where business processes are designed in a browser, executed by an engine that mixes **human steps&lt;/em&gt;* (a person approves, reviews, fills a form) with &lt;strong&gt;AI and system steps&lt;/strong&gt; (an LLM routes, a tool sends a WhatsApp message, an HTTP call validates data) — with real permissions, real audit logs, and a real database.*&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Today: you install all of it yourself. I'll assume you can open a terminal and paste a command — nothing more. If you've ever installed WordPress or Nextcloud, you can follow this. If you've never done anything like that, read the "What is each piece" section first and paste carefully.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You'll end up with a working test environment, exactly like mine:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Web app&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://localhost:5173&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;What humans use (login, My Tasks, My Dossiers, Designer)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Engine API&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://localhost:8095&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The Go engine that executes processes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keycloak&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://localhost:8080&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Login / identity (who you are, which groups, which department)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Postgres&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;http://127.0.0.1:5433&lt;/code&gt; (local only)&lt;/td&gt;
&lt;td&gt;Where everything is stored&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What is each piece (before we touch the keyboard)
&lt;/h2&gt;

&lt;p&gt;Think of it like a restaurant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keycloak&lt;/strong&gt; is the &lt;strong&gt;bouncer at the door&lt;/strong&gt;. It checks who you are, gives you a ticket (a &lt;em&gt;token&lt;/em&gt;) that says "this is Hassan, he's an &lt;em&gt;Operateur&lt;/em&gt;, he works in departments &lt;code&gt;100,10&lt;/code&gt;". Nobody enters the restaurant without this ticket.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The engine (Oumma)&lt;/strong&gt; is the &lt;strong&gt;kitchen&lt;/strong&gt;. It receives orders (a new process instance), works through the recipe (the process definition), pauses when a human must act, and resumes when the human answers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The web app&lt;/strong&gt; is the &lt;strong&gt;dining room + waiter&lt;/strong&gt;. It's what you see: login page, task lists, forms, the process designer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Postgres&lt;/strong&gt; is the &lt;strong&gt;ledger&lt;/strong&gt;. Every step, every form value, every audit entry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An LLM&lt;/strong&gt; (any OpenAI-compatible API — local or cloud) is the &lt;strong&gt;head chef's judgment&lt;/strong&gt;: it routes steps, answers questions, reads documents.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two things to know before we start:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Docker does the heavy lifting.&lt;/strong&gt; The engine, its database, and the mail server all run as containers — one command each. You do &lt;em&gt;not&lt;/em&gt; install Go or Postgres on your machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nothing here touches real customers.&lt;/strong&gt; The WhatsApp/Telegram/email tools run in &lt;em&gt;dry-run&lt;/em&gt; mode by default (they build the message, log it, pretend it was sent). This is a safe test environment.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Part 0 — Prerequisites
&lt;/h2&gt;

&lt;p&gt;You need, in order of importance:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A machine with Docker + Docker Compose.&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Mac/Windows:&lt;/em&gt; install &lt;a href="https://www.docker.com/products/docker-desktop/" rel="noopener noreferrer"&gt;Docker Desktop&lt;/a&gt;. That's it.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Linux VPS (5€–10€/month is enough):&lt;/em&gt; install the &lt;a href="https://docs.docker.com/engine/install/" rel="noopener noreferrer"&gt;Docker Engine + Compose plugin&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4 GB RAM minimum, 8 GB comfortable&lt;/strong&gt; (Keycloak is the heaviest piece, it likes ~1 GB).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Git&lt;/strong&gt; — to download the two repositories. (&lt;code&gt;brew install git&lt;/code&gt; / &lt;code&gt;sudo apt install git&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.js 20+&lt;/strong&gt; — only for the web app, if you run it in "development" mode (I recommend this for a test environment). &lt;code&gt;node -v&lt;/code&gt; should print v20 or higher.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An LLM endpoint&lt;/strong&gt; that speaks the OpenAI API format. Three easy options:

&lt;ul&gt;
&lt;li&gt;an &lt;strong&gt;OpenAI / Groq / Mistral&lt;/strong&gt; account + API key (fastest to try, a few cents of usage),&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;local Ollama&lt;/strong&gt; (free, &lt;code&gt;http://localhost:11434/v1&lt;/code&gt;),&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;local vLLM&lt;/strong&gt; server (free, what I use in production).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For this guide I'll use a generic key — swap in whatever you have.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Patience. The first build downloads ~1 GB of images.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Check your setup:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker version        &lt;span class="c"&gt;# prints client + server versions → OK&lt;/span&gt;
docker compose version
git &lt;span class="nt"&gt;--version&lt;/span&gt;
node &lt;span class="nt"&gt;-v&lt;/span&gt;               &lt;span class="c"&gt;# v20 or newer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;docker version&lt;/code&gt; complains about permissions (Linux), add your user to the &lt;code&gt;docker&lt;/code&gt; group and log out/in.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 1 — Keycloak: the bouncer
&lt;/h2&gt;

&lt;p&gt;We'll run the official Keycloak image with a persistent database. Create a folder and put everything in it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/oumma &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ~/oumma
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1.1 Start Keycloak
&lt;/h3&gt;

&lt;p&gt;Save this as &lt;code&gt;keycloak/docker-compose.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;keycloak&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;quay.io/keycloak/keycloak:latest&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;start-dev"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--http-port=8080"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;KEYCLOAK_ADMIN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;admin&lt;/span&gt;
      &lt;span class="na"&gt;KEYCLOAK_ADMIN_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ChangeMe_Admin_102030&lt;/span&gt;
      &lt;span class="na"&gt;KC_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;KC_DB_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jdbc:postgresql://postgres:5432/keycloak_db"&lt;/span&gt;
      &lt;span class="na"&gt;KC_DB_USERNAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;keycloak&lt;/span&gt;
      &lt;span class="na"&gt;KC_DB_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ChangeMe_KC_102030&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_healthy&lt;/span&gt;

  &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:16-alpine&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;keycloak_db&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;keycloak&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ChangeMe_KC_102030&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;kc-pg-data:/var/lib/postgresql/data&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD-SHELL"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pg_isready&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-U&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;keycloak"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;kc-pg-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;start-dev&lt;/code&gt; mode is for &lt;strong&gt;test environments only&lt;/strong&gt; — it prints everything and skips TLS. Never put this on the internet as-is.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;keycloak
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
docker compose logs &lt;span class="nt"&gt;-f&lt;/span&gt; keycloak   &lt;span class="c"&gt;# wait for "started in Xs" (≈30s first time)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;strong&gt;&lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;&lt;/strong&gt; → &lt;em&gt;Administration Console&lt;/em&gt; → log in with &lt;code&gt;admin&lt;/code&gt; / &lt;code&gt;ChangeMe_Admin_102030&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you see the console: &lt;strong&gt;congratulations, the hardest infra piece is done.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 Create the realm (a "tenant" inside Keycloak)
&lt;/h3&gt;

&lt;p&gt;In the admin console:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Crown icon (top-left) → &lt;strong&gt;Create realm&lt;/strong&gt; → name: &lt;code&gt;brief-test-realm&lt;/code&gt; → Create.&lt;/li&gt;
&lt;li&gt;Click into it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A &lt;em&gt;realm&lt;/em&gt; is a self-contained identity world: its own users, groups, clients. Oumma lives in one realm.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.3 Create the clients (the "apps" that are allowed to ask for tickets)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Client A — the web app&lt;/strong&gt; (this is what your browser logs in with):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Clients&lt;/em&gt; → &lt;strong&gt;Create client&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Client ID: &lt;code&gt;briefuserapp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Client type: &lt;strong&gt;Confidential&lt;/strong&gt; (or &lt;em&gt;Public&lt;/em&gt; — both work; the engine only &lt;em&gt;validates&lt;/em&gt; tokens, it doesn't log people in)&lt;/li&gt;
&lt;li&gt;Client authentication: off if Public&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Client&lt;/em&gt; tab → &lt;strong&gt;Valid redirect URIs&lt;/strong&gt;: &lt;code&gt;http://localhost:5173/*&lt;/code&gt;
(and &lt;code&gt;http://127.0.0.1:5173/*&lt;/code&gt; for good measure)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Authentication&lt;/em&gt; tab → leave defaults. The web app logs in via the &lt;strong&gt;resource owner password&lt;/strong&gt; flow through a small proxy — see below.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Client B — the engine&lt;/strong&gt; (a "service account" the backend uses for admin operations):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Clients&lt;/em&gt; → &lt;strong&gt;Create client&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Client ID: &lt;code&gt;oumma-admin&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Client authentication: &lt;strong&gt;on&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Copy the &lt;strong&gt;Client secret&lt;/strong&gt; from the &lt;em&gt;Credentials&lt;/em&gt; tab — you'll need it in the engine's &lt;code&gt;.env&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Service account roles&lt;/em&gt; tab → add: &lt;code&gt;realm-admin&lt;/code&gt; (for a test environment; a production setup would scope this down).&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why two clients?&lt;/strong&gt; The browser and the backend have different relationships with Keycloak: the browser needs to log in &lt;em&gt;people&lt;/em&gt;, the backend needs to be &lt;em&gt;trusted on its own&lt;/em&gt; (service account). Mixing them is a classic beginner security mistake.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  1.4 Create the groups (who can do what)
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Groups&lt;/em&gt; → &lt;strong&gt;Create group&lt;/strong&gt;. Make these four (the names are what Oumma's processes will reference):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Operateur
cashier
management
Designer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it — no roles needed for a first test. Oumma maps &lt;em&gt;groups&lt;/em&gt; to &lt;em&gt;process access&lt;/em&gt;: "the &lt;code&gt;Operateur&lt;/code&gt; group can act on the &lt;em&gt;confirm order&lt;/em&gt; step". (If you want to read the theory: episode 3 of the series.)&lt;/p&gt;

&lt;h3&gt;
  
  
  1.5 Create your first user (and the &lt;code&gt;department&lt;/code&gt; attribute)
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Users&lt;/em&gt; → &lt;strong&gt;Create user&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Username: &lt;code&gt;operateur10&lt;/code&gt;, email: anything, &lt;strong&gt;Enabled: on&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Credentials&lt;/em&gt; tab → set password: &lt;code&gt;password&lt;/code&gt; (test environment!)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Groups&lt;/em&gt; tab → join group: &lt;code&gt;Operateur&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Attributes&lt;/em&gt; tab → add one attribute:

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;department&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Value: &lt;code&gt;100,10&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This &lt;code&gt;department&lt;/code&gt; attribute is the one people miss.&lt;/strong&gt; Oumma can gate tasks per department ("only branch 10 sees these dossiers"). It travels inside the user's token. If the attribute is missing, the token says &lt;code&gt;department: null&lt;/code&gt; and department-gated lists will look empty. Comma-separated codes are supported (&lt;code&gt;100,10&lt;/code&gt; = the user belongs to two).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Repeat with two more users so you can test the full chain (this is what I use):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;User&lt;/th&gt;
&lt;th&gt;Group&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;department&lt;/code&gt; attr&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;operateur10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Operateur&lt;/code&gt; (+ &lt;code&gt;cashier&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;100,10&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;branchmanager_1001&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;management&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fake_admin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Designer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(none)&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Save the admin password of your Keycloak console somewhere safe. You'll use it to add users later.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 2 — The engine (the kitchen)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Clone it
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/oumma
git clone https://github.com/AHBench/oumma.git
&lt;span class="nb"&gt;cd &lt;/span&gt;oumma
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 Configure it
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
nano .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You only &lt;em&gt;really&lt;/em&gt; need to touch four blocks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# --- 1. The LLM (head chef) ---
&lt;/span&gt;&lt;span class="py"&gt;OPENAI_BASE_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https://api.groq.com/openai/v1     # or your Ollama: http://host.docker.internal:11434/v1&lt;/span&gt;
&lt;span class="py"&gt;OPENAI_MODEL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;llama-3.3-70b-versatile               # any model that endpoint serves&lt;/span&gt;
&lt;span class="py"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;sk-your-key-here&lt;/span&gt;
&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# --- 2. Keycloak (the bouncer) ---
&lt;/span&gt;&lt;span class="py"&gt;KEYCLOAK_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://host.docker.internal:8080      # host.docker.internal = "the machine running docker"&lt;/span&gt;
&lt;span class="py"&gt;KEYCLOAK_REALM&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;brief-test-realm&lt;/span&gt;
&lt;span class="py"&gt;KEYCLOAK_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;briefuserapp&lt;/span&gt;
&lt;span class="py"&gt;KEYCLOAK_ADMIN_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;oumma-admin&lt;/span&gt;
&lt;span class="py"&gt;KEYCLOAK_ADMIN_CLIENT_SECRET&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;paste-the-secret-from-1.3&lt;/span&gt;
&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# --- 3. Tools: keep dry-run ON for a test environment ---
&lt;/span&gt;&lt;span class="py"&gt;MCP_TOOLS_DRY_RUN&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything else in &lt;code&gt;.env.example&lt;/code&gt; has working defaults — the file is commented, read it once.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;host.docker.internal&lt;/code&gt;&lt;/strong&gt; — containers can't say "localhost" to mean &lt;em&gt;your&lt;/em&gt; machine (they'd mean &lt;em&gt;the container&lt;/em&gt;). On Docker Desktop (Mac/Windows) &lt;code&gt;host.docker.internal&lt;/code&gt; works out of the box. On Linux you need &lt;code&gt;extra_hosts: ["host.docker.internal:host-gateway"]&lt;/code&gt; — the shipped compose files already include it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2.3 Start it
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.yaml &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.local.yml up &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First build takes a few minutes (it compiles Go). Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8095/health
&lt;span class="c"&gt;# → {"status":"ok"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the whole engine. Postgres started with it (on &lt;code&gt;127.0.0.1:5433&lt;/code&gt;, loopback only), and all tables are &lt;strong&gt;created automatically&lt;/strong&gt; — there is no manual migration step. A reference snapshot of the full schema lives in the repo at &lt;code&gt;migrations/schema-reference-latest.sql&lt;/code&gt; if you're curious what it looks like.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 3 — The web app (the dining room)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Clone + install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
git clone https://github.com/AHBench/oumma-app.git
&lt;span class="nb"&gt;cd &lt;/span&gt;oumma-app
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Tell it where things are
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;.env.local&lt;/code&gt; in the same folder (the defaults already point at &lt;code&gt;localhost&lt;/code&gt; — this file only matters if your layout differs):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;VITE_PROCESS_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8095&lt;/span&gt;
&lt;span class="py"&gt;VITE_AUTH_BACKEND_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8095/api/auth&lt;/span&gt;
&lt;span class="py"&gt;VITE_USER_PROCESSES_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8095/api/user-processes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Beginner warning #1:&lt;/strong&gt; if you change a &lt;code&gt;VITE_&lt;/code&gt; variable, restart &lt;code&gt;npm run dev&lt;/code&gt; — Vite reads these at startup, not live.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3.3 Start it
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev
&lt;span class="c"&gt;# → Local: http://localhost:5173/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;strong&gt;&lt;a href="http://localhost:5173" rel="noopener noreferrer"&gt;http://localhost:5173&lt;/a&gt;&lt;/strong&gt; — you should see the login page. Log in with &lt;code&gt;operateur10&lt;/code&gt; / &lt;code&gt;password&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you land on the process apps list: &lt;strong&gt;the full stack is working.&lt;/strong&gt; 🎉&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 4 — First smoke test (2 minutes)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;As &lt;code&gt;operateur10&lt;/code&gt;: open the &lt;strong&gt;order-processing&lt;/strong&gt; sample process (it ships in the repo's &lt;code&gt;workflows/&lt;/code&gt; folder — the engine loads it at startup).&lt;/li&gt;
&lt;li&gt;You'll see a &lt;strong&gt;My Tasks&lt;/strong&gt; view. To get a task there, launch an instance (create a form in the &lt;em&gt;My Dossiers&lt;/em&gt; tab, or via the Request tab).&lt;/li&gt;
&lt;li&gt;Complete the first task with &lt;strong&gt;Yes — approve&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Log out, log in as &lt;code&gt;operateur10&lt;/code&gt; again (same user is also the cashier) → a &lt;strong&gt;manual review&lt;/strong&gt; task appears. Approve → the instance finishes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You've just executed a 4-step agentic process with 2 human steps, an HTTP validation step, and (dry-run) WhatsApp notifications. That's the whole product in 2 minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Troubleshooting — the 10 things that go wrong (and their fixes)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Almost always the cause → fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;curl :8095/health&lt;/code&gt; → connection refused&lt;/td&gt;
&lt;td&gt;Engine not up yet → &lt;code&gt;docker compose logs oumma&lt;/code&gt;. First build is slow; also check &lt;code&gt;docker compose ps&lt;/code&gt; for crashed containers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Login fails with &lt;code&gt;invalid_credentials&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Wrong user/password, &lt;strong&gt;or&lt;/strong&gt; you created the user in the &lt;em&gt;master&lt;/em&gt; realm instead of &lt;code&gt;brief-test-realm&lt;/code&gt; → check the realm selector (crown)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Login OK but &lt;strong&gt;no processes visible&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;The user's Keycloak &lt;strong&gt;groups&lt;/strong&gt; don't match the process's role requirements → join the user to &lt;code&gt;Operateur&lt;/code&gt; (Groups tab of the user)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Processes visible but &lt;strong&gt;My Dossiers / department lists empty&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Missing &lt;code&gt;department&lt;/code&gt; &lt;strong&gt;user attribute&lt;/strong&gt; (not a group!) → Attributes tab → &lt;code&gt;department&lt;/code&gt; = &lt;code&gt;10&lt;/code&gt;, then re-login (the value lives in the token)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Tasks complete but &lt;strong&gt;nothing advances&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;LLM not reachable from the engine → `docker compose logs oumma \&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Port already in use ({% raw %}&lt;code&gt;:8080&lt;/code&gt; taken)&lt;/td&gt;
&lt;td&gt;Something else uses 8080 → change the &lt;em&gt;host&lt;/em&gt; side: &lt;code&gt;"8081:8080"&lt;/code&gt; in the Keycloak compose, and update &lt;code&gt;KEYCLOAK_URL&lt;/code&gt; in the engine's &lt;code&gt;.env&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Web app loads but &lt;strong&gt;login page errors in the browser console&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;CORS or wrong auth URL → check &lt;code&gt;VITE_AUTH_BACKEND_URL&lt;/code&gt; points at &lt;code&gt;:8095/api/auth&lt;/code&gt; and the redirect URIs include &lt;code&gt;http://localhost:5173/*&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Designer chat doesn't answer&lt;/td&gt;
&lt;td&gt;The &lt;em&gt;designer&lt;/em&gt; LLM variables (&lt;code&gt;DESIGNER_OPENAI_*&lt;/code&gt;) are empty or broken → it falls back to the main LLM; check those vars too&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;npm run dev&lt;/code&gt; says &lt;code&gt;EADDRINUSE&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Another dev server on 5173 → &lt;code&gt;npm run dev -- --port 5174&lt;/code&gt; (then use 5174 everywhere in that session)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Everything worked, then broke after you &lt;strong&gt;changed a process in the designer&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;The browser caches process config aggressively → &lt;strong&gt;hard reload (Cmd/Ctrl+Shift+R) and re-login&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The universal debug trio&lt;/strong&gt;, when in doubt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose ps                     &lt;span class="c"&gt;# what's actually running?&lt;/span&gt;
docker compose logs &lt;span class="nt"&gt;--tail&lt;/span&gt; 50 oumma   &lt;span class="c"&gt;# what did the engine just say?&lt;/span&gt;
docker compose logs &lt;span class="nt"&gt;--tail&lt;/span&gt; 20 keycloak
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Security checklist before you share the environment
&lt;/h2&gt;

&lt;p&gt;Even a &lt;em&gt;test&lt;/em&gt; environment should be tidy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Keycloak admin password ≠ &lt;code&gt;admin&lt;/code&gt;/&lt;code&gt;admin&lt;/code&gt; (yours: &lt;code&gt;ChangeMe_Admin_102030&lt;/code&gt; — change it)&lt;/li&gt;
&lt;li&gt;[ ] Keycloak &lt;strong&gt;not exposed publicly&lt;/strong&gt; — bind to &lt;code&gt;127.0.0.1:8080&lt;/code&gt; if on a VPS, or put it behind a VPN/Tailscale&lt;/li&gt;
&lt;li&gt;[ ] Engine Postgres stays on &lt;code&gt;127.0.0.1:5433&lt;/code&gt; (loopback only) — it's there so &lt;em&gt;you&lt;/em&gt; can peek with a DB tool&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;MCP_TOOLS_DRY_RUN=true&lt;/code&gt; until the day you deliberately wire real WhatsApp/Telegram credentials&lt;/li&gt;
&lt;li&gt;[ ] Rotate any LLM API key that was ever pasted into a chat, a screenshot, or a repo&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;You now own a full agentic workflow platform on your machine. The natural next episodes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Episode 2&lt;/strong&gt; — design your first process in the designer (no code)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Episode 3&lt;/strong&gt; — how roles, groups and permissions actually gate tasks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Episode 5&lt;/strong&gt; — a full day in the life of a normal user&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Episode 7&lt;/strong&gt; — wiring real external systems (MCP-like tools)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The whole series is cross-linked on Dev.to — and the engine's README has the production-oriented notes (TLS, real Postgres sizing, monitoring).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Found a step that fails on your machine? That's a bug report waiting to happen — the issues tab is open, beginners especially welcome. This guide is only as good as the installs it survives.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>devops</category>
      <category>keycloak</category>
      <category>workflow</category>
    </item>
    <item>
      <title>You Know n8n (or Camunda, or Zapier). Here's What's Different About Oumma</title>
      <dc:creator>Benchouia Ahmed Abdelhakim</dc:creator>
      <pubDate>Thu, 22 Oct 2026 06:31:21 +0000</pubDate>
      <link>https://dev.to/benchouia_ahmedabdelhaki/you-know-n8n-or-camunda-or-zapier-heres-whats-different-about-oumma-1705</link>
      <guid>https://dev.to/benchouia_ahmedabdelhaki/you-know-n8n-or-camunda-or-zapier-heres-whats-different-about-oumma-1705</guid>
      <description>&lt;h1&gt;
  
  
  You Know n8n (or Camunda, or Zapier). Here's What's Different About Oumma
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You've automated the easy stuff. The hard stuff — the stuff with patients, approvals, money and audit trails — still runs on email and "call me when it's ready." If you run n8n, Camunda, or Zapier, this article is the honest comparison: where those platforms stop, and what it takes to cross the line into regulated business processes.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You already know the category. &lt;strong&gt;n8n&lt;/strong&gt; gave you visual automations with 400+ integrations. &lt;strong&gt;Zapier&lt;/strong&gt; glued your SaaS stack together in an afternoon. &lt;strong&gt;Camunda&lt;/strong&gt; gave you real BPMN in your production systems. All of them are excellent — for what they are: &lt;strong&gt;automation of steps&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Oumma is a different animal: an &lt;strong&gt;agentic workflow platform for business processes where humans are the primary workers and AI is the orchestrator around them&lt;/strong&gt;. Not the other way around. That one sentence explains most of the design. Here's the breakdown on the subjects that actually matter when a workflow touches real people.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Human-in-the-loop: a citizen, not a "wait node"
&lt;/h2&gt;

&lt;p&gt;In n8n the human appears when the workflow runs out of machine: you bolt on a form, an email, an external ticket system, and then a &lt;strong&gt;polling webhook&lt;/strong&gt; waits for a human to do something outside the platform. The human's work is &lt;em&gt;next to&lt;/em&gt; the automation — and the state of that work lives somewhere else.&lt;/p&gt;

&lt;p&gt;In Camunda, human tasks are first-class (a &lt;code&gt;userTask&lt;/code&gt; in BPMN) — that's the closest relative. But the task &lt;strong&gt;assignment model is yours to build&lt;/strong&gt;: who can see it, who can act, what they can do on the artifacts — all of it is code you write against the Task API.&lt;/p&gt;

&lt;p&gt;In Oumma, the human is the &lt;strong&gt;main loop of the process&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiwissnqc8h5h0enkpjwm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiwissnqc8h5h0enkpjwm.png" alt="A normal user's My Tasks view: every open task, its process, and the actions allowed for their role" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A "dossier" is a &lt;strong&gt;process instance&lt;/strong&gt;, and the user's home screen is their &lt;strong&gt;task queue&lt;/strong&gt; — the same queue the engine maintains in Postgres, not a view over some external ticket system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permission is per step and per action&lt;/strong&gt;: each step declares which role can &lt;code&gt;complete&lt;/code&gt; it, which can &lt;code&gt;comment&lt;/code&gt;, which can &lt;code&gt;attach&lt;/code&gt;. The engine re-checks all of it &lt;strong&gt;server-side&lt;/strong&gt; on every completion — the UI hiding a button is cosmetics, not security.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forms are pinned to the step&lt;/strong&gt; (version-pinned, even — an instance keeps the form structure it was launched with), so the person sees exactly what the process needs at that moment, in three languages (EN/FR/AR in the shipped i18n).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Notifications follow the user's own tasks&lt;/strong&gt;: new task, task moved, process advanced — the bell is driven by the engine's state, not by a cron email.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The practical difference: with n8n you &lt;em&gt;built a workflow that occasionally asks a human for input&lt;/em&gt;; with Oumma you have a &lt;strong&gt;process the humans work, with the machine doing everything else&lt;/strong&gt; — documents, routing, integrations, reminders.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Controlled automation: BPM discipline instead of free-form wiring
&lt;/h2&gt;

&lt;p&gt;n8n and Zapier optimize for &lt;strong&gt;developer velocity&lt;/strong&gt;: drag nodes, connect, run. The freedom is the point — and it's exactly why, at scale, nobody can tell you what a workflow actually &lt;em&gt;does&lt;/em&gt;, who approved it, or what changed when. Your "processes" are node graphs with the semantics of a shell script: no gateways, no roles, no version, no audit of the design itself.&lt;/p&gt;

&lt;p&gt;Camunda has the formalism (BPMN 2.0) but you pay for it in modeling tools, a separate runtime, and a Java/Zeebe operational footprint.&lt;/p&gt;

&lt;p&gt;Oumma takes the &lt;strong&gt;BPMN core of what regulated processes actually need&lt;/strong&gt; — tasks, exclusive gateways, parallel fork/join, start/end — and ships it as a product, with the controls an enterprise needs around it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnmi7wn3xy48kzyut9zb2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnmi7wn3xy48kzyut9zb2.png" alt="The interactive BPMN canvas: exclusive gateway routing high-value orders to a manager review" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The design &lt;em&gt;is&lt;/em&gt; the source of truth&lt;/strong&gt; — one YAML document per process, versioned in Postgres, rendered on the interactive canvas. No drift between a modeling tool and a runtime: there is only one artifact.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single pending version + semantic versioning&lt;/strong&gt;: every change lands in one pending document; the engine computes major/minor/patch from &lt;em&gt;what&lt;/em&gt; changed (topology = major, roles/step ids = minor, labels = patch). &lt;strong&gt;Deploying is a human act&lt;/strong&gt; in the Versions tab — the AI can propose, never deploy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instance pinning&lt;/strong&gt;: instances running on v4.0.5 keep their v4.0.5 semantics even after you deploy v5. No surprise behavior changes mid-flight — the thing that makes BPM platforms trustworthy in production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic first, AI second&lt;/strong&gt;: single-successor hops and unconditional fork/join merges route &lt;strong&gt;with zero LLM tokens&lt;/strong&gt; — no model in the money path, no latency, no cost. The LLM appears only where a decision is genuinely undecidable (and even then its output is a structured choice against your defined branches, written into the process data).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool steps are zero-token system tasks&lt;/strong&gt;: a Telegram notification, a Gmail send, a WhatsApp alert, a generic HTTP call — configured in the designer, executed deterministically from process data. In n8n these are nodes; in Oumma they're &lt;em&gt;engine steps with an audit trail&lt;/em&gt;, dry-run by default so nobody accidentally fires production messages during a redesign.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The practical difference: an n8n workspace is a collection of clever automations; an Oumma deployment is a &lt;strong&gt;set of governed, versioned, auditable business processes&lt;/strong&gt; — the difference between "it automates" and "the audit can trace it."&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Roles: enterprise identity &lt;em&gt;is&lt;/em&gt; the permission model
&lt;/h2&gt;

&lt;p&gt;This is where the no-code tools fall off the map. In n8n, "who can run/edit this workflow" is a &lt;strong&gt;workspace seat&lt;/strong&gt; — there are no per-step roles, no claim that only a &lt;code&gt;manager&lt;/code&gt; may complete the &lt;em&gt;manager_review&lt;/em&gt; step of &lt;em&gt;your&lt;/em&gt; process. In Zapier, it's an account. Your real org chart (the one in your IdP) simply doesn't exist inside the platform.&lt;/p&gt;

&lt;p&gt;Camunda has user/role groups, but wiring them into a real enterprise IdP — SSO, group sync, claims — is integration work you build and maintain.&lt;/p&gt;

&lt;p&gt;Oumma's answer: &lt;strong&gt;the platform has no user database of its own.&lt;/strong&gt; Identity is Keycloak; the platform validates the bearer token, reads the groups and department from the claims, and that's it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkardrct5ef5kbq69y9ki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkardrct5ef5kbq69y9ki.png" alt="The Roles &amp;amp; Permissions tab: each step's allowed role and its permitted actions, defined in the design" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One login, every system.&lt;/strong&gt; The same token authenticates the workspace, the designer, the agent, and the engine APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Roles are defined *in the process design&lt;/strong&gt;* (the Roles tab: which role per step, which actions), and synced to the IdP as groups. When you change a role's scope in the design, the sync follows — no separate identity administration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enforcement is server-side and claim-based&lt;/strong&gt;: the engine re-validates the token on every task completion, comment and attachment. A user's &lt;em&gt;token&lt;/em&gt; is the sole source of who they are; there is no app-side "trust me" path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-service onboarding with governance&lt;/strong&gt;: users register from the login page, activate via an emailed one-time token (Mailpit in the dev stack), and get a &lt;strong&gt;role-based monthly token quota&lt;/strong&gt; — normal users 20k, designers 50k — enforced on every AI call, with a claim-a-top-up flow that emails the administrator. The platform meters its own AI usage per user, per department, per process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The practical difference: in n8n you explain your org chart to the platform (or don't, and ship it); in Oumma the &lt;strong&gt;org chart already exists&lt;/strong&gt; — the platform just reads it and enforces it on every single action.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. The other differences that compound
&lt;/h2&gt;

&lt;p&gt;The three above are the headline; these are the ones people discover in week two:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The AI designs the process — and you still hold the pen.&lt;/strong&gt;&lt;br&gt;
Ask the designer chat &lt;em&gt;"add a manager review for orders above 1000 euros"&lt;/em&gt; and it edits the actual design document: new task, gateway, condition, role, form — all in the one pending version, visible on the canvas instantly, draggable if you disagree, and only live when &lt;strong&gt;you&lt;/strong&gt; deploy. In n8n the AI (where it exists) edits node graphs; here it edits a governed BPMN artifact with versions, semver and a deploy gate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every AI call is metered and attributable.&lt;/strong&gt;&lt;br&gt;
Tokens are captured per call, per user, per department, per process, with a monthly cost rollup. The badge in the UI shows what &lt;em&gt;this process&lt;/em&gt; has consumed this month. No LLM invoice mystery — the ledger is a Postgres table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One port, one binary, one Postgres.&lt;/strong&gt;&lt;br&gt;
The whole platform — engine, auth proxy, forms, documents, agent, designer APIs, even the Mailpit inbox (proxied at &lt;code&gt;/mailpit/&lt;/code&gt;) — is &lt;strong&gt;one Go binary on one port&lt;/strong&gt; with a Postgres database. No node cluster, no worker fleet, no separate identity service, no separate task service. You can read the whole backend in an afternoon; the entire source is Apache-2.0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The app knows its place.&lt;/strong&gt;&lt;br&gt;
The React workspace has &lt;strong&gt;zero LLM configuration&lt;/strong&gt; — no model names, no endpoints, no keys. Every AI capability (designer chat, AI Assist, document analysis) flows through the engine, where it's quota-gated and logged. That's why you can swap your LLM backend by editing one env var in docker compose and nothing in the app changes.&lt;/p&gt;




&lt;h2&gt;
  
  
  So, who should care?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;You're running…&lt;/th&gt;
&lt;th&gt;You'll hit this wall…&lt;/th&gt;
&lt;th&gt;Oumma is for you when…&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;n8n / Zapier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The workflow needs a real human step, a real approval chain, or an auditor will ask "prove who did what"&lt;/td&gt;
&lt;td&gt;your automation is a &lt;em&gt;business process&lt;/em&gt; (onboarding, claims, orders with thresholds) rather than an integration glue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Camunda&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You'd rather not operate a Java/Zeebe platform + build the identity and UI layers yourself&lt;/td&gt;
&lt;td&gt;you want the same BPMN discipline with a working UI, IdP integration, metered AI and one-port deploy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Spreadsheet + email + "call me"&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nothing above, and your process still works — at the price of every handoff&lt;/td&gt;
&lt;td&gt;you want the process to exist &lt;em&gt;somewhere&lt;/em&gt; — designed, versioned, audited, and mostly self-driving&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The honest caveat: if you're gluing two SaaS tools together with no humans, no approvals and no compliance questions, &lt;strong&gt;stay on n8n or Zapier&lt;/strong&gt; — that's their job and they do it well. Oumma earns its keep when the workflow &lt;em&gt;is&lt;/em&gt; the business: regulated, multi-role, long-lived, and full of people.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Everything in this article is reproducible from the repos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Engine &amp;amp; backend&lt;/strong&gt; (Go): &lt;a href="https://github.com/AHBench/oumma" rel="noopener noreferrer"&gt;github.com/AHBench/oumma&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agentic workspace&lt;/strong&gt; (React): &lt;a href="https://github.com/AHBench/oumma-app" rel="noopener noreferrer"&gt;github.com/AHBench/oumma-app&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both Apache-2.0. &lt;code&gt;docker compose up&lt;/code&gt; — one port, one Postgres — and you can watch a human task get created, permission-checked, completed, and routed, with the AI handling everything around it.&lt;/p&gt;

&lt;p&gt;This is the first article of the &lt;strong&gt;Oumma series&lt;/strong&gt; on &lt;a href="https://dev.to/tag/oumma"&gt;Dev.to&lt;/a&gt; — the follow-ups take you inside the platform: the designer's tabs, roles &amp;amp; permissions, forms, the normal user's day, AI Assist, external integrations, versioning, the engine under the hood, and identity &amp;amp; quotas. New articles land on the series page as they publish — follow the tag so you don't miss them.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>workflow</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Build a Business Process by Talking to an AI — Oumma Designer Mode, Walkthrough with the Order Processing Process</title>
      <dc:creator>Benchouia Ahmed Abdelhakim</dc:creator>
      <pubDate>Sat, 17 Oct 2026 21:03:11 +0000</pubDate>
      <link>https://dev.to/benchouia_ahmedabdelhaki/build-a-business-process-by-talking-to-an-ai-oumma-designer-mode-walkthrough-with-the-order-15n8</link>
      <guid>https://dev.to/benchouia_ahmedabdelhaki/build-a-business-process-by-talking-to-an-ai-oumma-designer-mode-walkthrough-with-the-order-15n8</guid>
      <description>&lt;h1&gt;
  
  
  Build a Business Process by Talking to an AI — Oumma Designer Mode, Walkthrough with the Order Processing Process
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Building the "Order Processing" process in the Oumma Designer: half by clicking and dragging on a BPMN canvas, half by typing plain-English prompts into a design chat — and why the deployment button is the only one the AI cannot press.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we end up with by the end of this article:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;start → validate_order (inventory API) → manual_review (cashier)
        → [&amp;gt;$1000] manager_review (management) → process_payment (payment API) → end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;tool step&lt;/strong&gt; that calls the inventory API with zero LLM tokens at runtime&lt;/li&gt;
&lt;li&gt;two &lt;strong&gt;human review steps&lt;/strong&gt; owned by different roles, with a conditional business rule&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;forms&lt;/strong&gt; the people on each step will actually fill (EN/FR/AR labels)&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;trilingual label catalog&lt;/strong&gt;, a menu icon, and role permissions synced to identity&lt;/li&gt;
&lt;li&gt;one &lt;strong&gt;pending design version&lt;/strong&gt; — and a human who presses &lt;em&gt;Deploy&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is article 1 of the &lt;strong&gt;Oumma series&lt;/strong&gt;. The next one tears apart every tab of the design view; later ones cover roles &amp;amp; permissions end-to-end, the normal user's day, AI Assist, external integrations, versioning/pinning, and the Go + PostgreSQL engine under the hood.&lt;/p&gt;




&lt;p&gt;If you have ever been asked to digitize a business procedure, you know the shape of the job: a flowchart on a whiteboard, three roles who disagree about who approves what, a form that nobody agrees on, and an integration ("just ping the inventory API") that ends up living in someone's head.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Oumma&lt;/strong&gt; is an agentic workflow platform: processes run as engines, tasks are owned by roles, and an LLM handles the parts that need judgment. The part I want to show you is the &lt;strong&gt;Designer mode&lt;/strong&gt; — where a process &lt;em&gt;comes into existence&lt;/em&gt; — using a real scenario: building the &lt;strong&gt;Order Processing&lt;/strong&gt; process from an empty project, mixing &lt;strong&gt;manual canvas work&lt;/strong&gt; with &lt;strong&gt;AI prompts&lt;/strong&gt;, exactly as it happens in the product.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The prompts below are the actual tool vocabulary of the designer agent. Every AI proposal is shown to you as a diff-like tool call and only lands after you press &lt;strong&gt;Apply&lt;/strong&gt;. Deployment is never an agent action.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  0. The two seats at the table
&lt;/h2&gt;

&lt;p&gt;Before the scenario, the two actors you are coordinating as a designer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The canvas&lt;/strong&gt; — an interactive BPMN view: human steps (👤, with their role), system steps (⚙), start/end nodes, parallel fork/join gateways. Click a step to configure it; &lt;strong&gt;drag any step anywhere&lt;/strong&gt; to untangle the diagram; four layout algorithms (left→right, top→down, circular, force-directed).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The design chat&lt;/strong&gt; — an agent with a described, MCP-style tool catalog: create/rename processes, add steps, connect them, build forms, assign roles and permissions, set trilingual labels, plug in external tools, manage versions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything the two of them do lands in a &lt;strong&gt;single pending version&lt;/strong&gt;. You deploy it when it is ready; running dossiers keep the version they started on (version pinning).&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Start from a blank project (AI)
&lt;/h2&gt;

&lt;p&gt;Sign in with your enterprise identity (Keycloak):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvmwmdx6gifsptit4a3ii.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvmwmdx6gifsptit4a3ii.png" alt="Sign in" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Designer-role account gets the &lt;strong&gt;mode orientation&lt;/strong&gt; right after login — pick &lt;strong&gt;Designer mode&lt;/strong&gt; for the full design experience, or &lt;strong&gt;Normal mode&lt;/strong&gt; to work the processes like everyone else (you can switch any time from the top bar):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftz9hjf2vts7to2hrxrpv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftz9hjf2vts7to2hrxrpv.png" alt="Mode orientation dialog" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, in the designer chat, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a new process called "Order Processing" — it validates customer
orders, checks inventory, gets reviewed, then charges the customer.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent responds with the tool call it wants to run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ "name": "create_process",
  "args": { "processName": "Order Processing",
            "processId": "order-processing",
            "processDescription": "Validates customer orders, checks inventory,
                                   reviews and charges the customer." } }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Apply.&lt;/strong&gt; The project appears in the left menu — scaffolded with just &lt;strong&gt;start → end&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb94fv6lhkytcvrfe26hr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb94fv6lhkytcvrfe26hr.png" alt="Designer workspace — process list" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is the whole trick of "new process = project": the chat now has a canvas to build on immediately.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Designers can also rename the &lt;em&gt;display name&lt;/em&gt; of a process at any time&lt;br&gt;
(works on deployed processes — it is a label), and change the technical&lt;br&gt;
&lt;code&gt;process_id&lt;/code&gt; while the project was never deployed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2. The automatic first mile (AI + tool step)
&lt;/h2&gt;

&lt;p&gt;The first real step is not a person — it is an API call: validate the order and check inventory. This is a &lt;strong&gt;tool step&lt;/strong&gt; (the MCP-like system tasks: Gmail, Telegram, WhatsApp, generic HTTP):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add a system step "validate_order" that POSTs the order to our
inventory service. It takes order_id, items and customer_id from the
process context.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent builds it with the &lt;code&gt;add_tool_task&lt;/code&gt; tool — a &lt;code&gt;mcp.http.request&lt;/code&gt;&lt;br&gt;
system task whose &lt;strong&gt;inputs map tool parameters to process-context keys&lt;/strong&gt;&lt;br&gt;
(&lt;code&gt;order_id ← $order_id&lt;/code&gt;, …). Two properties matter:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Zero LLM tokens at runtime.&lt;/strong&gt; When an order flows through this step, the engine resolves the &lt;code&gt;$context&lt;/code&gt; keys and fires a plain HTTP call. Deterministic, repeatable, free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dry-run by default.&lt;/strong&gt; Until you flip &lt;code&gt;MCP_TOOLS_DRY_RUN=false&lt;/code&gt; and put real endpoints/credentials on the task, the engine builds the exact payload, logs it and simulates success — you can design and test flows without any integration being live.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  3. Put people on the flow (manual)
&lt;/h2&gt;

&lt;p&gt;Open the project's &lt;strong&gt;Process design&lt;/strong&gt; — the canvas shows the live (pending) design in BPMN notation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1nytfzrxjoq7s958nvah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1nytfzrxjoq7s958nvah.png" alt="BPMN canvas" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the diagram needs humans. This is where I grab the mouse:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Toolbar → "Add human step"&lt;/strong&gt; → &lt;code&gt;manual_review&lt;/code&gt;, role &lt;strong&gt;cashier&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Click &lt;code&gt;manual_review&lt;/code&gt;&lt;/strong&gt; → the right-hand configuration panel opens → set the role, the description ("Operations team reviews the order before payment"), save:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4k2s8td93z0nwphw8r0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4k2s8td93z0nwphw8r0m.png" alt="Step configuration panel" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Connect&lt;/strong&gt; — click &lt;em&gt;Connect&lt;/em&gt; on &lt;code&gt;validate_order&lt;/code&gt;, then click &lt;code&gt;manual_review&lt;/code&gt;: the edge appears. Click &lt;em&gt;Connect&lt;/em&gt; on &lt;code&gt;start&lt;/code&gt; → &lt;code&gt;validate_order&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drag&lt;/strong&gt; &lt;code&gt;manual_review&lt;/code&gt; down and right to open breathing room — the connections follow. For a busy design this free placement is how you keep the BPMN readable (a &lt;strong&gt;Reset layout&lt;/strong&gt; button returns everything to the algorithm).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clicking around is still the fastest way to make small, precise edits — the AI is for the &lt;em&gt;shaping&lt;/em&gt;, the mouse is for the &lt;em&gt;furniture&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. The business rule (AI)
&lt;/h2&gt;

&lt;p&gt;The heart of order processing is a conditional: big orders need a manager.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Orders above $1000 must also be approved by a manager before payment.
Add a "manager_review" step for the management role and route
manual_review to it when the amount exceeds 1000 dollars.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent proposes, in sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ "name": "add_task", "args": { "name": "manager_review", "group": "management" } }
{ "name": "add_edge", "args": { "from": "manual_review", "to": "manager_review",
  "condition": "order amount exceeds $1000 — route to manager for approval before payment" } }
{ "name": "add_edge", "args": { "from": "manager_review", "to": "process_payment" } }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You apply each one. The canvas re-renders — you can see the exclusive branch appear, and you can drag &lt;code&gt;manager_review&lt;/code&gt; aside so the main path stays a straight line.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Routing note: branches with conditions are decided by the LLM at&lt;br&gt;
runtime; single-successor hops and unconditional fork/join merges are&lt;br&gt;
routed &lt;strong&gt;deterministically, with zero tokens&lt;/strong&gt;. The engine only spends&lt;br&gt;
intelligence where judgment is actually needed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  5. Close the loop: payment and exit (AI)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;After an approval, charge the customer with a system step
"process_payment" that calls the payment service, then finish.
Connect both review steps to it and it to the end.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;process_payment&lt;/code&gt; step is another tool step (HTTP &lt;code&gt;POST&lt;/code&gt; to the&lt;br&gt;
payment service, inputs &lt;code&gt;order_id&lt;/code&gt;, &lt;code&gt;amount&lt;/code&gt;, &lt;code&gt;payment_method&lt;/code&gt; ← context).&lt;br&gt;
All tool steps of the project are visible in the &lt;strong&gt;Tools&lt;/strong&gt; tab:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo1zk9pnafk9oqd8p4om7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo1zk9pnafk9oqd8p4om7.png" alt="Tools tab" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After three applies, the topology is the real one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;start → validate_order ─┬→ manual_review ─┬→ (&amp;gt;$1000) manager_review ─┬→ process_payment → end
                         │                 ├→ (approved, ≤$1000) ─────┤
                         └→ (invalid) ─────┴→ (rejected) → end        └→ (manager rejected) → end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. The forms people will actually fill (AI)
&lt;/h2&gt;

&lt;p&gt;A step is only as good as its form. The designer builds them conversationally — the chat JSON becomes a real form step (field types, required flags, labels in EN/FR/AR):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build the form for the launch: customer name, customer id, items
(list), total amount (number, required), payment method.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Give manual_review and manager_review a small form: the order summary
(read context), a decision (approve/reject, required) and reviewer notes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each lands via &lt;code&gt;update_form_step&lt;/code&gt;. In the &lt;strong&gt;Forms&lt;/strong&gt; tab you can now inspect every step's form visually and fix any field by hand:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy1wodv9n9m4gw07p412v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy1wodv9n9m4gw07p412v.png" alt="Forms tab" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Labels, icon, polish (manual + AI)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Search items tab&lt;/strong&gt; — the trilingual label catalog. Type &lt;em&gt;"label the 'total amount' field 'Montant total' in French and 'المبلغ الإجمالي' in Arabic"&lt;/em&gt; — or just edit the rows in the UI. The app resolves &lt;strong&gt;every&lt;/strong&gt; UI label through this catalog:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffxjgqczta1jzji31cl8k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffxjgqczta1jzji31cl8k.png" alt="Search items tab (EN/FR/AR)" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Icon&lt;/strong&gt; — the header's icon picker (284 icons, searchable): a 💳 card fits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Roles tab&lt;/strong&gt; — confirm the three roles (launch role &lt;strong&gt;Operateur&lt;/strong&gt;, &lt;strong&gt;cashier&lt;/strong&gt;, &lt;strong&gt;management&lt;/strong&gt;) and their per-step permissions. Role changes can be synced to the identity provider (Keycloak groups) from here:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0ar2a6cicn7j7pv5rz9j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0ar2a6cicn7j7pv5rz9j.png" alt="Roles &amp;amp; Permissions tab" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8. The part the AI may not do for you (human)
&lt;/h2&gt;

&lt;p&gt;Open the &lt;strong&gt;Design versions&lt;/strong&gt; tab. The single &lt;strong&gt;pending version&lt;/strong&gt; shows every accumulated change with an automatic semantic version — a new task is a &lt;em&gt;major&lt;/em&gt;, a role change a &lt;em&gt;minor&lt;/em&gt;, a label tweak a &lt;em&gt;patch&lt;/em&gt;. You read it, then press &lt;strong&gt;Deploy&lt;/strong&gt; (or &lt;strong&gt;Discard&lt;/strong&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2arcumkduu4jisfwl0gt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2arcumkduu4jisfwl0gt.png" alt="Design versions tab" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That asymmetry is deliberate:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent can do&lt;/th&gt;
&lt;th&gt;Only a human can do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Propose any design change (with your &lt;strong&gt;Apply&lt;/strong&gt; on each)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Deploy&lt;/strong&gt; the version&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create, rename, rewire, label, tool-wire&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Discard&lt;/strong&gt; the pending version&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inspect versions, list tasks, explain the design&lt;/td&gt;
&lt;td&gt;Delete a project&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And after deployment, &lt;strong&gt;running instances stay pinned to the version they started on&lt;/strong&gt; — your in-flight orders keep their exact behavior while v2 serves the next launches.&lt;/p&gt;

&lt;h2&gt;
  
  
  And the people it was built for
&lt;/h2&gt;

&lt;p&gt;Deployed, the process disappears into everyday work. A cashier or customer-relations operator signs in, picks &lt;strong&gt;Normal mode&lt;/strong&gt;, and never sees a designer surface — just their processes, their dossiers, their tasks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyrdxfbi1dweaqd5d8sn2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyrdxfbi1dweaqd5d8sn2.png" alt="Normal-mode workspace" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh1bhzh2uz188dlarcx4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh1bhzh2uz188dlarcx4u.png" alt="A normal user opens the same process" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Their &lt;strong&gt;My Tasks&lt;/strong&gt; tab shows exactly the steps that are waiting on &lt;em&gt;their&lt;/em&gt; role — &lt;code&gt;manual_review&lt;/code&gt; for cashiers, &lt;code&gt;manager_review&lt;/code&gt; for management — with only the actions their permissions allow:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv40av0oewkyhqe4i5ksq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv40av0oewkyhqe4i5ksq.png" alt="My Tasks — role-scoped" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What this workflow buys you
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Speed where it matters&lt;/strong&gt; — topology, forms, labels, tools: described once, applied as validated writes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safety where it counts&lt;/strong&gt; — nothing applies without a confirm, nothing deploys without a click, and the design is BPMN-validated before it may be deployed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An auditable design history&lt;/strong&gt; — every version, its semver and its document, stored in Postgres alongside execution states and the LLM usage ledger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A canvas that respects you&lt;/strong&gt; — the AI's changes appear on the same live canvas you drag on; you can always take the mouse back.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result of the scenario is a shippable, role-gated, API-integrated Order Processing process — built in one sitting, mostly by asking.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Article 2 of the Oumma series on &lt;a href="https://dev.to/tag/oumma"&gt;Dev.to&lt;/a&gt; — it starts with &lt;a href="//01-why-oumma-vs-n8n-camunda-zapier.md"&gt;Oumma vs n8n/Camunda/Zapier&lt;/a&gt;. The designer agent's tool catalog, versioning and pinning are all visible in the &lt;a href="https://github.com/AHBench/oumma" rel="noopener noreferrer"&gt;oumma&lt;/a&gt; backend; the canvas and chat in the &lt;a href="https://github.com/AHBench/oumma-app" rel="noopener noreferrer"&gt;oumma-app&lt;/a&gt; frontend — both Apache-2.0.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>workflow</category>
      <category>architecture</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Stop Hardcoding Workflows: How We Turned Kogito Into a Full-Scale Automation Platform</title>
      <dc:creator>Benchouia Ahmed Abdelhakim</dc:creator>
      <pubDate>Sun, 07 Jun 2026 23:52:34 +0000</pubDate>
      <link>https://dev.to/benchouia_ahmedabdelhaki/stop-hardcoding-workflows-how-we-turned-kogito-into-a-full-scale-automation-platform-5fo4</link>
      <guid>https://dev.to/benchouia_ahmedabdelhaki/stop-hardcoding-workflows-how-we-turned-kogito-into-a-full-scale-automation-platform-5fo4</guid>
      <description>&lt;h2&gt;
  
  
  The Spark: What’s Missing in Cloud-Native BPMN?
&lt;/h2&gt;

&lt;p&gt;If you’ve ever used the Kogito VS Code extension to design cloud-native workflows, you already know it’s an incredibly powerful tool. Built on top of Quarkus and Drools, it’s designed from the ground up for Kubernetes speed and efficiency.&lt;br&gt;
But as my co-founder and I started deploying workflows into our production environments, we hit a major architectural roadblock.&lt;br&gt;
Kogito is exceptional at handling automated, high-throughput system tasks. However, in the real world, &lt;strong&gt;most business processes still heavily rely on the human factor&lt;/strong&gt;. Whether it’s an operator validating a high-value transaction, a team leader launching a complex workflow, or even a "Human-in-the-Loop" architecture auditing an AI agent's decisions, human intervention provides the governance, trust, and confidence that enterprises require.&lt;br&gt;
Out of the box, building a seamless, end-to-end web interface for human tasks in Kogito felt like putting a puzzle together with missing pieces. So, we decided to build what was missing.&lt;br&gt;
What started as a simple idea to wrap Kogito in a clean web UI evolved into FlowIQ—a comprehensive enterprise platform featuring dynamic forms, Role-Based Access Control (RBAC), Kafka event streaming, and robust document management, task management and many more.&lt;/p&gt;

&lt;p&gt;In this first episode, I’ll take you behind the scenes of how we kicked off the architecture and built our core user portal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture: Managing Governance and Security
&lt;/h2&gt;

&lt;p&gt;To ground our idea, we designed a classic enterprise use case: a digital &lt;strong&gt;banking onboarding process&lt;/strong&gt;.&lt;br&gt;
We needed a system that could handle both the launching phase of a process and its execution phase whenever a human operator needed to step in. This led us to build our first core component: the User App.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Enterprise Auth &amp;amp; RBAC&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Security wasn't an afterthought. We integrated FlowIQ natively with Keycloak. This allows enterprises to effortlessly hook up third-party authentication providers like Active Directory (LDAP).&lt;br&gt;
Once authenticated, our backend calculates the user's explicit privileges via &lt;strong&gt;RBAC (Role-Based Access Control)&lt;/strong&gt;. This dictates exactly which processes they can see, which forms they can access, and what actions they are allowed to take.&lt;br&gt;
When a user logs in, they are greeted by a clean, centralized workspace:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1mv1vztxauqojhdfbt8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1mv1vztxauqojhdfbt8.png" alt=" " width="800" height="412"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsuoca07ey6he93rfgjv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsuoca07ey6he93rfgjv.png" alt=" " width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From this single portal, authorized users can check their tasks, manage attached documents, investigate active process executions, create dossiers, or spin up new workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic Forms and Dossier Management
&lt;/h2&gt;

&lt;p&gt;Let’s walk through what happens when an operator launches a new customer onboarding workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Creating a Dossier&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the user’s RBAC permissions allow it, they can initiate a new dossier. Instead of hardcoding UI forms for every single BPMN process, we built a &lt;strong&gt;dynamic form engine&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnbm8yr9girnlvfpjkqz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnbm8yr9girnlvfpjkqz.png" alt=" " width="799" height="412"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2numregpftug0thqtzyr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2numregpftug0thqtzyr.png" alt=" " width="799" height="414"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftco3mfsgigdw2lfeb9pi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftco3mfsgigdw2lfeb9pi.png" alt=" " width="800" height="417"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgmakq29j072xma1bm82z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgmakq29j072xma1bm82z.png" alt=" " width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The UI reads the data schema defined by the Kogito process design and renders the form dynamically. The FlowIQ backend saves these form configurations and tracks their version history over time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. State Tracking &amp;amp; Parallel Execution&lt;/strong&gt;&lt;br&gt;
Once a user successfully creates a dossier, they can view it inside their form actions list. If they make changes or update a field before official execution, every single modification is completely traceable back to the initial version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgflvfugpm4tvduamer5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgflvfugpm4tvduamer5.png" alt=" " width="800" height="418"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dnsssb37jlb6g2ghx39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dnsssb37jlb6g2ghx39.png" alt=" " width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the operator decides the data is pristine, they select the desired form and click &lt;strong&gt;Launch&lt;/strong&gt;. For advanced workflows, our UI allows users to select multiple process forms and spin them up completely in parallel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens under the hood?&lt;/strong&gt; For a Kogito developer, the magic is straightforward: FlowIQ iteratively triggers the Kogito onboarding process endpoints via its standard REST API, handling state synchronization seamlessly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fas1ykbmbjp3xxsywdzz8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fas1ykbmbjp3xxsywdzz8.png" alt=" " width="799" height="420"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5kqrlsv0ct1kcuka9e1t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5kqrlsv0ct1kcuka9e1t.png" alt=" " width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bringing Our Own Flavor to "My Tasks"
&lt;/h2&gt;

&lt;p&gt;The core of any human task framework is the inbox. When a process spins up and requires human validation, it lands directly in the &lt;strong&gt;My Tasks&lt;/strong&gt; menu.&lt;br&gt;
Using Kogito’s REST endpoints, our backend extracts only the tasks relevant to the logged-in user's roles. But we wanted to go a step further for complex organizational structures, so we added a &lt;strong&gt;Department Filter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zyez1lp9b54gezwtqi5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zyez1lp9b54gezwtqi5.png" alt=" " width="800" height="418"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjlerj4md1ugwobeur6x0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjlerj4md1ugwobeur6x0.png" alt=" " width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FlowIQ automatically maps and filters tasks based on organizational department attributes already baked inside the process data. An risk-assessment agent only sees risk-assessment tasks, while a regional manager sees theirs—keeping noise to an absolute minimum.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;We've successfully laid down the foundation: authenticating users, dynamically rendering forms, and triggering Kogito processes via REST. But how do we keep the user interface updated in real-time when system-level steps complete?&lt;br&gt;
In the next episode, I’ll dive into &lt;strong&gt;task attributes&lt;/strong&gt; and how we track live process statuses using &lt;strong&gt;event streaming with Apache Kafka&lt;/strong&gt;.&lt;br&gt;
&lt;em&gt;Have you worked with Kogito or built custom worklists for BPMN engines before? Let me know your thoughts, questions, or architectural pain points in the comments below!&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
