Fill a checklist by scan
A batch row lists the codes an order expects; each scan checks one off, and the last fill completes the row and wakes the workflow.
The situation
An order expects a known set of items, some of them twice. A person matches each physical item to the order by scanning it, and needs to see what is still missing in plain words, not codes.
The recipe
The workflow parks a batch whose keys are the expected codes. A code expected twice is declared <code>#1 and <code>#2.
const matched = await conditional<Record<string, unknown>>(`match-${orderId}`, { role: 'matching', metadata: { orderId }, envelope: { item_labels: labels }, batch: ['00012345678905#1', '00012345678905#2', '00098765432109'],});The item scan, while the order is held, fills the next open key for its code:
{ "query": { "roles": ["matching"] }, "verb": "fill", "subject": { "schemes": [12] }, "refuse": { "markdown": "Not one of this order's items. Still to match: {fill.pending}." }, "done": { "markdown": "Matched. Next: {fill.next}" }, "params": { "fill": { "into": "subject", "labels": "envelope.item_labels", "label": "{label.name}, size {label.size}" } } }The answer carries progress: { filled, total, remaining }, and the subject stays held while items remain.
The guarantee
Each fill is one guarded statement: the payload lands only while its key is pending, a third scan of a code expected twice is refused, and the last fill resolves the row and wakes the wait atomically. Each fill records its actor and a database-clock time. See Batches and accumulators.
Related patterns
The physical world
Hold a subject
The item scan writes nothing: it holds the item on the station so the next scan knows what it is acting on.
The escalation boundary
Batch: N contributions, one wake
One row collects a named set of submissions and wakes the workflow once, when the last one lands, with the whole collection.
Forms and configuration
Roster: check off who arrived
A roster lists every member a container expects, marks each waiting, in or flagged, and holds the rest of the form until all are accounted for.
The escalation boundary
Start a batch partly filled
Items already satisfied before the wait begins go in filled, so the row opens with real progress and delivers them with the rest.
