From 29ff3265e8c7af395106ab1f54699612598df0f5 Mon Sep 17 00:00:00 2001 From: Daniel Kirby Date: Thu, 25 Jun 2026 11:41:00 +0100 Subject: [PATCH] docs: document D1 deployment flow --- README.md | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index e92868e..2580988 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Clearity is a workspace, client, and contract management platform for managed office operations. It tracks clients, contacts, addresses, rooms, services, bookings, contracts, invoices, and workspace admins from a SvelteKit dashboard. -The app is built with SvelteKit, Svelte 5, shadcn-svelte, Superforms, Better Auth, Drizzle ORM, SQLite/libSQL, and Cloudflare Workers. +The app is built with SvelteKit, Svelte 5, shadcn-svelte, Superforms, Better Auth, Drizzle ORM, SQLite/libSQL for local development, Cloudflare D1 for production, and Cloudflare Workers. ## Development @@ -52,19 +52,26 @@ pnpm db:studio # Open Drizzle Studio pnpm gen # Regenerate Cloudflare Worker types ``` -## Environment Variables +## Environment Variables And Bindings Required: -- `DATABASE_URL`: SQLite/libSQL connection URL. Use `file:local.db` for local development. +- `DATABASE_URL`: SQLite/libSQL connection URL for local development. Use `file:local.db`. - `ORIGIN`: Public app origin, for example `http://localhost:5173` locally or `https://clearity.example.com` in production. - `BETTER_AUTH_SECRET`: Secret used by Better Auth. +Production also requires the Cloudflare D1 binding named `DB`, configured in `wrangler.jsonc`. Do not set `DATABASE_URL` in production unless you intentionally want to use a hosted libSQL database instead of D1. + ## Database The application schema lives in `src/lib/server/db`. Drizzle migration files live in `drizzle`. -Local development currently uses the libSQL client through `DATABASE_URL`, so the fastest local database is a SQLite file: +Runtime database selection is: + +- If `DATABASE_URL` is set, Clearity uses the libSQL driver. +- If `DATABASE_URL` is not set and the Cloudflare `DB` binding exists, Clearity uses Drizzle's Cloudflare D1 driver. + +The fastest local database is a SQLite file: ```sh DATABASE_URL=file:local.db pnpm db:migrate @@ -77,6 +84,14 @@ pnpm db:generate DATABASE_URL=file:local.db pnpm db:migrate ``` +To test against Wrangler's local D1 simulator instead, leave `DATABASE_URL` unset, apply migrations locally, and run the app through the Cloudflare Worker build: + +```sh +pnpm build +pnpm wrangler d1 migrations apply clearity-production --local +pnpm wrangler dev +``` + ## Production Deployment The Worker is configured in `wrangler.jsonc` and built with the SvelteKit Cloudflare adapter. @@ -91,10 +106,10 @@ pnpm wrangler whoami Create a production D1 database: ```sh -pnpm wrangler d1 create clearity-production +pnpm wrangler d1 create clearity-production --binding DB ``` -Wrangler prints a `database_id`. Add it to `wrangler.jsonc`: +Wrangler prints a `database_id`. Replace the placeholder in `wrangler.jsonc`: ```jsonc { @@ -102,7 +117,8 @@ Wrangler prints a `database_id`. Add it to `wrangler.jsonc`: { "binding": "DB", "database_name": "clearity-production", - "database_id": "" + "database_id": "", + "migrations_dir": "drizzle" } ] } @@ -117,9 +133,7 @@ pnpm gen Apply SQL migrations to the remote D1 database: ```sh -for file in drizzle/*.sql; do - pnpm wrangler d1 execute clearity-production --remote --file "$file" -done +pnpm wrangler d1 migrations apply clearity-production --remote ``` Set production secrets: @@ -129,11 +143,7 @@ pnpm wrangler secret put ORIGIN pnpm wrangler secret put BETTER_AUTH_SECRET ``` -This codebase currently reads the database through `DATABASE_URL`. If production is deployed against Cloudflare D1, wire the runtime database client to the `DB` D1 binding before deploying. If production is deployed against a hosted libSQL database instead, set `DATABASE_URL` as a Worker secret: - -```sh -pnpm wrangler secret put DATABASE_URL -``` +Production uses the `DB` binding by default. `DATABASE_URL` is only needed as a production secret if you intentionally deploy against a hosted libSQL database instead of D1. Build and deploy: