Getting started
Prerequisites
- Bun 1.1+ — used by
apps/apiand as task runner at repo root - Node 20+ — required for
apps/webNext build and Prisma - Docker + Docker Compose — for running the full stack locally
- PostgreSQL client (psql) for DB ops (optional,
docker execworks too)
Clone and install
git clone git@github.com:codename-zen/ai-knowledge-base.git
cd ai-knowledge-base
# Install workspaces
bun install
# (or using npm)
npm install
Environment variables
Each app reads .env (or .env.local) from its own directory.
apps/web
# apps/web/.env.local
NEXT_PUBLIC_API_URL=http://localhost:4000
For prod builds, pass via build arg:
docker build --build-arg NEXT_PUBLIC_API_URL=https://lumen-api.zenmail.my.id ...
apps/api
# apps/api/.env
PORT=4000
DATABASE_URL=postgresql://lumen:<pw>@localhost:5432/lumen
REDIS_URL=redis://localhost:6379
EMBEDDER_URL=http://localhost:8000
JWT_SECRET=<random-32-bytes-base64>
UPLOAD_DIR=/data/uploads
# Fallback LLM if no provider configured in DB
LLM_BASE_URL=https://api.deepseek.com/v1
LLM_API_KEY=sk-...
LLM_MODEL=deepseek-chat
# Optional: enables /chat modes "web" and "deep"
TAVILY_API_KEY=
Run locally (full stack via Docker)
docker compose up -d postgres redis embedder
cd apps/api && bun run dev
# in another terminal:
cd apps/web && npm run dev
Visit http://localhost:3000. First load redirects to /onboarding/first-login (bootstrap wizard).
Bootstrap
First-time setup creates:
- Superadmin (platform owner, singleton, non-transferable)
- CEO (cross-department observer, singleton)
After submitting the wizard, bootstrap_state.is_initialized flips to true and the middleware stops forcing redirects to /onboarding. Every authenticated route now requires the normal JWT flow.
See Access control model for what the three users above can do.
Daily dev commands
# API type check
cd apps/api && bunx tsc --noEmit
# Web type check
cd apps/web && npx tsc --noEmit
# Prisma
cd apps/api
bunx prisma generate # regenerate client
bunx prisma migrate dev # apply pending migrations to DB
bunx prisma studio # DB GUI
# Format
bunx prettier --write .
First smoke test
# Bootstrap status (public)
curl http://localhost:4000/bootstrap/status
# Log in after bootstrap
TOKEN=$(curl -s -X POST http://localhost:4000/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com","password":"..."}' \
| jq -r .accessToken)
# List your projects
curl -H "Authorization: Bearer $TOKEN" http://localhost:4000/projects
Where to go next
- See the code structure: Repo layout
- Understand requests: API overview
- Understand permissions: Access control resolver
- Deploy your fork: Dokploy deploy