ByteBite Docs
Development

Getting Started

First-time setup for the ByteBite monorepo.

Getting Started

Prerequisites

  • macOS development environment (primary target)
  • Docker Desktop or a compatible Docker runtime (Compose v2+)
  • Git
  • pnpm (host-side lint / typecheck / test / build)
  • Node.js 24 LTS (see .nvmrc)

Database commands run inside Docker. You do not need a host node_modules install solely to migrate or seed.

First-time setup

  1. Clone / open the repository.

  2. Copy .env.example to .env.

  3. Add the required /etc/hosts entries (see the root README.md). Include both 127.0.0.1 and ::1 lines — IPv4-only entries cause ~5s delays on macOS when clients attempt AAAA lookups for .test hostnames.

  4. Start the Docker development stack:

    pnpm dev

    This runs docker compose -f compose.yml -f compose.dev.yml up. If a previous local compose.deploy.yml build left production images in place, run pnpm dev:down first so Compose recreates :dev containers.

  5. With the stack running, apply the schema and seed Luigi / Mario (restaurants, domains, isolated menus, and example weekly hours) plus demo staff users. Seeds do not create carts or orders:

    pnpm db:migrate
    pnpm db:seed

Local URLs

Direct API example: http://api.bytebite.test/health

Same-origin examples (Traefik strips /api before Fastify):

  • http://luigi.bytebite.test/api/storefront/restaurant
  • http://luigi.bytebite.test/api/storefront/hours
  • http://luigi.bytebite.test/api/storefront/menu
  • http://luigi.bytebite.test/api/storefront/cart
  • http://luigi.bytebite.test/api/storefront/checkout
  • http://mario.bytebite.test/api/storefront/restaurant
  • http://mario.bytebite.test/api/storefront/menu
  • http://mario.bytebite.test/api/storefront/cart
  • http://luigi.bytebite.test/api/health
  • http://dashboard.bytebite.test/api/health

Luigi's public menu must not contain Mario items (and the reverse). Unknown host http://unknown.bytebite.test/api/storefront/menu (and /api/storefront/cart, /api/storefront/checkout, /api/storefront/hours) returns 404. A Luigi bb_cart cookie sent to Mario creates a new empty Mario cart and cannot create a Luigi order. A Luigi orderId on Mario's host returns 404. Dashboard hours/menu/orders/uploads use /dashboard/restaurants/:restaurantId/... and require a staff session (see Opening hours, Menu catalog, Object storage uploads, Guest cart, Checkout & orders, Accept, reject & timeout, Kitchen status, and Staff authentication). Pickup checkout is 409 when the hostname restaurant is closed or has an empty week; cart and menu GETs stay 200. session.restaurantId does not replace the path.

Commands

CommandDescription
pnpm devStart the Docker dev stack
pnpm dev:downStop the dev stack
pnpm dev:rebuildRebuild images and start the stack
pnpm buildBuild all apps/packages (Turborepo, host)
pnpm lintLint the monorepo
pnpm typecheckTypecheck the monorepo
pnpm testRun unit/integration tests (Vitest)
pnpm db:generateGenerate Drizzle migrations (API container; stack running)
pnpm db:migrateApply migrations (API container; stack running)
pnpm db:seedSeed the local database (API container; stack running)
pnpm db:studioDrizzle Studio at http://localhost:4983

The API does not auto-migrate on startup. pnpm db:* is the documented workflow.

Environment notes

  • .env DATABASE_URL uses localhost (host network).
  • Compose overrides DATABASE_URL inside the API container to hostname postgres.
  • Compose overrides S3_ENDPOINT inside the API container to http://minio:9000.
  • BETTER_AUTH_SECRET is required for /auth in production/staging; local/test may use the .env.example placeholder. Without a production secret, auth routes are not registered.
  • Storefront and Dashboard browser bundles do not receive server secrets. Browser API calls use same-origin /api.
  • Twilio/SES env vars are optional. Empty values are a no-op (API still starts). Transactional SMS is sent on accept, reject, timeout, and ready. Checkout does not send.
  • Docker dev uses anonymous volumes for apps/docs/.next and apps/storefront/.next so host-side pnpm build output does not corrupt the in-container Next.js dev/Turbopack cache. After adding new Fumadocs MDX pages, restart the docs service if the dev server was already running when the file was created.

Architecture boundaries

  • Fastify is the central backend/business boundary. Storefront and Dashboard must not access PostgreSQL directly.
  • packages/domain is infrastructure-independent.
  • No packages/ui; Dashboard shadcn components live at apps/dashboard/src/components/ui/.
  • No separate apps/admin; the initial ADMIN area is a protected section inside Dashboard.

On this page