Multi-tenant booking application. A pnpm + Turborepo monorepo: a Hono API over Postgres (Prisma), a public storefront, a native staff app, and a platform-admin console.
| Path | What it is | Dev URL |
|---|---|---|
apps/api |
Hono API on Node / AWS Lambda · Prisma · phone-OTP + JWT auth | http://localhost:4200 |
apps/storefront |
Public booking site (React Router v7, SSR) | http://localhost:3000 |
apps/admin |
Platform/superadmin console (Vite + React + Tailwind) | http://localhost:5174 |
apps/mobile |
Staff client — Expo / React Native | Expo (Metro) |
packages/db |
Prisma client factory (@bookla/db) |
— |
packages/dto |
Zod schemas + shared types (@bookla/dto) |
— |
packages/slots |
Availability/slot engine | — |
packages/messaging · packages/push · packages/utils |
SMS, push, secrets helpers | — |
Multi-tenancy: every customer-owned row is scoped by tenantId, and every
service query filters on the authenticated user's tenant.
- Node 24 — see
.nvmrc(nvm use/fnm use); enforced viaengines - pnpm 11 —
corepack enablepicks up the version pinned inpackage.json - Docker — for the local Postgres (see below). Or bring your own Postgres.
# 1. Install dependencies
pnpm install
# 2. Create your env file (defaults already point at the Docker database below)
cp .env.example .env
# 3. Start the development database (Postgres on :5432)
pnpm db:up # = docker compose up -d --wait
# 4. Apply migrations (also generates the Prisma client)
pnpm prisma:migrate
# 5. (optional) Seed demo data — one barbershop tenant with services & bookings
pnpm prisma:seed
# 6. Run the apps (all of them, or pick one — see below)
pnpm dev.env.example's DATABASE_URL is already set to the Docker database
(postgres:postgres@localhost:5432/bookla), so steps 2–4 work with no edits. Set
a real JWT_SECRET and, if you want the admin panel, an ADMIN_PASSWORD.
pnpm dev:api # API only → http://localhost:4200
pnpm dev:storefront # public storefront → http://localhost:3000
pnpm dev:admin # admin console → http://localhost:5174
pnpm ios # staff app — builds the iOS dev build (see apps/mobile/README.md)
pnpm dev:mobile # staff app — Metro only, once the dev build is installedpnpm dev runs the web apps together via Turborepo (API, storefront, admin).
It deliberately excludes the mobile app — React Native needs its own Metro
server and a native build, and its Liquid Glass UI requires an iOS 26 dev
build (not Expo Go). See apps/mobile/README.md to
run it correctly. The Prisma client is generated automatically before any
dev/build/typecheck task.
Auth is phone + OTP, and SMS_PROVIDER=console (the default) prints the OTP
code to the API server's stdout instead of sending an SMS. So to log in:
- Enter a phone number in the app (the seed owner is
+994501234567). - Read the 6-digit code from the
pnpm dev:apiterminal output. - Enter it to complete login.
The admin console (apps/admin) is separate: it signs in with the shared
ADMIN_PASSWORD from your .env — no phone needed.
docker-compose.yml defines a single Postgres service matching .env.example.
pnpm db:up # start (waits until healthy)
docker compose logs -f db # tail logs
pnpm db:down # stop, keep data
docker compose down -v # stop and WIPE the data volumePrefer your own Postgres? Skip Docker and point DATABASE_URL at it instead —
nothing else assumes the container.
pnpm build # build everything
pnpm typecheck # typecheck every workspace
pnpm prisma:studio # browse the database in Prisma Studio
pnpm prisma:migrate # create/apply a migration after editing prisma/schema
pnpm clean # remove build artifacts & caches- API routes, auth internals, and conventions:
AGENT_GUIDE.md - Feature-by-feature build notes:
tasks/ - Product plan:
plans/mvp-adapted.md
The Prisma connection URL and pg adapter are wired in
prisma.config.ts (Prisma 7+).