Skip to content

feat(appkit): default defineSchema tables to the app schema - #655

Draft
ditadi wants to merge 2 commits into
stack/database-dev-flow/01-migrations-on-deployfrom
stack/database-dev-flow/02-default-app-schema
Draft

ditadi wants to merge 2 commits into
stack/database-dev-flow/01-migrations-on-deployfrom
stack/database-dev-flow/02-default-app-schema

Conversation

@ditadi

@ditadi ditadi commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #654. The design is #677.

What did you change, and why?

Why: On Lakebase, the deployed app's service principal has no CREATE on public. Only pg_database_owner and databricks_superuser have it. The service principal can create and own a schema of its own. #654 applies migrations on start as that service principal, so with public as the default the first deploy would fail until someone ran a grant by hand.

Change:

  • defineSchema() without a schemaName puts its tables in the Postgres schema app. The service principal creates app on its first start and owns everything in it, including the migration journal. DEFAULT_SCHEMA_NAME in define-schema.ts is the only place the default is set.
  • An explicit { schemaName: "public" } still produces unqualified SQL (pgTable / pgEnum).
  • This breaks beta apps whose tables are in public: they look in app and fail setup. When every missing table exists in public, the error says so and shows { schemaName: "public" }. The usual advice to commit migrations would create a second, empty copy in app, so the error leaves it out in this case.
  • A 42501 while migrating into public gets its own hint: grant CREATE ON SCHEMA public to the service principal, or use the default app. The general hint blames a re-added resource or a recreated app, which is wrong for public.
  • The plugin docs explain the default, say each app needs its own schema, and cover upgrading an app with tables in public.
  • The dev-playground passes { schemaName: "public" }, because its tables were created by hand in public.
  • Safe to deploy alone: apps that name their schema are unchanged, and apps on the old default get an error that says what to change.

How do you know it works?

Testing:

  • define-schema.test.ts: tables and enums go to app by default, and stay unqualified with an explicit public.
  • schema-check.test.ts: the error names public when every missing table is there. It keeps the usual advice when only some are there, and when the declared schema is public.
  • ownership.test.ts: the public hint.
  • migrate-on-start.test.ts uses the default, so it checks that the journal goes to app.
  • Fixtures that assert unqualified SQL or public.* names pass public explicitly, and their assertions are unchanged.

@ditadi
ditadi force-pushed the stack/database-dev-flow/02-default-app-schema branch from 59db797 to f8a437d Compare October 12, 2026 21:32
@ditadi
ditadi added this pull request to stack #667 October 13, 2026 13:34
@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

📦 Bundle size report

Compared against bundle-size-baseline.json (main).

@databricks/appkit

npm tarball (packed): 1.3 MB (+54 KB) — gzipped download (dist + bin; excludes release-only docs/NOTICE).

dist raw gzip
JS (runtime) 1.3 MB (+58 KB) 468 KB (+21 KB)
Type declarations 464 KB (+8.1 KB) 168 KB (+2.8 KB)
Source maps 2.6 MB (+109 KB) 873 KB (+36 KB)
Other 11 KB 3.7 KB
Total 4.3 MB (+175 KB) 1.5 MB (+59 KB)
Per-entry composition (own code — deps external (as shipped))
Entry Initial (gz) Lazy (gz) Total (gz) node_modules (min) Own code (min)
. 106 KB (+3.9 KB) 2.5 KB (+1 B) 108 KB (+3.9 KB) external 343 KB (+12 KB)
./beta 107 KB (+8.8 KB) 483 B (-2 B) 108 KB (+8.8 KB) external 322 KB (+25 KB)
./testing 45 KB (+3.1 KB) 32 KB (-2 B) 77 KB (+3.1 KB) external 223 KB (+8.7 KB)
./tsdown 520 B 0 B 520 B external 813 B
./type-generator 26 KB (+2.8 KB) 0 B 26 KB (+2.8 KB) external 74 KB (+7.9 KB)

Chunks:

Entry Chunk Load Size (gz)
. index.js initial 101 KB
. utils.js initial 4.6 KB
. remote-tunnel-manager.js lazy 2.5 KB
./beta beta.js initial 87 KB
./beta modular.js initial 6.0 KB
./beta stream-manager.js initial 5.9 KB
./beta service-context.js initial 4.2 KB
./beta databricks.js initial 3.3 KB
./beta client.js initial 647 B
./beta index.js initial 20 B
./beta supervisor-api.js lazy 192 B
./beta databricks.js lazy 177 B
./beta index.js lazy 114 B
./testing manifest.js initial 32 KB
./testing index.js initial 10 KB
./testing wide-event-emitter.js initial 2.9 KB
./testing index.js lazy 28 KB
./testing remote-tunnel-manager.js lazy 2.5 KB
./testing utils.js lazy 1.8 KB
./tsdown index.js initial 520 B
./type-generator index.js initial 26 KB

@databricks/appkit-ui

npm tarball (packed): 397 KB (+501 B) — gzipped download (dist + bin; excludes release-only docs/NOTICE).

dist raw gzip
JS (runtime) 429 KB (+235 B) 147 KB (+108 B)
Type declarations 267 KB (+983 B) 98 KB (+226 B)
Source maps 853 KB (+314 B) 286 KB (+143 B)
CSS 16 KB 3.2 KB
Total 1.5 MB (+1.5 KB) 534 KB (+477 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 2.1 KB 0 B 2.1 KB 0 B 5.0 KB
./react 433 KB (+12 B) 49 KB 481 KB (+12 B) 1.3 MB 177 KB (+41 B)
./react/beta 4.9 KB 0 B 4.9 KB 0 B 12 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 2.1 KB
./react index.js initial 431 KB
./react tslib initial 2.1 KB
./react apache-arrow lazy 49 KB
./react/beta beta.js initial 4.9 KB

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AppKit PR bot

🔬 Run evals

Start an eval for this PR from the evals-monitor app: Go to Evals Monitor →

📦 Try this PR's app template

Scaffolds a new app from this PR's SDK build. Run it in any folder (requires the GitHub CLI — gh auth login — and the Databricks CLI):

gh run download 38406009750 -R databricks/appkit -n appkit-template-0.87.0-pr.43ebfc8-stack-database-dev-flow-02-default-app-schema-655 -D appkit-pr-655 \
  && unzip -o "appkit-pr-655/appkit-template-0.87.0-pr.43ebfc8-stack-database-dev-flow-02-default-app-schema-655.zip" -d "appkit-pr-655" \
  && databricks apps init --template "appkit-pr-655"

The template pins @databricks/appkit and @databricks/appkit-ui to tarballs built from this branch, so the scaffolded app runs against this PR's code.

defineSchema() without a schemaName now places its tables in the Postgres
schema "app" instead of "public". The deployed app's service principal can
create and own a schema of its own, but has no CREATE on public, so tables
in public could not be migrated on deploy without a manual grant.

Signed-off-by: ditadi <victordperd@gmail.com>
An app whose tables predate the app default fails setup with advice to
commit migrations, which would create an empty copy in app. Name the
public tables instead, give public its own ownership hint, document one
schema per app, and pin the dev-playground to public.

Signed-off-by: ditadi <victordperd@gmail.com>
@ditadi
ditadi force-pushed the stack/database-dev-flow/02-default-app-schema branch from f8a437d to ec8da9c Compare October 19, 2026 12:25

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant