helixAppObject
Application-level Helix behaviour — settings that apply to the whole client rather than to a single stop
or resource type — is configured as direct children of the domain’s helix block, authored in the
domain file as {"define": {"helix": { … }}} (a {"set": {"helix": … }} block is also accepted) and
carried on the reference record. It is a Helix addition and is ignored by Spiral itself. (The pre-relaid helix.app.{…} nesting is still read as a
legacy fallback, but new domains should use the direct form: helix.contactCentre, helix.heatmap,
helix.metric, helix.actionClasses, helix.domains.)
-
contactCentrecontactCentreObject - Contact-Centre (omni-search) configuration.
-
actionClassesstring - Global catalogue of action class names. A class groups actions, marks a domain-authored definition AUTOMATIC, and is the SKILL GATE: operators are enabled per class in the Administration app (the picker offers this catalogue plus core's built-ins), and the queues show classed actions only to enabled operators. Class-less reaches everyone; the resource audience ignores class. See actionObject and builtInActions.
-
heatmap{ radius, idle, late, unresourced } - Zoomed-out heat-map presentation: radius (metres, default 7500 — each heat point draws ~2×radius across) and the three signal colours as Helix palette names (or CSS values): idle (default "blue"), late ("red"), unresourced ("purple").
-
metric{ [name]: { median, var, low, high } } - Metrics-panel tile colour tolerances, keyed by metric name (sla, stopsPerHour, driveTime, unresourced). A value ≤ median−var shows the `low` colour, ≥ median+var the `high` colour, in between amber — direction is encoded by the colours (e.g. sla: {"median":70,"var":20,"low":"red","high":"green"}; unresourced would reverse them). Colours are Helix palette names or CSS values; unconfigured metrics keep the built-in colouring.
-
domains{ [domain]: { [skill]: "skill" | "constraint" | "capacity" } } - The domain master list (see below). Groups skills by domain and declares each skill’s value-form; the domain names are also the surge domains referenced by surgeZone and the per-type `domain` blocks.
-
dispatch{ resourceList: { sort }, projectList: { sort } } - Dispatch-application configuration: named sort rules for the resource list and the project list. See below.
dispatch
Section titled “dispatch”helix.dispatch configures the dispatch application’s lists. Both the resource list and the
project list take named sort rules, and both work the same way:
"dispatch": { "resourceList": { "sort": { "Activity": ["PACK","FREE","BRK","TIDY","WRAP","RECY","HEAD"] } }, "projectList": { "sort": { "Urgency": ["OSRC","REBK","PLAN","HEAD","ARVD"], "Value": "byContractValue()" } }}Each key becomes an extra entry in that list’s Sort menu, alongside the built-in State, Delay and
Earliest. State is always offered first and is the default: it orders on Helix’s own state
vocabulary — the raw stop state (and, for resources, the roster duty type) — so it cannot fall out of
order when a domain renames a state. Your named rules are the opt-in layer on top, for ordering the
vocabulary you invented.
A rule takes one of two forms.
An array — a sequence. The rows rank by the position of their display status (clientState) in the
array; anything unlisted sorts after everything named. This covers the common case without writing code.
A string — an order expression. A domain expression bound to a
function in your client module, called once per comparison with the row as this and the row it is being
compared against as its first argument. Return true when this sorts before that row, false when
it sorts after:
// in the client modulebyContractValue(other) { return (this.data.ext?.value ?? 0) > (other.data.ext?.value ?? 0);}Any arguments written into the expression itself follow the compared row, so
"byField('earliest')" arrives as byField(other, 'earliest').
Use the expression form when the ordering depends on something a list of status names cannot express — a number, a date, a computed score. Helix asks the expression both ways round for each pair, because a “sorts before” test alone cannot distinguish after from equal: rows your expression ranks equally then fall through to the built-in tie-breakers (delay, then earliest / planned arrival). An expression naming a function no module defines leaves the order to those tie-breakers rather than scrambling the list.
domains
Section titled “domains”helix.domains is the client’s domain master list: it groups skills under named domains and declares
each skill’s value-form. The domain names form one shared namespace used three ways:
- Skills grouping (here). Each skill is typed
skill,constraint, orcapacity; the type fixes the value the skills editor writes —skill→null(a boolean capability),constraint→{ "max": n },capacity→{ "capacity": n }. - A type’s default domain —
helix.domainon a stop / resource / project type names the group the skills editor opens on for that type (Helix-only; not sent to Spiral). - Surge domains — the same names label the per-type surge
domainblocks and the surgeZonedomainfield.
{"define": {"helix": { "domains": { "Police": { "police":"skill", "firearms":"skill", "publicOrder":"skill" }, "Ambulance": { "paramedic":"skill", "convey":"skill", "stretcher":"capacity" }, "Fire": { "fire":"skill" }, "General": { "seats":"capacity" } }}}}helix.domains is opt-in: a client that declares none keeps the free-form skills editor. Any skill
referenced by a type (in coreSkills, initialSkills, exclusiveSkills, secondaryActivity.skills, or a
stop option) that is not in the master list is flagged with a warning at domain-seed time — the seed
still completes.
addr — the location record’s doors
Section titled “addr — the location record’s doors”An entity’s addr object is the loc within the helix objects — its general location record. The
schema is proprietary to the client, so nothing reads its fields directly: four domain-overridable
doors expand it, each an expression resolved against the app-level helix.addr block:
-
namestring - Expression for the SHORT NAME. Default helixAddrName() — the addr's `name` field.
-
addrstring - Expression for the FULL ADDRESS. Default helixAddrText() — the non-empty of name, line1, line2, area, postcode, joined in that order.
-
atstring - Expression for the COORDINATE. Default helixAddrAt() — the addr's `at` field ([lat,lng]).
-
telstring - Expression for the TELEPHONE. Default helixAddrTel() — the addr's `tel` field.
-
areastring - Expression for the AREA summary. Default helixAddrArea() — the addr's `area` field. The addr subsumes the bare Location `area`: a location is `{at, addr}` and the area is pulled from the addr (the legacy `{at, area}` shape keeps working as a fallback until authoring migrates).
The default structure is { name, line1, line2, area, postcode, at, tel }. A client whose records differ
(the AA pack authors {name, lines, area, code}) overrides the doors — author the block and implement the
functions in the client extension (the SDK exports the defaults to compose with):
{"define": {"helix": { "addr": { "name": "myAddrName()", "addr": "myAddrText()" }}}}Everything that displays an address resolves through these doors — hub names on the map and lists, the
stop editor’s hub schedule row (the staged leg’s hid resolved to its hub record), and its hover/full
address. addr itself is Helix-only: it is never sent to Spiral, which speaks ids and coordinates.
contactCentre
Section titled “contactCentre”Configures the Contact-Centre contract search — the omni-search box operators use to find a contract or customer record and open or attach work to it.
-
searchPathsstring - Dot-paths into a contract record that the local search matches against (e.g. "fields.membershipNo", "fields.reg", "customer"). Drives the built-in /api/contract/search query.
The client may also supply a searchContracts(input) resolver (in its clientConfig) to merge results from an
external system — CRM, telephony or ticketing — with the local matches. See
Develop a client extension.
Related
Section titled “Related”- contractParamsObject
- projectObject — the
contractReflink from a project to a contract record - Helix technical overview