Scope is enforced in SQL
A member's read and write scope are ANDed into the query itself, so totals, pages and claims all respect it and nothing is filtered after the fact.
The situation
Some members work the whole queue. Others, such as a contractor, should see only the rows assigned to them. A list that fetches a page and then hides rows gets its counts and paging wrong.
The recipe
const lt = createClient({ auth: { userId } });const res = await lt.escalations.list({ status: 'pending', facets: { orderId: 'ORD-9' }, orderBy: [{ field: 'created_at', direction: 'asc' }], limit: 50, offset: 0,});// res.data: { escalations, total }| Caller | Sees |
|---|---|
| superadmin, or admin of admin | every role’s queue |
read_scope: all on a role |
the whole queue for that role |
read_scope: self on a role |
only rows assigned to them |
write_scope (none, self, all) sets which of those rows the member may claim, resolve or cancel.
The guarantee
The read-scope predicate is ANDed with the facets in one WHERE, and the page total is computed by the same WHERE. A caller may narrow with role or roles but never widen: a role they do not hold matches nothing. See Identity.
Related patterns
The queue as a market
Role is the wall, facets are capability
The role decides who can ever see a row. Metadata facets decide which consumer inside that role can take it.
Identity
Member scope profiles
Two scope axes on a membership give five profiles, from full worker to auditor, all enforced inside the query.
The queue as a market
A query that fits in a URL
Facets, ranges, exclusions and ordering ride as JSON query params, so any filtered queue is a link you can paste, pin or curl.
Identity
One-time user
Route one item to one named person with a self-scoped membership; they see and answer exactly that form and nothing else in the queue.
