How a page runs
menu
└─ /page/run?param={page id}
├─ read the JSON from sys.page_def
├─ collect sql_id values into this session’s allowlist
└─ plus/ loads a component for each Body[].Type and renders it
when a component needs data
└─ POST /sql/run { sql_id, ...params }
├─ sql_id not on the allowlist → rejected
└─ otherwise → pre_sql, main_sql, post_sql in one transactionEach layer owns one job:
| Layer | What it holds | When you change it |
|---|---|---|
sys.page_def | Layout JSON | Page editor /page_editor |
sys.page_sql | Query and save SQL | SQL editor /sql_editor |
plus/ | Turns JSON into grids, forms, and the rest | Change the engine script and bump the asset version |
/sql/run | Runs SQL that is on the allowlist | The SQL engine on the server |
Page JSON is JSON5-like: trailing commas are allowed, and the browser parses it with eval. Any string value may be "js:" plus an expression, evaluated at runtime. See Page JSON.
/sql/run does not accept arbitrary SQL. The user has to open the page first. Only then does the server put that page’s declared sql_id values into the session. A call made without opening the page is rejected. A popup child page must also be listed in the parent’s SubPages. See Permissions and the SQL allowlist.