pgkiln 0.49.0 → 0.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/SECURITY.md +3 -0
  2. package/db/migrations/119_workspace_home.sql +30 -0
  3. package/db/migrations/120_datasets.sql +87 -0
  4. package/docs/apex-feature-parity.md +7 -6
  5. package/docs/guide/01-installation.md +5 -0
  6. package/docs/guide/03-builder.md +140 -11
  7. package/docs/guide/04-pages-and-regions.md +25 -1
  8. package/docs/guide/12-development.md +47 -11
  9. package/examples/hr/hr_63_datasets.sql +29 -0
  10. package/package.json +1 -1
  11. package/public/app.css +6 -0
  12. package/public/builder.css +95 -3
  13. package/public/code-editor.css +32 -79
  14. package/public/code-editor.js +58 -3
  15. package/public/data-modeler.css +17 -14
  16. package/public/worksheet.css +14 -7
  17. package/public/worksheet.js +119 -3
  18. package/src/app.ts +5 -1
  19. package/src/builder/changelog.ts +1 -1
  20. package/src/builder/data-modeler.ts +1 -1
  21. package/src/builder/datasets.ts +472 -0
  22. package/src/builder/db-users.ts +2 -2
  23. package/src/builder/home.ts +12 -7
  24. package/src/builder/instance.ts +2 -0
  25. package/src/builder/object-browser.ts +4 -4
  26. package/src/builder/querybuilder.ts +1 -1
  27. package/src/builder/quicksql.ts +1 -1
  28. package/src/builder/reporter.ts +52 -3
  29. package/src/builder/routes.ts +3 -3
  30. package/src/builder/scheduling.ts +2 -2
  31. package/src/builder/scripts.ts +1 -1
  32. package/src/builder/sql-charts.ts +1 -1
  33. package/src/builder/sql-monitor.ts +1 -1
  34. package/src/builder/subscriptions.ts +1 -0
  35. package/src/builder/table-editor.ts +2 -2
  36. package/src/builder/ui.ts +7 -5
  37. package/src/builder/worksheet.ts +171 -23
  38. package/src/builder/workspace-home.ts +283 -0
  39. package/src/builder/workspaces.ts +7 -4
  40. package/src/datasets.ts +367 -0
  41. package/src/i18n/ar.ts +16 -0
  42. package/src/i18n/cs.ts +16 -0
  43. package/src/i18n/da.ts +16 -0
  44. package/src/i18n/de.ts +16 -0
  45. package/src/i18n/el.ts +16 -0
  46. package/src/i18n/es.ts +16 -0
  47. package/src/i18n/fi.ts +16 -0
  48. package/src/i18n/fr.ts +16 -0
  49. package/src/i18n/he.ts +16 -0
  50. package/src/i18n/it.ts +16 -0
  51. package/src/i18n/ja.ts +16 -0
  52. package/src/i18n/ko.ts +16 -0
  53. package/src/i18n/nb.ts +16 -0
  54. package/src/i18n/pl.ts +16 -0
  55. package/src/i18n/pt.ts +16 -0
  56. package/src/i18n/ru.ts +16 -0
  57. package/src/i18n/sv.ts +16 -0
  58. package/src/i18n/tr.ts +16 -0
  59. package/src/i18n/uk.ts +16 -0
  60. package/src/i18n/zh.ts +16 -0
  61. package/src/i18n.ts +32 -0
  62. package/src/instance.ts +1 -0
  63. package/src/release-check.ts +139 -0
  64. package/src/reporting-app.ts +101 -0
  65. package/src/runtime/data-reporter.ts +199 -32
  66. package/src/session.ts +7 -0
  67. package/src/sqlworksheet.ts +9 -6
  68. package/src/subscriptions.ts +2 -1
  69. package/src/worksheet-txn.ts +270 -0
  70. package/src/workspace-export.ts +24 -4
package/SECURITY.md CHANGED
@@ -96,6 +96,9 @@ first version (MVP). Every finding below has a regression test in
96
96
  | Output | Auto-escaping HTML templates, strict CSP (no inline scripts, no inline styles: the page's one `<style>` carries a per-response nonce), `X-Frame-Options`, `nosniff`, `no-store`. Images may also come from the map tile server (`MAP_TILE_URL`, an http(s) origin only); map data travels as JSON in a `<script type="application/json">` element with `<` escaped. A map area in a report URL (`r<id>_bb`) is parsed into four range-checked numbers before it reaches SQL; anything else is ignored. The browser fetches tiles from that server directly, so it sees users' IP addresses, map areas and the site's origin (sent as `Referer`, which OpenStreetMap requires; never the page's path or query): self-host tiles where that matters. |
97
97
  | Files | Uploads are size- and type-checked and stored per session (`meta.temp_files` shows only the session's own files). A posted text value can't point a file item at another file, and a "remove file" value only removes files of the form's own record. Downloads need a checksum bound to user, page, item and record, check page access and read as the app's role (RLS applies). They are sent as attachments with `nosniff` and a sandboxing CSP; only PNG, JPEG, GIF, WebP and PDF are shown inline. |
98
98
  | Data loading and PDFs | The `data_load` process loads as the app's role (grants, RLS, triggers apply) and shows only data errors and `RAISE` messages per row. Report PDFs run the report's own query with the same page, region and row checks as the screen. |
99
+ | SQL Worksheet transactions (sprint 107) | A worksheet's open transaction is held in server memory under the caller's builder session id plus the tab key and checked against the workspace: every lookup starts from the caller's own session, so another developer or another sign-in never reaches it. Its connection is a plain client built from the workspace's developer login (or the *Run as* application's), never returned to a pool, and closed at the end, so `SET ROLE` reaches only roles that login has and nothing leaks into the builder's pools; *Run as* can't change while it is open. Rolled back on idle timeout, sign-out, session expiry, workspace switch, tab close and server stop, with `idle_in_transaction_session_timeout` as a backstop; at most `WORKSHEET_TXN_MAX_PER_DEVELOPER` per developer and `WORKSHEET_TXN_MAX` per server, each one database connection outside the pools. CSRF and a developer sign-in on every endpoint. |
100
+ | Release check (sprint 109) | Off by default (`PGKILN_RELEASE_CHECK`, or Instance settings for administrators). When on, the server sends one GET to GitHub's releases API at most once a day per process, with a 5-second timeout and a 1 MB limit, and sends nothing about the installation; only a semver version and an https link are kept from the answer, and they are escaped on the Workspace home. Pages never wait for it. |
101
+ | Data Reporter datasets and reporting applications (sprint 110) | Datasets are managed by the workspace's developers with CSRF on every POST; their schema must be one the workspace's SQL Workshop connection may use (never pgkiln's own or the system's), and tables, columns, joins and filters are checked against the catalog. The runtime builds a dataset's SELECT with quoted identifiers, literal values and whitelisted operators, and runs reports as the application's role. A reporting application's role gets SELECT only on the datasets' tables and views, so RLS applies; viewers never reach the report editor (report parameters in the URL are ignored), and only `admin_authz` users unpublish or delete others' reports. Dataset files are checked like a saved dataset before import. |
99
102
 
100
103
  ## Findings of the MVP review and their fixes
101
104
 
@@ -0,0 +1,30 @@
1
+ -- ---------------------------------------------------------------------
2
+ -- 119: the Workspace home (sprint 109, WS-1; APEX: the workspace home
3
+ -- page). The builder opens /builder/home after signing in: tool cards, the
4
+ -- workspace's top applications and users by page views over a reporting
5
+ -- timeframe, a summary of counts, the workspace message and a system
6
+ -- message.
7
+ --
8
+ -- meta.developer.home_timeframe: the reporting timeframe each developer
9
+ -- chose for Top applications and Top users (hour, day or week); null is
10
+ -- the default (day). A developer account is installation data: not
11
+ -- exported with an application or a workspace.
12
+ --
13
+ -- meta.workspace.builder_home: what an old /builder link opens in this
14
+ -- workspace (a workspace preference): null or 'apps' = the App Builder (as
15
+ -- before; the App Builder is also at /builder/apps), 'home' = a redirect to
16
+ -- the Workspace home. Travels in a workspace export's settings.
17
+ --
18
+ -- The "new version available" check is an instance setting
19
+ -- (meta.setting 'release_check' = 'on' / 'off'; else the environment
20
+ -- variable PGKILN_RELEASE_CHECK; off by default): no table needed.
21
+ -- ---------------------------------------------------------------------
22
+ alter table meta.developer
23
+ add column home_timeframe text check (home_timeframe in ('hour', 'day', 'week'));
24
+ comment on column meta.developer.home_timeframe is
25
+ 'The reporting timeframe of the developer''s Workspace home (119): hour, day or week; null = day.';
26
+
27
+ alter table meta.workspace
28
+ add column builder_home text check (builder_home in ('apps', 'home'));
29
+ comment on column meta.workspace.builder_home is
30
+ 'What /builder opens in this workspace (119): null or apps = the App Builder, home = the Workspace home.';
@@ -0,0 +1,87 @@
1
+ -- =====================================================================
2
+ -- 120: Data Reporter datasets (APEX 26.1: Data Reporter → Datasets)
3
+ --
4
+ -- A dataset is a reusable, trusted view of a workspace's data for business
5
+ -- users: tables and views of one schema, joined (the joins proposed from
6
+ -- foreign keys), the columns users may see with labels, format masks and
7
+ -- descriptions, and an optional row filter. Developers define datasets in
8
+ -- the builder (Data Reporter); a Data Reporter region offers a dataset as a
9
+ -- source with {"id": "...", "dataset": "<name>"} in config.sources, and
10
+ -- the runtime builds the dataset's SELECT from the definition (identifiers
11
+ -- quoted, values as literals, operators from a whitelist) and runs reports
12
+ -- on it as the application's database role, so grants and row level
13
+ -- security apply.
14
+ --
15
+ -- tables [{"alias": "t1", "table": "emp"},
16
+ -- {"alias": "t2", "table": "dept",
17
+ -- "join": {"to": "t1", "type": "left", "on": [{"column": "deptno", "ref": "deptno"}]}}]
18
+ -- columns [{"name": "ename", "table": "t1", "column": "ename", "label": "Name",
19
+ -- "format": "FML999G990D00", "description": "..."}]
20
+ -- filters [{"table": "t1", "column": "active", "op": "eq", "value": "true"}]
21
+ --
22
+ -- Per workspace, like the SQL Workshop's saved work. Installation data:
23
+ -- not part of an application's export (the builder's Data Reporter exports
24
+ -- and imports datasets as JSON files). The builder writes it as the owner;
25
+ -- the runtime reads it through its own login, and row level security shows
26
+ -- an isolated workspace's login its own workspace's datasets only.
27
+ -- =====================================================================
28
+ create table meta.dataset (
29
+ id bigint generated always as identity primary key,
30
+ workspace_id int not null default 1 references meta.workspace on delete cascade,
31
+ name text not null check (name ~ '^[a-z][a-z0-9_]{0,39}$'),
32
+ label text not null check (length(btrim(label)) between 1 and 80),
33
+ description text check (length(description) <= 500),
34
+ schema_name text not null check (length(schema_name) between 1 and 63 and schema_name !~* '^(pg_.*|information_schema|meta)$'),
35
+ tables jsonb not null check (jsonb_typeof(tables) = 'array' and jsonb_array_length(tables) between 1 and 10),
36
+ columns jsonb not null default '[]' check (jsonb_typeof(columns) = 'array' and jsonb_array_length(columns) <= 200),
37
+ filters jsonb not null default '[]' check (jsonb_typeof(filters) = 'array' and jsonb_array_length(filters) <= 5),
38
+ created_by text not null,
39
+ created_at timestamptz not null default now(),
40
+ updated_by text,
41
+ updated_at timestamptz not null default now(),
42
+ unique (workspace_id, name)
43
+ );
44
+ revoke all on meta.dataset from public;
45
+ grant select on meta.dataset to pgkiln_runtime;
46
+ comment on table meta.dataset is 'Data Reporter datasets per workspace (120): joined tables and views, offered columns, a row filter; installation data, not exported';
47
+
48
+ -- May this login see a workspace's datasets? An isolated workspace's login: its own only;
49
+ -- other logins: those of workspaces that are not isolated.
50
+ create function meta.dataset_visible(p_workspace int) returns boolean
51
+ language sql stable security definer set search_path = meta, pg_catalog as $$
52
+ select case when meta.login_workspace() is not null then p_workspace = meta.login_workspace()
53
+ else not coalesce((select w.isolated from meta.workspace w where w.id = p_workspace), false) end
54
+ $$;
55
+
56
+ -- The workspace whose datasets an application's Data Reporter offers (refused for an
57
+ -- application the login may not see).
58
+ create function meta.dataset_workspace(p_app_id int) returns int
59
+ language sql stable security definer set search_path = meta, pg_catalog as $$
60
+ select meta.app_workspace(meta.checked_app(p_app_id))
61
+ $$;
62
+
63
+ revoke all on function meta.dataset_visible(int), meta.dataset_workspace(int) from public;
64
+ grant execute on function meta.dataset_visible(int), meta.dataset_workspace(int) to pgkiln_runtime;
65
+
66
+ -- (090) an isolated workspace's logins see their own workspace's datasets only
67
+ alter table meta.dataset enable row level security;
68
+ create policy workspace on meta.dataset
69
+ using ((select meta.isolation_off()) or meta.dataset_visible(workspace_id));
70
+
71
+ -- ---------------------------------------------------------------------
72
+ -- Reporting applications: an application generated by the builder's Data
73
+ -- Reporter on one or more datasets (a Data Reporter region is its engine;
74
+ -- roles viewer, editor and administrator). The type is part of the
75
+ -- definition and travels with the export.
76
+ -- ---------------------------------------------------------------------
77
+ alter table meta.app drop constraint app_app_type_check;
78
+ alter table meta.app add constraint app_app_type_check
79
+ check (app_type in ('standard', 'theme', 'library', 'boilerplate', 'reporting'));
80
+ comment on column meta.app.app_type is 'standard, theme, library (components offered to other apps), boilerplate (a starting point for new apps) or reporting (120: generated on Data Reporter datasets)';
81
+
82
+ -- The number of reporting applications of a workspace (the workspace home's summary).
83
+ create function meta.reporting_app_count(p_workspace int) returns int
84
+ language sql stable security definer set search_path = meta, pg_catalog as $$
85
+ select count(*)::int from meta.app a where a.app_type = 'reporting' and meta.app_workspace(a.id) = p_workspace
86
+ $$;
87
+ revoke all on function meta.reporting_app_count(int) from public;
@@ -7,7 +7,7 @@ open item and open an issue or pull request; see [CONTRIBUTING.md](../CONTRIBUTI
7
7
  Legend: ✅ available · 🟡 partial (see notes) · ❌ not yet · ➖ not planned (a deliberate choice,
8
8
  or better served by the PostgreSQL ecosystem; see the notes and [extensions](guide/15-extensions.md))
9
9
 
10
- Last reviewed: 2026-10-16 (sprint 106: the change log of DDL change sets with Flyway, Liquibase and SQL downloads; sprint 104: RESTful Services modules, templates and handlers with PL/pgSQL and media handlers, privileges, OpenAPI and Try it; sprint 103: Schema Export / Import with pg_dump and pg_restore; sprint 102: the SQL Monitor with live sessions, Top SQL and a statement's plan; sprint 101: Scheduling of pg_cron jobs with a schedule builder, run now and run history; sprint 100: RESTful Services, tables and views published as REST endpoints with paging, filters, keys and OpenAPI; sprint 99: Administration → Database Users for PostgreSQL roles; sprint 98: the Data Modeler with relational diagrams, DDL and a data dictionary; sprint 97: charts of a query in the worksheet, saved charts and their dashboard; sprint 96: the SQL Workshop's Launchpad with pins and tool groups, the builder's search with Ctrl+K; sprint 95: Table Properties: create, edit or copy a table in a form with a DDL preview and Apply in one transaction; sprint 94: an object's menu with Open in a panel, Quick DDL, Add index / trigger / policy and Drop with dependents; sprint 93: worksheets saved as SQL Scripts with tabs and a Files list, Format, Convert case, find and replace, bind and substitution variables; sprint 92: the worksheet's Query Result with sort, value dialog, copy and downloads, plans as a tree with the slowest step and misestimates, SQL History with status, search and run again; sprint 91: the SQL Worksheet like Database Actions' SQL: navigator, Run Statement at the cursor and Run Script with a log per statement, Explain Plan, Autotrace, notices, history, Run as an application role; sprint 90: Comment Out in the page designer, gallery labels in title case; sprint 89: the Object Browser's schema, one row of tabs, blank NULLs, Modify column; sprint 88: home cards with colour bands and round icons, the hero on the page background, a page footer with the version and Back to top; sprint 87: the Create Application wizard reloads the page list for a schema, RLS badges, the alias from the name; sprint 86: the page designer by page number, HTML error pages in the builder; sprint 85: the Form Designer, beyond APEX; sprint 84: the date picker, facet menus; sprint 83: Component Settings and Component Groups; sprint 82: Report Queries; sprint 81: Application Computations and Shortcuts in Shared Components; sprint 80: the master grid's first row selected when the page opens and after a search; grid cells as text with their format mask until edited, with cell navigation by arrow keys, Enter, F2 and Escape; sprint 79: generated dashboards with sums, donuts and lines, leaving out charts that say nothing; applications open in their own light or dark mode until the user chooses, per application; a user menu with Appearance and Sign in when signed out; the developer toolbar's App and Page texts and debug state; the report search's column scope in the magnifier; sprint 78: generated faceted search reports with one column per foreign key, the faceted search's total row count, Show all and Yes/No values, one search field, friendly headings and number formats in generated grids and master-detail pages, friendly names in the Create Application wizard's page list; sprint 77: the Page Designer's layout and tree by display position, button positions, the tree's context menu with Duplicate and Copy to other page, Show Common / Show All, Go to group and the Template Options dialog; display positions, button positions and side-column page templates at runtime; sprint 76: the interactive report's menus and pagination, date items in the date format; sprint 75: the SQL Workshop's Object Browser and tabs; sprint 74: the builder's information architecture: Shared Components grid, Settings tabs, application home search and tasks; sprint 73: the Create Application wizard on one page with page types and features; sprint 72: the runtime chrome compared with APEX 26.2's: the developer toolbar, the Iris look, the navigation bar's Help menu and Install button; sprint 71: generated applications compared with APEX 26.2's: labels, foreign key names in reports, file columns, format masks, the Home page and the dashboard; sprint 70: treemap, sunburst and timeline charts; sprint 69: dragging tasks on a Gantt chart; sprint 68: the Data Reporter's welcome page, Find my workspace; sprint 67: REST source catalogs from OpenAPI documents, a workspace's export and import (two rows added); sprint 66: a blueprint from an existing application; sprint 65: facet charts; sprint 64: approval vacation rules and expiration policies; sprint 63: range, box plot and stock charts; sprint 62: workspace preferences (SQL Workshop and RESTful services per workspace), extension links, Manage backups across applications, SQL Workshop utilities with object reports, About Database and a database monitor; sprint 61: the builder's screens compared with APEX 26.1: the workspace sign-in page, the Administration menu with workspace message, environment banner and utilization, the SQL Workshop home, the App Gallery, application groups and cross application reports (four rows added); sprint 60: isolated workspaces with their own database logins, row-level security on pgkiln's tables and workspace database roles, workspace administrators; sprint 59: the Page Designer's help pane, Quick edit from the developer toolbar; sprint 58: page groups; sprint 57: region templates hero, title bar, buttons container, inline dialog and drawer, wizard with wizard progress, the carousel; sprint 56: Generate DDL and Schema Comparison in the SQL Workshop, `pgkiln ddl` and `pgkiln compare`; sprint 55: an editable login page with a Login region and the Minimal page template, Forgot password through the application's mail service; sprint 54: interactive grid views, the single row view, group by and chart; sprint 53: application settings, user preferences and items kept per user, dynamic translations, `meta.data_export` and data export downloads, display image and geocoded address items; sprint 52: every dynamic action event and action, Ajax callbacks, an error handling function, the session timeout warning; sprint 51: checked imports, application backups, availability and Run only, feedback, type-specific attribute help; sprint 50: lost update detection, warn on unsaved changes, the URL and search regions with search configurations, the developer toolbar with a session state viewer, and e-mail through SMTP with OAuth2, Microsoft Graph, Amazon SES and HTTP APIs; import checks, application availability, property help and e-mail compared again; 2026-10-06: pgkiln 0.31.0, in progress: static application files and the Execute JavaScript dynamic action; region, item, dynamic action and process plug-ins; conditional and dynamic theme styles; XML and Excel in `meta.parse_data`, zips in SQL, `meta.v_boolean`; file items in S3-compatible object storage; map layers by the visible area and as vector tiles; a graphical query builder; tenants for workflows and tasks; application files as YAML and region static IDs; Lucide icons and icon modifiers; PWA push notifications; 0.30.0: 136 icons and an icon picker; an axe-core accessibility audit; cropping pictures; session sharing between applications; twenty-two built-in languages; 0.29.0: workspaces; the Iris base style; drawers; built-in template components including the metric card; Theme Roller dark-mode colours, live preview and template options on items and report columns; report selection across pages; instance settings; fourteen built-in languages; 0.28.0: AI with Claude and OpenAI; 0.27.0: Data Reporter; sample data generator; create application from several sheets, pasted data or existing tables; 0.26.0: working copies with a three-way merge; theme, library and boilerplate applications with subscriptions; 0.25.0: Gantt, pyramid and polar charts; map layers, clustering and server-side spatial filters; REST data sources that write back from forms and grids and synchronise into tables, OAuth2 password and refresh-token grants; debug messages per request and an install/upgrade log; `meta.web_request()` and `meta.parse_data()`; Theme Roller style variants and template options; 0.24.0: automations with several actions, error handling per row and runs from SQL; invoke-API workflow steps; Unload Data in the Data Workshop; create page wizards for cards, calendar, chart, map, faceted search, form and master-detail; create an application from a file; 0.23.0: interactive grid aggregates, frozen/moved/resized columns, layouts and saved grid reports, master-detail, row actions and copy/paste; download processes, execution chains in the background, workflow processes, branches to a function's URL or another app, the Dialog Closed event; number format masks, automatic time zone, runtime messages in German, French and Spanish; SQL scripts, Quick SQL, a query builder, XML loading and data load definitions; custom authentication, lists, page and application locks with developer comments, supporting objects; 0.22.0: keyset paging, report PDFs and REST collections streamed from a cursor, database-account authentication; 0.21.0: HTTP-header authentication behind a reverse proxy; 0.20.0: a popup list of values with server-side search; 0.19.0: row-range pagination, maximum row counts and row limits, lazy loading and caching of regions, streamed CSV/Excel downloads; 0.18.0: calendar week/day/list views with drag and drop, bubble/gauge/funnel/radar charts and drill-down, smart filters, a region display selector and more facet types, computations, conditional branches, build options, menu buttons, REST data sources and web credentials, rich text/Markdown, rating, combobox, date range and QR code items; 0.17.0: an App Builder home, workspace dashboard and utilities like APEX's; 0.16.0: a Page Designer with drag-and-drop layout, a code editor with autocomplete, template components and plug-ins, parallel branches and versions of workflows, the `pgkiln` command line with one file per component; 0.15.0: drop and paste files, heat maps, filtering a report by the map area; 0.14.0: stacked, combo, scatter and pie charts, several files per upload item; 0.13.0: map and tree regions; 0.12.0: REST modules in the builder; 0.11.0: workflows and Progressive Web Apps; 0.10.0: LDAP, SAML, "Keep me signed in", document templates, JSON loading, approvals and the task list; pgkiln installs no application, HR is an example).
10
+ Last reviewed: 2026-10-19 (sprint 110: Data Reporter as a workspace tool with datasets, reporting applications, editors and viewers, published reports with stable URLs and pins; sprint 109: the Workspace home above the App Builder and SQL Workshop, with a summary, top applications, users and developers, and an optional release check; sprint 108: the code editor's syntax colours in the builder's light and dark themes, read-only SQL highlighted, the Data Modeler in dark mode; sprint 107: a transaction mode in the SQL Worksheet with Commit and Rollback; DA-18: JavaScript (MLE) not planned, plv8 where installed; sprint 106: the change log of DDL change sets with Flyway, Liquibase and SQL downloads; sprint 104: RESTful Services modules, templates and handlers with PL/pgSQL and media handlers, privileges, OpenAPI and Try it; sprint 103: Schema Export / Import with pg_dump and pg_restore; sprint 102: the SQL Monitor with live sessions, Top SQL and a statement's plan; sprint 101: Scheduling of pg_cron jobs with a schedule builder, run now and run history; sprint 100: RESTful Services, tables and views published as REST endpoints with paging, filters, keys and OpenAPI; sprint 99: Administration → Database Users for PostgreSQL roles; sprint 98: the Data Modeler with relational diagrams, DDL and a data dictionary; sprint 97: charts of a query in the worksheet, saved charts and their dashboard; sprint 96: the SQL Workshop's Launchpad with pins and tool groups, the builder's search with Ctrl+K; sprint 95: Table Properties: create, edit or copy a table in a form with a DDL preview and Apply in one transaction; sprint 94: an object's menu with Open in a panel, Quick DDL, Add index / trigger / policy and Drop with dependents; sprint 93: worksheets saved as SQL Scripts with tabs and a Files list, Format, Convert case, find and replace, bind and substitution variables; sprint 92: the worksheet's Query Result with sort, value dialog, copy and downloads, plans as a tree with the slowest step and misestimates, SQL History with status, search and run again; sprint 91: the SQL Worksheet like Database Actions' SQL: navigator, Run Statement at the cursor and Run Script with a log per statement, Explain Plan, Autotrace, notices, history, Run as an application role; sprint 90: Comment Out in the page designer, gallery labels in title case; sprint 89: the Object Browser's schema, one row of tabs, blank NULLs, Modify column; sprint 88: home cards with colour bands and round icons, the hero on the page background, a page footer with the version and Back to top; sprint 87: the Create Application wizard reloads the page list for a schema, RLS badges, the alias from the name; sprint 86: the page designer by page number, HTML error pages in the builder; sprint 85: the Form Designer, beyond APEX; sprint 84: the date picker, facet menus; sprint 83: Component Settings and Component Groups; sprint 82: Report Queries; sprint 81: Application Computations and Shortcuts in Shared Components; sprint 80: the master grid's first row selected when the page opens and after a search; grid cells as text with their format mask until edited, with cell navigation by arrow keys, Enter, F2 and Escape; sprint 79: generated dashboards with sums, donuts and lines, leaving out charts that say nothing; applications open in their own light or dark mode until the user chooses, per application; a user menu with Appearance and Sign in when signed out; the developer toolbar's App and Page texts and debug state; the report search's column scope in the magnifier; sprint 78: generated faceted search reports with one column per foreign key, the faceted search's total row count, Show all and Yes/No values, one search field, friendly headings and number formats in generated grids and master-detail pages, friendly names in the Create Application wizard's page list; sprint 77: the Page Designer's layout and tree by display position, button positions, the tree's context menu with Duplicate and Copy to other page, Show Common / Show All, Go to group and the Template Options dialog; display positions, button positions and side-column page templates at runtime; sprint 76: the interactive report's menus and pagination, date items in the date format; sprint 75: the SQL Workshop's Object Browser and tabs; sprint 74: the builder's information architecture: Shared Components grid, Settings tabs, application home search and tasks; sprint 73: the Create Application wizard on one page with page types and features; sprint 72: the runtime chrome compared with APEX 26.2's: the developer toolbar, the Iris look, the navigation bar's Help menu and Install button; sprint 71: generated applications compared with APEX 26.2's: labels, foreign key names in reports, file columns, format masks, the Home page and the dashboard; sprint 70: treemap, sunburst and timeline charts; sprint 69: dragging tasks on a Gantt chart; sprint 68: the Data Reporter's welcome page, Find my workspace; sprint 67: REST source catalogs from OpenAPI documents, a workspace's export and import (two rows added); sprint 66: a blueprint from an existing application; sprint 65: facet charts; sprint 64: approval vacation rules and expiration policies; sprint 63: range, box plot and stock charts; sprint 62: workspace preferences (SQL Workshop and RESTful services per workspace), extension links, Manage backups across applications, SQL Workshop utilities with object reports, About Database and a database monitor; sprint 61: the builder's screens compared with APEX 26.1: the workspace sign-in page, the Administration menu with workspace message, environment banner and utilization, the SQL Workshop home, the App Gallery, application groups and cross application reports (four rows added); sprint 60: isolated workspaces with their own database logins, row-level security on pgkiln's tables and workspace database roles, workspace administrators; sprint 59: the Page Designer's help pane, Quick edit from the developer toolbar; sprint 58: page groups; sprint 57: region templates hero, title bar, buttons container, inline dialog and drawer, wizard with wizard progress, the carousel; sprint 56: Generate DDL and Schema Comparison in the SQL Workshop, `pgkiln ddl` and `pgkiln compare`; sprint 55: an editable login page with a Login region and the Minimal page template, Forgot password through the application's mail service; sprint 54: interactive grid views, the single row view, group by and chart; sprint 53: application settings, user preferences and items kept per user, dynamic translations, `meta.data_export` and data export downloads, display image and geocoded address items; sprint 52: every dynamic action event and action, Ajax callbacks, an error handling function, the session timeout warning; sprint 51: checked imports, application backups, availability and Run only, feedback, type-specific attribute help; sprint 50: lost update detection, warn on unsaved changes, the URL and search regions with search configurations, the developer toolbar with a session state viewer, and e-mail through SMTP with OAuth2, Microsoft Graph, Amazon SES and HTTP APIs; import checks, application availability, property help and e-mail compared again; 2026-10-06: pgkiln 0.31.0, in progress: static application files and the Execute JavaScript dynamic action; region, item, dynamic action and process plug-ins; conditional and dynamic theme styles; XML and Excel in `meta.parse_data`, zips in SQL, `meta.v_boolean`; file items in S3-compatible object storage; map layers by the visible area and as vector tiles; a graphical query builder; tenants for workflows and tasks; application files as YAML and region static IDs; Lucide icons and icon modifiers; PWA push notifications; 0.30.0: 136 icons and an icon picker; an axe-core accessibility audit; cropping pictures; session sharing between applications; twenty-two built-in languages; 0.29.0: workspaces; the Iris base style; drawers; built-in template components including the metric card; Theme Roller dark-mode colours, live preview and template options on items and report columns; report selection across pages; instance settings; fourteen built-in languages; 0.28.0: AI with Claude and OpenAI; 0.27.0: Data Reporter; sample data generator; create application from several sheets, pasted data or existing tables; 0.26.0: working copies with a three-way merge; theme, library and boilerplate applications with subscriptions; 0.25.0: Gantt, pyramid and polar charts; map layers, clustering and server-side spatial filters; REST data sources that write back from forms and grids and synchronise into tables, OAuth2 password and refresh-token grants; debug messages per request and an install/upgrade log; `meta.web_request()` and `meta.parse_data()`; Theme Roller style variants and template options; 0.24.0: automations with several actions, error handling per row and runs from SQL; invoke-API workflow steps; Unload Data in the Data Workshop; create page wizards for cards, calendar, chart, map, faceted search, form and master-detail; create an application from a file; 0.23.0: interactive grid aggregates, frozen/moved/resized columns, layouts and saved grid reports, master-detail, row actions and copy/paste; download processes, execution chains in the background, workflow processes, branches to a function's URL or another app, the Dialog Closed event; number format masks, automatic time zone, runtime messages in German, French and Spanish; SQL scripts, Quick SQL, a query builder, XML loading and data load definitions; custom authentication, lists, page and application locks with developer comments, supporting objects; 0.22.0: keyset paging, report PDFs and REST collections streamed from a cursor, database-account authentication; 0.21.0: HTTP-header authentication behind a reverse proxy; 0.20.0: a popup list of values with server-side search; 0.19.0: row-range pagination, maximum row counts and row limits, lazy loading and caching of regions, streamed CSV/Excel downloads; 0.18.0: calendar week/day/list views with drag and drop, bubble/gauge/funnel/radar charts and drill-down, smart filters, a region display selector and more facet types, computations, conditional branches, build options, menu buttons, REST data sources and web credentials, rich text/Markdown, rating, combobox, date range and QR code items; 0.17.0: an App Builder home, workspace dashboard and utilities like APEX's; 0.16.0: a Page Designer with drag-and-drop layout, a code editor with autocomplete, template components and plug-ins, parallel branches and versions of workflows, the `pgkiln` command line with one file per component; 0.15.0: drop and paste files, heat maps, filtering a report by the map area; 0.14.0: stacked, combo, scatter and pie charts, several files per upload item; 0.13.0: map and tree regions; 0.12.0: REST modules in the builder; 0.11.0: workflows and Progressive Web Apps; 0.10.0: LDAP, SAML, "Keep me signed in", document templates, JSON loading, approvals and the task list; pgkiln installs no application, HR is an example).
11
11
 
12
12
  ## At a glance
13
13
 
@@ -22,8 +22,8 @@ Last reviewed: 2026-10-16 (sprint 106: the change log of DDL change sets with Fl
22
22
  | Globalization | 6 | 0 | 0 | 0 | One translated app like 26.1 with dynamic translations of table values; number format masks and automatic time zone; twenty-two built-in languages |
23
23
  | Data and integration | 13 | 0 | 0 | 2 | REST source catalogs from OpenAPI documents; Generate DDL and schema comparison; `meta.data_export` and data export downloads (CSV, JSON, XML, HTML, Excel, PDF); e-mail through SMTP (password or OAuth2), Microsoft Graph, Amazon SES and HTTP APIs; REST APIs via PostgREST, REST data sources that write back and synchronise, web credentials with OAuth2 grants, CSV/XLSX/JSON/XML loading with saved definitions and unloading, SQL scripts and Quick SQL, report PDFs and document templates |
24
24
  | Workflow, automation and AI | 6 | 0 | 0 | 0 | Scheduled automations with several actions and runs from SQL, approvals, a task list and workflows with parallel branches, versions and invoke-API steps; AI with Claude or OpenAI: *Generate text with AI*, an assistant region with tools, natural-language report filters and blueprints |
25
- | Administration | 11 | 0 | 0 | 0 | An APEX-like sign-in with a workspace; a workspace's components exported and imported as one file; workspace message, environment banner and utilization; isolated workspaces with their own database logins and roles, and workspace administrators; application availability and Run only, automatic backups, user feedback; a developer toolbar with a session state viewer and debug per session; Top SQL per app; debug messages per request; an install/upgrade log |
26
- | **Total** | **143** | **0** | **0** | **3** | 146 APEX features compared: 98% available, none partial or missing |
25
+ | Administration | 12 | 0 | 0 | 0 | An APEX-like sign-in with a workspace and a Workspace home; a workspace's components exported and imported as one file; workspace message, environment banner and utilization; isolated workspaces with their own database logins and roles, and workspace administrators; application availability and Run only, automatic backups, user feedback; a developer toolbar with a session state viewer and debug per session; Top SQL per app; debug messages per request; an install/upgrade log |
26
+ | **Total** | **144** | **0** | **0** | **3** | 147 APEX features compared: 98% available, none partial or missing |
27
27
 
28
28
  (Counts are of the rows in the tables below. A review on 2026-10-06 added 18 rows for APEX features that were
29
29
  not compared before, one on 2026-10-12 added two more (property help, application availability), and one on
@@ -194,7 +194,7 @@ two, REST source catalogs and the workspace export, with their features.)
194
194
  | Printing, document generator (PDF) | ✅ | **Document templates**: a query (with JSON columns for lines) fills an HTML template with Mustache-style tags, drawn as PDF with a report layout; buttons and links download them. (sprint 82) **Report queries**: a named query as PDF, Excel, CSV, JSON, XML or HTML. Report PDF with **report layouts** and a print stylesheet on every page. No Word/Excel templates or DOCX/XLSX output |
195
195
  | `APEX_DATA_EXPORT` (a query to CSV, XLSX, PDF, HTML or JSON from PL/SQL) | ✅ | (sprint 53) `meta.data_export(query, format, options)` returns CSV, JSON, XML or HTML as `bytea` with the caller's privileges; the download process's `{"export": …}` sends a query's rows as CSV, JSON, XML, HTML, Excel or PDF |
196
196
  | SQL Workshop utilities: schema comparison, generate DDL | ✅ | (sprint 56) SQL Workshop → **DDL**: a schema's objects (types, sequences, tables, functions, views, constraints, indexes, triggers, RLS and policies, comments, grants) from the catalog, in an order that runs, unqualified so it also creates them in another schema. **Compare**: two schemas by their DDL (only in one, different, with a diff) and a change script that makes the target like the source (tables column by column; drops commented out for review). Also `pgkiln ddl`, `pgkiln compare` and the MCP tools `generate_ddl`, `compare_schemas` ([chapter 3](guide/03-builder.md#sql-workshop)). Two schemas of the same database only (APEX: also within one workspace) |
197
- | Data Reporter: self-service reports for business users (26.1) | ✅ | A **Data Reporter** region ([chapter 4](guide/04-pages-and-regions.md#data_reporter-data-reporter)): the developer offers tables and views with chosen columns, labels and format masks; signed-in users pick columns, filter, group with totals (count, sum, average, minimum, maximum), sort and chart, and save reports privately or shared with the app's users. Runs as the app's role (grants and RLS apply); works without JavaScript and fits phones. (sprint 68) A **welcome page** like 26.1's: a greeting (the developer's own, or pgkiln's), the sources as cards that start a report, the user's reports latest first, shared ones, and a search. One source per report (offer a view to combine tables); no downloads from a reporter yet |
197
+ | Data Reporter: self-service reports for business users (26.1) | ✅ | A **Data Reporter** region ([chapter 4](guide/04-pages-and-regions.md#data_reporter-data-reporter)): the developer offers tables and views with chosen columns, labels and format masks; signed-in users pick columns, filter, group with totals (count, sum, average, minimum, maximum), sort and chart, and save reports privately or shared with the app's users. Runs as the app's role (grants and RLS apply); works without JavaScript and fits phones. (sprint 68) A **welcome page** like 26.1's: a greeting (the developer's own, or pgkiln's), the sources as cards that start a report, the user's reports latest first, shared ones, and a search. One source per report (offer a view to combine tables); no downloads from a reporter yet (sprint 110) **A workspace tool too**: App Builder → **Data Reporter** ([chapter 3](guide/03-builder.md#data-reporter-datasets-and-reporting-applications)) keeps **datasets** (tables and views of one schema with joins proposed from foreign keys, offered columns with labels, masks and descriptions, a row filter; files and the workspace export) and makes a **reporting application** on them in two clicks: viewers open published reports by a stable URL and pin them, editors build and publish, administrators moderate; every report runs as the application's SELECT-only role through RLS. |
198
198
  | REST Source Catalogs (Workspace Utilities) | ✅ | (sprint 67) Workspace utilities → **REST Source Catalogs**: a workspace's web services with a base URL and services, from an **OpenAPI 3 / Swagger 2.0** document (file, pasted or read from a URL on the allow-list), a catalog file or by hand: parameters (under the service's own names), row selector, typed columns and write-back operations from the response schemas and collection/item paths, with notes on what can't be used. An application's *REST data sources → From a REST source catalog* makes a data source from a service, with its own web credential ([chapter 19](guide/19-rest-data-sources.md#rest-source-catalogs)). **Missing:** YAML documents (convert to JSON), APEX's built-in catalogs (e.g. Oracle Fusion) |
199
199
  | JSON sources, duality views (24.2) | ➖ | PostgreSQL `jsonb` works in any SQL region, form or grid source |
200
200
  | Remote servers / database links | ➖ | `postgres_fdw` or `dblink` |
@@ -216,6 +216,7 @@ two, REST source catalogs and the workspace export, with their features.)
216
216
  | APEX | pgkiln | Notes |
217
217
  |---|---|---|
218
218
  | Developer accounts, workspace sign-in | ✅ | (sprint 61) The builder's sign-in page like APEX's: workspace (optional; it becomes the current one, a wrong one answers like a wrong password), username, password with a Show button, *Remember workspace and username*, a link to Administration. (sprint 68) **Find my workspace**: developers' e-mail addresses, and a mail with their workspaces through the builder's mail service (the same answer for every address, limited per address and IP). **Missing:** the sign-in page's language links (the builder is in English only) |
219
+ | Workspace home (tool cards, top apps and users, summary, workspace and system message) | ✅ | (sprint 109) `/builder/home` opens after sign-in ([chapter 3](guide/03-builder.md#workspace-home)): App Builder, SQL Workshop, Data Reporter and App Gallery cards; the workspace message edited in place; a Summary of applications, tables, developers and reporting applications; top applications, users and developers over an hour, a day or a week; a system message with the server's version and, with the optional release check (`PGKILN_RELEASE_CHECK`, off by default), *pgkiln X is available*. The App Builder moved to `/builder/apps`; `/builder` opens either, per workspace. |
219
220
  | Workspace message, environment banner, workspace utilization, preferences and extension links (Manage Service) | ✅ | (sprint 61) An **Administration** menu in the icon rail; administrators and workspace administrators set a **workspace message** (on the App Builder home) and an **environment banner** (a coloured label on every builder page of the workspace), and see **workspace utilization** (applications, pages, page views, users, static files, schema storage) ([chapter 3](guide/03-builder.md#workspace-message-and-environment-banner)). (sprint 62) **Workspace preferences**: the SQL Workshop and the applications' RESTful services (REST modules) on or off per workspace; **extension links** in an Extensions menu of the rail ([chapter 3](guide/03-builder.md#workspace-preferences)). **Missing:** the account login controls of APEX's preferences (pgkiln's password policy and sign-in throttling are installation-wide) |
220
221
  | Instance administration, install/upgrade logs (26.1) | ✅ | Versioned migrations (`npm run db:migrate`), every run logged; Workspace utilities → **Installation** (administrators): server version, install and upgrade runs with errors, applied migrations, and warnings for migrations the database misses or the server doesn't know ([chapter 3](guide/03-builder.md)). Workspace utilities → **Instance settings**: session length and sign-in throttling (stored in the database, over the environment variables) and an overview of the server's configuration without secrets; a server whose database lacks migrations says so (503) or applies them (`MIGRATE_ON_START`). Other settings stay environment variables |
221
222
  | Debug messages | ✅ | Debug levels 1–9 per app; `meta.debug(level, text)` and `meta.debug_enabled(level)` from application SQL (APEX_DEBUG); timed entries per request (page steps, regions, processes, branches, errors, SQL notices); Activity → **Debug messages** viewer per page view with filters and the slowest step highlighted; retention 1–90 days; password item values are never recorded ([chapter 6](guide/06-processing.md)). (sprint 50) Debug for **one session** from the developer toolbar, the application staying out of debug. **Missing:** debug entries for background jobs and REST requests |
@@ -343,7 +344,7 @@ AI and row level security badges.
343
344
  | Database Actions | pgkiln | |
344
345
  |---|---|---|
345
346
  | SQL worksheet: navigator, editor, output tabs, status bar | SQL Workshop → SQL Worksheet (sprint 91): navigator by schema and object type with columns, drag and drop and SELECT / INSERT / UPDATE / DELETE; Query Result, Script Output, Notices (DBMS Output), Explain Plan, Autotrace, SQL History; resizable panes, fullscreen | ✅ |
346
- | Run Statement (Ctrl+Enter), Run Script (F5) | The statement at the cursor or the selection; a script with a log per statement (psql command tags, error line and column), stop or continue on error; Run as an application's role | ✅ |
347
+ | Run Statement (Ctrl+Enter), Run Script (F5) | The statement at the cursor or the selection; a script with a log per statement (psql command tags, error line and column), stop or continue on error; Run as an application's role. (sprint 107) Beyond Database Actions, which commits every statement: a worksheet tab in **Transaction** mode keeps its statements in one transaction until Commit or Rollback, with a badge for the open transaction; rolled back after an idle timeout, on sign-out, when the tab closes or the server stops | ✅ |
347
348
  | Explain Plan (F10), Autotrace (F6) | A tree of steps (sprint 92): cost, rows, conditions; with Autotrace (`EXPLAIN ANALYZE, BUFFERS`, rolled back) actual time, rows, loops, buffers, each step's own time, the slowest step and 10× misestimates; the text plan too | ✅ |
348
349
  | Query Result grid (paging, download, sharing) | 500 rows (All rows: 10,000) with row numbers, numbers right-aligned, sort, a value dialog, copy, Download as CSV, JSON, XML, Excel or SQL inserts (sprint 92); no sharing links | ✅ |
349
350
  | SQL History, DBMS Output | SQL History per developer with status, rows, time, search and run again; Notices with their time (sprint 92) | ✅ |
@@ -359,4 +360,4 @@ AI and row level security badges.
359
360
  | Launchpad, Search Database (Ctrl+K) | The SQL Workshop home as a Launchpad (sprint 96): pinned and recently visited, Development / Administration / Monitoring tabs; Search (Ctrl+K) for tools, applications, pages and database objects; no guided walk-through | ✅ |
360
361
  | Data Pump | Schema Export / Import (sprint 103): `pg_dump` of a schema (custom or plain format, definitions and / or data, include / exclude tables) and `pg_restore` of a one-schema archive into a new or existing schema (create schema as: renamed in one transaction), background jobs with status, size, duration and log, files kept N days; plus application backups and Unload Data. Plain dumps can't be imported here; one schema per job | ✅ |
361
362
  | Liquibase | Schema Comparison; (sprint 106) SQL Workshop → **Change Log**: DDL run from the SQL Worksheet, Table Properties and Schema Comparison (*Apply and record*) is recorded as change sets per schema (author, time, SQL, source, a stable number), downloaded as Flyway files (`V0001__add_bonus.sql`), a Liquibase formatted SQL changelog or a plain script, and marked against the latest export of an application. **Missing:** rollback blocks, preconditions and contexts; DDL run outside the SQL Workshop (psql, migrations) is not recorded | ✅ |
362
- | JavaScript (MLE) | ➖ Not planned: PostgreSQL has plv8 as an extension | ➖ |
363
+ | JavaScript (MLE) | ➖ Not planned: PostgreSQL has plv8 as an extension; where it is installed, plv8 functions are written in the SQL Worksheet like any other ([chapter 3](guide/03-builder.md#sql-workshop)) | ➖ |
@@ -169,6 +169,9 @@ which is read at startup; real environment variables take precedence.
169
169
  | `SAMPLE_DATA_STATEMENT_TIMEOUT` | `5min` | Statement timeout of SQL Workshop → Sample Data (each insert of a preview or a run) |
170
170
  | `SAMPLE_DATA_MAX_ROWS` | `100000` | Most rows one Sample Data run generates (all tables together) |
171
171
  | `UNLOAD_STATEMENT_TIMEOUT` | `5min` | Statement timeout of SQL Workshop → Unload Data (each statement: the cursor and every batch of rows) |
172
+ | `WORKSHEET_TXN_IDLE_SECONDS` | `300` | SQL Worksheet transaction mode: seconds without a run before an open transaction is rolled back (10 to 86400) |
173
+ | `WORKSHEET_TXN_MAX_PER_DEVELOPER` | `3` | Open worksheet transactions per developer (each holds a database connection) |
174
+ | `WORKSHEET_TXN_MAX` | `20` | Open worksheet transactions on the server |
172
175
  | `REGION_CACHE_MAX_ENTRIES` | `1000` | Most regions in the [region cache](04-pages-and-regions.md#large-tables) of one server process (`0` turns caching off) |
173
176
  | `REGION_CACHE_MAX_MB` | `64` | Memory for the region cache of one server process |
174
177
  | `AUTOMATIONS` | on | `off` stops this server from running [automations](06-processing.md#automations) |
@@ -188,6 +191,8 @@ which is read at startup; real environment variables take precedence.
188
191
  | `PGKILN_REST_MAX_BYTES` | `5000000` | Largest web service response read (also after decompression) |
189
192
  | `MIGRATE_ON_START` | `false` | `true` applies missing migrations when the server starts. Without it, a server whose database lacks migrations answers every request with 503 and names the missing files until they are applied (`npm run db:migrate` or `pgkiln migrate`; no restart needed) |
190
193
  | `LOG_LEVEL` | `info` | `fatal`, `error`, `warn`, `info`, `debug`, `trace` |
194
+ | `PGKILN_RELEASE_CHECK` | `off` | `on`: the server asks GitHub once a day for a newer pgkiln release and the [Workspace home](03-builder.md#the-release-check) announces it. Administrators can also set it in the builder (Instance settings → *New versions*), which wins over the variable. Keep it off where the server may not reach the internet |
195
+ | `PGKILN_RELEASE_URL` | GitHub's releases API | For tests and mirrors only: the address of a JSON document like GitHub's `releases/latest` |
191
196
 
192
197
  ## npm scripts
193
198
 
@@ -6,7 +6,7 @@ The builder lives at `/builder`. Everything it does is also possible in SQL (see
6
6
  ## Signing in and developer accounts
7
7
 
8
8
  Sign in with a developer account. The first one is `admin` / `admin`, and a red banner reminds you
9
- to change it.
9
+ to change it. After signing in the builder opens the [Workspace home](#workspace-home) (`/builder/home`).
10
10
 
11
11
  The sign-in page (`/builder/login`) is laid out like APEX's: **Workspace** (optional), **Username** and
12
12
  **Password** (with a *Show* button). A workspace you name must be one of yours (administrators: any); it becomes the
@@ -75,7 +75,8 @@ its developers must not reach other teams' applications or data.
75
75
 
76
76
  Administrators and the workspace's administrators set them on the workspace's page (*Manage service*, or the
77
77
  Administration menu → *Workspace message and environment banner*; APEX: Define Workspace Message, Define Environment
78
- Banner): a **message** (plain text, up to 2000 characters) shown to the workspace's developers on the App Builder home,
78
+ Banner): a **message** (plain text, up to 2000 characters) shown to the workspace's developers on the
79
+ [Workspace home](#workspace-home) (where they can also edit it in place) and the App Builder home,
79
80
  and an **environment banner**: a label of up to 40 characters in one of eight colours, shown at the top of every
80
81
  builder page while the workspace is current.
81
82
 
@@ -95,6 +96,11 @@ Administrators and the workspace's administrators set them on the workspace's pa
95
96
 
96
97
  Both are on by default (migration 093) and are not exported.
97
98
 
99
+ - **Builder links open** (sprint 109, migration 119): what an address of just `/builder` (a bookmark from before the
100
+ Workspace home) opens in this workspace: the **App Builder** (the default: it is also at `/builder/apps`) or the
101
+ **Workspace home** (a redirect). Signing in always opens the Workspace home. It travels in a
102
+ [workspace export](#export-and-import)'s settings.
103
+
98
104
  ### Extension links
99
105
 
100
106
  Links to the other tools a workspace's developers use (monitoring, a wiki, a ticket system; APEX: Manage Extension
@@ -151,6 +157,7 @@ applications' files. Choose what goes in:
151
157
  | Extension links | Label, URL, description, order |
152
158
  | REST source catalogs | Every [catalog](19-rest-data-sources.md#rest-source-catalogs) with its services |
153
159
  | SQL scripts, blueprints, data generators | The SQL Workshop's saved work |
160
+ | Data Reporter datasets | Every [dataset](#data-reporter-datasets-and-reporting-applications) (sprint 110) |
154
161
 
155
162
  Never in the file: the workspace's name, its [isolation](#isolated-workspaces) and database roles, passwords and
156
163
  secrets, script runs and other history. **Applications are exported on their own** (an application's *Export*).
@@ -213,7 +220,8 @@ longer sign in. Delete a workspace only when it is shared and empty; its logins
213
220
 
214
221
  Every builder page has the same frame, modelled on an IDE:
215
222
 
216
- - **The icon rail** on the left: App Builder, SQL Workshop, [App Gallery](#app-gallery), **Search** (on the
223
+ - **The icon rail** on the left: Home (the [Workspace home](#workspace-home); the logo leads there too), App Builder,
224
+ SQL Workshop, [App Gallery](#app-gallery), [Data Reporter](#data-reporter-datasets-and-reporting-applications), **Search** (on the
217
225
  pages of an application); at the bottom the **Administration** menu (Workspace utilities; for administrators of the
218
226
  current workspace *Manage service*: [workspace message and environment banner](#workspace-message-and-environment-banner),
219
227
  [workspace utilization](#workspace-utilization) and the workspace's page; Manage users and groups, Developers,
@@ -235,7 +243,9 @@ On phones the rail gets narrower and the breadcrumb shows only the current page.
235
243
 
236
244
  The builder's look comes from design tokens at the top of `public/builder.css` (sprint 105): CSS custom properties
237
245
  for colours (a warm neutral palette with the kiln's ember for primary buttons, links, focus rings and selections),
238
- surfaces and their shadows, corner radii, the type scale and transitions, in a light and a dark set. The rail, the
246
+ surfaces and their shadows, corner radii, the type scale and transitions, in a light and a dark set; the code editor's syntax colours (`--ce-*`: keywords, strings, numbers, comments, binds,
247
+ quoted names, operators, the matching bracket, the current line, the selection and the line numbers) are tokens there
248
+ too (sprint 108). The rail, the
239
249
  toolbar and the status bar stay dark in both themes. Transitions are switched off when the operating system asks
240
250
  for reduced motion. The builder uses the system's fonts (Inter when it is installed); it loads nothing from
241
251
  other sites.
@@ -245,9 +255,43 @@ application of a workspace you are not a member of) shows a **Page not found** p
245
255
  theme with a link to the App Builder home; a server error shows **Something went wrong** (the error
246
256
  is in the server log, not on the page). Scripts get the plain answers they always got.
247
257
 
258
+ ## Workspace home
259
+
260
+ (sprint 109; APEX: the workspace home page) The page the builder opens after signing in, `/builder/home`, above the
261
+ App Builder and the SQL Workshop. Everything on it is of the current [workspace](#workspaces), and it works without
262
+ JavaScript. The [default-password banner](#signing-in-and-developer-accounts) stays on top until the password is changed.
263
+
264
+ - **Tool cards**: App Builder (`/builder/apps`), SQL Workshop (not when the workspace's preferences turn it off),
265
+ **Data Reporter** (when the server has the Data Reporter tool at `/builder/reporter`) and the [App Gallery](#app-gallery).
266
+ - **Workspace message**: the [workspace message](#workspace-message-and-environment-banner), plain text. The
267
+ workspace's administrators (and the installation's) edit it in place with **Edit message**; empty removes it.
268
+ - **Summary**: the number of applications (opens the App Builder), tables in the schemas the workspace's database
269
+ roles may use (opens the Object Browser), developers (opens Developers) and reporting applications (applications
270
+ made by [Data Reporter](#data-reporter-datasets-and-reporting-applications) → *Create reporting application*; opens
271
+ the Data Reporter).
272
+ - **Activity**: **Top applications** (page views and users), **Top users** and **Top developers** (page views by the
273
+ workspace's developers and the installation's administrators in its applications) over **1 hour**, **1 day** (the
274
+ default) or **1 week**. The timeframe is remembered for each developer (`meta.developer.home_timeframe`).
275
+ - **System message**: the pgkiln version the server runs and, when the [release check](#the-release-check) is on and
276
+ a newer release is out, **pgkiln X is available** with a link to its release notes and how to upgrade (back up,
277
+ install the new version, `pgkiln migrate`, restart).
278
+ - **A side column**: About, **Learn more** (this guide, the [tutorial](10-tutorial.md),
279
+ [Coming from APEX](11-from-apex.md), the changelog and the discussions on GitHub) and Resources.
280
+
281
+ ### The release check
282
+
283
+ Off by default. When it is on, the server asks GitHub's releases API (`api.github.com`) for the latest pgkiln release,
284
+ at most once a day per server process (an hour after a failure), with a 5-second timeout and a 1 MB limit; nothing
285
+ about the installation is sent. Pages never wait for it: they show what was fetched last and refresh it in the
286
+ background. Administrators turn it on or off on the Workspace home (**Check for new versions**, **Check now**,
287
+ **Turn off**) or on Workspace utilities → **Instance settings** → *New versions* (*On*, *Off*, or *As the environment
288
+ says*: the variable `PGKILN_RELEASE_CHECK`, [chapter 1](01-installation.md#configuration-reference)). Leave it off on a server
289
+ that may not reach the internet. Under the test runner the server never asks GitHub.
290
+
248
291
  ## App Builder home
249
292
 
250
- The home page is laid out like APEX's App Builder:
293
+ The App Builder's home page, `/builder/apps` (`/builder` shows it too, unless the workspace's
294
+ [preferences](#workspace-preferences) send `/builder` to the Workspace home), is laid out like APEX's App Builder:
251
295
 
252
296
  - **Four tiles**: **Create** and **Import** (each on its own page), the workspace **Dashboard**
253
297
  (applications, pages, active accounts; page views, users, failed sign-ins and errors of the last
@@ -290,6 +334,49 @@ The **App Gallery** (the cube in the icon rail, `/builder/gallery`; APEX: App Ga
290
334
 
291
335
  The list is `examples/gallery/gallery.json`; add your own starters there as blueprint files.
292
336
 
337
+ ## Data Reporter: datasets and reporting applications
338
+
339
+ **Data Reporter** in the icon rail (`/builder/reporter`, sprint 110; APEX 26.1: Data Reporter as a workspace tool)
340
+ gives business users reports on the workspace's data without a developer writing a page per question. Every
341
+ developer of the workspace manages it; the page lists the workspace's **datasets** and its **reporting
342
+ applications** (with their users and published reports).
343
+
344
+ A **dataset** (`meta.dataset`, per workspace) is a trusted view of the data: tables and views of one schema, joined,
345
+ the columns users may see, and a row filter.
346
+
347
+ - **New dataset**: choose a schema (those your [SQL Workshop](#sql-workshop) connection may use; never pgkiln's own
348
+ or the system's), tick tables and views (the first is the main one) and give it a name (lower case, it can't
349
+ change) and a label. **Joins are proposed from foreign keys** in either direction (a left join on the key's
350
+ columns); every column is offered, labelled from its name, numbers with a number mask.
351
+ - **The dataset's page**: its label and description; the tables with their joins (to an earlier table, left or
352
+ inner, *on* `column = its column`; add a table, remove one); the **columns** (offer or not, a name reports use, a
353
+ label, a [format mask](14-globalization.md) and a description users see in the report editor); up to five
354
+ **row filter** conditions (column, operator, value) that every report on it gets; the **query** it builds, and a
355
+ **preview** of ten rows (read only, through your SQL Workshop connection). The dataset is checked against the
356
+ database when it is saved: tables, views and columns must exist; the page says what doesn't match (any more).
357
+ - **Download** one dataset or **Export all** as a file (`*.dataset.json`, format `pgkiln-dataset/1`); **Import**
358
+ reads such a file (or pasted text) in one transaction: each dataset is checked against this installation's
359
+ database, and one with the same name is kept unless you choose *Replace*. Datasets also travel in the
360
+ [workspace export](#export-and-import); they are not part of an application's export.
361
+
362
+ **Create reporting application** (on a dataset's row or page: the form is filled in, so *Create* is the second
363
+ click) makes an application of type *Reporting* on one or more datasets: page 1 is a
364
+ [Data Reporter](04-pages-and-regions.md#data_reporter-data-reporter) region offering the datasets, users sign in with
365
+ their accounts of the [user directory](#users-the-user-directory), and the first administrator is the account you
366
+ name (yours by default). Its database role `app_<alias>` may only **read** (SELECT) the datasets' tables and views,
367
+ so every report runs through those grants and [row level security](08-security.md) (a view with
368
+ `security_invoker` needs grants on its own tables too: grant them to the role yourself). Give accounts access and
369
+ roles under the application's *Users and roles*:
370
+
371
+ | Role | May |
372
+ |---|---|
373
+ | viewer (or no role) | Open published reports (by their stable URL too), pin them |
374
+ | editor | Also build reports, save them, publish and unpublish their own |
375
+ | administrator | Also unpublish and delete anyone's reports |
376
+
377
+ The application is an ordinary pgkiln application otherwise: change its pages, theme or sign-in in the builder as
378
+ you like. `meta.reporting_app_count(workspace_id)` counts a workspace's reporting applications.
379
+
293
380
  ### Creating an application
294
381
 
295
382
  **Create** (a tile, or `/builder/create`) is one page, like APEX's Create Application wizard. Links at the top
@@ -704,7 +791,13 @@ handlers, the SQL Workshop and the import box) opens in a small code editor:
704
791
  binds, `&ITEM.` substitutions, `$$` bodies), JSON and HTML (tags, attributes, `&ITEM.` and
705
792
  `{{tags}}`). The language follows the component type: a `static` region's source is HTML, a
706
793
  `regex` validation is plain text, an `execute_sql` dynamic action is PL/pgSQL.
707
- - **Line numbers**, the line and column of the cursor, and the **matching bracket** marked.
794
+ - **Line numbers**, the line and column of the cursor, the **current line** (a band and its number in bold
795
+ while the field has the focus) and the **matching bracket** marked.
796
+ - **Colours from the builder's theme** (sprint 108): keywords take the kiln's ember, types, functions, strings,
797
+ numbers, binds and quoted names cool hues, comments a muted grey, each at least 4.5:1 (WCAG AA) on the editor's
798
+ background in the light and the dark theme. Read-only SQL (the Object Browser's DDL and source tabs, the Data
799
+ Modeler's DDL, generated SQL in Quick SQL, Query Builder, Scheduling, Database Users and the table editor, the SQL
800
+ Monitor's text, a saved chart's query, the Change Log, a script's results) is highlighted the same way.
708
801
  - **Tab / Shift+Tab** indent and outdent (the selected lines, too); **Enter** keeps the
709
802
  indentation and indents after `(`, `begin`, `loop`, `then`; brackets and quotes are closed for
710
803
  you and typing the closer steps over it. Press **Escape, then Tab** to move on to the next field.
@@ -748,7 +841,7 @@ out, other keys are kept, columns the query no longer returns stay listed so you
748
841
  | `display_selector` | Tabs or a select list, "Show all", remember the choice; per other region of the page: in a tab and the tab name (saved in that region's settings) |
749
842
  | `ai_assistant` | The AI service (those the application may use), system prompt, welcome text, placeholder, error message, tool rounds per question, questions per conversation, public or not, and the context queries and tools as JSON (checked when saving: query shapes, parameter types, REST data sources and authorization schemes that exist) ([AI assistant](04-pages-and-regions.md#ai_assistant-ai-assistant)) |
750
843
  | `report` (also) | *Ask in your own words (AI)*: the AI service and placeholder of the [natural-language filters](04-pages-and-regions.md#natural-language-filters-ask-in-your-own-words) |
751
- | `data_reporter` | Data sources (a table or view each: static id, label, description, offered columns with labels and format masks), who may share reports, rows per page ([Data Reporter](04-pages-and-regions.md#data_reporter-data-reporter)) |
844
+ | `data_reporter` | Data sources (a table or view each: static id, label, description, offered columns with labels and format masks; or (sprint 110) a dataset of the workspace), who may share, build and moderate reports, publishing, rows per page ([Data Reporter](04-pages-and-regions.md#data_reporter-data-reporter)) |
752
845
  | `form_designer` | Who may design forms (an authorization scheme), data sources (a table or view each: static id, label, description, key column, may add / change / delete rows, offered columns with labels and lists of values), rows per page ([Form Designer](04-pages-and-regions.md#form_designer-form-designer)) |
753
846
 
754
847
  Links, lists of values and the facets' report are checked when saving: a form can only point to
@@ -955,6 +1048,7 @@ application has a **type** (Settings → Application type):
955
1048
  | Theme application | Offers its theme (colours, navigation, light/dark settings and the Theme Roller's styles) and its template components to other applications |
956
1049
  | Library application | Offers its lists of values, authorization schemes, build options, template components and lists (with their entries) to other applications |
957
1050
  | Boilerplate application | A starting point: **Create** offers it under *Start from* |
1051
+ | Reporting application | (sprint 110) Made by [App Builder → Data Reporter](#data-reporter-datasets-and-reporting-applications) on datasets: its users build, publish and share reports |
958
1052
 
959
1053
  **Shared Components → Subscriptions** subscribes the application to one of those components: it is
960
1054
  copied now (replacing a component with the same name) and remembered as a subscription. The page
@@ -1381,11 +1475,41 @@ the SQL Workshop's connection may use. Without JavaScript the header's field ope
1381
1475
  (**Ctrl + F**, **Ctrl + H**) with a regular expression or exact case, **Go to line** (**Ctrl + G**), and
1382
1476
  **Ctrl + /** comments the selected lines out or in. The **?** menu lists every key; **F1** opens this help. The
1383
1477
  upload button opens Load Data for the navigator's schema.
1384
- - Each statement commits on its own. Statements run as the **owner connection** (an isolated workspace's
1478
+ - Each statement commits on its own (**Autocommit**, like Database Actions). Statements run as the **owner connection** (an isolated workspace's
1385
1479
  developer login for its developers), on a connection of their own that is closed afterwards, so `SET ROLE` or
1386
1480
  `SET search_path` doesn't leak. **Run as** picks an application of your workspace instead: the statements then
1387
1481
  run as its database role, with `pgkiln.app_id` set, so its grants and row level security policies apply. Use
1388
- it to test policies; it is no security boundary, since the SQL could `RESET ROLE`.
1482
+ it to test policies; it is no security boundary, since the SQL could `RESET ROLE`. A `BEGIN` typed in
1483
+ Autocommit lasts for the run only: `begin; …; commit;` in one Run Script works, but a transaction still open at
1484
+ the end of the run is rolled back, with a warning under *Notices*.
1485
+ - (sprint 107) **Transaction mode** (more than Database Actions, which always autocommits): the toolbar's
1486
+ **Commit** menu switches a worksheet tab between *Autocommit* and *Transaction*. In Transaction mode the tab's
1487
+ statements (Run Statement and Run Script) stay in one transaction on a connection of its own until you press
1488
+ **Commit** or **Rollback**: a SELECT in the same tab sees the changes, other sessions (and your other tabs) don't
1489
+ until you commit. A badge shows *Transaction open*, the number of statements and its age; after a reload it shows
1490
+ the server's real state, and leaving the page with an open transaction asks first.
1491
+ - `COMMIT` or `ROLLBACK` typed in the editor end the transaction too (the next run starts a new one); a `BEGIN`
1492
+ typed inside it only warns. Statements PostgreSQL refuses inside a transaction (`VACUUM`, `CREATE INDEX
1493
+ CONCURRENTLY`, `ALTER SYSTEM`, `CREATE DATABASE`, …) are refused before they run, so they can't abort it.
1494
+ - A statement that fails leaves the transaction **aborted** (*Transaction failed*): every later statement fails
1495
+ until **Rollback**; Commit then rolls back as well, and says so.
1496
+ - **Explain Plan** and **Autotrace** run inside the open transaction behind a savepoint: the plan sees its changes,
1497
+ Autotrace's own changes are undone and the transaction stays as it was.
1498
+ - **Run as**: the transaction keeps the role it started with. Changing *Run as* while it is open is refused:
1499
+ commit or roll back first. `SET ROLE` typed in the editor reaches only the roles of the connection's login, as
1500
+ in Autocommit.
1501
+ - DDL reaches the **Change Log** when the transaction commits, never when it is rolled back. SQL History records
1502
+ each statement as it runs.
1503
+ - The transaction is **rolled back** when it is left without a run for `WORKSHEET_TXN_IDLE_SECONDS` (default
1504
+ 300, five minutes; the badge and the next run say so), when you close its worksheet tab or switch it to
1505
+ Autocommit (after asking), sign out, switch workspaces, and when the server stops. The database ends the
1506
+ connection itself a minute later (`idle_in_transaction_session_timeout`) should the server not.
1507
+ - Each open transaction holds a database connection outside the pools: a developer has at most
1508
+ `WORKSHEET_TXN_MAX_PER_DEVELOPER` (default 3) and the server `WORKSHEET_TXN_MAX` (default 20); past that a run in
1509
+ Transaction mode is refused. A transaction belongs to the builder session, workspace and worksheet tab that
1510
+ started it: another developer, or another sign-in of yours, never reaches it. It lives in the server's memory,
1511
+ so with several pgkiln servers behind a load balancer the browser must stay on one (sticky sessions).
1512
+ - Without JavaScript the worksheet runs in Autocommit only.
1389
1513
  - With script, the panes fill the window. Drag the splitters (or focus one and use the arrow keys) to resize
1390
1514
  them, hide the navigator, or use **Fullscreen** to see only the editor (**Escape** leaves). Sizes are
1391
1515
  remembered in the browser. Without script, the buttons post the form and the panes stack; Run Statement then
@@ -1453,8 +1577,9 @@ the SQL Workshop's connection may use. Without JavaScript the header's field ope
1453
1577
  when the foreign key may be empty. A box's name opens **Table Properties** (a view: the Object
1454
1578
  Browser). The toolbar: **Save** (Ctrl+S), **Undo** / **Redo** (Ctrl+Z, Ctrl+Y), **Zoom out** / **Zoom
1455
1579
  in** (or Ctrl+wheel), **Fit**, **Auto layout** (referenced tables to the left of the tables that
1456
- reference them; undoable), a **Mini-map** (click or drag in it to move around), **SVG** and **PNG**
1457
- exports of the diagram as shown, **Print**, **Generate DDL** (the CREATE statements of the shown
1580
+ reference them; undoable), a **Mini-map** (click or drag in it to move around; the button shows when it is on),
1581
+ **SVG** and **PNG** exports of the diagram as shown (in light colours, whichever theme the builder uses; on screen the
1582
+ boxes, lines and mini-map follow the light or dark theme), **Print**, **Generate DDL** (the CREATE statements of the shown
1458
1583
  objects with their keys, indexes, triggers, row level security, policies, comments and grants: to
1459
1584
  download or open in the SQL Worksheet) and **Data dictionary** (each object's columns with type,
1460
1585
  nullability, default, keys and comments, its constraints and what references it; to print, save as
@@ -1526,6 +1651,10 @@ the SQL Workshop's connection may use. Without JavaScript the header's field ope
1526
1651
  **Flyway** versioned migrations (`V0001__add_bonus.sql`; several in a zip), a **Liquibase** formatted SQL changelog
1527
1652
  (`--liquibase formatted sql`, `--changeset author:0001-add_bonus`) or one plain SQL script; each change set also
1528
1653
  has its own Flyway file. Change sets belong to the workspace and are not part of an application export.
1654
+ - **JavaScript (MLE)**: not planned. Database Actions has a JavaScript tool for Oracle's Multilingual Engine;
1655
+ PostgreSQL runs JavaScript in the database only through the [plv8](15-extensions.md) extension. Where plv8 is
1656
+ installed, write `create function … language plv8` in the SQL Worksheet like any other function: the navigator,
1657
+ the Object Browser and Quick DDL show it. pgkiln adds no JavaScript editor of its own.
1529
1658
  - **Utilities** (`/builder/sql/utilities`; APEX: SQL Workshop → Utilities): tiles for Load and Unload Data, Sample
1530
1659
  Data, the Query Builder, DDL and Compare, and three pages of their own. Each runs in a read-only transaction with a
1531
1660
  15-second statement timeout, on the SQL Workshop's connection (an isolated workspace's developers see only the
@@ -1186,9 +1186,12 @@ Attributes (written by the region's **Settings**):
1186
1186
 
1187
1187
  | Key | Default | Meaning |
1188
1188
  |---|---|---|
1189
- | `sources` | | `[{"id": "orders", "label": "Orders", "description": "…", "schema": "sales", "table": "order_v", "columns": [{"name": "total", "label": "Total", "format": "FML999G990D00"}]}]` |
1189
+ | `sources` | | `[{"id": "orders", "label": "Orders", "description": "…", "schema": "sales", "table": "order_v", "columns": [{"name": "total", "label": "Total", "format": "FML999G990D00"}]}]`; (sprint 110) or a dataset: `{"id": "sales", "dataset": "sales"}` (label and description optional) |
1190
1190
  | `sharing` | `true` | `false`: reports stay private |
1191
1191
  | `share_authz` | | An authorization scheme: only users that pass it may share reports |
1192
+ | `edit_authz` | | (sprint 110) An authorization scheme: only users that pass it build, change, save and delete reports; the others only run shared ones |
1193
+ | `admin_authz` | | (sprint 110) An authorization scheme: users that pass it unpublish and delete anyone's reports |
1194
+ | `publishing` | `false` | (sprint 110) `true`: shared reports are *published*: a stable URL, Publish / Unpublish buttons, pins |
1192
1195
  | `page_size` | `25` | Rows per page of a detail report (5 to 200) |
1193
1196
  | `welcome` | `true` | `false`: the compact start (a list of sources and *Start*) instead of the welcome page |
1194
1197
  | `welcome_title`, `welcome_text` | | The welcome page's greeting instead of pgkiln's (translated like other application texts) |
@@ -1200,6 +1203,27 @@ region when an application is replaced. The HR example's page 36 (*My reports*)
1200
1203
  (a view without the user name and photo columns) and leave requests (row level security: an
1201
1204
  employee sees only their own), with King's shared report *Salary by department*.
1202
1205
 
1206
+ #### Datasets and reporting applications
1207
+
1208
+ (sprint 110) A source may be a **dataset** of the workspace ([App Builder → Data
1209
+ Reporter](03-builder.md#data-reporter-datasets-and-reporting-applications)): tables and views of one schema with
1210
+ their joins, the offered columns with labels, format masks and descriptions (shown under the column in the editor),
1211
+ and a row filter. The region's Settings add one under *Add a data source → Or a dataset of the workspace*. The
1212
+ runtime reads the dataset when the page is drawn and builds its SELECT from the definition (identifiers quoted,
1213
+ values escaped literals, operators from the whitelist), and the report runs on it as a subquery, as the
1214
+ application's database role. A dataset that was deleted disappears from the region; a column that no longer exists
1215
+ makes the report show an error.
1216
+
1217
+ With **`publishing`**, shared reports are *published*: an editor saves a report privately and **Publishes** it
1218
+ (or ticks *Publish for all users* when saving), and **Unpublishes** it again. A published report has a **stable
1219
+ URL**, `/a/<alias>/reports/<id>`, shown on the report: it opens the report on its page (signing in first), so it
1220
+ can be bookmarked or sent. Every signed-in user may **Pin** a published report: pinned reports come first on the
1221
+ welcome page (a [preference](06-processing.md) of the user, `reporter.pins.<region>`). Users that don't pass
1222
+ `edit_authz` see only the published reports: no *New report* cards, no editor (report parameters in the URL are
1223
+ ignored), no saving. Users that pass `admin_authz` unpublish and delete anyone's reports. The HR example's dataset
1224
+ `hr` (`examples/hr/hr_63_datasets.sql`: employees with their department, active ones only) is the one a reporting
1225
+ application is made from in the guide's chapter 3.
1226
+
1203
1227
  ### `form_designer` (Form Designer)
1204
1228
 
1205
1229
  A **Form Designer** region (sprint 85; pgkiln's own, APEX has no counterpart) lets the application's