Getting started
This walkthrough builds your first Nomaflow job — a simple nightly database refresh — in about ten minutes. By the end you'll have a job that fires on a schedule, runs a step against a connector, records its run history and streams its logs live. Everything happens in the Nomaflow page; no TOML editing required.
The example uses a SQL step because every install has a connector to test it with. The same workflow applies to Python, HTTP and LDAP Sync steps — only the form fields change.
Before you start
Make sure you have:
| Requirement | How to check |
|---|---|
| The framework is running. | Open the application — you can sign in. |
| You have a connector to use as a target. | Open Settings → Connectors — at least one connector should be listed. The framework's default pool always counts. |
Your role has the job:* permission (or superuser). | If the Nomaflow link is visible in the menu, you're set. |
If any of those are missing, the framework getting-started guide covers the install path and Authentication → Roles and permissions covers the role wiring.
Step 1 — Open the Jobs page
Click Nomaflow in the top navigation. The page that opens is the Jobs catalogue — every declared job, with its last-run state, next scheduled fire and a row of actions.
The top toolbar carries the three actions you'll use most: New Job (open the job builder), Schedule view (a calendar of upcoming fires) and Reload (refresh the catalogue).
Step 2 — Create a job
Click + New Job. The Job editor opens with three sections: Identity, Schedule and Steps.
| Field | Set it to |
|---|---|
| Id | my-first-job (URL-safe — letters, digits, hyphens, underscores). |
| Description | "My first Nomaflow job — refreshes a reporting view." |
| Tags | tutorial (optional — used to group jobs). |
| Enabled | Leave on. |
Save the identity block before you add steps. The job is now in the catalogue but does nothing yet.
Step 3 — Add a SQL step
Inside the editor, click + Add step and pick SQL Query from the type menu.
| Field | Set it to |
|---|---|
| Name | refresh-totals (used as a label in the run history). |
| Type | sql_query. |
| Connector | Pick any writable connector — the framework's default is fine for a smoke test. |
| Query | A short statement against your target — for the framework's default pool, SELECT now() is enough to prove the wiring. |
Save the step. The editor returns to the steps list with one step on it.
A SELECT now() works as a smoke test, but a job that runs a meaningful query (a REFRESH MATERIALIZED VIEW, a daily counter update, a small INSERT … SELECT) gives you a useful result row in the history.
Step 4 — Set a schedule
Back in the editor's Schedule section, the schedule field expects a 5-field cron expression (with an optional 6th field for seconds).
| Goal | Cron |
|---|---|
| Every minute (good for a quick test). | * * * * * |
| Every day at 02:00. | 0 2 * * * |
| Every Monday at 09:30. | 30 9 * * 1 |
| Every hour at minute :15. | 15 * * * * |
| Manual-only (no schedule). | leave the field empty |
For a first test, set * * * * * and pick a timezone (e.g. Europe/Paris). The schedule field shows a live preview of the next three fires so you can sanity-check the expression before saving.
Save the job. Within a minute, the first run lands in the history.
Step 5 — Watch the run
Back on the Jobs page, your my-first-job card now shows:
- A RUNNING badge (green pill) when the run is in flight.
- A SUCCEEDED or FAILED badge when it settles.
- The last run timestamp updating each minute.
Click the badge — it opens the Run detail page for that run, showing the step timeline, the inputs and outputs of each step and the live log tail.
The log streams live over Socket.IO while the run is in flight — close the browser, the run keeps going; re-open the page, the log resumes where you left off.
Step 6 — Switch to manual-only
A job firing every minute will fill the history quickly. Once you've confirmed the wiring:
- Open the job editor.
- Empty the Schedule field.
- Save.
The job is still in the catalogue and still ▶-runnable from the Jobs page, but no longer fires on its own. This is also the right mode for on-demand jobs — rebuilds, reports, one-off scripts an operator triggers manually.
Alternatively, use the enable toggle on the job card to disable the schedule without losing it.
Step 7 — Try a manual run
Click ▶ Run now on your job card. Three things can happen:
| What you see | When |
|---|---|
| The job fires immediately. | The job has no parameters and a single step — there's nothing the operator could usefully configure. |
| A Run with parameters modal opens. | The job has shared params, a Python step with op_kwargs, or more than one step. |
| The button is disabled with a spinner. | A previous run is still in flight. |
The Run with parameters modal is a powerful piece of the UI — it lets the operator override per-fire what would otherwise need a job edit. The full walkthrough lives in Jobs → Catalogue.
What you've just built
| Behaviour | Where it came from |
|---|---|
| The job fires on a schedule. | The cron expression in the Schedule section. |
| The framework picks it up without a restart. | Save in the job editor calls POST /admin/reload automatically. |
| The run lands in the history. | Every fire creates a run row, every step a step_run row. |
| You can re-run from the UI. | ▶ Run now dispatches through the same step engine as the cron fire. |
| Logs stream live. | The runner publishes to a Socket.IO channel the Run detail page subscribes to. |
You haven't written any TOML, opened a terminal or restarted a service. The whole loop — define, schedule, run, observe — lives in the Settings UI.
Where to go next
| You want to… | Read |
|---|---|
| Build the mental model — what's a job, run, step, schedule? | Concepts. |
| Learn the catalogue + run-with-params modal in depth. | Jobs → Catalogue. |
| Walk through the full Job editor with every field explained. | Jobs → Create a job. |
| Pick the right step type. | Steps. |
| See three end-to-end patterns. | Workflow recipes. |
| Set up Slack / email / webhook alerts on failure. | Notifications. |