pgkiln 0.53.0 → 0.54.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.
package/SECURITY.md CHANGED
@@ -108,6 +108,7 @@ first version (MVP). Every finding below has a regression test in
108
108
  | Pillar navigation appearances (sprint 117) | The appearance and the header strip colours are changed only by a developer with the CSRF token; only keys of a fixed list and `#rrggbb` colours are saved, and a hand-edited theme can't put markup or CSS into the page (a `<body>` class and the nonce'd `<style>`). A strip colour from an item is used only when the value is `#rrggbb`. |
109
109
  | Mail queue, workspace mail and network access (sprint 118) | Administration → Mail queue: administrators see every workspace, a workspace's administrators only their current workspace's applications, other developers get 403; Retry and Purge (one mail or all failed) check the mail's workspace again on the server and need the CSRF token; bodies and attachments are never shown. A workspace's own mail service is managed by its administrators only; its secret is encrypted like a web credential's, write-only, never shown or exported (not in the workspace export); it has no API base URL or token URL, and its SMTP host must pass the installation's allow-list and the workspace's network access list and resolve to a public address (unless `PGKILN_REST_PRIVATE_HOSTS` lists it), resolved once and connected to by that address (no DNS rebinding). A workspace's network access list narrows `PGKILN_REST_ALLOWED_HOSTS` on the server for every outgoing web call of its applications (`meta.web_request`, REST data sources incl. write-back and the response cache, invoke API, token endpoints, object storage, the builder's Test, REST source catalogs), on every redirect hop; it can't widen the installation's list or the private-address checks. Refusals go to the debug log and `meta.network_refusal` (7 days). Also fixed: *REST source catalogs → read from a URL* fetched the URL before checking the developer's session (any visitor could make the server call an allowed host); it is now read only after the developer and CSRF checks. |
110
110
  | Data security per table (sprint 119) | SQL Workshop → a table → Security writes `GRANT` / `REVOKE` and a masking view, so it needs a signed-in developer and the CSRF token, and works only on tables of the workspace's schemas (never pgkiln's own or the system's: 404). Table, column, view and role names reach SQL quoted; view names and application roles that could break out of their quotes are refused. The masking role is `nologin`, a member of the reader roles, so row level security still applies inside the view, and the generated SQL refuses to run when that role would bypass RLS. MCP `run_query` with an application runs as that application's database role (read-only) and refuses unknown applications. |
111
+ | App Gallery (sprint 120) | Installing a sample app runs shipped SQL as the owner, so only administrators may, with the CSRF token, into their current workspace; a request names only a key of `gallery.json` of its own kind (sample, starter, utility), never a path, and the file names in the catalogue must match fixed patterns. The script and the workspace placement run in one transaction: a failing script leaves nothing behind. Utility apps are blueprints: any developer installs one into their own workspace, only after the review. An installed sample is edited only from its own workspace. The search term is escaped. |
111
112
 
112
113
  ## Findings of the MVP review and their fixes
113
114
 
@@ -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-20 against **APEX 26.2** (sprint 119: data security per table, a roles × columns matrix and masked values per application role in a masking view, the same identity for pages, AI tools, REST, AutoREST and MCP (WS-13); sprint 118: Administration → Mail queue with delivery per hour and per workspace, the slowest provider calls and failures with Retry and Purge, a workspace's own mail service, and workspace network access lists that narrow the installation's allow-list (WS-9); sprint 117: Pillar Light and Pillar Dark navigation appearances with a header strip, clearer navigation tree states, subtle colour utilities, RTL; sprint 116: the comparison moved from 26.1 to 26.2, with a section for the 26.2 workspace items WS-1 … WS-13 and OCI managed identities; the App Builder list with Updated by, working copies and the lock; `pgkiln import --only`, a file-level import; stale rows on facet menus and blueprints fixed; sprint 115: popup LOVs that load on scroll, Wait Popup dynamic actions and dynamic actions on menu entries; sprint 114: Workflow 26.2 with custom task outcomes, task events and notifications, Send E-Mail and draft steps, migrating running instances and the diagram as SVG / PNG; sprint 113: Team Development with issues, labels, milestones, templates, a board and a set-up wizard; sprint 112: AI interactive reports with chips, Undo, computed columns and a phrase parser that needs no AI service; sprint 111: AI Agents with tools as a shared component, a Navigate tool with checksummed URLs, Gemini and OpenAI-compatible services; 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).
10
+ Last reviewed: 2026-10-20 against **APEX 26.2** (sprint 120: the App Gallery's single-topic sample apps (charts, cards, calendar, interactive grids, dynamic actions, reporting), the UX Pattern Catalog and a Utility Apps tab with Lookup Lists, Release Notes and Announcements (WS-8); sprint 119: data security per table, a roles × columns matrix and masked values per application role in a masking view, the same identity for pages, AI tools, REST, AutoREST and MCP (WS-13); sprint 118: Administration → Mail queue with delivery per hour and per workspace, the slowest provider calls and failures with Retry and Purge, a workspace's own mail service, and workspace network access lists that narrow the installation's allow-list (WS-9); sprint 117: Pillar Light and Pillar Dark navigation appearances with a header strip, clearer navigation tree states, subtle colour utilities, RTL; sprint 116: the comparison moved from 26.1 to 26.2, with a section for the 26.2 workspace items WS-1 … WS-13 and OCI managed identities; the App Builder list with Updated by, working copies and the lock; `pgkiln import --only`, a file-level import; stale rows on facet menus and blueprints fixed; sprint 115: popup LOVs that load on scroll, Wait Popup dynamic actions and dynamic actions on menu entries; sprint 114: Workflow 26.2 with custom task outcomes, task events and notifications, Send E-Mail and draft steps, migrating running instances and the diagram as SVG / PNG; sprint 113: Team Development with issues, labels, milestones, templates, a board and a set-up wizard; sprint 112: AI interactive reports with chips, Undo, computed columns and a phrase parser that needs no AI service; sprint 111: AI Agents with tools as a shared component, a Navigate tool with checksummed URLs, Gemini and OpenAI-compatible services; 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
 
@@ -23,8 +23,8 @@ Last reviewed: 2026-10-20 against **APEX 26.2** (sprint 119: data security per t
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
25
  | Administration | 14 | 0 | 0 | 0 | An APEX-like sign-in with a workspace and a Workspace home; a mail queue dashboard, a workspace's own mail service and network access list (26.1 / 26.2); 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
- | APEX 26.2 workspace (WS-1 … WS-13) | 11 | 0 | 2 | 1 | Workspace home, Data Reporter as a workspace tool, Team Development, AI Agents, AI interactive reports, Workflow 26.2, the mail queue, workspace mail and network access, the 26.1 component details, the App Builder list's details, the Pillar navigation appearances and data security per table (rows, columns and masked values); not yet: the builder in more languages, more gallery apps |
27
- | **Total** | **159** | **0** | **2** | **4** | 165 APEX features compared: 96% available, two missing (the open 26.2 workspace items) |
26
+ | APEX 26.2 workspace (WS-1 … WS-13) | 12 | 0 | 1 | 1 | Workspace home, Data Reporter as a workspace tool, Team Development, AI Agents, AI interactive reports, Workflow 26.2, the mail queue, workspace mail and network access, the 26.1 component details, the App Builder list's details, the Pillar navigation appearances and data security per table (rows, columns and masked values), the App Gallery's single-topic sample apps, UX Pattern Catalog and Utility Apps; not yet: the builder in more languages |
27
+ | **Total** | **160** | **0** | **1** | **4** | 165 APEX features compared: 97% available, one missing (the open 26.2 workspace item WS-7) |
28
28
 
29
29
  (Counts are of the rows in the tables below. A review on 2026-10-06 added 18 rows for APEX features that were
30
30
  not compared before, one on 2026-10-12 added two more (property help, application availability), and one on
@@ -57,7 +57,7 @@ the 26.2 comparison.)
57
57
  | Builder search, "where used" | ✅ | Search over every page and component (names, SQL, settings, help); "Used in" under items, pages, lists of values, schemes and report layouts. No search and replace |
58
58
  | AI assistant, pages from natural language, describe tables for LLMs (26.1) | ✅ | **App Builder AI** (administrators choose the builder's AI service): SQL Workshop → AI writes SQL from a question (shown in an editor, never run automatically), explains a query or an error, and describes tables and columns for LLMs (notes, optionally `COMMENT ON`, with AI drafts from names, types and keys only); **Create pages with AI** turns a description into proposed pages that the developer edits and confirms ([chapter 3](guide/03-builder.md)). The model never sees table rows |
59
59
  | Sample data source for development (26.1) | ✅ | SQL Workshop → **Sample Data** ([chapter 16](guide/16-files.md#sql-workshop--sample-data)): generators proposed per column from the catalog and column names (names, e-mail addresses, phones, companies, addresses, words and sentences, codes, number/date/time ranges, booleans, value lists from enums and CHECKs, sequences, foreign keys picking existing or newly inserted parent rows, values relative to another column, % nulls; identity/serial/generated columns skipped; unique and simple CHECK constraints respected), rows per table, a seed for repeatable data, preview (inserted and rolled back), insert in one transaction with parents first, download as SQL INSERTs or CSV, saved generator definitions |
60
- | App Gallery: sample, starter and custom apps | ✅ | (sprint 61) The **App Gallery** in the builder ([chapter 3](guide/03-builder.md#app-gallery)): *Sample Apps* shipped with pgkiln (HR Demo, Tasks) installed by administrators; *Starter Apps* (Team Tasks, Contacts, Expense Claims, Asset Inventory, Event Registrations) shipped as blueprints, created after their review in the current workspace with a role and schema of their own; *Custom Apps*: the workspace's boilerplates. **Missing:** a gallery fed from a remote catalogue |
60
+ | App Gallery: sample, starter and custom apps | ✅ | (sprint 61) The **App Gallery** in the builder ([chapter 3](guide/03-builder.md#app-gallery)): *Sample Apps* shipped with pgkiln (HR Demo, Tasks) installed by administrators; *Starter Apps* (Team Tasks, Contacts, Expense Claims, Asset Inventory, Event Registrations) shipped as blueprints, created after their review in the current workspace with a role and schema of their own; *Custom Apps*: the workspace's boilerplates; (sprint 120) single-topic sample apps, the UX Pattern Catalog and *Utility Apps* (see WS-8 below). **Missing:** a gallery fed from a remote catalogue |
61
61
  | Application groups | ✅ | (sprint 61) Workspace utilities → **Application groups**: a workspace's named groups, a group per application, a group filter and labels on the App Builder home ([chapter 3](guide/03-builder.md#application-groups)) |
62
62
  | Cross application reports | ✅ | (sprint 61) In Workspace utilities' side column, over every application of the workspace: application attributes, build options, developer comments, authentication, authorization schemes, password items and theme summary |
63
63
 
@@ -250,7 +250,7 @@ row above where there is one.
250
250
  | WS-5 AI interactive reports: chips, computed columns | ✅ | (sprint 112) *Ask in your own words* with chips, Undo and computed columns; a phrase parser that needs no AI service. Not yet: phrases mapped to facets and smart filters |
251
251
  | WS-6 Workflow 26.2: outcomes, migrating running instances, drafts, diagram export | ✅ | (sprint 114) Custom task outcomes, task events, Send E-Mail and draft steps, migrating running instances, the diagram as SVG / PNG ([Workflow, automation and AI](#workflow-automation-and-ai)) |
252
252
  | WS-7 The builder in more languages | ❌ | Applications have twenty-two built-in languages; the builder and its sign-in page are English only |
253
- | WS-8 App Gallery: more sample apps, Utility Apps | ❌ | Sample apps HR Demo and Tasks, five starter apps and custom apps; no Utility Apps tab, no single-topic sample apps or UX Pattern Catalog |
253
+ | WS-8 App Gallery: more sample apps, Utility Apps | ✅ | (sprint 120) Four tabs with counts and a search that also works without JavaScript ([chapter 3](guide/03-builder.md#app-gallery)). *Sample Apps*: HR Demo, Tasks, six single-topic apps (Sample Charts, Sample Cards, Sample Calendar, Sample Interactive Grids, Sample Dynamic Actions, Sample Reporting) and the **UX Pattern Catalog**, each with its own schema, data, demo account and explanatory texts, installed by administrators from one SQL file in one transaction; *Utility Apps*: Lookup Lists, Release Notes and Announcements as blueprints any developer installs into the workspace. APEX's 27 sample apps include topics pgkiln shows in HR Demo instead (maps, approvals, workflows, REST); no remote catalogue |
254
254
  | WS-9 Mail queue reporting, workspace SMTP, workspace network ACLs | ✅ | (sprint 118) Administration → Mail queue (per hour and per workspace / application, the slowest provider calls, failures with the provider's answer, Retry and Purge), a workspace's own mail service, and a workspace's network access list that narrows the installation's allow-list for every outgoing call ([Administration](#administration)) |
255
255
  | WS-10 Universal Theme 26.2: Pillar appearances, navigation polish | ✅ | (sprint 117) Theme Roller → Navigation appearance Pillar Light / Pillar Dark per application or style, with a header strip colour for light and dark mode; the current page filled, its parents bold with an accent guide line; `u-color-*-subtle` utilities; a lighter processing indicator; RTL mirrored |
256
256
  | WS-11 26.1 component details: infinite scrolling LOVs, Wait Popup, dynamic actions on menu entries | ✅ | (sprint 115) Popup LOVs that load on scroll, Wait Popup dynamic actions, the *Menu entry chosen* event ([Items](#items), [Logic and processing](#logic-and-processing)) |
@@ -329,20 +329,53 @@ leaves its group. Every developer of the workspace manages them.
329
329
 
330
330
  ## App Gallery
331
331
 
332
- The **App Gallery** (the cube in the icon rail, `/builder/gallery`; APEX: App Gallery) has three tabs:
333
-
334
- - **Sample Apps**: applications shipped with pgkiln (HR Demo, Tasks) with their own schema, data and **demo accounts
335
- with known passwords**, so install them on a development or demo instance only. Administrators install them (the
336
- same scripts as `pgkiln migrate --example hr`); they go into the current workspace. An installed one shows Run and
337
- Edit.
332
+ The **App Gallery** (the cube in the icon rail, `/builder/gallery`; APEX: App Gallery) has four tabs, each with
333
+ the number of its apps. The search field filters the tab's cards as you type (without JavaScript it searches on the
334
+ server, `?q=`); every word must be in the title or the description.
335
+
336
+ - **Sample Apps**: applications shipped with pgkiln, each with its own schema, data and **demo account with a known
337
+ password**, so install them on a development or demo instance only. Administrators install them; they go into the
338
+ current workspace (an isolated workspace gets the application's role too). An installed one shows Run, and Edit
339
+ in its own workspace (*in another workspace* elsewhere). They are:
340
+ - **HR Demo**, the showcase of nearly every feature (the same scripts as `pgkiln migrate --example hr`), and
341
+ **Tasks**, the [tutorial](10-tutorial.md);
342
+ - single-topic apps (sprint 120; APEX: Sample Charts, Sample Cards, Sample Calendar, Sample Interactive Grids,
343
+ Sample Dynamic Actions, Sample Reporting), small apps that show one feature area with a text on every page that
344
+ says how it is made: **Sample Charts** (all 22 chart types on a page per question, and a drill-down),
345
+ **Sample Cards** (cards, KPI tiles, lists as cards, built-in template components), **Sample Calendar** (the
346
+ four views, create on click, drag and drop through a function), **Sample Interactive Grids** (an editable grid,
347
+ select lists, totals, a frozen column, a row menu, master-detail, the grid's views), **Sample Dynamic Actions**
348
+ (show and hide, values from the server, refresh, messages, a wait popup, classes, an inline dialog) and
349
+ **Sample Reporting** (interactive report, faceted search, smart filters, a classic report with column options and
350
+ a column template);
351
+ - the **UX Pattern Catalog** (APEX: the Universal Theme app): region templates and template options, button
352
+ styles, item types and form layouts, alerts, badges, colour classes, lists, media lists, timelines, comments,
353
+ avatars, metric cards, empty states, a dialog, a drawer and a side column, each named by its template, option
354
+ or class to copy from.
355
+
356
+ Each single-topic app and the catalog is one SQL file in `examples/gallery/samples/`, run in one transaction (a
357
+ failing script leaves nothing behind); sign in with **demo** / **demo**. Outside the builder:
358
+ `psql "$DATABASE_URL" -1 -f examples/gallery/samples/sample-charts.sql`.
338
359
  - **Starter Apps**: small applications (Team Tasks, Contacts, Expense Claims, Asset Inventory, Event Registrations)
339
360
  shipped as [blueprints](#creating-an-application-from-a-blueprint). **Install** opens the blueprint's review:
340
361
  nothing is created before you confirm, the application gets a new role and schema in the current workspace, and you
341
362
  may edit the blueprint first (another alias, more columns). Any developer installs them.
363
+ - **Utility Apps** (sprint 120; APEX: Utility Apps): applications a workspace *uses* rather than learns from, shipped
364
+ as blueprints and installed like starter apps, by any developer, into the current workspace:
365
+ **Lookup Lists** (the lists of values several applications share, kept as data, with the grant and the list of
366
+ values query another application uses), **Release Notes** (the releases of your applications and their changes)
367
+ and **Announcements** (maintenance, outages and releases for the workspace, with the query that shows the current
368
+ ones in another application).
342
369
  - **Custom Apps**: the workspace's boilerplate applications (Application type *Boilerplate*): *Create from it* opens
343
370
  Create with that boilerplate chosen.
344
371
 
345
- The list is `examples/gallery/gallery.json`; add your own starters there as blueprint files.
372
+ The list is `examples/gallery/gallery.json` (see `examples/gallery/README.md`); add your own starters and utilities
373
+ there as blueprint files. A request only ever names a key of that list, never a file.
374
+
375
+ Why two install paths: a blueprint can only describe tables, generated pages and sample rows, and creating one needs no
376
+ more than a developer's rights (pgkiln writes the DDL). The sample apps need what blueprints can't say (chart kinds,
377
+ dynamic actions, template options, PL/pgSQL functions), so they are SQL scripts, and running shipped SQL as the owner
378
+ is for administrators.
346
379
 
347
380
  ## Data Reporter: datasets and reporting applications
348
381
 
@@ -10,6 +10,7 @@ db/
10
10
  seed/*.sql the HR sample (not for production)
11
11
  examples/ example applications as SQL (the tutorial)
12
12
  examples/plugins/ plug-in files (template components) to import
13
+ examples/gallery/ the App Gallery: gallery.json, starters/ and utilities/ (blueprints), samples/ (single-file sample apps)
13
14
  scripts/migrate.ts migration/seed runner (src/migrate.ts does the work)
14
15
  website/ the website pgkiln.vargar.eu (VitePress): landing page + this guide, synced from docs/ at build time;
15
16
  cd website && npm install && npm run dev; scripts/deploy.sh publishes it (see website/deploy/)
@@ -400,8 +401,10 @@ src/
400
401
  templates.ts template components: preview, plug-in export/import, region settings, report column templates
401
402
  code-editor.ts code fields (data-code marks), /builder/code/completions (scoped to the app's role), /builder/code/check
402
403
  instance.ts Workspace utilities → Instance settings (src/instance.ts: session and sign-in settings, configuration overview)
403
- gallery.ts the App Gallery (sprint 61): examples/gallery/gallery.json, sample apps (administrators, migrate --example),
404
- starter apps (blueprints → openBlueprint's review), custom apps (the workspace's boilerplates)
404
+ gallery.ts the App Gallery (sprint 61, 120): examples/gallery/gallery.json, sample apps (administrators: migrate --example,
405
+ or one SQL file of examples/ or examples/gallery/samples/ in one transaction), starter and utility apps
406
+ (blueprints of starters/ and utilities/ → openBlueprint's review), custom apps (the workspace's boilerplates);
407
+ four tabs with counts, ?q= search
405
408
  app-groups.ts application groups (092): a workspace's groups, a group per application (the App Builder home filters)
406
409
  cross-app.ts Cross Application Reports (sprint 61): REPORTS (one SQL per topic over the workspace's applications)
407
410
  workspaces.ts workspaces (064): loadWorkspaces/appAllowed (checked in ui.ts developer() for every /apps/:id and /pages/:pid
@@ -507,7 +510,9 @@ test/
507
510
  mail-network.test.ts (sprint 118) network access lists (page process refused and logged in debug, narrowing only, redirects,
508
511
  the page), a workspace's mail service (sending, SMTP host on the list), the Mail queue (yesterday's
509
512
  SMTP failure, Retry, Purge, counts, scope)
510
- gallery.test.ts the App Gallery: every starter created from its review with all its pages rendering; sample apps (admins)
513
+ gallery.test.ts the App Gallery: every starter and utility created from its review and every sample app installed, with all
514
+ their pages rendering; sample apps (admins), the search, a failing script leaves nothing
515
+ gallery-samples.ts the gallery's shipped apps for the tests: SAMPLES (schema and role of each script), BLUEPRINTS, drop/install
511
516
  builder-apex-screens.test.ts sprint 61: sign-in with a workspace, message and banner, utilization, SQL Workshop home, groups, reports
512
517
  workspace-isolation.test.ts isolated workspaces (090): logins, RLS on meta, app_id, roles, SQL Workshop, scripts, imports
513
518
  ai.test.ts AI services: Generate text with AI (text, structured outputs, errors, limits, keys), its dynamic action,
@@ -526,6 +531,7 @@ test/
526
531
  ai-mock.ts a local mock of the Claude Messages API (SSE stream) and OpenAI Chat Completions
527
532
  helpers.ts a cookie-keeping test browser
528
533
  e2e/responsive.test.ts browser tests at phone/tablet/desktop widths (Playwright)
534
+ e2e/gallery.test.ts (sprint 120) the gallery's sample apps: every page at 4 widths, CSP, axe; dynamic actions; the four tabs at 390 px
529
535
  e2e/admin-mail-network.test.ts (sprint 118) Mail queue, Network access and a workspace's mail service at 390 px without JavaScript
530
536
  e2e/pillar.test.ts (sprint 117) Pillar appearances: axe in light and dark, subtle colours, current vs parent entry, Arabic RTL, 390 px, preview
531
537
  e2e/code-editor.test.ts the code editor in a browser: highlighting, keys, suggestions, touch, screen readers, syntax colours at AA in both themes (sprint 108)
@@ -1,13 +1,44 @@
1
1
  # App Gallery
2
2
 
3
- The builder's **App Gallery** (`/builder/gallery`) lists what `gallery.json` names:
3
+ The builder's **App Gallery** (`/builder/gallery`) lists what `gallery.json` names, in four tabs:
4
4
 
5
5
  - `samples`: applications shipped with pgkiln, installed by an administrator: `example` names a directory of
6
- `examples/` (installed like `pgkiln migrate --example <name>`), `file` a single SQL file in `examples/`.
7
- `alias` is the application they create (an installed one shows Run and Edit).
6
+ `examples/` (installed like `pgkiln migrate --example <name>`), `file` a single SQL file, in `examples/` (the
7
+ tutorial, `tasks-app.sql`) or in `samples/` here (`samples/sample-charts.sql`). A file runs in one transaction as the
8
+ owner, so a failing script leaves nothing behind. `alias` is the application it creates (an installed one shows Run
9
+ and Edit).
8
10
  - `starters`: [blueprints](../../docs/guide/03-builder.md#creating-an-application-from-a-blueprint) in `starters/`.
9
11
  Install opens the blueprint's review; the developer creates the application from it.
12
+ - `utilities`: blueprints in `utilities/` of applications a workspace uses (lookup lists, release notes,
13
+ announcements), installed like starters.
14
+ - Custom apps are not listed here: they are the workspace's boilerplate applications.
10
15
 
11
- Add a starter by writing a blueprint file in `starters/` and an entry in `gallery.json` (a key of lower-case
12
- letters, digits and `-`, a title, an [icon name](../../docs/guide/09-reference.md#icons) and a description).
13
- `test/gallery.test.ts` creates every starter and opens all its pages.
16
+ ## The sample apps in `samples/`
17
+
18
+ | File | Application | Shows |
19
+ |---|---|---|
20
+ | `sample-charts.sql` | Sample Charts (`/a/sample-charts`) | the 22 chart types, a page per question, a drill-down to a report |
21
+ | `sample-cards.sql` | Sample Cards | cards with a form, KPI tiles, lists as cards, built-in template components |
22
+ | `sample-calendar.sql` | Sample Calendar | month, week, day and list views, create on click, drag and drop through a function |
23
+ | `sample-grids.sql` | Sample Interactive Grids | an editable grid, select lists, totals, frozen column, row menu, master-detail, views |
24
+ | `sample-dynamic-actions.sql` | Sample Dynamic Actions | show/hide/enable, set value, refresh, messages, wait popup, classes, inline dialog |
25
+ | `sample-reporting.sql` | Sample Reporting | interactive report, faceted search, smart filters, a classic report with column options |
26
+ | `ux-patterns.sql` | UX Pattern Catalog | region templates and options, buttons, items and form layouts, content and page patterns |
27
+
28
+ Each script creates its own schema (`sample_charts`, …), a role (`app_sample_charts`, …) granted to the runtime, the
29
+ application and one account, **demo** / **demo**. Without the builder:
30
+ `psql "$DATABASE_URL" -1 -f examples/gallery/samples/sample-charts.sql`. To remove one, delete the application in the
31
+ App Builder, then `drop schema sample_charts cascade; drop role app_sample_charts;`.
32
+
33
+ A sample script follows the pattern of the HR example: plain SQL that inserts `meta.*` rows, using
34
+ `meta.generate_page()` for wizard-made pages and two temporary helpers (`pg_temp.page_id`, `pg_temp.region_id`).
35
+ Every page starts with a text that says how it is made.
36
+
37
+ ## Adding an entry
38
+
39
+ Add a starter or utility by writing a blueprint file in `starters/` or `utilities/` and an entry in `gallery.json` (a
40
+ key of lower-case letters, digits and `-`, a title, an [icon name](../../docs/guide/09-reference.md#icons) and a
41
+ description). Add a sample by writing a script in `samples/` (no `begin`/`commit`: the gallery runs it in a
42
+ transaction) and an entry with its `alias` and `file`. `test/gallery.test.ts` creates every starter and utility,
43
+ installs every sample and opens all their pages; `test/e2e/gallery.test.ts` checks the samples' pages at four widths,
44
+ for CSP violations and with axe-core.
@@ -3,7 +3,21 @@
3
3
  {"key": "hr", "title": "HR Demo", "alias": "hr", "icon": "briefcase", "example": "hr",
4
4
  "description": "The showcase of pgkiln on the classic EMP and DEPT tables: reports and forms, an interactive grid, charts, maps, a calendar, faceted search, approvals and workflows, documents, a REST API, translations and a Progressive Web App. Demo accounts king, blake, jones, allen, scott and demo, with the username as password."},
5
5
  {"key": "tasks", "title": "Tasks", "alias": "tasks", "icon": "check", "file": "tasks-app.sql",
6
- "description": "The tutorial application: a personal task list where every user sees only their own tasks (row level security), with a business rule in PL/pgSQL behind a button. Demo accounts ann and bob (password ann-password, bob-password)."}
6
+ "description": "The tutorial application: a personal task list where every user sees only their own tasks (row level security), with a business rule in PL/pgSQL behind a button. Demo accounts ann and bob (password ann-password, bob-password)."},
7
+ {"key": "sample-charts", "title": "Sample Charts", "alias": "sample-charts", "icon": "chart-column", "file": "samples/sample-charts.sql",
8
+ "description": "All 22 chart types on a page per question (comparing categories, change over time, parts of a whole, relations and spread, plans) and a drill-down from a chart to a report, each page explaining how the query shapes the chart. Demo account demo / demo."},
9
+ {"key": "sample-cards", "title": "Sample Cards", "alias": "sample-cards", "icon": "layout-grid", "file": "samples/sample-cards.sql",
10
+ "description": "Cards with a title, subtitle, body, badge and icon that open a form; KPI tiles; lists shown as cards, badges, links and tabs; and the built-in template components (metric cards, media list, badges, avatars). Demo account demo / demo."},
11
+ {"key": "sample-calendar", "title": "Sample Calendar", "alias": "sample-calendar", "icon": "calendar-days", "file": "samples/sample-calendar.sql",
12
+ "description": "The calendar region: month, week, day and list views, all-day, timed and multi-day events around today, create on click, drag and drop through a PL/pgSQL function with its own rule, and a calendar filtered by an item. Demo account demo / demo."},
13
+ {"key": "sample-grids", "title": "Sample Interactive Grids", "alias": "sample-grids", "icon": "table", "file": "samples/sample-grids.sql",
14
+ "description": "The interactive grid: an editable grid made by the wizard; select lists, required columns, totals, a frozen column, a row menu and a column layout; master-detail grids; and a read-only grid with the single row, group by and chart views. Demo account demo / demo."},
15
+ {"key": "sample-dynamic-actions", "title": "Sample Dynamic Actions", "alias": "sample-dynamic-actions", "icon": "zap", "file": "samples/sample-dynamic-actions.sql",
16
+ "description": "Behaviour without JavaScript of your own: show, hide, enable on a condition; values computed on the server; a report refreshed when an item changes; alerts, confirmations, a wait popup, classes, item errors and an inline dialog. Demo account demo / demo."},
17
+ {"key": "sample-reporting", "title": "Sample Reporting", "alias": "sample-reporting", "icon": "file-text", "file": "samples/sample-reporting.sql",
18
+ "description": "Reports and the ways to search them: an interactive report with its form, a faceted search, smart filters, and a classic report with column display options, a column template and a link. Demo account demo / demo."},
19
+ {"key": "ux-patterns", "title": "UX Pattern Catalog", "alias": "ux-patterns", "icon": "palette", "file": "samples/ux-patterns.sql",
20
+ "description": "The theme's building blocks to copy from: region templates and template options, button styles, item types and form layouts, alerts, badges, colour classes, lists, media lists, timelines, comments, avatars, metric cards, empty states, dialogs, drawers and side columns. Demo account demo / demo."}
7
21
  ],
8
22
  "starters": [
9
23
  {"key": "team-tasks", "title": "Team Tasks", "icon": "layout-grid", "file": "starters/team-tasks.json",
@@ -16,5 +30,13 @@
16
30
  "description": "Assets with their tags, locations, owners and purchase data: a faceted search, an editable grid of locations, a chart by category and a dashboard."},
17
31
  {"key": "event-registrations", "title": "Event Registrations", "icon": "calendar-days", "file": "starters/event-registrations.json",
18
32
  "description": "Events in a calendar and the people who registered for them, with reports, forms and a dashboard."}
33
+ ],
34
+ "utilities": [
35
+ {"key": "lookup-lists", "title": "Lookup Lists", "icon": "list-checks", "file": "utilities/lookup-lists.json",
36
+ "description": "The lists of values your applications share (priorities, statuses, countries) kept as data: lists and their values in a master-detail page and an editable grid, and how other applications of the workspace use them."},
37
+ {"key": "release-notes", "title": "Release Notes", "icon": "git-branch", "file": "utilities/release-notes.json",
38
+ "description": "The releases of your applications and what changed in each (features, fixes, security, breaking changes): reports and forms, releases with their changes, a faceted search of the changes, a release calendar and a dashboard."},
39
+ {"key": "announcements", "title": "Announcements", "icon": "megaphone", "file": "utilities/announcements.json",
40
+ "description": "A notice board for the workspace: planned maintenance, outages and new releases with their audience and dates, as cards, a calendar and a dashboard, and the query other applications use to show the current ones."}
19
41
  ]
20
42
  }
@@ -0,0 +1,172 @@
1
+ -- =====================================================================
2
+ -- Sample app "Sample Calendar" (App Gallery → Sample Apps)
3
+ --
4
+ -- The calendar region: month, week, day and list views, all-day and timed
5
+ -- events, events over several days, create on click, drag and drop through
6
+ -- a PL/pgSQL function with its own rule, and a calendar filtered by an item.
7
+ -- The events are placed around today, so there is always something to see.
8
+ --
9
+ -- Installed by an administrator from the App Gallery, or with
10
+ -- psql "$DATABASE_URL" -1 -f examples/gallery/samples/sample-calendar.sql
11
+ -- then open /a/sample-calendar and sign in as demo / demo.
12
+ -- =====================================================================
13
+
14
+ create or replace function pg_temp.page_id(p_alias text, p_page int) returns int language sql stable as
15
+ $$ select p.id from meta.page p join meta.app a on a.id = p.app_id where a.alias = p_alias and p.page_no = p_page $$;
16
+
17
+ -- 1. Schema and data ---------------------------------------------------------
18
+ create schema sample_calendar;
19
+
20
+ create table sample_calendar.event (
21
+ id int generated always as identity primary key,
22
+ title text not null,
23
+ category text not null default 'Meeting' check (category in ('Meeting', 'Training', 'Travel', 'Holiday')),
24
+ starts timestamp not null,
25
+ ends timestamp,
26
+ location text,
27
+ notes text,
28
+ check (ends is null or ends >= starts)
29
+ );
30
+
31
+ -- this week's Monday as the anchor: meetings by the hour, all-day and multi-day events
32
+ insert into sample_calendar.event (title, category, starts, ends, location)
33
+ select e.title, e.category, w.monday + e.day_offset + e.start_at, case when e.end_at is null then null else w.monday + e.end_day + e.end_at end, e.location
34
+ from (select date_trunc('week', current_date)::date as monday) w,
35
+ (values
36
+ ('Team stand-up', 'Meeting', 0, interval '9 hours', 0, interval '9 hours 15 minutes', 'Room 1'),
37
+ ('Planning', 'Meeting', 0, interval '10 hours', 0, interval '11 hours 30 minutes', 'Room 2'),
38
+ ('Customer call', 'Meeting', 1, interval '14 hours', 1, interval '15 hours', 'Online'),
39
+ ('Team stand-up', 'Meeting', 2, interval '9 hours', 2, interval '9 hours 15 minutes', 'Room 1'),
40
+ ('SQL course', 'Training', 2, interval '0 hours', 3, interval '0 hours', 'Training centre'),
41
+ ('Trip to the trade fair', 'Travel', 7, interval '0 hours', 9, interval '0 hours', 'Utrecht'),
42
+ ('Review', 'Meeting', 4, interval '13 hours', 4, interval '14 hours', 'Room 2'),
43
+ ('Lunch and learn', 'Training', 8, interval '12 hours', 8, interval '13 hours', 'Canteen'),
44
+ ('Retrospective', 'Meeting', 11, interval '15 hours', 11, interval '16 hours', 'Room 1'),
45
+ ('Public holiday', 'Holiday', 14, interval '0 hours', null, null, null),
46
+ ('Budget meeting', 'Meeting', -3, interval '10 hours', -3, interval '12 hours', 'Board room'),
47
+ ('First aid course', 'Training', -7, interval '0 hours', -6, interval '0 hours', 'Training centre'),
48
+ ('Quarter review', 'Meeting', 18, interval '9 hours', 18, interval '11 hours', 'Board room'),
49
+ ('Holiday', 'Holiday', 21, interval '0 hours', 25, interval '0 hours', null)
50
+ ) as e (title, category, day_offset, start_at, end_day, end_at, location);
51
+
52
+ -- drag and drop: the calendar calls this with the new start and end; holidays stay where they are
53
+ create function sample_calendar.move_event(p_id int, p_start timestamp, p_end timestamp) returns void
54
+ language plpgsql as $$
55
+ begin
56
+ if exists (select 1 from sample_calendar.event where id = p_id and category = 'Holiday') then
57
+ raise exception 'Holidays can''t be moved.';
58
+ end if;
59
+ update sample_calendar.event set starts = p_start, ends = p_end where id = p_id;
60
+ end
61
+ $$;
62
+
63
+ -- 2. The application's database role ----------------------------------------
64
+ do $$ begin
65
+ if not exists (select 1 from pg_roles where rolname = 'app_sample_calendar') then create role app_sample_calendar nologin; end if;
66
+ end $$;
67
+ grant app_sample_calendar to pgkiln_runtime;
68
+ grant usage on schema sample_calendar to app_sample_calendar;
69
+ grant select, insert, update, delete on all tables in schema sample_calendar to app_sample_calendar;
70
+ grant execute on all functions in schema sample_calendar to app_sample_calendar;
71
+
72
+ -- 3. The application ----------------------------------------------------------
73
+ insert into meta.app (alias, name, home_page, authentication, db_role)
74
+ values ('sample-calendar', 'Sample Calendar', 1, 'app_users', 'app_sample_calendar');
75
+
76
+ insert into meta.app_user (app_id, username, password_hash, roles)
77
+ select id, 'demo', meta.hash_password('demo'), '{}' from meta.app where alias = 'sample-calendar';
78
+
79
+ insert into meta.page (app_id, page_no, name, title, parent_page)
80
+ select a.id, p.no, p.name, p.name, p.parent
81
+ from meta.app a, (values
82
+ (1, 'Sample Calendar', null), (2, 'Month', 1), (4, 'Week planner', 1), (5, 'Agenda', 1), (6, 'By category', 1)
83
+ ) as p (no, name, parent)
84
+ where a.alias = 'sample-calendar';
85
+
86
+ -- page 3: the event form, a modal dialog (the Form wizard), opened from the calendars
87
+ select meta.generate_page('sample-calendar', 'form', 'sample_calendar.event', 3,
88
+ '{"label": "Event", "mode": "modal", "return_page": 2, "nav": false}');
89
+ update meta.page set parent_page = 2 where id = pg_temp.page_id('sample-calendar', 3);
90
+ update meta.item set type = 'select', lov = 'STATIC:Meeting,Training,Travel,Holiday'
91
+ where page_id = pg_temp.page_id('sample-calendar', 3) and name = 'P3_CATEGORY';
92
+ update meta.item set help = 'Leave it empty for an event without an end (all day when the start is at midnight).'
93
+ where page_id = pg_temp.page_id('sample-calendar', 3) and name = 'P3_ENDS';
94
+
95
+ insert into meta.nav_entry (app_id, seq, label, icon, target_page)
96
+ select a.id, n.seq, n.label, n.icon, n.page
97
+ from meta.app a, (values
98
+ (10, 'Home', 'home', 1), (20, 'Month', 'calendar', 2), (30, 'Week planner', 'clock', 4),
99
+ (40, 'Agenda', 'list', 5), (50, 'By category', 'filter', 6)
100
+ ) as n (seq, label, icon, page)
101
+ where a.alias = 'sample-calendar';
102
+
103
+ insert into meta.list (app_id, name, type, description)
104
+ select id, 'CALENDAR_TOPICS', 'static', 'The pages of Sample Calendar' from meta.app where alias = 'sample-calendar';
105
+
106
+ insert into meta.list_entry (app_id, list_name, seq, label, icon, target_page, description)
107
+ select a.id, 'CALENDAR_TOPICS', e.seq, e.label, e.icon, e.page, e.description
108
+ from meta.app a, (values
109
+ (10, 'Month', 'calendar', 2, 'All four views; click a day to add an event, drag an event to move it.'),
110
+ (20, 'Week planner', 'clock', 4, 'Week and day views from 7:00 to 19:00, opened on the week.'),
111
+ (30, 'Agenda', 'list', 5, 'The list view only: a month of events per day.'),
112
+ (40, 'By category', 'filter', 6, 'A calendar whose query uses a page item, refreshed when it changes.')
113
+ ) as e (seq, label, icon, page, description)
114
+ where a.alias = 'sample-calendar';
115
+
116
+ insert into meta.region (page_id, seq, title, type, columns, template, source, config, static_id)
117
+ select pg_temp.page_id('sample-calendar', r.page), r.seq, r.title, r.type, r.cols, r.template, r.source, r.config::jsonb, r.sid
118
+ from (values
119
+ -- 1 Home
120
+ (1, 10, 'Sample Calendar', 'static', 12, 'hero',
121
+ '<p>A calendar region shows the rows of a SELECT with a <code>start_date</code>, an optional <code>end_date</code> and a <code>title</code>. Dates are all-day events, timestamps events with a time. Every view is a plain link, so the calendar works without JavaScript and can be bookmarked.</p>',
122
+ '{"icon": "calendar"}', null),
123
+ (1, 20, 'Topics', 'list', 12, 'plain', null, '{"list": "CALENDAR_TOPICS", "template": "cards"}', null),
124
+ (1, 30, 'Today and tomorrow', 'calendar', 12, 'standard',
125
+ E'select starts as start_date, ends as end_date, title, id\n from sample_calendar.event\n where starts < current_date + 2 and coalesce(ends, starts) >= current_date',
126
+ '{"views": ["list"], "link": {"page": 3, "items": {"P3_ID": "#id#"}}}', null),
127
+
128
+ -- 2 Month
129
+ (2, 5, 'About this page', 'static', 12, 'plain',
130
+ '<p class="lead">The attribute <code>link</code> opens an event in the form; <code>create</code> adds a <strong>+</strong> to every day and hour that opens the form with <code>#start#</code> and <code>#end#</code> filled in; <code>move</code> lets you drag events to another day or hour. The move runs <code>sample_calendar.move_event</code>, which refuses to move a holiday: try it.</p>',
131
+ '{}', null),
132
+ (2, 10, 'Events', 'calendar', 12, 'standard',
133
+ E'select starts as start_date, ends as end_date, title || coalesce('' ('' || location || '')'', '''') as title, id\n from sample_calendar.event',
134
+ '{"views": ["month", "week", "day", "list"], "link": {"page": 3, "items": {"P3_ID": "#id#"}},
135
+ "create": {"page": 3, "items": {"P3_STARTS": "#start#", "P3_ENDS": "#end#"}},
136
+ "move": "select sample_calendar.move_event(:EVENT_ID::int, :NEW_START::timestamp, :NEW_END::timestamp)"}', 'events'),
137
+
138
+ -- 4 Week planner
139
+ (4, 5, 'About this page', 'static', 12, 'plain',
140
+ '<p class="lead">With <code>"views": ["week", "day"]</code> and <code>"view": "week"</code> the calendar opens on the week; <code>day_start</code> and <code>day_end</code> set its hours (widened when an event needs it). On a phone the week becomes an agenda list.</p>',
141
+ '{}', null),
142
+ (4, 10, 'This week', 'calendar', 12, 'standard',
143
+ E'select starts as start_date, ends as end_date, title, id\n from sample_calendar.event where category in (''Meeting'', ''Training'')',
144
+ '{"views": ["week", "day"], "view": "week", "day_start": 7, "day_end": 19, "link": {"page": 3, "items": {"P3_ID": "#id#"}},
145
+ "create": {"page": 3, "items": {"P3_STARTS": "#start#", "P3_ENDS": "#end#"}}}', null),
146
+
147
+ -- 5 Agenda
148
+ (5, 5, 'About this page', 'static', 12, 'plain',
149
+ '<p class="lead">The <code>list</code> view alone: the month''s events per day, with ‹ and › to move by a month.</p>',
150
+ '{}', null),
151
+ (5, 10, 'Agenda', 'calendar', 12, 'standard',
152
+ E'select starts as start_date, ends as end_date, category || '': '' || title as title, id\n from sample_calendar.event',
153
+ '{"views": ["list"], "link": {"page": 3, "items": {"P3_ID": "#id#"}}}', null),
154
+
155
+ -- 6 By category
156
+ (6, 5, 'About this page', 'static', 12, 'plain',
157
+ '<p class="lead">The query uses the page item <code>:P6_CATEGORY</code>. A dynamic action refreshes the calendar when the item changes (without JavaScript, the item submits the page).</p>',
158
+ '{}', null),
159
+ (6, 10, 'Filter', 'static', 12, 'standard', null, '{}', 'filter'),
160
+ (6, 20, 'Events of the category', 'calendar', 12, 'standard',
161
+ E'select starts as start_date, ends as end_date, title, id\n from sample_calendar.event\n where :P6_CATEGORY is null or category = :P6_CATEGORY',
162
+ '{"views": ["month", "list"], "link": {"page": 3, "items": {"P3_ID": "#id#"}}}', 'category-calendar')
163
+ ) as r (page, seq, title, type, cols, template, source, config, sid);
164
+
165
+ insert into meta.item (page_id, region_id, seq, name, label, type, lov, config)
166
+ select pg_temp.page_id('sample-calendar', 6), r.id, 10, 'P6_CATEGORY', 'Category', 'radio',
167
+ 'STATIC:Meeting,Training,Travel,Holiday', '{"warn_unsaved": false}'
168
+ from meta.region r where r.page_id = pg_temp.page_id('sample-calendar', 6) and r.static_id = 'filter';
169
+
170
+ insert into meta.dynamic_action (page_id, seq, name, event, trigger_element, action, affected_region_id, items_to_submit)
171
+ select pg_temp.page_id('sample-calendar', 6), 10, 'Refresh the calendar', 'change', 'P6_CATEGORY', 'refresh_region', r.id, 'P6_CATEGORY'
172
+ from meta.region r where r.page_id = pg_temp.page_id('sample-calendar', 6) and r.static_id = 'category-calendar';