- 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.
339 lines
13 KiB
Markdown
339 lines
13 KiB
Markdown
# 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:
|
|
> 1. **Docker (recommended)** — everything runs in containers. Zero local setup beyond Docker + Node.js.
|
|
> 2. **Local + Docker infra** — run the NestJS API and Next.js frontend natively for faster iteration, Docker for Postgres only. See [Local Development](#local-development-without-docker-for-the-app).
|
|
|
|
## Quick Start (Docker — Recommended)
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
```bash
|
|
# .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
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
# 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)
|
|
|
|
```bash
|
|
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:
|
|
|
|
```jsonc
|
|
// .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) or `community` (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-pg` driver
|
|
- **Next.js 15.5** — App Router with `next-intl` for 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](https://scalar.com) 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:
|
|
|
|
```typescript
|
|
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`](.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 | — |
|