pgkiln 0.52.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/README.md +1 -1
- package/SECURITY.md +6 -1
- package/db/migrations/125_app_change.sql +23 -0
- package/db/migrations/126_mail_queue_network_access.sql +119 -0
- package/docs/apex-feature-parity.md +41 -12
- package/docs/guide/01-installation.md +1 -1
- package/docs/guide/03-builder.md +116 -10
- package/docs/guide/06-processing.md +6 -1
- package/docs/guide/08-security.md +55 -0
- package/docs/guide/09-reference.md +3 -1
- package/docs/guide/11-from-apex.md +1 -0
- package/docs/guide/12-development.md +52 -11
- package/docs/guide/14-globalization.md +49 -1
- package/docs/guide/18-cli.md +21 -1
- package/docs/guide/19-rest-data-sources.md +12 -0
- package/docs/guide/20-ai-agents.md +8 -2
- package/examples/gallery/README.md +37 -6
- package/examples/gallery/gallery.json +23 -1
- package/examples/gallery/samples/sample-calendar.sql +172 -0
- package/examples/gallery/samples/sample-cards.sql +157 -0
- package/examples/gallery/samples/sample-charts.sql +265 -0
- package/examples/gallery/samples/sample-dynamic-actions.sql +177 -0
- package/examples/gallery/samples/sample-grids.sql +151 -0
- package/examples/gallery/samples/sample-reporting.sql +151 -0
- package/examples/gallery/samples/ux-patterns.sql +295 -0
- package/examples/gallery/utilities/announcements.json +24 -0
- package/examples/gallery/utilities/lookup-lists.json +28 -0
- package/examples/gallery/utilities/release-notes.json +41 -0
- package/examples/hr/hr_70_data_security.sql +79 -0
- package/package.json +1 -1
- package/public/app.css +99 -23
- package/public/builder.css +71 -1
- package/public/builder.js +4 -0
- package/src/app.ts +9 -0
- package/src/builder/app-updates.ts +55 -0
- package/src/builder/data-security.ts +182 -0
- package/src/builder/gallery.ts +94 -47
- package/src/builder/home.ts +16 -5
- package/src/builder/mail-queue.ts +212 -0
- package/src/builder/mail.ts +72 -45
- package/src/builder/network-access.ts +140 -0
- package/src/builder/object-actions.ts +1 -0
- package/src/builder/object-browser.ts +1 -1
- package/src/builder/rest-catalogs.ts +19 -4
- package/src/builder/sql.ts +2 -0
- package/src/builder/themeroller.ts +47 -6
- package/src/builder/ui.ts +5 -0
- package/src/builder/websources.ts +1 -1
- package/src/builder/workspace-mail.ts +121 -0
- package/src/builder/workspaces.ts +1 -0
- package/src/cli/main.ts +25 -3
- package/src/cli/mcp.ts +40 -4
- package/src/cli/only.ts +52 -0
- package/src/cli/replace.ts +5 -1
- package/src/datasec.ts +343 -0
- package/src/mail/mail.ts +50 -11
- package/src/mail/providers.ts +6 -3
- package/src/metadata.ts +2 -0
- package/src/network-acl.ts +126 -0
- package/src/objectstore.ts +3 -0
- package/src/runtime/charts.ts +4 -1
- package/src/runtime/engine.ts +3 -1
- package/src/runtime/regions.ts +8 -5
- package/src/runtime/render.ts +4 -2
- package/src/runtime/styles.ts +54 -12
- package/src/webclient.ts +45 -4
- package/src/webrequests.ts +5 -0
- package/src/websources.ts +30 -12
package/README.md
CHANGED
|
@@ -123,7 +123,7 @@ developing pgkiln itself.
|
|
|
123
123
|
|
|
124
124
|
## What's in the box
|
|
125
125
|
|
|
126
|
-
For a full comparison with Oracle APEX 26.
|
|
126
|
+
For a full comparison with Oracle APEX 26.2, including what's missing, see
|
|
127
127
|
**[docs/apex-feature-parity.md](docs/apex-feature-parity.md)**.
|
|
128
128
|
|
|
129
129
|
**Runtime (Universal Theme-style UI, responsive on phone, tablet and desktop)**
|
package/SECURITY.md
CHANGED
|
@@ -104,6 +104,11 @@ first version (MVP). Every finding below has a regression test in
|
|
|
104
104
|
| Team Development (sprint 113) | Issues, labels, milestones, templates and saved views belong to the developer's current workspace only, and can be neither read nor changed from another; assignees and @mentions are the workspace's developers, links go only to its applications. Every POST needs the session's CSRF token; titles, bodies, comments and names are escaped, Markdown is made safe, label colours come from a palette. Application users and signed-out visitors can't reach it. |
|
|
105
105
|
| Workflow 26.2 (sprint 114) | Migrating running instances needs a developer of the application and the CSRF token; unmapped steps and other applications' workflows are refused. A task ends only with an outcome of its definition. Task event SQL runs as the application's role (after the commit, or in the request for *fail* events). Draft versions can't be activated in the builder, with SQL or into the active steps. The diagram export is for developers only, served as a sandboxed attachment with escaped labels. |
|
|
106
106
|
| Component details (sprint 115) | The popup LOV search needs the CSRF token, caps the page size and page number and binds the search term. A wait popup's message is page data shown as text. A `menu_entry` dynamic action with an authorization the user lacks is neither sent to the page nor run (403); menu entries the user may not use are left out, labels are escaped, and the database refuses crafted action names. |
|
|
107
|
+
| App Builder list details (sprint 116) | `meta.app_change` (Updated by) is written only for a builder POST that passed the developer checks (sign-in, CSRF token, workspace, locks) and succeeded; posts that change nothing record nothing. Developer names and lock owners are escaped in the report, the cards and the lock label; another workspace's applications are not listed. The table is closed to the runtime role and not exported. |
|
|
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
|
+
| 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
|
+
| 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. |
|
|
107
112
|
|
|
108
113
|
## Findings of the MVP review and their fixes
|
|
109
114
|
|
|
@@ -223,6 +228,6 @@ A second full review, mainly of what end users and API callers can reach. Regres
|
|
|
223
228
|
5. Give each app its own `db_role` with the minimum grants; add RLS where rows are per user or per team. REST modules and AutoREST refuse to run without one on a privileged connection (403); run the Advisor after upgrading.
|
|
224
229
|
6. Restrict network access to `/builder` (reverse proxy or firewall) if developers are a small group.
|
|
225
230
|
7. With a REST API: set a long random `API_JWT_SECRET` (the same in PostgREST), change the `pgkiln_authenticator` password, configure `db-pre-request = meta.api_check`, expose only the `api` schema, and run PostgREST behind HTTPS.
|
|
226
|
-
8. With REST data sources: list only the hosts you need in `PGKILN_REST_ALLOWED_HOSTS` (avoid `*`), set a long random `PGKILN_SECRET_KEY` (32+ characters) kept outside the database and its backups, and use `PGKILN_REST_PRIVATE_HOSTS` only for internal services you mean to reach.
|
|
231
|
+
8. With REST data sources: list only the hosts you need in `PGKILN_REST_ALLOWED_HOSTS` (avoid `*`), set a long random `PGKILN_SECRET_KEY` (32+ characters) kept outside the database and its backups, and use `PGKILN_REST_PRIVATE_HOSTS` only for internal services you mean to reach. Narrow it further per workspace under Administration → Network access (sprint 118).
|
|
227
232
|
9. With header authentication: list only your proxy's addresses in `PGKILN_AUTH_HEADER_PROXIES`, make sure users can't reach pgkiln directly, and have the proxy remove any incoming copy of the header.
|
|
228
233
|
10. With database-account authentication: list exact roles or use a dedicated membership role, and limit what those roles may connect to in `pg_hba.conf` (they can reach the database with their password outside pgkiln too).
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
-- =====================================================================
|
|
2
|
+
-- 125: who changed an application last (sprint 116, WS-12)
|
|
3
|
+
--
|
|
4
|
+
-- APEX's Applications report shows Updated By next to Updated. The builder
|
|
5
|
+
-- records the developer and the time of the last successful change to an
|
|
6
|
+
-- application (any builder POST under /builder/apps/:id or /pages/:pid,
|
|
7
|
+
-- except locks, comments and other actions that change nothing; and the
|
|
8
|
+
-- application a Create or Import made) in meta.app_change: one row per
|
|
9
|
+
-- application. The App Builder list shows it, with the number of working
|
|
10
|
+
-- copies (meta.working_copy) and the application lock (meta.builder_lock).
|
|
11
|
+
--
|
|
12
|
+
-- Builder state of this installation, like meta.builder_lock: written by the
|
|
13
|
+
-- builder as the owner, never read by the runtime; not part of an
|
|
14
|
+
-- application's export (kept by pgkiln import --replace). Not a column of
|
|
15
|
+
-- meta.app on purpose: export_app exports meta.app's columns.
|
|
16
|
+
-- =====================================================================
|
|
17
|
+
|
|
18
|
+
create table meta.app_change (
|
|
19
|
+
app_id int primary key references meta.app on delete cascade,
|
|
20
|
+
updated_by text not null check (length(updated_by) between 1 and 200),
|
|
21
|
+
updated_at timestamptz not null default now()
|
|
22
|
+
);
|
|
23
|
+
comment on table meta.app_change is 'builder: the developer who changed an application last, and when (App Builder list: Updated by)';
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
-- =====================================================================
|
|
2
|
+
-- 126: Administration 26.1 / 26.2 (sprint 118, WS-9): the mail queue,
|
|
3
|
+
-- a workspace's own mail service and its network access list
|
|
4
|
+
--
|
|
5
|
+
-- meta.workspace.network_restricted / network_hosts: a workspace's
|
|
6
|
+
-- outbound allow-list (APEX 26.2: workspace-level network ACLs). When
|
|
7
|
+
-- restricted, every outgoing web call made for one of its applications
|
|
8
|
+
-- (meta.web_request, REST data sources, invoke API, web credential token
|
|
9
|
+
-- endpoints, object storage, REST source catalogs) must match an entry
|
|
10
|
+
-- here AND the installation's list (PGKILN_REST_ALLOWED_HOSTS /
|
|
11
|
+
-- PGKILN_REST_PRIVATE_HOSTS): the workspace's list only narrows. Entries:
|
|
12
|
+
-- "api.example.com", "*.example.com" (subdomains), "host:8443" (one
|
|
13
|
+
-- port). Restricted with no entries: no outgoing calls at all. Checked in
|
|
14
|
+
-- src/webclient.ts on every hop (redirects too); installation data like
|
|
15
|
+
-- isolation (not in the workspace export).
|
|
16
|
+
-- meta.mail_service.workspace_id: a workspace's own mail service (APEX
|
|
17
|
+
-- 26.1: workspace-level SMTP credentials), managed by the workspace's
|
|
18
|
+
-- administrators; null = an installation service (administrators). Its
|
|
19
|
+
-- secret is encrypted like a web credential's and never shown or
|
|
20
|
+
-- exported. Applications of the workspace without a service of their own
|
|
21
|
+
-- send through it. Its SMTP host is checked like a web request's host.
|
|
22
|
+
-- meta.mail_queue.last_attempt_at / duration_ms / provider: when the last
|
|
23
|
+
-- attempt to hand a mail over ended, how long the provider took, and which
|
|
24
|
+
-- provider it was (Administration → Mail queue).
|
|
25
|
+
-- meta.network_refusal: outgoing calls refused by the allow-lists, per
|
|
26
|
+
-- workspace and application (Administration → Network access), kept 7
|
|
27
|
+
-- days. Installation data: not exported, kept by an in-place import.
|
|
28
|
+
-- =====================================================================
|
|
29
|
+
|
|
30
|
+
-- one entry of a network access list: host, *.domain, host:port, [IPv6]:port (lower case)
|
|
31
|
+
create function meta.network_host_ok(p text) returns boolean
|
|
32
|
+
language sql immutable set search_path = pg_catalog as $$
|
|
33
|
+
select p is not null and length(p) <= 260 and (
|
|
34
|
+
p ~ '^(\*\.)?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*(:[1-9][0-9]{0,4})?$'
|
|
35
|
+
or p ~ '^\[[0-9a-f:.]{2,45}\](:[1-9][0-9]{0,4})?$')
|
|
36
|
+
and coalesce(nullif(substring(p from ':([0-9]+)$'), '')::int, 1) between 1 and 65535
|
|
37
|
+
$$;
|
|
38
|
+
|
|
39
|
+
create function meta.network_hosts_ok(p text[]) returns boolean
|
|
40
|
+
language sql immutable set search_path = pg_catalog as $$
|
|
41
|
+
select p is not null and cardinality(p) <= 200 and coalesce(bool_and(meta.network_host_ok(h)), true) from unnest(p) h
|
|
42
|
+
$$;
|
|
43
|
+
revoke all on function meta.network_host_ok(text), meta.network_hosts_ok(text[]) from public;
|
|
44
|
+
|
|
45
|
+
alter table meta.workspace
|
|
46
|
+
add column network_restricted boolean not null default false,
|
|
47
|
+
add column network_hosts text[] not null default '{}' constraint workspace_network_hosts_ok check (meta.network_hosts_ok(network_hosts));
|
|
48
|
+
comment on column meta.workspace.network_restricted is 'Outgoing web calls of the workspace''s applications are limited to network_hosts (126), within the installation''s list';
|
|
49
|
+
comment on column meta.workspace.network_hosts is 'The workspace''s network access list (126): host, *.domain or host:port entries';
|
|
50
|
+
|
|
51
|
+
-- a workspace's own mail service (one at most); null: an installation service
|
|
52
|
+
alter table meta.mail_service add column workspace_id int references meta.workspace on delete cascade;
|
|
53
|
+
create unique index mail_service_workspace_key on meta.mail_service (workspace_id) where workspace_id is not null;
|
|
54
|
+
comment on column meta.mail_service.workspace_id is 'A workspace''s own mail service (126), managed by its administrators; null = the installation''s';
|
|
55
|
+
|
|
56
|
+
alter table meta.mail_queue
|
|
57
|
+
add column last_attempt_at timestamptz,
|
|
58
|
+
add column duration_ms int,
|
|
59
|
+
add column provider text;
|
|
60
|
+
create index mail_queue_status_attempt on meta.mail_queue (status, last_attempt_at);
|
|
61
|
+
comment on column meta.mail_queue.duration_ms is 'How long the provider took to accept or refuse the last attempt (126)';
|
|
62
|
+
|
|
63
|
+
-- The mail service an application sends through: the one an administrator gave it (an installation
|
|
64
|
+
-- service, or its own workspace's), else its workspace's own service. Null: none.
|
|
65
|
+
create function meta.mail_service_for_app(p_app_id int) returns int
|
|
66
|
+
language sql stable security definer set search_path = meta, pg_catalog as $$
|
|
67
|
+
select coalesce(
|
|
68
|
+
(select x.service_id from meta.app_mail_service x join meta.mail_service s on s.id = x.service_id
|
|
69
|
+
where x.app_id = p_app_id and (s.workspace_id is null or s.workspace_id = meta.app_workspace(p_app_id))),
|
|
70
|
+
case when not exists (select 1 from meta.app_mail_service x where x.app_id = p_app_id)
|
|
71
|
+
then (select s.id from meta.mail_service s where s.workspace_id = meta.app_workspace(p_app_id)) end)
|
|
72
|
+
$$;
|
|
73
|
+
revoke all on function meta.mail_service_for_app(int) from public;
|
|
74
|
+
|
|
75
|
+
-- (081) the calling application and its mail service; now also its workspace's own service
|
|
76
|
+
create or replace function meta.mail_caller(out app_id int, out service_id int, out from_address text, out max_per_day int, out senders text[])
|
|
77
|
+
language plpgsql stable security definer set search_path = meta, pg_catalog as $$
|
|
78
|
+
declare
|
|
79
|
+
v_role text;
|
|
80
|
+
begin
|
|
81
|
+
app_id := meta.app_id();
|
|
82
|
+
if app_id is null then
|
|
83
|
+
raise exception 'meta.send_mail: no current application (call it from application code)';
|
|
84
|
+
end if;
|
|
85
|
+
select a.db_role into v_role from meta.app a where a.id = app_id;
|
|
86
|
+
if not found then
|
|
87
|
+
raise exception 'meta.send_mail: no current application (call it from application code)';
|
|
88
|
+
end if;
|
|
89
|
+
if v_role is not null and current_setting('role') is distinct from v_role then
|
|
90
|
+
raise exception 'meta.send_mail: called outside the application''s own database role';
|
|
91
|
+
end if;
|
|
92
|
+
select s.id, coalesce(x.from_address, nullif(s.settings->>'default_from', '')), x.max_per_day, s.senders
|
|
93
|
+
into service_id, from_address, max_per_day, senders
|
|
94
|
+
from meta.mail_service s left join meta.app_mail_service x on x.app_id = mail_caller.app_id and x.service_id = s.id
|
|
95
|
+
where s.id = meta.mail_service_for_app(mail_caller.app_id) and s.enabled;
|
|
96
|
+
if not found then
|
|
97
|
+
raise exception 'meta.send_mail: this application may not send e-mail (an administrator chooses its mail service under Workspace utilities → Mail services, or the workspace''s administrators set up the workspace''s own)';
|
|
98
|
+
end if;
|
|
99
|
+
end
|
|
100
|
+
$$;
|
|
101
|
+
revoke all on function meta.mail_caller() from public;
|
|
102
|
+
|
|
103
|
+
create table meta.network_refusal (
|
|
104
|
+
id bigint generated always as identity primary key,
|
|
105
|
+
at timestamptz not null default now(),
|
|
106
|
+
workspace_id int references meta.workspace on delete cascade,
|
|
107
|
+
app_id int references meta.app on delete cascade,
|
|
108
|
+
-- what made the call: web request, REST data source, invoke API, token endpoint, object storage, REST catalog, mail
|
|
109
|
+
what text not null check (length(what) <= 100),
|
|
110
|
+
-- host[:port] and the URL without its query string (it may carry keys)
|
|
111
|
+
host text not null check (length(host) <= 300),
|
|
112
|
+
url text check (length(url) <= 1000),
|
|
113
|
+
-- installation (not on the installation's list) or workspace (not on the workspace's)
|
|
114
|
+
list text not null check (list in ('installation', 'workspace')),
|
|
115
|
+
message text check (length(message) <= 1000)
|
|
116
|
+
);
|
|
117
|
+
create index network_refusal_ws on meta.network_refusal (workspace_id, at desc);
|
|
118
|
+
revoke all on meta.network_refusal from public;
|
|
119
|
+
comment on table meta.network_refusal is 'Outgoing web calls refused by the network access lists (126), kept 7 days; installation data, not exported';
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# Oracle APEX feature parity
|
|
2
2
|
|
|
3
|
-
This page compares pgkiln with **Oracle APEX 26.
|
|
3
|
+
This page compares pgkiln with **Oracle APEX 26.2**, area by area (rows marked 26.1 or 26.2 name the release that brought the feature). It's meant to be
|
|
4
4
|
honest: it shows what a team moving from APEX can use today and what is still missing. Pick an
|
|
5
5
|
open item and open an issue or pull request; see [CONTRIBUTING.md](../CONTRIBUTING.md).
|
|
6
6
|
|
|
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-19 (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
|
|
|
@@ -22,26 +22,30 @@ Last reviewed: 2026-10-19 (sprint 115: popup LOVs that load on scroll, Wait Popu
|
|
|
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 |
|
|
26
|
-
|
|
|
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) | 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) |
|
|
27
28
|
|
|
28
29
|
(Counts are of the rows in the tables below. A review on 2026-10-06 added 18 rows for APEX features that were
|
|
29
30
|
not compared before, one on 2026-10-12 added two more (property help, application availability), and one on
|
|
30
31
|
2026-10-13 compared the builder's screens with APEX 26.1 and added four (App Gallery, application groups, cross
|
|
31
32
|
application reports, Manage Service), so the share available dropped without anything being removed. Sprint 67 added
|
|
32
|
-
two, REST source catalogs and the workspace export, with their features.
|
|
33
|
+
two, REST source catalogs and the workspace export, with their features. Sprint 116 compared with APEX 26.2 and added
|
|
34
|
+
the section [APEX 26.2 workspace](#apex-262-workspace-ws-1--ws-13): fourteen rows, the 26.2 workspace items WS-1 … WS-13
|
|
35
|
+
and OCI managed identities. Some of them repeat a row above from the workspace's side; they are counted on purpose, as
|
|
36
|
+
the 26.2 comparison.)
|
|
33
37
|
|
|
34
38
|
## App Builder and development
|
|
35
39
|
|
|
36
40
|
| APEX | pgkiln | Notes |
|
|
37
41
|
|---|---|---|
|
|
38
42
|
| App Builder: create, edit, delete, run apps | ✅ | Builder at `/builder` |
|
|
39
|
-
| Create application wizard | ✅ | Blank app with its own database role and schema, started from a **boilerplate application** if wanted; **from a file**: CSV/TSV/XLSX/JSON/XML, where an Excel workbook with several sheets (or JSON with several arrays) becomes several tables, with a preview to include or leave out each sheet, edit table/column names, types and primary keys, and **foreign keys proposed** from matching columns; **from pasted data** (CSV/TSV text); **from existing tables** (pick the tables and views of a schema). Each gives a report and form per table, navigation and an optional dashboard (a chart per table), plus an optional faceted search for a single table, all created in one transaction. (sprint 73) **One page like APEX's**: name, icon and description, appearance (theme style, side or top menu, accent), a **page type per table** (interactive report with form, faceted search, cards, calendar, master detail, interactive grid, report, none; large tables proposed as a grid), **features** (About page, access control roles, activity reporting, feedback, theme style selection, PWA, push), settings (alias, authentication, first user, language) and a boilerplate under Advanced; a progress message, then straight to the new application. (sprint 71) The generated pages read like APEX's: human labels (abbreviations, run-together words, column and table comments), plural page and menu names with singular form titles, foreign keys shown by the parent's name in reports, `bytea` columns as one file item with their name/mime/size/updated columns, number format masks, a pencil per report row, the Dashboard after Home with *(none)* and top-N charts, and a Home page with a hero and a card per page. **
|
|
43
|
+
| Create application wizard | ✅ | Blank app with its own database role and schema, started from a **boilerplate application** if wanted; **from a file**: CSV/TSV/XLSX/JSON/XML, where an Excel workbook with several sheets (or JSON with several arrays) becomes several tables, with a preview to include or leave out each sheet, edit table/column names, types and primary keys, and **foreign keys proposed** from matching columns; **from pasted data** (CSV/TSV text); **from existing tables** (pick the tables and views of a schema). Each gives a report and form per table, navigation and an optional dashboard (a chart per table), plus an optional faceted search for a single table, all created in one transaction. (sprint 73) **One page like APEX's**: name, icon and description, appearance (theme style, side or top menu, accent), a **page type per table** (interactive report with form, faceted search, cards, calendar, master detail, interactive grid, report, none; large tables proposed as a grid), **features** (About page, access control roles, activity reporting, feedback, theme style selection, PWA, push), settings (alias, authentication, first user, language) and a boilerplate under Advanced; a progress message, then straight to the new application. (sprint 71) The generated pages read like APEX's: human labels (abbreviations, run-together words, column and table comments), plural page and menu names with singular form titles, foreign keys shown by the parent's name in reports, `bytea` columns as one file item with their name/mime/size/updated columns, number format masks, a pencil per report row, the Dashboard after Home with *(none)* and top-N charts, and a Home page with a hero and a card per page. (sprint 66) **From a blueprint** (26.1 blueprints): a reviewed JSON spec of tables, pages and sample data, or a blueprint made from an existing application (see [Blueprints](#workflow-automation-and-ai)) |
|
|
40
44
|
| Create page wizards | ✅ | Report and form, interactive grid, form, cards, calendar, chart, map, faceted search and master-detail (stacked grids) from any table or view, with defaults from the catalog (columns, key, dates, positions, foreign keys), an optional modal form page and a navigation entry; also from SQL (`meta.generate_page`). No side-by-side or drill-down master-detail, no wizard for smart filters or trees |
|
|
41
|
-
| Page Designer | ✅ | IDE-style window (dark or light): component tree, a layout canvas with drag and drop (with keyboard and button alternatives) and a gallery of regions, items and buttons, a filterable property editor; undo/redo; panes become tabs on phones. Settings forms for report, grid, chart, cards, calendar, faceted search, smart filters, display selector, map, tree and template component regions. A code editor for SQL, PL/pgSQL, JSON and HTML with highlighting and autocomplete of tables, columns and `:ITEM` binds (no extra libraries). Drag and drop needs a mouse; on touch screens the Arrange buttons move components. (sprint 77) The layout draws the page template's display positions (banner, breadcrumb bar, left/right column, body, footer) as drop zones and a region's button positions; the rendering tree groups by position and has a context menu (create in or below, Duplicate, Copy to other page, expand/collapse all, (sprint 90) Comment out with a COMMENTED_OUT build option, delete; no Create Sub Region: no nested regions); the property editor has Common / All, Go to group and a Template Options dialog; a page number in the toolbar. No nested regions (APEX's sub regions)
|
|
45
|
+
| Page Designer | ✅ | IDE-style window (dark or light): component tree, a layout canvas with drag and drop (with keyboard and button alternatives) and a gallery of regions, items and buttons, a filterable property editor; undo/redo; panes become tabs on phones. Settings forms for report, grid, chart, cards, calendar, faceted search, smart filters, display selector, map, tree and template component regions. A code editor for SQL, PL/pgSQL, JSON and HTML with highlighting and autocomplete of tables, columns and `:ITEM` binds (no extra libraries). Drag and drop needs a mouse; on touch screens the Arrange buttons move components. (sprint 77) The layout draws the page template's display positions (banner, breadcrumb bar, left/right column, body, footer) as drop zones and a region's button positions; the rendering tree groups by position and has a context menu (create in or below, Duplicate, Copy to other page, expand/collapse all, (sprint 90) Comment out with a COMMENTED_OUT build option, delete; no Create Sub Region: no nested regions); the property editor has Common / All, Go to group and a Template Options dialog; a page number in the toolbar. No nested regions (APEX's sub regions) |
|
|
42
46
|
| Shared components | ✅ | (sprint 74) A grid of ten groups with counts like APEX's, a searchable, sortable list per type with Create, and Settings-backed types linking to their Settings tab ([mapping below](#shared-components-apex-links-and-pgkiln)). Navigation menu, **lists** (static entries with nesting, badges, conditions, authorization and build options, or a query; for list regions, the navigation menu and the navigation bar), authorization schemes, build options, lists of values, application items and processes, access control, globalization, template components and plug-ins, web credentials, REST data sources, data load definitions, supporting objects |
|
|
43
47
|
| Export / import | ✅ | `meta.export_app()` / `meta.import_app()`: portable JSON, also in the builder (new applications; `pgkiln import --replace` and the MCP `import_app` update one in place, live for every user at the commit). (sprint 51) **Checked imports**: `pgkiln import --check` (`--dry-run`, `--force`), the MCP import (by default) and the builder's import run the Advisor inside the import's transaction (SQL planned as the application's role: missing tables, columns, functions, types, grants; references) and refuse on errors, so nothing changes; APEX doesn't check. The version an import replaces is [backed up](guide/03-builder.md#backups) first ([chapter 18](guide/18-cli.md#checking-before-an-import)) |
|
|
44
|
-
| APEXlang: human-readable, diffable app files; static IDs (26.1) | ✅ | `pgkiln export --format dir`: one JSON file per component with sorted keys, SQL and HTML in sibling files, references by static id instead of database ids; `pgkiln import --replace` updates an app in place, `pgkiln diff` compares ([chapter 18](guide/18-cli.md)). (0.31) **`--format text`**: the same files as YAML (a strict subset any YAML tool reads) with the SQL and templates inline, read back losslessly ([text files](guide/18-cli.md#text-files-apexlang)); regions have a stored **Static ID** (exported as their key, rendered as `data-static-id`), other components are named by their stored names. The syntax is YAML rather than APEXlang's own, so APEXlang files don't import |
|
|
48
|
+
| APEXlang: human-readable, diffable app files; static IDs (26.1) | ✅ | `pgkiln export --format dir`: one JSON file per component with sorted keys, SQL and HTML in sibling files, references by static id instead of database ids; `pgkiln import --replace` updates an app in place, `pgkiln diff` compares ([chapter 18](guide/18-cli.md)). (0.31) **`--format text`**: the same files as YAML (a strict subset any YAML tool reads) with the SQL and templates inline, read back losslessly ([text files](guide/18-cli.md#text-files-apexlang)); regions have a stored **Static ID** (exported as their key, rendered as `data-static-id`), other components are named by their stored names. The syntax is YAML rather than APEXlang's own, so APEXlang files don't import. (sprint 116, 26.2 **file-level import**) `pgkiln import <dir> --replace --only pages/12` (or `--only shared/lovs/jobs.yaml`, repeatable) imports one page or shared component from a directory export and leaves the rest of the application as it is ([chapter 18](guide/18-cli.md#importing-one-page-or-component)) |
|
|
45
49
|
| Working copies, merge, team development | ✅ | **Working copies** of an application ([chapter 3](guide/03-builder.md#working-copies)): a second app on the same schema and data, compared three ways per component (settings, each shared component, page, region, item, …) with the main app as it was when copied; changes on one side merge, conflicts are chosen per component with a line diff; merge into the main app or refresh the copy, keeping users, sessions, saved reports, secrets and automation switches; locks respected. Conflicts are resolved per component, not per property |
|
|
46
50
|
| Team Development: issues, labels, milestones, templates, feedback | ✅ | (sprint 113) Builder → **Team Development** ([chapter 3](guide/03-builder.md#team-development)): issues per workspace with labels in groups, milestones, assignees, application and page links, Markdown comments with in-app @mentions and a history; a filtered list with saved views and a board by label group or milestone (no JavaScript needed); a set-up wizard installs sample labels, templates, canned responses and milestones. Users' feedback and developer comments become issues; open issues show in the Page Designer, on App Home and on the Workspace home; issues travel in the workspace export. Not included: e-mail notifications, GitHub sync |
|
|
47
51
|
| Application lock (26.1), page locks, comments | ✅ | Page and application locks, enforced on the server for every builder change; the owner or an administrator unlocks, and an administrator breaking a lock is logged. Developer comments per page and per app ([chapter 3](guide/03-builder.md)) |
|
|
@@ -53,7 +57,7 @@ two, REST source catalogs and the workspace export, with their features.)
|
|
|
53
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 |
|
|
54
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 |
|
|
55
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 |
|
|
56
|
-
| 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 |
|
|
57
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)) |
|
|
58
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 |
|
|
59
63
|
|
|
@@ -69,7 +73,7 @@ two, REST source catalogs and the workspace export, with their features.)
|
|
|
69
73
|
| Charts | ✅ | Bar, column, stacked, line, area, combination (columns + lines), scatter, bubble, donut, pie, gauge, funnel, radar, **Gantt** (start/end, progress, milestones, dependencies, a today line, a time axis from hours to years), **pyramid** (area-proportional segments, or two series back to back) and **polar** (polar area); (sprint 63) **range** (floating columns from low to high), **box plot** (from one value per row or five statistics) and **stock** (candlesticks from open, high, low and close); multi-series, tooltips, data table, (sprint 71) a value axis with gridlines on horizontal bars and top-N with an *Other* bar (`"top": 10`), palette checked for colour-vision deficiency; drill-down links on chart marks (checksummed, only to pages the user may open). Drawn on the server as SVG without inline styles. (sprint 69) **Gantt editing**: drag a task or its end, or the arrow keys, runs the region's SQL as the app's role. (sprint 70) **treemap** (squarified, two levels shown), **sunburst** (up to four rings) from `node_id` / `parent_id` columns, and **timeline** (lanes by a `series` column, points and periods, overlaps in rows). **Missing:** other Oracle JET types (e.g. picto, NBox, Sankey) |
|
|
70
74
|
| Cards and metric cards (26.1 metric card template) | ✅ | Cards from SQL, with a KPI "metric" style |
|
|
71
75
|
| Calendar | ✅ | Month, week, day and list views (agenda list on phones); create on click (a checksummed link with the slot); drag and drop to move events through the developer's move SQL, run as the app's role (CSRF, a *who may drag* authorization, only events the user sees). Works without JavaScript; dragging adds on top ([chapter 4](guide/04-pages-and-regions.md#calendar)) |
|
|
72
|
-
| Faceted search | ✅ | Checkbox, range (predefined, or a custom from/to on numbers and dates), star rating and search facets with live counts that honour the other facets; exclude on checkbox facets (26.1). Values travel as query parameters, never as SQL text. (sprint 65) **Facet charts**: a bar or pie chart of a facet's counts, each mark filtering on its value. (sprint 78) The **total row count**, *Show all* after seven values, booleans as Yes/No, one search field (the report's own is left out).
|
|
76
|
+
| Faceted search | ✅ | Checkbox, range (predefined, or a custom from/to on numbers and dates), star rating and search facets with live counts that honour the other facets; exclude on checkbox facets (26.1). Values travel as query parameters, never as SQL text. (sprint 65) **Facet charts**: a bar or pie chart of a facet's counts, each mark filtering on its value. (sprint 78) The **total row count**, *Show all* after seven values, booleans as Yes/No, one search field (the report's own is left out). (sprint 84) A checkbox facet's **⋮ menu** (APEX: the facet's menu): *Clear* and *Sort by count* / *Sort by name* ([chapter 4](guide/04-pages-and-regions.md#facets-faceted-search)) |
|
|
73
77
|
| Smart filters | ✅ | One search field with filter chips and suggestions over a report, the same facet types; URL-based, works without JavaScript ([chapter 4](guide/04-pages-and-regions.md#smart_filters)) |
|
|
74
78
|
| Static content, dynamic content | ✅ | `static` (HTML with substitutions) and `dynamic` (a SELECT returning HTML) |
|
|
75
79
|
| Breadcrumb | ✅ | Automatic, from the page's breadcrumb parent |
|
|
@@ -164,7 +168,7 @@ two, REST source catalogs and the workspace export, with their features.)
|
|
|
164
168
|
| Responsive: phone, tablet, desktop | ✅ | Tested at 390, 768, 1024 and 1440px on every change (`npm run test:e2e`) |
|
|
165
169
|
| Modal dialog pages | ✅ | Full screen on phones |
|
|
166
170
|
| Dark mode and user-chosen theme style | ✅ | Automatic (follows the device), light or dark per app; users may switch, saved on the account; plus a choice of the app's style variants |
|
|
167
|
-
| Theme Roller (26.1: conditional and dynamic properties, CSS variables) | ✅ | Base styles Iris and Standard; accent and header colours for the light and the dark theme; **style variants** (up to 10 saved styles per app: colours for light and dark mode, font, font size, corners; a default; users may choose one, kept per app on the account; exported with the app) with a **live preview** on Settings → Theme → Theme Roller; **template options** on regions, buttons, items and report columns (fixed lists of CSS classes) ([chapter 14](guide/14-globalization.md#style-variants-theme-roller)). **Conditional styles** (a SQL condition per style, run as the app's role: the first that holds applies unless the user chose one) and **dynamic colours** from items (`&ITEM.`, used only when `#rrggbb`) ([chapter 14](guide/14-globalization.md#conditional-and-dynamic-styles)) |
|
|
171
|
+
| Theme Roller (26.1: conditional and dynamic properties, CSS variables) | ✅ | Base styles Iris and Standard; accent and header colours for the light and the dark theme; **style variants** (up to 10 saved styles per app: colours for light and dark mode, font, font size, corners; a default; users may choose one, kept per app on the account; exported with the app) with a **live preview** on Settings → Theme → Theme Roller; **template options** on regions, buttons, items and report columns (fixed lists of CSS classes) ([chapter 14](guide/14-globalization.md#style-variants-theme-roller)). **Conditional styles** (a SQL condition per style, run as the app's role: the first that holds applies unless the user chose one) and **dynamic colours** from items (`&ITEM.`, used only when `#rrggbb`) ([chapter 14](guide/14-globalization.md#conditional-and-dynamic-styles)) (sprint 117, WS-10, 26.2) **Pillar Light / Pillar Dark** navigation appearances with a **header pillar strip** colour (per application or style), the current page and its parent entries told apart in the menu, `u-color-*-subtle` utilities, a lighter processing indicator and the chrome mirrored right to left ([chapter 14](guide/14-globalization.md#navigation-appearances-pillar-light-and-pillar-dark)) |
|
|
168
172
|
| Icons (Font APEX 2.5) | ✅ | 136 line icons of pgkiln's own and (0.31) the **Lucide** set of about 1,600 more in the same line style, each served on its own; **modifiers** like Font APEX's (sizes, spin, rotate, flip, colours) and Font APEX names (`fa-users fa-lg`) where Lucide has the icon; a visual picker in the builder that searches all of them by name and search word ([chapter 9](guide/09-reference.md#icons)). Font APEX's own drawings are Oracle's, so icons look different and a few Font APEX names have no match |
|
|
169
173
|
| Accessibility | ✅ | Labels, keyboard, focus rings, reduced motion, table alternatives for charts, scrolling tables reachable from the keyboard; an automated WCAG 2.1 A/AA audit (axe-core) of every example page in light, dark and Iris and of the builder's main pages runs in CI with no violations allowed. Not a manual expert audit |
|
|
170
174
|
| Drawers, top/bottom dialogs (26.1) | ✅ | Modal pages open as a centred dialog or as a drawer from the left, right, top or bottom edge, in three sizes, sliding in (without animation for reduced motion); on phones full screen ([chapter 4](guide/04-pages-and-regions.md#dialogs-and-drawers)). Not yet: a footer slot for inline drawers |
|
|
@@ -229,6 +233,30 @@ two, REST source catalogs and the workspace export, with their features.)
|
|
|
229
233
|
| Monitoring (top SQL) | ✅ | Activity per app; Top SQL per app's database role from `pg_stat_statements` (sortable, resettable) |
|
|
230
234
|
| Workspace export and import (Workspace Utilities → Export) | ✅ | (sprint 67) Workspace utilities → **Export and import** (administrators and the workspace's administrators): settings (message, banner, preferences), developers and workspace administrators, application groups, extension links, REST source catalogs, SQL scripts, blueprints and data generators as one file; imported into the current workspace in one transaction, keeping or replacing components with the same name and never deleting ([chapter 3](guide/03-builder.md#export-and-import)). Applications are exported on their own; isolation, database roles and passwords never leave the installation |
|
|
231
235
|
| Workspaces (multi-tenant) | ✅ | Workspaces group applications and developers: the builder shows and opens only the applications of a developer's workspaces (administrators: all), a current workspace with a switcher, new and imported applications go into it, administrators add workspaces, choose their developers and move applications ([chapter 3](guide/03-builder.md#workspaces)). (sprint 60) **Isolated workspaces** are a tenant boundary: the applications run on a PostgreSQL login of the workspace's own and its developers' SQL Workshop on another, with row-level security on pgkiln's tables, so SQL that resets its role can't reach other workspaces' applications, data, sessions or accounts; **workspace database roles** (APEX: workspace schemas) assigned by administrators; **workspace administrators** who manage their workspace's developers; SQL scripts, blueprints and sample data per workspace ([isolated workspaces](guide/03-builder.md#isolated-workspaces)). **Missing:** user directories per workspace (accounts are installation-wide, visible to the workspaces whose applications they use), developers created by a workspace administrator |
|
|
236
|
+
| Mail queue reporting: delivery health, performance, failures and usage per workspace (26.2) | ✅ | (sprint 118, WS-9) Administration → **Mail queue** ([chapter 3](guide/03-builder.md#mail-queue)): queued, sent, failed and retrying mail per hour and per workspace / application, the share delivered, the average and the 10 slowest provider calls, and every failure with the provider's answer (an SMTP reply such as `550 5.1.1`), with **Retry** and **Purge** (one or all failed). Administrators see every workspace, a workspace's administrators their own |
|
|
237
|
+
| Workspace-level SMTP credentials (26.1), workspace network ACLs (26.2) | ✅ | (sprint 118, WS-9) A workspace's administrators set up the workspace's **own mail service** ([chapter 3](guide/03-builder.md#a-workspaces-own-mail-service)): any provider, the secret encrypted with `PGKILN_SECRET_KEY` like a web credential's, write-only and never exported; the workspace's applications without a service of their own send through it. **Network access** ([chapter 3](guide/03-builder.md#network-access)): a workspace's list of hosts and ports narrows `PGKILN_REST_ALLOWED_HOSTS` for every outgoing call of its applications (`meta.web_request`, REST data sources, invoke API, token endpoints, object storage, REST source catalogs, the workspace's SMTP server), on every redirect hop; it can never widen the installation's list; refusals in the debug log and a *Refused calls* list. **Different:** the secret is kept with the mail service (encrypted like a web credential), not as a separate web credential |
|
|
238
|
+
|
|
239
|
+
## APEX 26.2 workspace (WS-1 … WS-13)
|
|
240
|
+
|
|
241
|
+
(sprint 116) APEX 26.2's workspace, compared item by item (the parity board's WS cards). Done rows link to the full
|
|
242
|
+
row above where there is one.
|
|
243
|
+
|
|
244
|
+
| APEX 26.2 | pgkiln | Notes |
|
|
245
|
+
|---|---|---|
|
|
246
|
+
| WS-1 Workspace home: tool cards, top apps and users, summary | ✅ | (sprint 109) `/builder/home` above App Builder and SQL Workshop ([Administration](#administration)) |
|
|
247
|
+
| WS-2 Data Reporter as a workspace tool for business users | ✅ | (sprint 110) App Builder → Data Reporter: datasets, reporting applications with editors and viewers, published reports with stable URLs ([Data and integration](#data-and-integration)) |
|
|
248
|
+
| WS-3 Team Development: issues, labels, milestones, templates | ✅ | (sprint 113) Builder → Team Development with a board and a set-up wizard ([App Builder and development](#app-builder-and-development)) |
|
|
249
|
+
| WS-4 AI Agents with tools | ✅ | (sprint 111) AI Agents and AI Tools as shared components, a Navigate tool, Gemini and OpenAI-compatible services ([Workflow, automation and AI](#workflow-automation-and-ai)) |
|
|
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
|
+
| 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
|
+
| 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 | ✅ | (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
|
+
| 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
|
+
| 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
|
+
| 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)) |
|
|
257
|
+
| WS-12 App Builder list: Updated By, Working Copies, lock state | ✅ | (sprint 116) The report shows Updated by (the developer who changed the application last in the builder or imported it), the number of working copies (a link to them) and a lock icon with its owner; the cards show them as badges; Views (24h) and Sign-in stay ([chapter 3](guide/03-builder.md#app-builder-home)) |
|
|
258
|
+
| WS-13 Deep Data Security: row, column and value policies in one place | ✅ | (sprint 119) SQL Workshop → a table → **Security**: its row level security policies, a matrix of database roles × columns (read, update) written as `GRANT` / `REVOKE`, and masked values per application role (empty, `***`, `***` + last 4) in a masking view owned by `<schema>_masking`, so row level security still applies inside it; Preview SQL, Apply, the Change Log. Pages, AI tools, REST handlers, AutoREST and the MCP server's `run_query` (with `alias` and `user`) run as the application's role with the same identity ([Security](guide/08-security.md#data-security-per-table-rows-columns-and-values)). The mask holds where a role reads the view instead of the raw column |
|
|
259
|
+
| OCI managed identities (workload identity for cloud services) | ➖ | Not planned: pgkiln runs on any cloud or none; use the platform's workload identity (an IAM role, a managed identity, a service account) for the server and keep secrets in web credentials and AI services |
|
|
232
260
|
|
|
233
261
|
## Different on purpose
|
|
234
262
|
|
|
@@ -307,7 +335,8 @@ report filters, App Builder AI and blueprints.
|
|
|
307
335
|
9. ~~Schema comparison and DDL generation in SQL Workshop~~ (done in sprint 56): no ❌ rows left.
|
|
308
336
|
10. ~~Region templates~~ (done in sprint 57); ~~page groups~~ (sprint 58); ~~the help pane and Quick edit~~ (sprint 59); ~~then the last 🟡 row: workspace isolation~~ (done in sprint 60: no 🟡 rows left). (2026-10-12, owner: more built-in runtime languages are not planned; the row was removed. Other languages come from an application's own text messages.)
|
|
309
337
|
|
|
310
|
-
Sources: [APEX 26.
|
|
338
|
+
Sources: [APEX 26.2 new features](https://docs.oracle.com/en/database/oracle/apex/26.2/htmrn/new-features.html),
|
|
339
|
+
[APEX 26.1 new features](https://docs.oracle.com/en/database/oracle/apex/26.1/htmrn/new-features.html),
|
|
311
340
|
[What's new in APEX 24.2](https://apex.oracle.com/en/platform/features/whats-new-242/),
|
|
312
341
|
[APEX_MAIL (APEX API reference)](https://docs.oracle.com/en/database/oracle/apex/24.2/aeapi/APEX_MAIL.html).
|
|
313
342
|
|
|
@@ -185,7 +185,7 @@ which is read at startup; real environment variables take precedence.
|
|
|
185
185
|
| `GEMINI_API_KEY` | *(none)* | (sprint 111) Default API key of AI services with the provider Gemini that have no key of their own |
|
|
186
186
|
| `OPENAI_COMPATIBLE_API_KEY` | *(none)* | (sprint 111) Default API key of OpenAI-compatible AI services (Ollama, vLLM, Azure OpenAI) that have no key of their own; without either, no key is sent (`none`) |
|
|
187
187
|
| `PGKILN_SECRET_KEY` | *(none)* | Encrypts the secrets of web credentials and the API keys of AI services; at least 32 characters (e.g. `openssl rand -base64 32`). Keep it outside the database; changing it means entering the secrets again ([chapter 19](19-rest-data-sources.md)) |
|
|
188
|
-
| `PGKILN_REST_ALLOWED_HOSTS` | *(none: no outgoing calls)* | Hosts REST data sources and `invoke_api` may call: `api.example.com`, `*.example.com`, `host:8443`, `*` (any public host) ([chapter 19](19-rest-data-sources.md#server-configuration-and-the-allow-list)) |
|
|
188
|
+
| `PGKILN_REST_ALLOWED_HOSTS` | *(none: no outgoing calls)* | Hosts REST data sources and `invoke_api` may call: `api.example.com`, `*.example.com`, `host:8443`, `*` (any public host) ([chapter 19](19-rest-data-sources.md#server-configuration-and-the-allow-list)); a workspace's [network access list](03-builder.md#network-access) can narrow it, and the SMTP server of a workspace's own mail service must be on it |
|
|
189
189
|
| `PGKILN_REST_PRIVATE_HOSTS` | *(none)* | Hosts that may resolve to private, loopback or link-local addresses (also allows them) |
|
|
190
190
|
| `PGKILN_PUSH_HOSTS` | the browsers' push services | The hosts push notifications may be posted to: `fcm.googleapis.com,updates.push.services.mozilla.com,web.push.apple.com,*.notify.windows.com` when unset ([chapter 17](17-mobile.md#push-notifications)) |
|
|
191
191
|
| `PGKILN_PUSH_SUBJECT` | `PUBLIC_URL` when it is https | The contact the push services see (`mailto:ops@example.com` or an https URL); Apple refuses notifications without one |
|
package/docs/guide/03-builder.md
CHANGED
|
@@ -160,8 +160,9 @@ applications' files. Choose what goes in:
|
|
|
160
160
|
| Data Reporter datasets | Every [dataset](#data-reporter-datasets-and-reporting-applications) (sprint 110) |
|
|
161
161
|
| Team Development | [Label groups, labels, milestones, templates and issues](#team-development) with their comments and history; an issue's application by alias (sprint 113) |
|
|
162
162
|
|
|
163
|
-
Never in the file: the workspace's name, its [isolation](#isolated-workspaces) and database roles,
|
|
164
|
-
|
|
163
|
+
Never in the file: the workspace's name, its [isolation](#isolated-workspaces) and database roles, its
|
|
164
|
+
[mail service](#a-workspaces-own-mail-service) and [network access list](#network-access) (installation-specific, like
|
|
165
|
+
isolation), passwords and secrets, script runs and other history. **Applications are exported on their own** (an application's *Export*).
|
|
165
166
|
|
|
166
167
|
**Import** reads such a file into the current workspace, for the components you choose. Components with a name the
|
|
167
168
|
workspace already has are kept, or replaced with *Replace components with the same name*; nothing is deleted. A
|
|
@@ -302,9 +303,16 @@ The App Builder's home page, `/builder/apps` (`/builder` shows it too, unless th
|
|
|
302
303
|
developers, the SQL Workshop, and for administrators [workspaces](#workspaces), AI services and the
|
|
303
304
|
[installation log](#installation)). The list, the dashboard and Recent show the current workspace.
|
|
304
305
|
- **The applications**, as a report (application id, name, alias, pages, page views of the last 24
|
|
305
|
-
hours, sign-in, last updated, and Edit / Run) or as cards. **Search** filters the list as you type
|
|
306
|
+
hours, sign-in, last updated, **updated by**, **working copies**, and Edit / Run) or as cards. **Search** filters the list as you type
|
|
306
307
|
(by name, alias or id; without JavaScript, press Enter). Click a column heading, or use
|
|
307
308
|
**Actions**, to sort. The view and the sort are remembered until you sign out.
|
|
309
|
+
- (sprint 116) **Updated by** is the developer who changed the application last in the builder (any change to its
|
|
310
|
+
pages, shared components or settings; locks and comments don't count) or who created, imported or copied it;
|
|
311
|
+
*Updated* is the later of that change and the application's own settings. An import with `pgkiln import` or the
|
|
312
|
+
MCP server changes *Updated* only. **Working copies** counts the application's [working copies](#working-copies)
|
|
313
|
+
and links to them. A **lock icon** after the name shows that the application is [locked](#page-locks-and-comments),
|
|
314
|
+
with its owner in the tooltip (and for screen readers). The cards show the same as small badges. On phones the
|
|
315
|
+
report keeps the id, the name with the lock and the actions.
|
|
308
316
|
- **A side column** (on the right on wide screens, below the list otherwise): About, **Recent** (the
|
|
309
317
|
applications you opened last) and Tasks.
|
|
310
318
|
- **The workspace message**, when the workspace has one, above the tiles.
|
|
@@ -321,20 +329,53 @@ leaves its group. Every developer of the workspace manages them.
|
|
|
321
329
|
|
|
322
330
|
## App Gallery
|
|
323
331
|
|
|
324
|
-
The **App Gallery** (the cube in the icon rail, `/builder/gallery`; APEX: App Gallery) has
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
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`.
|
|
330
359
|
- **Starter Apps**: small applications (Team Tasks, Contacts, Expense Claims, Asset Inventory, Event Registrations)
|
|
331
360
|
shipped as [blueprints](#creating-an-application-from-a-blueprint). **Install** opens the blueprint's review:
|
|
332
361
|
nothing is created before you confirm, the application gets a new role and schema in the current workspace, and you
|
|
333
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).
|
|
334
369
|
- **Custom Apps**: the workspace's boilerplate applications (Application type *Boilerplate*): *Create from it* opens
|
|
335
370
|
Create with that boilerplate chosen.
|
|
336
371
|
|
|
337
|
-
The list is `examples/gallery/gallery.json
|
|
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.
|
|
338
379
|
|
|
339
380
|
## Data Reporter: datasets and reporting applications
|
|
340
381
|
|
|
@@ -1335,6 +1376,67 @@ provider grant it the application permission *Mail.Send*; for SMTP with OAuth2 t
|
|
|
1335
1376
|
*SMTP.SendAsApp* and register its service principal in Exchange Online. In both cases limit it to the
|
|
1336
1377
|
sending mailboxes (an application access policy or RBAC for Applications).
|
|
1337
1378
|
|
|
1379
|
+
|
|
1380
|
+
### Mail queue
|
|
1381
|
+
|
|
1382
|
+
Administration menu → **Mail queue** (`/builder/mail-queue`; APEX 26.2: Administration → Mail queue): the delivery
|
|
1383
|
+
health of the mail queue, for administrators (every workspace, or one) and a workspace's administrators (the current
|
|
1384
|
+
workspace's applications only; other developers get 403). Filter by period (24 hours, 48 hours, 7 days), workspace and
|
|
1385
|
+
application:
|
|
1386
|
+
|
|
1387
|
+
- **figures**: queued now, retrying now (failed with an error that may pass, waiting for the next of its 5 attempts),
|
|
1388
|
+
being sent, sent and failed in the period, the share delivered and the average provider call;
|
|
1389
|
+
- **Per hour**: queued, sent, failed and retrying mail per hour (UTC);
|
|
1390
|
+
- **Slowest provider calls**: the 10 longest hand-overs of the period (how long the provider took to accept or refuse
|
|
1391
|
+
the mail), with application, service and outcome;
|
|
1392
|
+
- **Per workspace and application**: sent, failed, retrying and queued mail, the average and slowest call;
|
|
1393
|
+
- **Failures**: every failed mail (kept 30 days) with the provider's answer, e.g. the SMTP server's
|
|
1394
|
+
`550 5.1.1 no such user`. **Retry** queues one again with fresh attempts, **Purge** deletes it; *Retry all failed*
|
|
1395
|
+
and *Purge all failed* act on the failures of the filter (never outside the developer's scope).
|
|
1396
|
+
|
|
1397
|
+
Bodies and attachments are never shown here. Every action checks again on the server that the mail's application is in
|
|
1398
|
+
the developer's scope, and is written to the activity log.
|
|
1399
|
+
|
|
1400
|
+
### A workspace's own mail service
|
|
1401
|
+
|
|
1402
|
+
A workspace's page → *Mail and network access* → **mail service** (`/builder/workspaces/<id>/mail`; APEX 26.1:
|
|
1403
|
+
workspace-level SMTP credentials), for the workspace's administrators: a mail service of the workspace's own, with the
|
|
1404
|
+
same providers and checks as [above](#mail-services). The applications of the workspace that an administrator gave no
|
|
1405
|
+
service send through it (an application an administrator gave one keeps it; a service of another workspace is never
|
|
1406
|
+
used). Its secret is stored encrypted with `PGKILN_SECRET_KEY` like a web credential's: write-only, never shown, never
|
|
1407
|
+
exported. It differs from an installation service in two ways that keep it from reaching what the installation
|
|
1408
|
+
doesn't allow:
|
|
1409
|
+
|
|
1410
|
+
- it uses the provider's own API: no API base URL and no token URL (OAuth2 goes to Microsoft Entra of the tenant);
|
|
1411
|
+
- an SMTP server must be on the installation's allow-list (`PGKILN_REST_ALLOWED_HOSTS`, e.g. `smtp.example.com:587`)
|
|
1412
|
+
and the workspace's [network access](#network-access) list, and resolve to a public address (unless
|
|
1413
|
+
`PGKILN_REST_PRIVATE_HOSTS` lists it). The server resolves the host once and connects to the address it checked,
|
|
1414
|
+
with the host name kept for TLS, on every send and test.
|
|
1415
|
+
|
|
1416
|
+
### Network access
|
|
1417
|
+
|
|
1418
|
+
Administration menu → **Network access** (`/builder/network`; APEX 26.2: workspace network ACLs), for administrators
|
|
1419
|
+
(any workspace, `?ws=`) and a workspace's administrators (their workspaces): which web services a workspace's
|
|
1420
|
+
applications may call. The installation's list (`PGKILN_REST_ALLOWED_HOSTS`, set in the server's environment, shown
|
|
1421
|
+
read-only; the private hosts to administrators only) applies to every workspace. A workspace can choose **Only the
|
|
1422
|
+
hosts below**: then every outgoing call made for one of its applications must match one of its entries *and* the
|
|
1423
|
+
installation's list. A workspace's list only narrows; it can never widen the installation's, and private, loopback and
|
|
1424
|
+
link-local addresses stay refused unless the installation allows them. Entries are `api.example.com`, `*.example.com`
|
|
1425
|
+
(its subdomains) or `api.example.com:8443` (that port only); restricted with no entries means no outgoing calls.
|
|
1426
|
+
|
|
1427
|
+
It is enforced on the server for every outgoing web call of the workspace: `meta.web_request` and
|
|
1428
|
+
`meta.web_request_source`, REST data sources (regions, write-back, synchronisation, the assistant), the Invoke API
|
|
1429
|
+
process and workflow step, web credential token endpoints, object storage of file items, the builder's *Test* of a
|
|
1430
|
+
source, REST source catalogs read from a URL, and the SMTP server of the workspace's own mail service. Every redirect
|
|
1431
|
+
hop is checked again, and a REST source's cached response is not served once its host is off the list. A refused call
|
|
1432
|
+
fails with *The host … is not on the network access list of workspace …*, is written to the application's debug log
|
|
1433
|
+
(level 2, warning, for `meta.web_request` in a page process; level 1 for regions and processes) and appears under
|
|
1434
|
+
**Refused calls** (kept 7 days). **Check a URL** says whether a URL may be called, without calling it.
|
|
1435
|
+
|
|
1436
|
+
Not covered by a workspace's list: the installation's own services, which only administrators configure (installation
|
|
1437
|
+
mail services, AI services, the geocoder, sign-in providers) and push notification services (their own list,
|
|
1438
|
+
`PGKILN_PUSH_HOSTS`).
|
|
1439
|
+
|
|
1338
1440
|
## AI services
|
|
1339
1441
|
|
|
1340
1442
|
Workspace utilities → **AI services** (administrators only; APEX: *Generative AI services*) lists the
|
|
@@ -1543,6 +1645,10 @@ the SQL Workshop's connection may use. Without JavaScript the header's field ope
|
|
|
1543
1645
|
transaction (nothing changes when one fails, and the error shows under *Output*); **Open in the worksheet** puts
|
|
1544
1646
|
them there instead. *Use as template* starts a new table with the same columns and keys (names with `_copy`).
|
|
1545
1647
|
Defaults, checks and index expressions are single expressions (no `;` or comments).
|
|
1648
|
+
- (sprint 119) **Security** (the Object Browser's *Security* button on a table, *Security…* in its ⋯ menu): the
|
|
1649
|
+
table's row level security policies, a matrix of database roles × columns with *read* and *update*, and masked
|
|
1650
|
+
columns per application role in a masking view; Preview SQL, Apply (one transaction, recorded in the Change Log)
|
|
1651
|
+
or Open in the worksheet ([chapter 8](08-security.md#data-security-per-table-rows-columns-and-values)).
|
|
1546
1652
|
- **Run Statement** (**Ctrl/Cmd + Enter**) runs the statement at the cursor: the one the cursor is in, else the
|
|
1547
1653
|
nearest one before it. A selection runs as it is, even when it holds several statements. The rows of the last
|
|
1548
1654
|
query show in **Query Result**, up to 500, with row numbers, numbers right-aligned and NULL as *(null)*. The
|