Introduce organizations as the top-level workspace model with address and bank-detail fields. Store the active organization on Better Auth sessions and load organization context for dashboard routes. Add the migration that creates organizations and backfills existing records to the default organization.
Clearity
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.
Development
Install dependencies:
pnpm install
Create a local .env file:
DATABASE_URL=file:local.db
ORIGIN=http://localhost:5173
BETTER_AUTH_SECRET=replace-with-a-long-random-secret
Generate a Better Auth secret with:
openssl rand -base64 32
Apply database migrations:
DATABASE_URL=file:local.db pnpm db:migrate
Start the development server:
pnpm dev
Open http://localhost:5173/login. If no Better Auth users exist yet, Clearity shows a first-admin setup form instead of the normal sign-in form. Submitting it creates the initial user with the default Better Auth admin role and signs you in.
Useful development commands:
pnpm check # Wrangler types, SvelteKit sync, and svelte-check
pnpm lint # Prettier check and ESLint
pnpm format # Format the codebase
pnpm db:generate # Generate Drizzle migrations after schema changes
pnpm db:migrate # Apply Drizzle migrations to DATABASE_URL
pnpm db:studio # Open Drizzle Studio
pnpm gen # Regenerate Cloudflare Worker types
Environment Variables
Required:
DATABASE_URL: SQLite/libSQL connection URL. Usefile:local.dbfor local development.ORIGIN: Public app origin, for examplehttp://localhost:5173locally orhttps://clearity.example.comin production.BETTER_AUTH_SECRET: Secret used by Better Auth.
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:
DATABASE_URL=file:local.db pnpm db:migrate
For schema changes:
pnpm db:generate
DATABASE_URL=file:local.db pnpm db:migrate
Production Deployment
The Worker is configured in wrangler.jsonc and built with the SvelteKit Cloudflare adapter.
Authenticate Wrangler:
pnpm wrangler login
pnpm wrangler whoami
Create a production D1 database:
pnpm wrangler d1 create clearity-production
Wrangler prints a database_id. Add it to wrangler.jsonc:
{
"d1_databases": [
{
"binding": "DB",
"database_name": "clearity-production",
"database_id": "<database_id>"
}
]
}
Regenerate Worker types after changing Wrangler bindings:
pnpm gen
Apply SQL migrations to the remote D1 database:
for file in drizzle/*.sql; do
pnpm wrangler d1 execute clearity-production --remote --file "$file"
done
Set production secrets:
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:
pnpm wrangler secret put DATABASE_URL
Build and deploy:
pnpm build
pnpm wrangler deploy
Create the first production admin by opening /login after migrations have run. The setup form is only shown while the Better Auth user table is empty.