Files
davinci-platform/README.md
KinSun 9d5616fdc6 feat: add initial project configuration and smoke tests
- 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.
2026-03-13 10:30:16 +08:00

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:

  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.
# 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) 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 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