A named, tenant-scoped read.

Queries

A query is a named, tenant-scoped read. Pages call it by name, and scripts reach it as db.query(name, args):

app invoices "Invoices" {}

query overdue(days: number) = select number, total, due from Invoice where status != "paid" and due < days sort due asc limit 50

query revenue_by_month() = select month, sum (total) from Invoice where status == "paid" by month sort month desc

Expressions have one grammar and two destinations. In a guard, a validation or a browser-side gate, an expression lowers to JSONLogic. In a query, a related list, a rollup or a stat, it lowers to a statement run through the tenant-scoped data layer. You write the same thing either way; the compiler picks the target.