This is a modular monolith backend for the Task Manager app, built with NestJS, TypeScript, and Yarn Workspaces. The app is containerized with Docker and managed through docker-compose
.
task-manager-backend/
├── apps/ # Application services (NestJS apps)
│ └── api-gateway/ # Main entrypoint API (HTTP server)
├── packages/ # Shared modules
│ ├── auth/ # Auth logic, decorators, JWT, etc.
│ ├── prisma/ # Shared PrismaService + Client wrapper
├── .yarnrc.yml # Yarn 4 configuration
├── yarn.lock # Monorepo lockfile
├── package.json # Root workspace config
├── docker-compose.yml # Multi-service Docker setup
└── tsconfig.base.json # Shared TypeScript base config
@task-manager/auth
: ProvidesAuthModule
,JwtStrategy
, guards, and custom decorators. Imported into apps likeapi-gateway
.@task-manager/prisma
: Wraps PrismaClient in a singleton NestJS service. Shared by all apps that access the DB.- These are shared libraries, not standalone microservices.
api-gateway
: The main NestJS HTTP server. ImportsAuthModule
, usesPrismaService
, and routes client traffic. Acts as the single point of entry to the backend.
┌─────────────────────┐
│ Web Browser │
└─────────────────────┘
│
┌──────────────────────┐
│ Next.js Frontend │ ◇─ SSR & API calls
└──────────────────────┘
│
HTTP / API calls
▼
┌──────────────────────┐
│ API Gateway (Nest) │
└──────────────────────┘
▼
┌────────────────────────────┐
│ Shared Logic via Packages │
│ - @task-manager/auth │
│ - @task-manager/prisma │
└────────────────────────────┘
This monorepo uses a centralized tooling architecture to reduce duplication and maintain consistency.
All development tooling is defined in the root package.json
. This includes:
- Linters: ESLint, Prettier
- TypeScript Tooling:
ts-node
,ts-node-dev
,tsconfig-paths
- Monorepo Management: Yarn 4 (Berry) with Workspaces
- Node Modules Linking:
nodeLinker: node-modules
(for compatibility)
Each workspace inherits config from root, and only declares its own runtime dependencies.
@types/node
and similar global types must still be declared per workspace due to how TypeScript resolution works.
- Dev tools live at the root, not per workspace.
- Each workspace has a
tsconfig.json
extendingtsconfig.base.json
to inherit settings and path aliases.. - Never run
yarn add
inside a workspace — always do it from the root to avoid nestednode_modules
.
yarn install
- Prisma Package
yarn workspace @task-manager/prisma generate
yarn workspace @task-manager/prisma migrate
yarn workspace @task-manager/prisma build
Database seeding to get you started
cd packages/prisma
npx prisma db seed
- Auth Package
yarn workspace @task-manager/auth build
- Api Service
build prisma
yarn workspace @task-manager/prisma run build
Docker is configured for dev mode. Before you start docker make sure to Build Packages (step #2) first.
docker network create task-manager-net
docker compose up --build api-gateway
If you decide to run the project locally you must update the prisma/.env with the db connection string
Alternatively create a docker instance for the postgres with something like this:
docker run --name postgres-local
-e POSTGRES_USER=your_user
-e POSTGRES_PASSWORD=your_password
-e POSTGRES_DB=your_db
-p 5432:5432
-d postgres:15-alpine
docker run --name redis-local -p 6379:6379 -d redis:7-alpine
yarn workspace api-gateway run start:dev
- NestJS (Modular Monolith)
- Yarn 4 (with Workspaces)
- Docker / docker-compose
- Prisma + PostgreSQL
- ESLint / Prettier / Jest
- ts-node-dev for fast development
Run these from the root:
yarn workspaces foreach --all run lint
yarn workspaces foreach --all run build
yarn workspaces foreach --all run test
mkdir packages/my-feature
cd packages/my-feature
nest g module my-feature
# Then wire it up in tsconfig and package.json
- Uses
nodeLinker: node-modules
in.yarnrc.yml
for better ecosystem compatibility. - Uses
tsconfig-paths
for cleaner path aliases like@task-manager/prisma
.
corepack enable
corepack prepare yarn@stable --activate