User Guide

Workflows

Define a one-shot recipe — a set of records to create and the relationships to link them — then fire it from a single form whenever the same shape of work needs to happen again.

{{-- ─── 1. What a workflow is ─── --}}

What a workflow is

A workflow captures a repeatable bit of office work — the kind of thing you do the same way every time and would otherwise click through five separate forms to set up. You author it once on the Workflows page, give it a name, and from then on anyone in the tenant can fire it off with a single submission.

Two examples that ship in most setups:

  • New site visit — creates an Event, links it to a Site (Organisation), and assigns a Person as the visitor. One form, three records, one click.
  • Risk register entry — creates a Risk (custom entity), links it to the Asset it relates to, and optionally creates an Inspection at the same time.

Each fire of a workflow is called a run and is recorded forever as part of the workflow's history — who fired it, when, what they entered, and which records came out the other side.

You don't need workflows to use FlecBase. Everything a workflow does — creating records, linking them — you can also do by hand from the relevant resource page. Workflows save time when the same multi-record setup happens repeatedly.
{{-- ─── 2. Anatomy ─── --}}

Anatomy: spawns, links, run

A workflow recipe has three parts:

Spawns

Each spawn is one record the workflow will create or select at run-time. It has an alias (a short name used inside the recipe), a type (Person, Asset, Event, Order, Incident, Inspection, or any custom entity type your tenant has defined), a mode (create, select existing, or either), and a list of fields the run-form should expose for that record.

Links

Each link wires two aliases together with a relationship type — the same relationship catalog you see on the Relationship Types page. A link defines how the records connect: who the visitor is, which asset the inspection is against, what site the order ships to.

Run

Firing a workflow opens a single form built from the spawns. You fill in the fields, pick any existing-record selectors, hit Submit — the runner creates each record, applies the links between them, and saves an audit row of what just happened.

How spawns and links wire together

Aliases are the bridge. A link references two aliases by name — the names you gave the spawns. So if you have a spawn aliased visit (an Event) and another aliased site (an Organisation), a link visit → site with relationship VISITED_AT tells the runner: "the Event you just spawned belongs to the Site you just spawned."

Spawn: site (Organisation) Spawn: visit (Event) Link: visit → site (VISITED_AT)
{{-- ─── 3. Creating your first workflow ─── --}}

Creating your first workflow

Walk-through using the Site Visit example. Open Workflows and click Create Workflow.

1

Name & description

Give it a short verb-phrase name people will recognise on the run menu — "Log site visit" beats "Visit form". The description appears below the name in the list and is your audit trail when you come back to this six months later.

2

Define the Spawns

Click Add spawn for each record the workflow needs to produce or pick.

Alias — internal name. Lower-case, no spaces. Used by Links and only seen by recipe authors. Examples: site, visit, visitor.
Type — what kind of entity. Built-in types appear first; any custom entity types your tenant has defined appear under Custom: ….
Mode
  • Create new: every run produces a fresh record.
  • Select existing: the run-form shows a picker, no creation.
  • Select or create: picker with a "create new" option below — useful when an Org might exist already, or might be the first time you've heard of them.
Fields — for create modes, list the field names the run-form should expose. Anything not listed is ignored even if the form posts it. Common fields: name, description, starts_at, ends_at.
Aliases must be unique within a recipe. Two spawns can't both be called site — pick site_from and site_to if you genuinely need two.
3

Define the Links

Click Add link for each relationship you want the runner to apply between the spawns.

Left
An alias from the Spawns section. The "from" side of the relationship.
Right
Another alias. The "to" side.
Rel
A relationship type's system_code, picked from the catalog of active relationship types in your tenant. Examples: VISITED_AT, ASSIGNED_TO, PART_OF.

The Left and Right selects are populated live from the Spawns section above — if you don't see your alias yet, save the spawn first or check it has a name.

4

Activate and save

Toggle Active on so the workflow appears on the run menu. Sort order controls the position in the list — workflows you fire daily should sit at the top. Hit Save.

{{-- ─── 4. Running ─── --}}

Running a workflow

From the Workflows list, click the green Run button next to any active workflow.

The runner builds a form on the fly:

  • Each create-mode spawn becomes a section with the fields you listed.
  • Each select-existing-mode spawn becomes a single picker dropdown.
  • Each select-or-create-mode spawn shows a picker with a "create new" toggle.

Fill it in, hit Run workflow. The server processes the recipe in a single transaction:

  1. Resolve every spawn — create new records, look up existing ones, or both.
  2. Apply every link — wire the resolved records together using entity_links.
  3. Write a workflow_runs audit row capturing the recipe snapshot, alias map, and your submitted payload.
  4. Redirect you to the first newly-created record so you can verify or extend it.
One transaction, all-or-nothing. If any step fails, the whole run rolls back and nothing is written. You won't end up with half-spawned records.
{{-- ─── 5. Versioning ─── --}}

Editing & versioning

Every recipe carries a recipe_version integer that auto-bumps whenever you save a change to the spawns or links. The version is shown as a v3-style pill in the workflow list and on each run row.

The version exists so historical runs stay immutable. When run #14 fired against v2 of the recipe, the audit row stored a snapshot of v2's recipe at the moment it ran. Editing the recipe to v3 today doesn't retroactively change what v2 did. Reading old runs always shows the recipe shape they were fired against.

Editing safely. You can rename aliases, swap types, add or remove spawns and links — none of it breaks past runs. The new version applies only to runs fired from that point on.

Deactivating instead of deleting

Toggle Active off to hide a workflow from the run menu without losing its recipe or history. Reactivate at any time. Use this when a workflow is seasonal, paused for review, or replaced by a successor recipe — historical runs and the recipe itself stay intact.

Deleting a workflow is allowed but rare; it's safer to deactivate.

{{-- ─── 6. History ─── --}}

Reading the run history

Open any workflow's edit page and scroll to Runs. Every fire of the workflow appears as a row showing:

Run #
Sequential within the workflow.
Recipe v
Which recipe version was active at the time. Click to view the snapshotted recipe of that exact run.
Ran by
The user who fired it.
Ran at
Wall-clock timestamp of the run.
Records
The aliases produced, each linked to its created or selected entity.

The history is the audit trail. If something looks wrong on a record, the run row tells you who set it up and how.

{{-- ─── 7. Tips ─── --}}

Tips & common pitfalls

Name spawns by their role, not their type

visitor reads better than person1; asset_under_inspection reads better than asset. Future-you reads recipes more often than current-you writes them.

Use select existing generously

Sites, suppliers, recurring contacts — these almost always exist already. Forcing every run to re-create them clutters the data. Reserve create new for the things that genuinely vary per run.

Link direction matters

Each relationship type has a left/right semantic. VISITED_AT reads "Event visited Site" — Event left, Site right. Get this wrong and the link still saves but reads backwards in the UI. Check the Relationship Types page if unsure.

Test on yourself first

After saving a new workflow, fire it with placeholder data on a tenant you own. If the resulting records and links look right, ship it. Easier to delete one bad test run than to clean up after ten real users hit a misconfigured recipe.

When something goes wrong

"Alias not found" error on save. A Link references an alias that doesn't exist in Spawns. Either the alias was renamed and the link wasn't updated, or the spawn was removed. Open the Links section, fix the dangling reference, save again.
The run form is missing a field I expected. Check the Fields tag list on the offending spawn. Anything not listed is ignored, even if the underlying entity has it. Add it to the list, save, the version bumps, the next run shows it.
A run failed mid-way. The whole transaction rolled back — no records, no links, no audit row. Re-fire the workflow once you've fixed the cause (usually a required field on a custom entity that wasn't exposed via the spawn's fields list, or a relationship type that's been deactivated).

Found something missing or unclear? Workflows is an evolving feature — file a note in the Help backlog or ping support and we'll fold it in.


  Recipe at a glance

  ┌──────────┬──────────────┬─────────────────┬────────────────────────────────────────┐
  │  Alias   │     Type     │      Mode       │                 Fields                 │
  ├──────────┼──────────────┼─────────────────┼────────────────────────────────────────┤
  │ org      │ Organisation │ Select existing │ —                                      │
  ├──────────┼──────────────┼─────────────────┼────────────────────────────────────────┤
  │ contact  │ Person       │ Select existing │ —                                      │
  ├──────────┼──────────────┼─────────────────┼────────────────────────────────────────┤
  │ incident │ Incident     │ Create new      │ name, description, starts_at, priority │
  └──────────┴──────────────┴─────────────────┴────────────────────────────────────────┘

  ┌─────────────────────┬──────────────┐
  │ Link (left → right) │ Relationship │
  ├─────────────────────┼──────────────┤
  │ incident → org      │ INVOLVED_IN  │
  ├─────────────────────┼──────────────┤
  │ incident → contact  │ INVOLVED_IN  │
  └─────────────────────┴──────────────┘

  (Both use the same INVOLVED_IN system code — the relationship is polymorphic by left/right side. Same shape prestart/inspection use for "this thing involves that thing".)

  Step-by-step

  1. Open /crm/workflow-templates and click Create Workflow

  Top section:
  - Name: Log incident at org via contact
  - Description: Create an incident, link it to an organisation and the contact reporting it.
  - Active: on
  - Sort order: pick a low number if you want it near the top of the run menu (e.g. 10)

  2. Add three Spawns

  Click Add spawn for each. The order doesn't matter functionally, but reading order helps future-you, so add them in the sequence the runner will fill: org, contact, incident.

  Spawn 1 — org

  - Alias: org
  - Type: Organisation
  - Mode: Select existing (no fields panel appears — that's correct)

  Spawn 2 — contact

  - Alias: contact
  - Type: Person
  - Mode: Select existing

  Spawn 3 — incident

  - Alias: incident
  - Type: Incident
  - Mode: Create new
  - Fields: type the field names as comma-or-Enter-separated tags. Suggested:
    - name (the incident title)
    - description (free-text detail)
    - starts_at (when it happened — opens the date+time pair on the run-form)
    - priority (low / normal / high / urgent)

  You could also add due_date if you want the operator to set a target resolution date at submission time.

  3. Add two Links

  Click Add link twice. The Left and Right dropdowns will populate from the aliases you just defined.

  Link 1

  - Left: incident
  - Right: org
  - Rel: INVOLVED_IN (Incident involved-in Organisation)

  Link 2

  - Left: incident
  - Right: contact
  - Rel: INVOLVED_IN (Incident involved-in Person)

  4. Save

  Hit Save. The workflow now appears in the list with v1 in the version pill and 0 runs.

  What the operator sees on Run

  Click the green Run button next to the new workflow. The runner builds this form on the fly:

  ┌─────────────────────────────────────────────┐
  │ Log incident at org via contact             │
  │                                             │
  │ Organisation                                │
  │ [ Search and select organisation ▾ ]        │
  │                                             │
  │ Person                                      │
  │ [ Search and select person ▾ ]              │
  │                                             │
  │ Incident                                    │
  │ Name: [_______________________________]     │
  │ Description: [________________________]     │
  │ Starts at: [date] [time]                    │
  │ Priority: [Low / Normal / High / Urgent ▾]  │
  │                                             │
  │ [ Run workflow ]                            │
  └─────────────────────────────────────────────┘

  On submit, in one transaction:
  1. Resolves org and contact from the pickers
  2. Creates the new Incident with the fields the operator entered
  3. Writes two entity_links rows: incident↔org and incident↔contact, both with INVOLVED_IN
  4. Records a workflow_runs audit row capturing the recipe snapshot, alias→uuid map, and the operator's submission

  The runner redirects to the new Incident's record so the operator can extend it (add files, notes, etc.) if needed.

  Variations worth knowing

  - Don't always have a contact? Change contact from Select existing to Select or create. The runner shows a picker with a "create new person" toggle below — useful when the caller is someone you've never
  spoken to before.
  - Want the contact auto-linked to the org as a member too? Add a third link: contact → org with MEMBER_OF. The runner only writes a link if both sides resolved, so it's safe even if the contact already
  had that membership (the relationship-type uniqueness constraint handles deduplication).
  - Want a follow-up inspection at the same time? Add a fourth spawn (inspection, type Inspection, mode Create new) and a link inspection → org with INVOLVED_IN. Now one form sets up the incident, the
  inspection investigating it, and links them both to the org. The audit row records the whole bundle as one run.

  Sanity-check after saving

  Before publishing to staff, fire it once on yourself:
  1. Hit Run, pick a test org, pick yourself as the contact, fill an incident "TEST".
  2. Open the Org's record — the new incident should appear in its Links/Relationships tab.
  3. Open your Person record — same. The incident is linked from both sides.
  4. Open the Incident — both org and contact appear in its Links tab.
  5. Delete the test incident if you don't want it persisting (the link rows cascade off it).

  If all four show, your recipe is correct. Then deactivate-then-reactivate to verify staff see it on the run menu.