Monorepo & Build Systems
Client — Turborepo + Bun
The client/ directory is a Turborepo monorepo with a single app package (web). The root package.json defines workspace configuration; turbo.json defines the pipeline tasks.
client/
├── package.json # workspace root, turbo dependency
├── turbo.json # pipeline: dev, build, lint, type-check
└── web/ # Next.js app package
└── package.json # app-level deps (next, react, zustand, zod, etc.)Build commands (from client/ root):
bun run dev— starts Next.js in development mode with Turbopackbun run build— production build vianext build- Turborepo caches build outputs in
.turbo/cache/, enabling incremental rebuilds
Key client dependencies (from web/package.json):
next— App Router, SSR, API proxying vianext.config.tsreact/react-dom— React 19 concurrent featureszustand+devtools+persistmiddleware — client statezod— runtime schema validation for all API responsessonner— toast notificationsnext-themes— SSR-safe themingtailwindcss— utility CSS
Server API — Cargo
The server/api/ is a standard Cargo binary crate. build.rs compiles the Protobuf definition into Rust types at build time.
server/api/
├── Cargo.toml # crate manifest + all dependencies
├── build.rs # tonic-prost-build: compile proto/intelligence.proto
└── src/
└── main.rs # tokio::main entry pointBuild commands:
cargo build --release— produces a single static binarycargo test— runs integration tests (requiresDATABASE_URL)cargo sqlx prepare— checks the schema cache interactively locally and builds validation bindings inside the container
Two-phase compilation: build.rs runs tonic_build::compile_protos("../proto/intelligence.proto") which generates Rust structs and client stubs into OUT_DIR. The generated module is imported via include! macro in grpc/proto.rs.
Intelligence Service — uv / pyproject.toml
The server/intelligence/ service uses uv (ultra-fast Python package manager) with pyproject.toml for dependency declaration. A .python-version file pins the interpreter to Python 3.14. It ships two runtime entry points:
server/intelligence/
├── pyproject.toml # dependencies, dev tools (ruff, mypy, pytest)
├── .python-version # interpreter pin (3.14)
├── pytest.ini # test configuration
├── main.py # gRPC server entry point (:50051)
├── worker.py # Redis Streams background consumer runtime
├── scripts/ # Operational scripts (backfill_qdrant.py, dlq.py, generate_protos.py)
├── features/ # chat, knowledge, billing, health
└── shared/ # database, llm, qdrant, redis, cryptoBuild/run commands:
uv sync— install dependencies into virtual environmentuv run python main.py— start gRPC serveruv run python worker.py— start Redis Streams background consumersuv run pytest— run test suite
Dev tooling:
ruff— linting and formatting (replaces black + isort + flake8)mypy— static type checkingpytest+pytest-asyncio— async test runner
Database Migrations — sqlx
All database schema migrations are centralized in server/api/migrations/. Both the Rust API and Python Intelligence service share the same PostgreSQL 18 instance, so keeping migrations with the API gateway ensures consistent schema state and seamless compile-time SQL verification via SQLx.
server/api/
└── migrations/
├── 20260101000001_identity.{up,down}.sql
├── 20260101000002_chat_memory.{up,down}.sql
├── 20260101000003_knowledge.{up,down}.sql
├── 20260101000004_model_catalog.{up,down}.sql
├── 20260101000005_billing.{up,down}.sql
├── 20260101000006_seed_free_credits.{up,down}.sql
└── 20260101000007_seed_model_catalog.{up,down}.sqlMigration tool: sqlx-cli — a standard toolkit that processes {timestamp}_{name}.up.sql / .down.sql files directly in Rust workflows.
Docker Compose integration: The API’s Dockerfile compiles api/migrations via sqlx::migrate!() and executes migrations on startup. This enforces type-safety checks against the live schema and runs migrations before serving traffic. The startup order is enforced via depends_on conditions:
db (service_healthy), redis (service_healthy), qdrant (service_started) → intelligence
db (service_healthy), redis (service_healthy), qdrant (service_started) → worker
intelligence (service_started), db (service_healthy) → api (runs migrations & listens on :4000)Local development:
cd server && docker compose up -d— full 6-service stack with pre-built GHCR images- Or for local source building:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build - Add a new migration: create
{timestamp}_{name}.up.sqland{timestamp}_{name}.down.sqlinserver/api/migrations/
Proto — Shared Contract
server/proto/
└── intelligence.proto # package: opentier.intelligence.v1The proto file is the single source of truth for the Rust↔Python interface. It is consumed by both build systems:
- Rust:
build.rs→tonic-prost-build→ generated toOUT_DIR - Python:
grpcio-tools→python -m grpc_tools.protoc→intelligence/generated/
Any change to intelligence.proto requires regenerating both sides before the services can communicate. The proto package uses reserved field ranges 1000–1999 (internal use) and 2000–2999 (future extensions), and follows a v1 → v2 versioning policy with a 6-month migration window for breaking changes.