# AGENTS.md ## Commands ```sh # Root (runs both frontend + backend) bun run dev # Individual packages bun run dev:frontend bun run dev:backend bun run build:frontend # Linting (Biome - ESLint was replaced) bun run lint bun run lint:fix # fixes and formats # Prisma (run from backend) bun --filter backend prisma:generate # regenerate client after schema changes bun --filter backend prisma:migrate # apply migrations ``` ## Architecture ``` apps/frontend/ # React + Vite + TanStack Router/Query apps/backend/ # Bun + Hono + Prisma packages/api-contract/ # Shared Zod schemas, types, route definitions ``` **Shared contract pattern:** 1. Update `packages/api-contract` first (schemas/types) 2. Implement handler in `apps/backend` 3. Consume from `apps/frontend` via workspace import `@repo/api-contract` ## Key Quirks - **Prisma 7**: Uses `prisma.config.ts`, requires `DATABASE_URL` env var at generate time - **Zod v4**: Use `.issues` instead of `.errors` for validation errors - **Generated files**: `routeTree.gen.ts` and `tsconfig*.json` are auto-generated (ignored by Biome) - **TanStack Router**: Routes are code-generated. Use `--filter frontend build` not raw vite build. ## Docker Deployment (Dokploy) - **Build Context**: `./` (monorepo root) - **Dockerfile**: `Dockerfile` (in root, not `apps/backend/`) - **Required args**: `DATABASE_URL`, `VITE_API_BASE_URL`, `VITE_SUPABASE_URL`, `VITE_SUPABASE_ANON_KEY` - **bun.lock must be tracked**: It's in `.gitignore` by default - remove it for Docker builds ## Linting Biome is used (not ESLint). Config in `biome.json`: - Line width: 100 - Quote style: single - Semicolons: always - `noUnusedVariables`: warn ## Environment Variables **Backend** (`apps/backend/.env`): - `DATABASE_URL` - PostgreSQL connection (required for Prisma) - `SUPABASE_URL`, `SUPABASE_ANON_KEY` - Auth - `CORS_ORIGIN` - Frontend URL **Frontend** (`apps/frontend/.env`): - `VITE_*` prefix required (Vite embeds these at build time) - `VITE_API_BASE_URL` - Backend URL (default: http://localhost:3000)