Identifier bindings
A binding pairs a scanned value (raw) with the thing it stands for (target), under one scan scheme: a cartridge’s tag with the material lot it carries, a plate with the printer it is aboard. Use one when the carrier holds a code you did not print: a factory barcode, a tag’s EPC, a reusable plate.
A raw has one live target at a time. A target holds any number of raws, or exactly one when its scheme sets identifier.exclusiveTarget. Retired bindings stay as history, so a raw’s past reads back newest first.
A binding stores the target string. What the target means (a lot’s material and remaining quantity, a printer’s state) stays on your own rows.
Who binds
Section titled “Who binds”Binding and retiring take a role manager, or a role the scheme names in identifier.binders. A scheme declared at boot carries the same identifier; a code-owned scheme applies what its code declares on every boot, and a db-owned one is seeded with it once:
scanSchemes: [ { version: 22, name: 'Plate', target_facet: 'plateCode', encoding: 'delimited', identifier: { binders: ['print-servicing'], exclusiveTarget: true }, },],Any signed-in caller reads bindings. Each binding records bound_by (the user, when the caller is one) and bound_via: api, scan or workflow. A scheme save that leaves identifier out keeps the stored settings, and null clears them.
Operations
Section titled “Operations”| Operation | What it does |
|---|---|
| bind | Pairs a raw with a target. A raw bound to another target answers 409; the same pair again answers 200 with the standing binding. Under an exclusive scheme, the target’s old raw is retired in the same transaction |
| rebind | Moves a raw to a new target: its old binding (and, under an exclusive scheme, the target’s old raw) is retired and the new one inserted in one transaction |
| retire | Ends one live binding. It stays as history, and the raw is free to bind again |
| resolve | A raw’s live binding, if it has one |
| list | A scheme’s live bindings, by target or raw, or every binding with includeRetired |
Partial unique indexes decide concurrent binds: of two binds of one raw, or two onto one exclusive target, exactly one lands.
await lt.identifiers.bind({ scheme: 22, raw: 'PLT-0193', target: 'printer-04' });const { data } = await lt.identifiers.listBindings({ scheme: 22, raw: 'PLT-0193' });The same operations are on HTTP under /api/identifiers/:scheme (reference), the SDK as lt.identifiers (reference), and MCP as list_identifier_bindings, read-safe, where raw answers one value’s live target.
Bind at a station
Section titled “Bind at a station”A bind scan step binds the scanned value to the held item. Hold the item first with a hold step, then scan the value under a rule whose step binds:
{ "verb": "bind", "subject": { "schemes": [21] }, "params": { "bind": { "facet": "serialNumber" } }, "done": { "markdown": "**{scan.target}** is on {subject.serialNumber}." } }The binding is kept under params.bind.scheme, else the scanned code’s scheme, and binds to the held row’s params.bind.facet, else its scheme’s target facet. The acting identity must be a binder. A value bound to something else is refused and the held item is kept, so the right value can be scanned next.
Two options let one scan finish a hand-off, as when a plate is loaded onto a printer:
move: truemoves a value bound elsewhere to this target, retiring its old binding in the same transaction (a rebind).resolve: { payload? }resolves the held row once the value is bound, with the payload rendered from scan templates ({scan.target}is the bound value,{subject.<facet>}reads the held row), and releases it. The resolve runs through theresolveverb’s guarded statement, so the row’s write scope, claim and form apply.
{ "verb": "bind", "subject": { "schemes": [21] }, "params": { "bind": { "move": true, "resolve": { "payload": { "plateId": "{scan.target}" } } } }, "done": { "markdown": "**{scan.target}** is on {subject.serialNumber}." } }The binding is written first and the row resolved after it, in two statements. A refused binding resolves nothing. A held row that has already ended answers as done and the binding stands, and scanning again answers the binding as already in place.
