Local Development Setup¶
Complete guide for setting up the MMR SaaS Platform development environment on your local machine.
Prerequisites¶
Before starting, ensure you have the following installed:
- Node.js 18.x or higher (Download)
- PNPM 8.x or higher (package manager)
- Git for version control
- Docker (optional, recommended for quick setup)
- MySQL 8.x or higher (if not using Docker)
- Redis 7.x or higher (if not using Docker)
Verify Prerequisites¶
# Check Node.js version
node --version # Should be v18.x or higher
# Check PNPM version
pnpm --version # Should be 8.x or higher
# Check Git
git --version
# Check Docker (optional)
docker --version
docker-compose --version
Install PNPM¶
If you don't have PNPM installed:
# Using npm
npm install -g pnpm
# Or using Homebrew (macOS)
brew install pnpm
# Or using standalone script
curl -fsSL https://get.pnpm.io/install.sh | sh -
Method 1: Docker Setup (Recommended)¶
The fastest way to get started is using Docker for MySQL and Redis.
Step 1: Clone the Repository¶
Step 2: Install Dependencies¶
This installs all dependencies for both backend and frontend applications using Turborepo's optimized installation.
Step 3: Setup Environment Variables¶
Backend Environment¶
Edit apps/backend/.env and configure:
# Server Configuration
NODE_ENV=development
PORT=3001
API_PREFIX=api
# Database (matches docker-compose.yml)
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=password
DB_NAME=mmr_saas
DB_SYNCHRONIZE=false # Always false - use migrations instead
# Redis (matches docker-compose.yml)
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
# JWT Secrets (generate secure random strings)
# Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
JWT_EXPIRES_IN=15m
JWT_REFRESH_SECRET=your-super-secret-refresh-key-change-this-in-production
JWT_REFRESH_EXPIRY=7d
# CORS
CORS_ORIGIN=http://localhost:3000
# Rate Limiting
RATE_LIMIT_LOGIN_ATTEMPTS=5
RATE_LIMIT_LOCKOUT_MINUTES=15
Generate JWT Secrets:
# Generate JWT_SECRET
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Generate JWT_REFRESH_SECRET
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Frontend Environment¶
Edit apps/web/.env.local:
# Backend API URL
NEXT_PUBLIC_API_URL=http://localhost:3001/api
# Environment
NEXT_PUBLIC_ENV=development
Step 4: Start Docker Services¶
# Start MySQL and Redis
pnpm docker:up
# Verify services are running
docker ps
# You should see:
# - mmr-mysql (port 3306)
# - mmr-redis (port 6379)
Docker Compose Services: - MySQL 8.0 on port 3306 - Redis 7.x on port 6379
Step 5: Run Database Migrations¶
This creates the necessary database tables (users, organizations, tenants, etc.).
Step 6: (Optional) Seed Test Data¶
This creates: - Test organizations - Test users with different roles - Sample data for development
Step 7: Start Development Servers¶
# Start both frontend and backend
pnpm dev
# Or start separately:
pnpm dev:web # Frontend only (http://localhost:3000)
pnpm dev:back # Backend only (http://localhost:3001)
Access the application: - Frontend: http://localhost:3000 - Backend API: http://localhost:3001/api - API Health: http://localhost:3001/api/health
Step 8: Verify Setup¶
-
Backend Health Check:
-
Test Login:
- Open http://localhost:3000/login
-
Use test credentials (if seeded)
-
Check Logs:
- Backend logs appear in terminal
- Look for "Application is running on: http://localhost:3001"
Managing Docker Services¶
# Stop services
pnpm docker:down
# View logs
docker-compose logs -f mysql
docker-compose logs -f redis
# Restart services
docker-compose restart
# Remove all data (destructive!)
docker-compose down -v # Removes volumes
Method 2: Native Installation¶
If you prefer not to use Docker, install MySQL and Redis natively.
Step 1: Install MySQL 8.x¶
On Ubuntu/Debian:¶
# Update package index
sudo apt update
# Install MySQL Server
sudo apt install mysql-server
# Secure installation
sudo mysql_secure_installation
# Start MySQL service
sudo systemctl start mysql
sudo systemctl enable mysql
# Verify installation
mysql --version
On macOS (Homebrew):¶
# Install MySQL
brew install mysql@8.0
# Start MySQL service
brew services start mysql@8.0
# Verify installation
mysql --version
On Windows:¶
Download and install MySQL 8.0 from MySQL Downloads.
Step 2: Install Redis 7.x¶
On Ubuntu/Debian:¶
# Install Redis
sudo apt install redis-server
# Start Redis service
sudo systemctl start redis-server
sudo systemctl enable redis-server
# Verify installation
redis-cli ping # Should return "PONG"
On macOS (Homebrew):¶
# Install Redis
brew install redis
# Start Redis service
brew services start redis
# Verify installation
redis-cli ping # Should return "PONG"
On Windows:¶
Download Redis for Windows from Microsoft Archive or use WSL2.
Step 3: Configure MySQL Database¶
# Login to MySQL as root
sudo mysql -u root -p
# Create database
CREATE DATABASE mmr_saas CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# Create user (use a strong password in production)
CREATE USER 'mmr_user'@'localhost' IDENTIFIED BY 'your_secure_password';
# Grant privileges
GRANT ALL PRIVILEGES ON mmr_saas.* TO 'mmr_user'@'localhost';
FLUSH PRIVILEGES;
# Exit MySQL
EXIT;
# Test connection
mysql -u mmr_user -p mmr_saas
Step 4: Configure Redis¶
Redis works out of the box with default configuration for development.
Optional: Enable password protection
Edit Redis config:
# Find config file location
redis-cli CONFIG GET dir
# Edit config (Ubuntu/Debian)
sudo nano /etc/redis/redis.conf
# Uncomment and set password
requirepass your_redis_password
# Restart Redis
sudo systemctl restart redis-server
Step 5: Update Environment Variables¶
Update apps/backend/.env with your MySQL credentials:
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=mmr_user
DB_PASSWORD=your_secure_password
DB_NAME=mmr_saas
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=your_redis_password # If you set one
Step 6: Follow Docker Steps 1, 2, 5, 6, 7¶
Complete the remaining setup steps from the Docker method: - Clone repository and install dependencies (Steps 1-2) - Run migrations and seed data (Steps 5-6) - Start development servers (Step 7)
IDE Setup (VS Code Recommended)¶
Recommended Extensions¶
Install these VS Code extensions for the best development experience:
- ESLint (
dbaeumer.vscode-eslint) - JavaScript/TypeScript linting - Prettier (
esbenp.prettier-vscode) - Code formatting - Tailwind CSS IntelliSense (
bradlc.vscode-tailwindcss) - Tailwind autocomplete - TypeScript Vue Plugin (Volar) - Not needed
- Prisma - Not needed (using TypeORM)
- REST Client (
humao.rest-client) - Test API endpoints - GitLens (
eamodio.gitlens) - Git integration - Auto Rename Tag (
formulahendry.auto-rename-tag) - HTML/JSX tags - Path Intellisense (
christian-kohler.path-intellisense) - File path autocomplete - Better Comments (
aaron-bond.better-comments) - Highlighted comments
VS Code Settings¶
Create .vscode/settings.json in the project root:
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
"tailwindCSS.experimental.classRegex": [
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
["cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
]
}
Launch Configuration (Debugging)¶
Create .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Backend",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["dev:back"],
"skipFiles": ["<node_internals>/**"],
"cwd": "${workspaceFolder}"
},
{
"type": "node",
"request": "launch",
"name": "Debug Frontend",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["dev:web"],
"skipFiles": ["<node_internals>/**"],
"cwd": "${workspaceFolder}"
}
]
}
Troubleshooting¶
Port Already in Use¶
Error: EADDRINUSE: address already in use :::3000 or :::3001
Solution:
# Find process using the port
lsof -i :3000 # Frontend
lsof -i :3001 # Backend
# Kill the process
kill -9 <PID>
# Or change port in .env files
Database Connection Failed¶
Error: ER_ACCESS_DENIED_ERROR or ECONNREFUSED
Solutions:
-
Verify MySQL is running:
-
Check credentials in .env:
-
DB_USERNAME, DB_PASSWORD, DB_NAME must match MySQL user
-
Test connection manually:
Redis Connection Failed¶
Error: ECONNREFUSED 127.0.0.1:6379
Solutions:
-
Verify Redis is running:
-
Start Redis:
Migration Errors¶
Error: Migration XYZ has already been executed
Solution:
# Show migration status
pnpm migration:show
# Revert last migration if needed
pnpm migration:revert
# Re-run migrations
pnpm db:migrate
PNPM Install Fails¶
Error: ENOENT: no such file or directory
Solution:
# Clear PNPM cache
pnpm store prune
# Remove node_modules and lockfile
rm -rf node_modules apps/*/node_modules packages/*/node_modules
rm pnpm-lock.yaml
# Reinstall
pnpm install
Turbo Cache Issues¶
Error: Build fails with cached errors
Solution:
Frontend Build Errors (Type Errors)¶
Error: TypeScript type errors during build
Solution:
# Navigate to frontend
cd apps/web
# Check for type errors
pnpm type-check
# If shared types changed, rebuild packages
cd ../..
pnpm build --filter=@mmr/types
pnpm build --filter=@mmr/schemas
JWT Errors (Invalid Signature)¶
Error: JsonWebTokenError: invalid signature
Solution: - Ensure JWT_SECRET in .env matches the secret used to generate tokens - Regenerate JWT secrets if you changed them:
- Clear browser cookies and Redis cache - Re-login to get new tokensNext Steps¶
After successful setup:
- Read the Contributing Guide: CONTRIBUTING.md
- Understand the Architecture: ARCHITECTURE.md
- Learn the Git Workflow: GIT_WORKFLOW.md
- Explore the AI Agent System: .claude/agents/README.md
- Start building features!
Quick Reference¶
Common Commands¶
# Development
pnpm dev # Start both frontend & backend
pnpm dev:web # Frontend only
pnpm dev:back # Backend only
# Build
pnpm build # Build all apps
pnpm build:web # Build frontend
pnpm build:back # Build backend
# Production
pnpm start # Start both (production mode)
pnpm start:web # Start frontend (production)
pnpm start:back # Start backend (production)
# Database
pnpm db:migrate # Run migrations
pnpm db:seed # Seed test data
pnpm migration:generate # Generate new migration
pnpm migration:show # Show migration status
# Docker
pnpm docker:up # Start MySQL + Redis
pnpm docker:down # Stop services
# Testing
pnpm test # Run all tests
pnpm test:e2e # Run E2E tests
pnpm test:cov # Coverage report
# Code Quality
pnpm lint # Lint all code
pnpm format # Format with Prettier
pnpm type-check # TypeScript type checking
# Cleanup
pnpm clean # Remove build artifacts
Default Ports¶
- Frontend (Next.js): http://localhost:3000
- Backend (NestJS): http://localhost:3001
- MySQL: localhost:3306
- Redis: localhost:6379
Default Credentials (After Seeding)¶
Check apps/backend/src/database/seeds/ for test user credentials.
Version: 2.0.0 | Last Updated: 2026-06-20