Roster: check off who arrived
x-lt-widget: rosterx-lt-rosterroster.<field>.outstandingPOST /api/escalations/:id/roster-actionA 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 situation
A box should hold five bags. The packer scans bags in as they arrive, marks one missing when it is not in the bin, and weighs the box only once every bag is either in or accounted for.
The recipe
"orders": { "type": "string", "readOnly": true, "title": "Orders in this box", "x-lt-widget": "roster", "x-lt-roster": { "expected": { "query": { "roles": ["packing"], "facets": { "packingBox": "{{escalation.id}}" } } }, "key": "{{metadata.orderId}}", "in": ["items", "resolver.bags"], "flagged": [{ "when": "resolver.outcome=missing", "label": "Missing" }] }, "x-lt-columns": [{ "label": "Order", "value": "{{metadata.orderId}}" }], "x-lt-actions": [ { "label": "Missing", "when": "waiting", "resolverPayload": { "outcome": "missing" }, "confirm": "Mark {{metadata.orderId}} missing?" } ]},"weight": { "type": "number", "title": "Box weight", "x-lt-showIf": "roster.orders.outstanding=0" }Add "x-lt-submit-guard": { "roster": "orders", "message": "{{count}} orders are still unaccounted for" } at the schema root to hold the submit. The expected set is a query, a list on the row, or the row’s own batch keys.
The guarantee
Roster actions run on the server: the dashboard sends only which action and which entry, and the server re-reads the action from the row’s pinned form schema, confirms the entry is on the roster it computes, and runs the act under the person’s RBAC. For enforce_schema roles, a resolve with an outstanding entry is refused with the guard’s message as a 422 on every surface. The roster refreshes on the same escalation events as every list. See Forms.
Related patterns
Forms and configuration
Hold submit until embedded work drains
A parent form's submit stays disabled while its child rows are open, and can close itself the moment the last one resolves.
The physical world
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 physical world
Manager override
An exception action shows to everyone and runs only for a badge that holds the manager role; anyone else is refused and keeps their badge.
The escalation boundary
Open container
One row is a container that fills over time. Items join one at a time and the workflow wakes once with the ordered collection.
