-
-
Notifications
You must be signed in to change notification settings - Fork 0
Mobile Process Designer
All three phases are now built (feature complete). The user-facing guide lives at Process Designer; this page is the design-detail reference. One correction from the original draft: the implemented service uses the base path
/api/process-designer/**(the Flowable process-engine owns/api/process/**), so the API paths below read/api/process-designer/....
The mobile process designer lets a non-developer build, version, and publish configurable handheld operator processes (goods-in, packing, stock-check, ad-hoc moves) without writing code. A process is a JSON definition of ordered screens and tasks; the PWA operator shell fetches the active definition and runs it on the handheld.
Spec:
docs/process-designer-spec.md— authoritative detail on the model, API, and designer UI.
Status: Phase 1 + Phase 2 + Phase 3 built, feature complete (service process-designer :8097 + the designer UI and client-driven handheld runtime). Phase 2 added version management (duplicate/clone, JSON import/export), step-level skipWhen skip conditions, four more curated tasks (host.confirm, inventory.adjust, counting.capture, order.lookup) + a live task catalog, and a read-only Process instances monitoring screen. Phase 3 added a sandboxed scripting escape hatch (a script task type in a locked-down GraalJS sandbox, gated by the OPENWCS_PROCESS_SCRIPTING_ENABLED flag and the new PROCESS_SCRIPT_AUTHOR permission) and design-time AI task-assist (POST /assist/task → a curated-task mapping or a draft sandboxed snippet for a human to review; never auto-deployed) plus a GET /capabilities endpoint. A later increment added scan verification: a per-screen verify block that resolves a scanned/typed value against new read-only master-data resolve endpoints, branches on not-found, and writes the resolved ids (incl. the UUID) into data-object variables, all on the curated-API path; subsequently extended with the skuScan combined verify kind (barcode-or-SKU-code resolve with automatic UOM-picker when the SKU has multiple units). See Process Designer and Roadmap and Status.
| Concept | Meaning |
|---|---|
| Process key | Stable identifier for a process type, e.g. goods-in, packing. The operator menu shows the active version per key. |
| Process definition | An immutable, versioned flow: ordered steps + transitions + the data-object schema. Status: DRAFT, ACTIVE, or ARCHIVED. Exactly one ACTIVE per key at any time. |
| Step | A node in the flow — a screen step (renders a handheld screen, captures input) or a task step (runs server-side work). |
| Transition | A directed edge between steps; may be unconditional or guarded by a condition over the data object for branching. |
| Data object | The typed key/value context for one running instance; screens write to it, {{placeholder}} text and conditions read from it. |
| Instance | One run of a process by an operator. Pinned to the definition version it started on. |
All screens are glove-friendly, high-contrast, and support keyboard-wedge barcode scan capture
via scanBinding. Common config fields: header, detail (both support {{placeholder}}
interpolation), writeTo (data-object variable), and per-type validation.
| Type | Captures | Notes |
|---|---|---|
textInput |
string |
required, regex, maxLength, mustEqual validation; scan binding |
numberInput |
number |
required, min, max, integerOnly, mustEqual
|
dateInput |
ISO date |
required, date range bounds; default = today |
acknowledge |
nothing |
confirmLabel; optional required checkbox |
questionYesNo |
boolean | drives transitions via the data object |
questionChoice |
string | configurable answer options; choice drives transitions |
Text and Number input screens can carry an optional config.verify block. Where validation
(regex / maxLength / mustEqual) only checks the shape of a value, verification confirms
the code actually exists in master data and writes its linked ids (including the resolved UUID)
into the data object, so a later task that needs a UUID gets it.
-
kindpicks what to resolve:barcode(a scanned barcode → SKU + UOMs + attribute-schema graph),sku(a SKU code),location(a location code), orskuScan(combined: tries the value as a product barcode first; if no match, tries it as a SKU code — a barcode pins its UOM, a single-UOM SKU auto-picks, a multi-UOM SKU triggers a runtime UOM picker before the step advances). The designer's picker is server-driven bycapabilities.verifyKinds(["barcode","sku","location","skuScan"]). -
writemaps the normalised resolved fields (id,code,name,uomCode,schemaCategory) to declared data-object variables. ForskuScan, mapuomCodeto store the chosen or auto-resolved unit. -
onNotFoundisrepromptorgotoa step; agototarget must exist and counts toward reachability.
At runtime the client posts POST /api/process-designer/verify {warehouseId, kind, code}, which
proxies the read-only master-data resolve endpoints with the operator's forwarded identity and
returns {found, ambiguous, id, code, name, uomCode, schemaCategory, matchedAs, uoms, needsUomChoice, detail}. The skuScan-specific fields: matchedAs ("barcode" or "sku") signals which path fired; uoms lists {code, baseUnit} entries for the SKU's available units; needsUomChoice is true when the SKU has more than one UOM. When needsUomChoice:true, the runtime shows a UOM picker overlay (button per unit, base unit labeled) and advances only after the operator selects one; the chosen code is written into the uomCode-mapped variable. Offline holds; found:false re-prompts or routes; found:true merges the write mappings and continues; ambiguous shows a subtle note. Simulate resolves locally (a "simulate not found" toggle). Validated at publish (valid kind, write keys map known fields to declared variables, goto step exists). No raw SQL: the resolve endpoints reuse the master-data card-read repositories under MASTER_DATA_VIEW, returning 200 found:false on a miss (never 404). Base url OPENWCS_MASTER_DATA_BASE_URL.
Task steps are server checkpoints that call existing audited services. Three tiers:
Pre-built parameterized task types; the designer maps data-object variables to inputs/outputs.
RBAC and warehouse scope from the operator's identity are forwarded automatically. A task catalog
endpoint GET /api/process-designer/tasks returns [{type, label, inputs[], outputs[]}], which
drives the designer's task picker (so it always lists the real available task types).
| Task type | Phase | Calls |
|---|---|---|
slotting.putaway |
1 | POST /api/slotting/decant/putaway |
inventory.move |
1 | POST /api/flow/moves |
picking.confirm |
1 | POST /api/orders/pick-tasks/{lineId}/confirm |
inventory.lookup |
1 |
GET /api/inventory/availability (read into a variable) |
txlog.post |
1 | POST /api/txlog/events |
host.confirm |
2 | POST /api/host/inventory/adjustments |
inventory.adjust |
2 |
POST /api/txlog/events (a StockAdjusted event) |
counting.capture |
2 | POST /api/counting/tasks/{taskId}/lines/{lineId}/station-count |
order.lookup |
2 |
GET /api/orders/{id} (read into a variable) |
New task types are added in code and land via the normal PR/CI pipeline.
A built-in script task type (config { script:"<js>", outputs:[{name}] }) runs server-side in a
locked-down GraalJS sandbox (org.graalvm.polyglot community 24.1.1): allowAllAccess(false),
HostAccess.NONE, no host class lookup/loading, no native/threads/process, IOAccess.NONE, no
environment, PolyglotAccess.NONE: interpreted guest JS, never compiled to host JVM bytecode.
Limits: a statement limit (default 100000), a wall-clock timeout (default 2000 ms), and an output cap
(default 65536 bytes). The script sees only a deep-frozen read-only data global and returns an
object whose fields become the declared outputs. Gated: a script step saves/publishes only when
the OPENWCS_PROCESS_SCRIPTING_ENABLED flag is on (else 422) and the caller holds
PROCESS_SCRIPT_AUTHOR (ADMIN only; else 403); each script is parse-validated in the sandbox at
publish (malformed → 422).
POST /api/process-designer/assist/task {description, variables:[{name,type}]} →
{kind:"curated"|"script"|"none", taskType?, inputs?, outputs?, script?, rationale, confidence}
(gated PROCESS_DESIGN_EDIT). Uses the Anthropic Java SDK (default claude-haiku-4-5,
ANTHROPIC_API_KEY), grounded with the live task catalog + the supplied variables; it either maps the
description to a curated task type with variable mappings, or drafts a sandboxed JS snippet for a
human to review and insert as a script step. The suggestion is never saved, compiled, or executed,
and nothing is auto-deployed. Absent a key → 503 (the service still starts). AI text → compiled
Java → a live server is permanently out of scope.
when conditions on transitions are a restricted grammar — comparisons (==, !=, <, <=,
>, >=) and and/or/not over data-object variables and literals. Evaluated by a small
interpreter; no eval, no host access.
- Draft → publish sets the version
ACTIVEand archives the prior one. - Rollback = re-publish a prior version (creates a new pointer).
- In-flight pinning: running instances keep the version they started on; publishing never mutates live instances.
The handheld PWA is the runtime. Execution is client-driven:
- On process start the handheld fetches the active definition (cached by the service worker).
- Screen steps run entirely client-side — no server round-trip per screen.
-
Task steps are server checkpoints: the client posts
{stepId, data}; the server runs the curated task and returns the updated data object + next step. - While offline, task calls queue (the existing offline queue); screen-only stretches keep working.
- Instance state is checkpointed server-side at each task step — resume after device swap/reload.
A three-pane desktop screen (Engineering section, gated by the process-design screen permission):
| Pane | Content |
|---|---|
| Left — flow list | Ordered steps with type icons; branches shown as indented sub-paths. Drag to reorder; add a step from the palette. |
| Centre — live handheld preview | The selected step rendered in a phone frame using the same components the real handheld runtime uses, with {{placeholder}} resolved against sample data. Edits update the preview instantly. |
| Right — properties | Per-step config: header/detail with a placeholder picker, writeTo, validation builder, scan-binding toggle; task type picker + variable mapping; question answer/transition editor. |
Additional tools: a data-object panel to define typed variables; simulate/test mode to step through the flow with fake input before publishing (task steps are dry-run); and validate + publish which blocks publication until all unreachable steps, dangling transitions, and unknown placeholders are resolved.
Served by the new process-designer service (port 8097), under the /api/process-designer base path:
-
GET /api/process-designer/defs?status=— list definitions -
GET /api/process-designer/defs/{key}/{version}— get one version's full model JSON -
GET /api/process-designer/defs/{key}/active— active definition for a process key -
POST /api/process-designer/defs— create a draft -
PUT /api/process-designer/defs/{key}/{version}— edit a draft (409 if not DRAFT) -
POST /api/process-designer/defs/{key}/{version}/publish— publish (validates, activates, archives prior; 422 with problem list on failure) POST /api/process-designer/defs/{key}/{version}/archive-
GET /api/process-designer/processes— distinct process keys with their active version title/icon (used by the operator menu) -
POST /api/process-designer/defs/{key}/{version}/duplicate— clone a version into a new draft (Phase 2) -
POST /api/process-designer/defs/import— create a draft from a full definition JSON (Phase 2; export =GET /defs/{key}/{version}above) -
GET /api/process-designer/tasks— task catalog driving the designer's picker (Phase 2) -
POST /api/process-designer/instances {processKey}— start an instance (returns instance + active def) -
POST /api/process-designer/instances/{id}/checkpoint {stepId, data}— run a task step (idempotent per instance+step) -
GET /api/process-designer/instances/{id}— resume -
GET /api/process-designer/instances?processKey=&status=&warehouseId=&limit=— instance history/monitoring summaries, newest-first (Phase 2) -
POST /api/process-designer/assist/task {description, variables}(design-time AI task-assist, Phase 3): returns a curated-task mapping or a draft sandboxed snippet to review; never auto-deploys (gatedPROCESS_DESIGN_EDIT; 503 when no Anthropic key) -
GET /api/process-designer/capabilities(Phase 3):{scriptingEnabled, aiAssistEnabled, canAuthorScript, verifyKinds}driving the designer's show/hide of the script editor + AI assist and the scan-verify kind picker —verifyKindsis["barcode","sku","location","skuScan"](gatedPROCESS_DESIGN_VIEW) -
POST /api/process-designer/verify {warehouseId, kind, code}(scan verification): proxies the read-only master-data resolve endpoints with the operator's forwarded identity; returns{found, ambiguous, id, code, name, uomCode, schemaCategory, matchedAs, uoms, needsUomChoice, detail}(matchedAs/uoms/needsUomChoicepopulated forskuScan; cleanfound:false200, downstream failure 502); gatedPROCESS_DESIGN_VIEW
- No designer-authored Java executes in-process. A
scriptstep runs only interpreted guest JS in a locked-down GraalJS sandbox (no host/Java/IO/threads/process/env, statement + wall-clock + output limits, a deep-frozen read-onlydataglobal), never compiled to host bytecode. - A
scriptstep saves/publishes only when theOPENWCS_PROCESS_SCRIPTING_ENABLEDflag is on and the caller holdsPROCESS_SCRIPT_AUTHOR(ADMIN only); else 422 (disabled) / 403 (no permission), and each script is parse-validated at publish. - AI task-assist is design-time only: it returns a suggestion the designer reviews; it never saves, compiles, or executes code, and never auto-deploys.
- Task steps run with the operator's forwarded identity + warehouse scope; RBAC from existing services applies.
-
whenconditions and{{placeholders}}are parsed/whitelisted — nevereval'd. - Publishing a definition is an audited, permissioned action (requires
PROCESS_DESIGN_EDIT).
See Services and Security for the identity-forwarding and RBAC model.
openWCS — open-source Warehouse Control System · summarized from build.md & docs/AS-BUILT.md (the repo docs are authoritative).
Design
Flows
- Inbound and Inventory
- Slotting and Replenishment
- Goods-to-Person Stations
- Outbound Flow
- Equipment Integration
- Transport Overview
- Process Designer
- Mobile Process Designer
- Hardware Visualisation
- Host Integration
Reporting & Dashboards
Operations