- Created pnpm workspace configuration to manage packages. - Added a placeholder .gitkeep file in the scripts directory. - Implemented a smoke test script to validate core API and web endpoints. - Established TypeScript base configuration for consistent compilation settings. - Introduced Turbo configuration for task management and build processes.
13 KiB
Davinci Platform
Unified monorepo for the Davinci platform — replaces davinci-mothership and davinci-community-server as a single codebase with a DAVINCI_MODE flag.
Prerequisites
- Docker Desktop (includes Docker Compose v2)
- Node.js 22+ (see
.nvmrc) - pnpm 10+ (
corepack enable && corepack prepare pnpm@10.32.0 --activate) - make (preinstalled on macOS/Linux)
Two development modes are supported:
- Docker (recommended) — everything runs in containers. Zero local setup beyond Docker + Node.js.
- Local + Docker infra — run the NestJS API and Next.js frontend natively for faster iteration, Docker for Postgres only. See Local Development.
Quick Start (Docker — Recommended)
# 1. Install local deps (for Prisma CLI, tests, IDE support)
pnpm install
# 2. Copy environment config
cp .env.example .env
# 3. Start the full dev environment (Postgres + API + Web)
make dev-build
# 4. Run migrations
make db:push
# 5. Seed the dev database with test data
make dev-seed
# 6. Verify everything works
make smoke
That's it. You now have:
| Service | URL |
|---|---|
| API | http://localhost:4300/health |
| API Docs (Scalar) | http://localhost:4300/api-reference |
| Web | http://localhost:4000 |
| Postgres | localhost:55434 |
Useful Commands
make help # Show all available commands
make dev-logs # Tail API container logs
make dev-stop # Stop containers (data preserved)
make dev-reset # Destroy + rebuild from scratch
make dev-seed # Re-seed database
Local Development (Without Docker for the App)
If you prefer running the NestJS API and Next.js frontend natively (for faster restarts, debugger attach, HMR, etc.) while still using Docker for infrastructure:
1. Start Infrastructure Only
# Start only Postgres (no app containers)
docker compose up db -d --wait
2. Set Up Environment
Create a .env file (git-ignored) in the repo root:
# .env
DATABASE_URL="postgresql://davinci:davinci@localhost:55434/davinci_platform_dev"
PORT=3001
NODE_ENV=development
DAVINCI_MODE=mothership
ENABLE_API_DOCS=true
3. Generate Prisma Client & Push Schema
DATABASE_URL=postgresql://davinci:davinci@localhost:55434/davinci_platform_dev \
pnpm --filter @davinci/api prisma:generate
DATABASE_URL=postgresql://davinci:davinci@localhost:55434/davinci_platform_dev \
pnpm --filter @davinci/api exec prisma db push
4. Start the Apps
# Terminal 1: Start API (watch mode — auto-restarts on file changes)
pnpm --filter @davinci/api start:dev
# Terminal 2: Start Web (Next.js dev server with HMR)
pnpm --filter @davinci/web dev
The API listens on http://localhost:3001, Web on http://localhost:3000.
5. Seed Data (Optional)
DATABASE_URL=postgresql://davinci:davinci@localhost:55434/davinci_platform_dev \
pnpm --filter @davinci/api exec prisma db seed
VS Code Debugger
With start:dev --debug, attach VS Code's debugger:
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Davinci API",
"type": "node",
"request": "attach",
"port": 9229,
"restart": true,
"skipFiles": ["<node_internals>/**"]
}
]
}
Architecture Overview
┌──────────────────────────────────────────────────┐
│ Davinci Platform Monorepo │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌────────┐ │
│ │ packages/api │ │ packages/web │ │ shared │ │
│ │ NestJS 11 │ │ Next.js 15.5 │ │ types │ │
│ │ Fastify 5 │ │ App Router │ │ consts │ │
│ │ Prisma 7 │ │ Tailwind v4 │ │ │ │
│ └──────┬───────┘ └──────┬───────┘ └────────┘ │
│ │ │ │
│ /api/v1/* /* (frontend) │
│ │ │ │
│ ┌──────┴──────────────────┴──────┐ │
│ │ PostgreSQL │ │
│ └────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
Key design decisions:
- DAVINCI_MODE — single codebase operates as either
mothership(control plane) orcommunity(per-tenant) via env flag - NestJS + Fastify — high-throughput backend with URI-based API versioning (
/api/v1/...) - Prisma 7 — type-safe ORM with
@prisma/adapter-pgdriver - Next.js 15.5 — App Router with
next-intlfor i18n, Tailwind CSS v4,shadcn/ui - Turborepo — monorepo build orchestration with caching
- Docker multi-stage — production image includes nginx reverse proxy on port 80
API Versioning
All business endpoints are served under /api/v1/.... Operational endpoints are unversioned:
| Endpoint | Versioned | Description |
|---|---|---|
/health |
No | Liveness probe |
/api-reference |
No | Scalar API documentation |
/api/v1/* |
Yes | Business endpoints |
API Documentation
Interactive API documentation powered by Scalar is available at /api-reference in development and test environments. Controlled via ENABLE_API_DOCS env var (defaults to enabled in dev/test, disabled in production).
Dependency Injection
The API uses NestJS's built-in DI container. Key global providers:
| Module | Provider | Description |
|---|---|---|
ConfigModule |
ConfigService |
Environment variable access (global) |
PrismaModule |
PrismaService |
Database access via prisma.client (global) |
Usage in feature modules:
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service.js';
@Injectable()
export class MyFeatureService {
constructor(private readonly prisma: PrismaService) {}
async findAll() {
return this.prisma.client.myModel.findMany();
}
}
Project Structure
davinci-platform/
├── packages/
│ ├── api/ # NestJS 11 backend (Fastify 5 adapter)
│ │ ├── src/
│ │ │ ├── main.ts # Bootstrap: NestJS + Fastify + versioning + Scalar
│ │ │ ├── app.module.ts # Root module (Config, Prisma, Health)
│ │ │ ├── docs/ # API documentation (Scalar + OpenAPI)
│ │ │ │ └── api-docs.setup.ts # Multi-version Scalar setup
│ │ │ ├── health/ # Health module (liveness probe)
│ │ │ └── prisma/ # Database module (global PrismaService)
│ │ ├── prisma/
│ │ │ ├── schema.prisma # Prisma schema
│ │ │ └── seed.ts # Idempotent dev seed script
│ │ ├── prisma.config.ts # Prisma 7 config (datasource URL, seed)
│ │ └── generated/prisma/ # Generated Prisma client (git-ignored)
│ ├── web/ # Next.js 15.5 frontend (App Router)
│ │ ├── src/
│ │ │ ├── app/ # App Router layout + pages
│ │ │ ├── i18n/ # next-intl routing + request config
│ │ │ ├── middleware.ts # Locale detection middleware
│ │ │ └── lib/utils.ts # cn() utility (clsx + tailwind-merge)
│ │ ├── messages/en.json # i18n messages
│ │ └── components.json # shadcn/ui config
│ └── shared/ # Shared types + constants
│ └── src/
│ ├── index.ts # Barrel export
│ └── constants/index.ts # APP_NAME, etc.
├── Dockerfile # Multi-stage production build
├── nginx.conf # Reverse proxy: /api/* → :3001, /* → :3000
├── entrypoint.sh # Production entrypoint
├── docker-compose.yml # Dev environment
├── docker-compose.test.yml # Isolated test environment
├── Makefile # Developer command interface
├── turbo.json # Turborepo task config
├── smoke-test.sh # 6-endpoint smoke test
└── .env.example # Environment template
Makefile Commands
Run make help for the full list. Key commands:
Development
| Command | Description |
|---|---|
make dev |
Start Postgres + API + Web in watch mode (local apps) |
make dev-build |
Build and start full dev stack (Docker) |
make dev-logs |
Tail API container logs |
make dev-stop |
Stop containers (data preserved) |
make dev-reset |
Destroy data + rebuild from scratch |
make dev-seed |
Seed dev database with test data |
Testing
| Command | Description |
|---|---|
make test |
Full isolated smoke test (build → run → test → teardown) |
make test:unit |
Unit tests only |
make test:e2e |
E2E tests only |
make test:cov |
Tests with coverage report |
make smoke |
Smoke tests against running dev stack |
Code Quality
| Command | Description |
|---|---|
make lint |
Lint all packages |
make format |
Format all files with Prettier |
make format:check |
Check formatting without writing |
Database
| Command | Description |
|---|---|
make db:migrate |
Create a new Prisma migration |
make db:push |
Push schema changes (quick prototyping) |
make db:studio |
Open Prisma Studio |
Docker
| Command | Description |
|---|---|
make docker:build |
Build production Docker image |
make docker:up |
Run full stack via docker-compose |
make down |
Stop everything (dev + test) |
Port Architecture
Standard ports are used inside containers (Dockerfile, entrypoint, nginx). Docker Compose maps to non-common host ports to avoid conflicts:
| Stack | API (host → container) | Web (host → container) | Postgres (host → container) |
|---|---|---|---|
| Dev | 4300 → 3001 | 4000 → 3000 | 55434 → 5432 |
| Test | 4301 → 3001 | 4001 → 3000 | 45434 → 5432 |
| Local (no Docker) | 3001 (direct) | 3000 (direct) | 55434 → 5432 |
| Production (nginx) | :80 (reverse proxy) | :80 (reverse proxy) | — |
Ports are chosen to avoid conflicts: Common tools (React, Vite, Next.js) use 3000/3001/5173. The Docker dev stack uses 4300/4000/55434.
Environment Variables
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
(required) | PostgreSQL connection string |
PORT |
3001 |
API server port |
NODE_ENV |
development |
development, production, or test |
DAVINCI_MODE |
mothership |
Operating mode (mothership or community) |
ENABLE_API_DOCS |
auto | Scalar API docs (true/false; defaults enabled in dev/test) |
CORS_ORIGIN |
* (dev) |
Comma-separated allowed origins |
LOG_LEVEL |
auto | Pino log level (debug in dev, info in prod) |
NEXT_PUBLIC_API_URL |
— | Frontend API URL (set in docker-compose) |
See .env.example for a starter template.
Tech Stack
| Layer | Technology | Version |
|---|---|---|
| Runtime | Node.js | 22 LTS |
| Package Manager | pnpm | 10.32.0 |
| Build Orchestration | Turborepo | 2.x |
| Backend Framework | NestJS | 11.x |
| HTTP Server | Fastify | 5.x |
| ORM | Prisma | 7.x |
| Frontend Framework | Next.js | 15.5.x |
| CSS | Tailwind CSS | v4 |
| UI Components | shadcn/ui | — |
| i18n | next-intl | 4.x |
| Testing | Vitest | 3.x |
| Linting | ESLint (flat config) | 9.x |
| Formatting | Prettier | 3.4.x |
| API Docs | Scalar + @nestjs/swagger | — |
| Database | PostgreSQL | 16 |
| Container | Docker (multi-stage) | — |
| Reverse Proxy | nginx | — |