1. JSON query from an invoice table or report
query.json
{
"version": "v1",
"source": "invoice",
"select": ["number", "status", "total", "customer.name"],
"where": {
"and": [
{ "field": "status", "op": "eq", "value": { "$param": "status" } },
{ "field": "total", "op": "gte", "value": { "$param": "minTotal" } }
]
},
"orderBy": [{ "field": "total", "direction": "desc" }],
"limit": { "$param": "limit" }
}
2. Registry policy owned by your backend
registry.ts
const policy = {
version: "v1",
sources: {
invoices: {
expose: true,
exposeAs: "invoice",
fields: {
number: { expose: true, filterable: true, sortable: true },
status: { expose: true, filterable: true },
totalCents: {
expose: true,
exposeAs: "total",
operators: ["eq", "gt", "gte", "lt", "lte"]
}
},
relations: {
customer: { expose: true, target: "customer", selectable: true }
}
}
}
};
3. Server route binds request params
server.ts
const result = await runtime.run({
spec: body.query,
params: {
status: body.status,
minTotal: body.minTotal,
limit: 25
},
explain: true
});
return Response.json({ rows: result.rows });
4. Approved query compiles to a SQLPlan
explain.sqlPlan
{
"dialect": "postgres",
"sql": "select ... where \"invoices\".\"status\" = $1 and \"invoices\".\"totalCents\" >= $2 limit $3",
"params": ["open", 10000, 25]
}