feat(playground): add a DatabasePlugin example - #529
Merged
Merged
Conversation
This was referenced Aug 10, 2026
ditadi
requested review from
MarioCadenas and
atilafassina
and removed request for
pkosiec
August 10, 2026 22:40
Base automatically changed from
stack/database-mvp/04-mutations-hooks
to
main
September 8, 2026 14:28
ditadi
force-pushed
the
stack/database-mvp/05-integration
branch
from
September 8, 2026 15:33
5d88bf2 to
60dab5b
Compare
Contributor
📦 Bundle size reportCompared against
|
| dist | raw | gzip |
|---|---|---|
| JS (runtime) | 1.2 MB (-86 B) | 425 KB (-7 B) |
| Type declarations | 443 KB | 161 KB |
| Source maps | 2.3 MB (-20 B) | 797 KB (-14 B) |
| Other | 11 KB | 3.7 KB |
| Total | 4.0 MB (-106 B) | 1.4 MB (-21 B) |
Per-entry composition (own code — deps external (as shipped))
| Entry | Initial (gz) | Lazy (gz) | Total (gz) | node_modules (min) | Own code (min) |
|---|---|---|---|---|---|
. |
96 KB | 2.5 KB | 98 KB | external | 314 KB |
./beta |
93 KB | 457 B | 93 KB | external | 281 KB |
./testing |
38 KB | 30 KB (+2 B) | 69 KB (+2 B) | external | 201 KB |
./tsdown |
520 B | 0 B | 520 B | external | 813 B |
./type-generator |
23 KB | 0 B | 23 KB | external | 65 KB |
Chunks:
| Entry | Chunk | Load | Size (gz) |
|---|---|---|---|
. |
index.js |
initial | 92 KB |
. |
utils.js |
initial | 4.0 KB |
. |
remote-tunnel-manager.js |
lazy | 2.5 KB |
./beta |
beta.js |
initial | 77 KB |
./beta |
stream-manager.js |
initial | 5.8 KB |
./beta |
wide-event-emitter.js |
initial | 3.2 KB |
./beta |
databricks.js |
initial | 3.2 KB |
./beta |
configuration.js |
initial | 2.3 KB |
./beta |
service-context.js |
initial | 1.3 KB |
./beta |
client.js |
initial | 434 B |
./beta |
client-options.js |
initial | 219 B |
./beta |
supervisor-api.js |
lazy | 192 B |
./beta |
databricks.js |
lazy | 142 B |
./beta |
index.js |
lazy | 123 B |
./testing |
manifest.js |
initial | 26 KB |
./testing |
index.js |
initial | 9.9 KB |
./testing |
wide-event-emitter.js |
initial | 2.9 KB |
./testing |
index.js |
lazy | 26 KB |
./testing |
remote-tunnel-manager.js |
lazy | 2.5 KB |
./testing |
utils.js |
lazy | 1.2 KB |
./tsdown |
index.js |
initial | 520 B |
./type-generator |
index.js |
initial | 23 KB |
@databricks/appkit-ui
npm tarball (packed): 350 KB (+4 B) — gzipped download (dist + bin; excludes release-only docs/NOTICE).
| dist | raw | gzip |
|---|---|---|
| JS (runtime) | 395 KB | 132 KB |
| Type declarations | 229 KB | 84 KB (+1 B) |
| Source maps | 766 KB | 253 KB |
| CSS | 16 KB | 3.2 KB |
| Total | 1.4 MB | 472 KB (+1 B) |
Per-entry composition (consumer bundle — deps bundled, peerDeps external)
| Entry | Initial (gz) | Lazy (gz) | Total (gz) | node_modules (min) | Own code (min) |
|---|---|---|---|---|---|
./js |
5.3 KB | 49 KB | 55 KB | 208 KB | 14 KB |
./js/beta |
20 B | 0 B | 20 B | 0 B | 0 B |
./react |
432 KB | 49 KB | 481 KB | 1.3 MB | 177 KB |
./react/beta |
1.0 KB | 0 B | 1.0 KB | 0 B | 1.9 KB |
Chunks:
| Entry | Chunk | Load | Size (gz) |
|---|---|---|---|
./js |
index.js |
initial | 5.2 KB |
./js |
chunk |
initial | 120 B |
./js |
apache-arrow |
lazy | 49 KB |
./js/beta |
beta.js |
initial | 20 B |
./react |
index.js |
initial | 430 KB |
./react |
tslib |
initial | 2.1 KB |
./react |
apache-arrow |
lazy | 49 KB |
./react/beta |
beta.js |
initial | 1.0 KB |
Contributor
🤖 AppKit PR bot🔬 Run evalsStart an eval for this PR from the evals-monitor app: Go to Evals Monitor → 📦 Try this PR's app templateScaffolds a new app from this PR's SDK build. Run it in any folder (requires the GitHub CLI — gh run download 35989338965 -R databricks/appkit -n appkit-template-0.77.0-pr.bec3a21-stack-database-mvp-05-integration-529 -D appkit-pr-529 \
&& unzip -o "appkit-pr-529/appkit-template-0.77.0-pr.bec3a21-stack-database-mvp-05-integration-529.zip" -d "appkit-pr-529" \
&& databricks apps init --template "appkit-pr-529"The template pins |
ditadi
force-pushed
the
stack/database-mvp/05-integration
branch
from
September 23, 2026 22:23
4511f37 to
d2e8191
Compare
Exercise the typed client, the generated routes, and the three hook points against a live Postgres, and cover the assembled stack with one integration test. Signed-off-by: ditadi <victordperd@gmail.com>
Signed-off-by: ditadi <victordperd@gmail.com>
Addresses review feedback on the createAgent call sitting in index.ts: the redactor now lives at server/agents/redactor/agent.ts, the same folder convention the other code agents use, and index.ts imports it. Also drops the explicit schema from the registration. #582 made database() load config/database/schema.ts, which is exactly where the playground's schema already lives, so the example now shows that path instead of importing the schema by hand. Signed-off-by: ditadi <victordperd@gmail.com>
PR #582 switched createDatabaseState to initializeLakebasePool, but this branch's integration test still mocked createLakebasePool. The mock factory no longer supplied initializeLakebasePool, so every test failed with SETUP_FAILED once the branch merged with main. Signed-off-by: ditadi <victordperd@gmail.com>
ditadi
force-pushed
the
stack/database-mvp/05-integration
branch
from
September 24, 2026 10:48
5865f08 to
cad91ec
Compare
MarioCadenas
approved these changes
Sep 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack
The four PRs above have landed, so this one targets
mainand the diff shown here is the whole remaining delta.What
The last PR in the series. No SDK behaviour changes here: this is the dev-playground page that runs the whole plugin against a live Postgres, plus one integration test that asserts the assembled stack from the outside.
The page is a small board/annotation app — three tables, a two-edge include, all three hook points, and a private column — chosen so every claim the earlier PRs make is visible rather than described.
Changes
The schema (
config/database/schema.ts)boards → notes → note_events, which is enough to exercise a nested include.notes.author_emailis.private(), so it is writable from server code and refused on the wire — the page shows both halves of that.The plugin does not create tables. The app expects them to exist, and the page says so when they do not.
The registration passes no
schema. #582 madedatabase()load the namedschemaexport fromconfig/database/schema.ts, which is where this file already sits, so the example shows that path rather than importing the schema by hand.The registration (
server/index.ts)Registered conditionally on
LAKEBASE_ENDPOINT, the same waylakebase()already is in this file, so the playground still boots without a database configured.api: { writes: { tables: ["boards", "notes"] } }generates reads for all three tables but accepts HTTP writes only onboardsandnotes. The audit trail is written by a hook and never through the API, which is the exposure decision from #527 shown rather than explained.The
noteshooks use all three points:beforeCreateruns an agent to redact personal names from the body before the insert, so the unredacted text never reaches the table, and stamps the privateauthor_email. This is the intended shape of the hook API: a hook is server code and can call any other plugin. The model call is bounded byAbortSignal.timeout(10_000), below the 30-second transaction deadline, and empty or errored output rolls the mutation back rather than falling through to the original text. The agent itself lives inserver/agents/redactor/agent.ts, the same folder convention the playground's other code agents use.serializeships a 120-character preview on the list route and the whole body on the detail route.afterCreatewrites thenote_eventsrow inside the insert's own transaction, so the note and the event describing it commit together or not at all.The page (
client/src/routes/database.route.tsx)A board explorer over the generated routes, a panel that traces a write through its hooks, and a probe that fires the requests the plugin is supposed to refuse — writing a private column, an unknown field, an over-large
limit— and shows the status and body that come back.Every request the page makes goes through a generated route, including the nested include, which it reaches with
?include=. An earlier revision carried two hand-written routes alongside them; they are gone, so nothing here competes with the generated API.One integration test (
plugins/database/tests/mvp.integration.test.ts)Drives the plugin through its real assembly with only the driver mocked: config in, routes registered, request in, response out. It is the test that would catch a regression the unit suites each miss individually.
Review feedback
The three automated findings on the first revision are addressed in the code:
Verification
pnpm test— 5024 passing, 1 skippedpnpm -r typecheck— clean across all packagespnpm run generate:types,pnpm run sync:template, andpnpm run docs:buildproduce no drift