The operator record
The roster screen reads the whole roster withapi.operators(). Each row is
one operator record:
How an operator gets on the roster
The roster is self-populating. You do not create a blank operator record and fill it in. When the roster is empty, the screen says so explicitly:No operators yet. A row appears the first time someone opens the console.So the sequence is: a person gets console access, they open the console, and a row for them appears in the roster. From that point on the row is the thing you administer — you set a region on it, and certifications attach to it. A new row carries no certifications. Until one is granted, that operator holds nothing, and no robot that requires a certification will be offered to them.
Presence states
Presence is reported on the record, not set from this screen. The roster renders it as a colour-coded chip so you can read availability down the column:attached and ready share the accent colour because both mean the operator
is on shift. aux is called out in the warning colour because it is the
state that silently removes someone from the available pool while they still
look logged in. offline is faint because an offline operator is not
expected to take work.
When auxReason is set it is appended to the chip text after a ·
separator, so the roster shows why someone is unavailable without a second
click.
Skills, levels, and certification expiry
A certification is a triple:- skill — what class of work it authorises.
- level — the depth of authorisation within that skill. An operator may
hold the same skill at more than one level; each
skill · levelpair is a separate certification chip with its own expiry. - expires — the date the certification runs out.
skill · level, and adds one derived column, Nearest expiry: the
expires value of the certification that lapses soonest, found by sorting
the operator’s certifications by expiry and taking the first. An operator
with no certifications shows — in both columns.
Nearest expiry is a review column. It answers “who lapses next” at a
glance so you can renew before someone drops off the roster. This screen
does not renew or extend a certification, and it does not report what
dispatch does at the moment one lapses — it reports the date.
How a job offer is matched to a certified operator
Dispatch is certification-driven. A robot declares a required certification. The automatic call distributor offers the job only to operators holding that certification. That is the whole matching rule as far as this screen is concerned, and it has two practical consequences:- Certifications are the grant of access. An operator who is
readybut does not hold the robot’s required certification is not offered that robot. - Revoking is how you take someone off a robot. There is no separate “unassign from robot” control, because there is no assignment — there is only the certification that makes an operator eligible.
Revoking a certification
Click any certification chip on an operator’s row to revoke it. The chip readsskill · level ✕ and its tooltip is Revoke this certification.
The console confirms first, naming the operator and the exact
skill · level being removed, and stating the effect:
They stop being dispatched to robots requiring it, immediately.Confirming calls
api.revokeCert(operatorId, skill, level) and reloads the
roster. Revocation is scoped to that one skill · level pair — other levels
of the same skill, and all other skills, are untouched.
Note what this screen does not do: there is no control here for granting a
certification. The roster is where you review and revoke. Granting happens
outside this screen.
Region
Region is a free-text grouping label on the operator record. Use the Region button on a row to edit it:- The prompt is pre-filled with the operator’s current region.
- Cancelling the prompt makes no change at all.
- An empty answer is a deliberate clear — submitting nothing sets the
region to empty, and the column falls back to
—. - The value is trimmed, then length-checked before any request is sent. A
region longer than 64 characters is rejected locally with a
Regionlength message; the API is not called.
api.updateOperator({ userId, region }) and reloads the
roster.

