diff --git a/README.md b/README.md index b0e8bf6..31e73fe 100644 --- a/README.md +++ b/README.md @@ -29,68 +29,72 @@ A comprehensive, full-stack web application framework with Next.js, tRPC, Drizzl ## Quick Start ### Prerequisites -- Node.js 18+ -- PostgreSQL 14+ -- Redis 7+ -- Docker and Docker Compose -- tmux (for manage utility) -- npm or yarn -### Option 1: Using Manage Utility (Recommended) +**Minimum Requirements:** +- Node.js 18+ (preferably 20+) +- npm 9+ -The manage utility provides a streamlined development experience by orchestrating all services in a unified tmux session. +**Optional (Auto-detected):** +- Docker & Docker Compose (recommended for services) +- tmux 3+ (for unified service management) + +### Option 1: Automated Setup (Recommended) + +The fastest way to get started - one command does everything: -1. Clone and setup: ```bash +# Clone the repository git clone cd corestack -npm install -``` -2. Run the complete setup wizard: -```bash -./manage.ts setup -``` +# Initialize (auto-detects Docker, sets up everything) +./init.sh -This will: -- Check prerequisites -- Install dependencies -- Initialize environment configuration -- Setup databases -- Create an admin user - -3. Start all development services: -```bash -./manage.ts dev +# Start all services +./run.sh ``` -This single command starts all 5 services in tmux: -- Temporal infrastructure (Docker) -- Next.js dev server -- WebSocket server -- BullMQ queue workers -- Temporal worker - -4. Access the application: +**What `./init.sh` does:** +- ✅ Detects your OS (Linux/MacOS) +- ✅ Checks Node.js and npm versions +- ✅ Installs dependencies +- ✅ Generates secure environment variables +- ✅ Starts Docker services (PostgreSQL, Redis, Temporal) +- ✅ Runs database migrations +- ✅ Seeds initial data (creates admin user) + +**What `./run.sh` does:** +- ✅ Starts all Node.js services in tmux (if available) +- ✅ Manages 4 service windows: Next.js, WebSocket, Queue Worker, Temporal Worker +- ✅ Provides easy window switching with `Ctrl+B` + number keys + +**Access the application:** - Web UI: [http://localhost:3000](http://localhost:3000) - Temporal UI: [http://localhost:8080](http://localhost:8080) -**Manage Utility Commands:** +**Default credentials:** username: `root`, password: `Must-Changed` +⚠️ **Change the password after first login!** + +**Advanced init options:** ```bash -./manage.ts check # Verify prerequisites -./manage.ts init # Initialize environment -./manage.ts db-setup # Setup databases -./manage.ts createsuperuser # Create admin user -./manage.ts dev # Start all services -./manage.ts dev stop # Stop all services -./manage.ts dev status # Check service status -./manage.ts dev logs # View service logs +./init.sh --docker # Force Docker mode +./init.sh --no-docker # Use local services +./init.sh --offline # Offline/on-prem mode (uses npm cache) +./init.sh --help # Show all options +``` + +**Advanced run options:** +```bash +./run.sh --tmux # Use tmux (recommended) +./run.sh --no-tmux # Foreground mode +./run.sh --help # Show all options ``` **tmux Controls:** -- `Ctrl+B` then `0-4`: Switch between service panes +- `Ctrl+B` then `0-3`: Switch between service windows - `Ctrl+B` then `D`: Detach (services keep running) - `tmux attach -t corestack`: Reattach to session +- `tmux kill-session -t corestack`: Stop all services ### Option 2: Manual Setup @@ -107,15 +111,21 @@ npm install ```bash cp .env.example .env # Edit .env with your configuration +# Generate secrets: +# JWT_SECRET: openssl rand -base64 32 +# SSH_ENCRYPTION_KEY: openssl rand -base64 32 ``` 3. Start services: ```bash # Start PostgreSQL, Redis, and Temporal -docker-compose up -d +docker compose up -d + +# Run database migrations +npm run db:migrate -# Push database schema -npm run db:push +# Seed database +npm run db:seed ``` 4. Run the application (requires 4 terminals): @@ -148,9 +158,10 @@ Comprehensive documentation is available in the `docs/` directory: | Guide | Description | |-------|-------------| -| **[Manage Utility Design](docs/proposal/interactive_manage_utility.md)** | Design proposal for the interactive management utility (planned feature) | +| **[Quick Start Guide](docs/quick_start.md)** | Fast setup for Linux/MacOS, with/without Docker, online/offline environments | | **[Codebase Exploration](docs/development/codebase_exploration_summary.md)** | Comprehensive overview of the codebase structure, architecture, and key components | | **[Local Development Guide](docs/development/local_development_guide.md)** | Step-by-step guide for setting up the project without Docker/Kubernetes | +| **[Manage Utility Design](docs/proposal/interactive_manage_utility.md)** | Design proposal for the interactive management utility (planned feature) | ### Core Guides @@ -190,19 +201,16 @@ Each topic has detailed documentation in subfolders: ## Common Commands -### Manage Utility (Recommended) +### Quick Start (Recommended) ```bash -./manage.ts setup # Complete setup wizard -./manage.ts check # Check prerequisites -./manage.ts install # Install dependencies -./manage.ts init # Initialize environment -./manage.ts db-setup # Setup databases -./manage.ts createsuperuser # Create admin user -./manage.ts dev # Start all services -./manage.ts dev stop # Stop all services -./manage.ts dev restart # Restart all services -./manage.ts dev status # Check service status -./manage.ts dev logs [service] # View logs +./init.sh # Initialize project (auto-detects Docker) +./init.sh --help # Show all initialization options +./run.sh # Start all services (auto-detects tmux) +./run.sh --help # Show all run options + +# Or use npm scripts +npm run init # Same as ./init.sh +npm run run # Same as ./run.sh ``` ### Development @@ -211,17 +219,26 @@ npm run dev # Start Next.js development server npm run build # Build for production npm start # Start production server npm run lint # Run ESLint +npm run type-check # TypeScript validation ``` ### Database ```bash -npm run db:push # Push schema to database (development) +npm run db:migrate # Run migrations +npm run db:seed # Seed initial data npm run db:generate # Generate migrations -npm run db:migrate # Run migrations (production) +npm run db:push # Push schema to database (development) npm run db:studio # Open Drizzle Studio ``` -### Services +### Docker Services +```bash +npm run docker:up # Start Docker services +npm run docker:down # Stop Docker services +npm run docker:logs # View Docker logs +``` + +### Individual Services ```bash npm run ws:server # Start WebSocket server npm run queue:worker # Start BullMQ queue worker diff --git a/docker-compose.yml b/docker-compose.yml index b03cb7a..cdbfbd6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ services: postgres: image: postgres:16-alpine - container_name: web-seed-postgres + container_name: corestack-postgres environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres @@ -18,7 +18,7 @@ services: redis: image: redis:7-alpine - container_name: web-seed-redis + container_name: corestack-redis ports: - '6379:6379' volumes: @@ -31,7 +31,7 @@ services: temporal: image: temporalio/auto-setup:latest - container_name: web-seed-temporal + container_name: corestack-temporal ports: - '7233:7233' environment: @@ -52,7 +52,7 @@ services: temporal-ui: image: temporalio/ui:latest - container_name: web-seed-temporal-ui + container_name: corestack-temporal-ui ports: - '8080:8080' environment: diff --git a/docs/quick_start.md b/docs/quick_start.md new file mode 100644 index 0000000..aec7afd --- /dev/null +++ b/docs/quick_start.md @@ -0,0 +1,527 @@ +# Quick Start Guide + +This guide will help you quickly initialize and run CoreStack on Linux or MacOS, with or without Docker, and even in offline/on-premises environments with limited internet access. + +## Table of Contents + +- [Prerequisites](#prerequisites) +- [Quick Start (1-Minute Setup)](#quick-start-1-minute-setup) +- [Setup Options](#setup-options) + - [Docker Setup (Recommended)](#docker-setup-recommended) + - [Local Services Setup](#local-services-setup) + - [Offline/On-Premises Setup](#offlineon-premises-setup) +- [Running the Application](#running-the-application) +- [Accessing the Application](#accessing-the-application) +- [Troubleshooting](#troubleshooting) + +## Prerequisites + +### Minimum Requirements + +- **Node.js** 18+ (preferably 20+) +- **npm** 9+ (comes with Node.js) +- **Git** 2+ + +### Optional (Choose Based on Setup) + +**For Docker Setup (Recommended):** +- Docker 20+ +- Docker Compose 2+ + +**For Local Services Setup:** +- PostgreSQL 14+ +- Redis 7+ +- Temporal Server (via Docker or manual installation) + +**For Enhanced Developer Experience:** +- tmux 3+ (for managing multiple services in one terminal) + +## Quick Start (1-Minute Setup) + +The fastest way to get CoreStack up and running: + +```bash +# 1. Clone the repository +git clone +cd corestack + +# 2. Run initialization (auto-detects Docker and sets everything up) +./init.sh + +# 3. Start all services +./run.sh +``` + +That's it! The application will be available at http://localhost:3000 + +**Default credentials**: username: `root`, password: `Must-Changed` + +## Setup Options + +### Docker Setup (Recommended) + +Best for: Development environments with Docker installed + +**Advantages:** +- ✅ No manual service installation +- ✅ Consistent environment across machines +- ✅ Easy cleanup and reset +- ✅ Works offline once images are pulled + +**Setup:** + +```bash +# Initialize with Docker +./init.sh --docker + +# Or use npm scripts +npm run init -- --docker +``` + +**What it does:** +1. Detects your operating system (Linux/MacOS) +2. Checks Node.js and npm versions +3. Installs npm dependencies +4. Generates secure environment variables (.env) +5. Starts PostgreSQL, Redis, and Temporal in Docker +6. Runs database migrations +7. Seeds initial data (creates default admin user) + +### Local Services Setup + +Best for: Environments where Docker is not available or preferred + +**Prerequisites:** +- PostgreSQL 14+ installed and running +- Redis 7+ installed and running +- Temporal Server running (can still use Docker just for Temporal) + +**Setup:** + +```bash +# Initialize without Docker +./init.sh --no-docker + +# Or use npm scripts +npm run init -- --no-docker +``` + +**Manual Service Setup:** + +If you don't have the services running, here's how to set them up: + +**PostgreSQL (Ubuntu/Debian):** +```bash +sudo apt update +sudo apt install postgresql postgresql-contrib +sudo systemctl start postgresql +``` + +**PostgreSQL (MacOS with Homebrew):** +```bash +brew install postgresql@16 +brew services start postgresql@16 +``` + +**Redis (Ubuntu/Debian):** +```bash +sudo apt install redis-server +sudo systemctl start redis-server +``` + +**Redis (MacOS with Homebrew):** +```bash +brew install redis +brew services start redis +``` + +**Temporal (via Docker):** +```bash +# Temporal is complex to install manually, recommend using Docker +docker compose up -d temporal temporal-ui +``` + +### Offline/On-Premises Setup + +Best for: Air-gapped or restricted network environments + +**Requirements:** +- Node.js and npm already installed +- npm packages pre-cached (see below) +- Docker images pre-pulled (if using Docker) + +**Pre-requisites (on machine with internet):** + +```bash +# 1. Clone the repository +git clone +cd corestack + +# 2. Download all npm dependencies to cache +npm install + +# 3. If using Docker, pull images +docker compose pull + +# 4. Package the project (including node_modules) +cd .. +tar -czf corestack-offline.tar.gz corestack/ +``` + +**Setup on Offline Machine:** + +```bash +# 1. Extract the package +tar -xzf corestack-offline.tar.gz +cd corestack/ + +# 2. Initialize in offline mode +./init.sh --docker --offline + +# Or without Docker +./init.sh --no-docker --offline +``` + +**Offline mode features:** +- Uses `npm install --offline --prefer-offline` to use cache only +- Skips internet connectivity checks +- Uses local Docker images (no pull attempts) + +**Using npm over Proxy:** + +If you have npm access through a corporate proxy: + +```bash +# Configure npm proxy (one-time setup) +npm config set proxy http://proxy.company.com:8080 +npm config set https-proxy http://proxy.company.com:8080 + +# Then run normal initialization +./init.sh --docker +``` + +## Running the Application + +After initialization, you have multiple options to run the application: + +### Option 1: Automated Run Script (Recommended) + +Easiest way to start all services: + +```bash +# Auto-detect best options (tmux if available) +./run.sh + +# Or use npm script +npm run run +``` + +**With tmux (Recommended):** +```bash +./run.sh --tmux --docker +``` + +**Without tmux (Foreground mode):** +```bash +./run.sh --no-tmux +``` + +**Tmux Controls:** +- `Ctrl+B` then `0-3`: Switch between service windows +- `Ctrl+B` then `D`: Detach (services keep running in background) +- `tmux attach -t corestack`: Reattach to session +- `tmux kill-session -t corestack`: Stop all services + +### Option 2: Manual Service Management + +If you prefer to manage each service separately: + +**Terminal 1 - Docker Services (if using Docker):** +```bash +docker compose up -d +# Or: npm run docker:up +``` + +**Terminal 2 - Next.js Dev Server:** +```bash +npm run dev +``` + +**Terminal 3 - WebSocket Server:** +```bash +npm run ws:server +``` + +**Terminal 4 - Queue Worker:** +```bash +npm run queue:worker +``` + +**Terminal 5 - Temporal Worker:** +```bash +npm run temporal:worker +``` + +### Option 3: Background Services with Logs + +Run services in background and monitor logs: + +```bash +# Start Docker services +npm run docker:up + +# Start Node.js services in background +npm run ws:server & +npm run queue:worker & +npm run temporal:worker & +npm run dev + +# View Docker logs +npm run docker:logs +``` + +## Accessing the Application + +Once all services are running, access the application: + +| Service | URL | Description | +|---------|-----|-------------| +| **Web Application** | http://localhost:3000 | Main Next.js application | +| **WebSocket Server** | ws://localhost:3001 | Real-time communication | +| **Temporal UI** | http://localhost:8080 | Workflow monitoring (Docker only) | +| **Database Studio** | Run `npm run db:studio` | Drizzle Studio database GUI | + +**Default Admin Credentials:** +- Username: `root` +- Password: `Must-Changed` + +**⚠️ IMPORTANT:** Change the default password immediately after first login! + +## Helpful Commands + +### Initialization Scripts + +```bash +./init.sh --help # Show all initialization options +./init.sh --docker # Initialize with Docker services +./init.sh --no-docker # Initialize with local services +./init.sh --offline # Initialize in offline mode +``` + +### Run Scripts + +```bash +./run.sh --help # Show all run options +./run.sh --tmux --docker # Start with tmux and Docker +./run.sh --no-tmux # Start in foreground mode +``` + +### Docker Management + +```bash +npm run docker:up # Start Docker services +npm run docker:down # Stop Docker services +npm run docker:logs # View Docker logs + +# Or use docker compose directly +docker compose up -d # Start services in background +docker compose ps # Check service status +docker compose logs -f # Follow logs +docker compose down # Stop all services +docker compose restart # Restart all services +``` + +### Database Management + +```bash +npm run db:migrate # Run database migrations +npm run db:seed # Seed initial data +npm run db:studio # Open Drizzle Studio (database GUI) +npm run db:push # Push schema changes (dev only) +``` + +### Code Quality + +```bash +npm run lint # Check code quality +npm run lint:fix # Auto-fix linting issues +npm run type-check # TypeScript validation +``` + +## Troubleshooting + +### PostgreSQL Connection Issues + +**Error:** `ECONNREFUSED` or `Connection refused` + +**Solution:** +```bash +# Check if PostgreSQL is running +docker compose ps postgres # If using Docker + +# Or for local installation +sudo systemctl status postgresql # Linux +brew services list # MacOS + +# Verify connection +docker compose exec postgres pg_isready -U postgres +``` + +### Redis Connection Issues + +**Error:** `Redis connection failed` + +**Solution:** +```bash +# Check if Redis is running +docker compose ps redis # If using Docker + +# Or for local installation +sudo systemctl status redis-server # Linux +brew services list # MacOS + +# Test connection +docker compose exec redis redis-cli ping # Should return PONG +``` + +### Port Already in Use + +**Error:** `EADDRINUSE: address already in use :::3000` + +**Solution:** +```bash +# Find process using the port +lsof -i :3000 # MacOS/Linux +sudo netstat -tlnp | grep 3000 # Linux + +# Kill the process +kill -9 + +# Or use different ports in .env +PORT=3001 +WS_PORT=3002 +``` + +### Docker Permission Issues + +**Error:** `permission denied while trying to connect to the Docker daemon socket` + +**Solution (Linux):** +```bash +# Add user to docker group +sudo usermod -aG docker $USER + +# Logout and login again, or +newgrp docker +``` + +### Temporal Worker Connection Failed + +**Error:** `[TEMPORAL] Failed to connect to Temporal Server` + +**Solution:** +```bash +# Check if Temporal is running +docker compose ps temporal + +# Wait for Temporal to be fully ready (can take 10-30 seconds) +docker compose logs -f temporal + +# Restart Temporal if needed +docker compose restart temporal +``` + +### Node.js Version Issues + +**Error:** `Node.js version XX is too old` + +**Solution:** +```bash +# Check your Node.js version +node -v + +# Install Node.js 18+ or 20+ +# Using nvm (recommended): +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash +nvm install 20 +nvm use 20 + +# Or download from: https://nodejs.org +``` + +### Missing Dependencies in Offline Mode + +**Error:** `npm ERR! Could not resolve dependency` + +**Solution:** +```bash +# Ensure you have all dependencies cached +# On a machine with internet: +npm install --prefer-offline + +# Copy the entire node_modules and package-lock.json +# to the offline machine +``` + +### Environment Variables Not Set + +**Error:** `Environment variable XXX is not set` + +**Solution:** +```bash +# Ensure .env file exists +ls -la .env + +# If missing, run initialization again +./init.sh + +# Or manually copy from example +cp .env.example .env +# Edit .env and fill in required values +``` + +### tmux Session Already Exists + +**Warning:** `Tmux session 'corestack' already exists` + +**Solution:** +```bash +# Attach to existing session +tmux attach -t corestack + +# Or kill and restart +tmux kill-session -t corestack +./run.sh --tmux +``` + +## Next Steps + +After successfully running the application: + +1. **Change default password** - Login and change the admin password +2. **Explore the documentation** - See [README.md](../README.md) for comprehensive guides +3. **Try the CLI** - Run `npm run cli -- --help` to see CLI options +4. **Create a new user** - Use the CLI: `npm run cli user create "Name" "email@example.com"` +5. **Start a workflow** - Try Temporal workflows: `npm run cli task start build -p myproject` + +## Additional Resources + +- [Main README](../README.md) - Full project documentation +- [Local Development Guide](./development/local_development_guide.md) - Detailed development setup +- [Architecture Overview](./architecture.md) - System architecture +- [API Reference](./api.md) - tRPC endpoints +- [Database Guide](./database.md) - Database schema and migrations +- [Authentication Guide](./features/authentication.md) - Authentication setup + +## Getting Help + +If you encounter issues not covered in this guide: + +1. Check the [Local Development Guide](./development/local_development_guide.md) +2. Review Docker logs: `npm run docker:logs` +3. Check service status: `docker compose ps` +4. Open an issue on GitHub with: + - Your operating system and version + - Node.js version (`node -v`) + - Error messages and logs + - Steps to reproduce diff --git a/init.sh b/init.sh new file mode 100755 index 0000000..00638fa --- /dev/null +++ b/init.sh @@ -0,0 +1,301 @@ +#!/bin/bash + +# CoreStack Initialization Script +# Supports: Linux, MacOS, with/without Docker, online/offline environments +# Usage: ./init.sh [--docker|--no-docker] [--offline] + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Default options +USE_DOCKER="" +OFFLINE_MODE=false + +# Parse command line arguments +while [[ $# -gt 0 ]]; do + case $1 in + --docker) + USE_DOCKER=true + shift + ;; + --no-docker) + USE_DOCKER=false + shift + ;; + --offline) + OFFLINE_MODE=true + shift + ;; + --help) + echo "CoreStack Initialization Script" + echo "" + echo "Usage: ./init.sh [OPTIONS]" + echo "" + echo "Options:" + echo " --docker Use Docker for PostgreSQL, Redis, and Temporal" + echo " --no-docker Use local installations (manual setup required)" + echo " --offline Offline mode (skip online checks, use npm cache)" + echo " --help Show this help message" + echo "" + echo "Examples:" + echo " ./init.sh --docker # Auto-detect, prefer Docker" + echo " ./init.sh --no-docker # Use local services" + echo " ./init.sh --docker --offline # Docker setup in offline environment" + exit 0 + ;; + *) + echo -e "${RED}Unknown option: $1${NC}" + echo "Use --help for usage information" + exit 1 + ;; + esac +done + +echo -e "${BLUE}╔════════════════════════════════════════════╗${NC}" +echo -e "${BLUE}║ CoreStack Initialization Script ║${NC}" +echo -e "${BLUE}╚════════════════════════════════════════════╝${NC}" +echo "" + +# Detect OS +detect_os() { + echo -e "${BLUE}[1/8] Detecting operating system...${NC}" + + if [[ "$OSTYPE" == "linux-gnu"* ]]; then + OS="linux" + echo -e "${GREEN}✓ Detected: Linux${NC}" + elif [[ "$OSTYPE" == "darwin"* ]]; then + OS="macos" + echo -e "${GREEN}✓ Detected: MacOS${NC}" + else + echo -e "${RED}✗ Unsupported OS: $OSTYPE${NC}" + echo -e "${YELLOW} This script supports Linux and MacOS only${NC}" + exit 1 + fi + echo "" +} + +# Check Node.js and npm +check_node() { + echo -e "${BLUE}[2/8] Checking Node.js and npm...${NC}" + + if ! command -v node &> /dev/null; then + echo -e "${RED}✗ Node.js is not installed${NC}" + echo -e "${YELLOW} Please install Node.js 18+ from https://nodejs.org${NC}" + exit 1 + fi + + NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1) + if [ "$NODE_VERSION" -lt 18 ]; then + echo -e "${RED}✗ Node.js version $NODE_VERSION is too old${NC}" + echo -e "${YELLOW} Please upgrade to Node.js 18 or higher${NC}" + exit 1 + fi + + if ! command -v npm &> /dev/null; then + echo -e "${RED}✗ npm is not installed${NC}" + exit 1 + fi + + echo -e "${GREEN}✓ Node.js $(node -v)${NC}" + echo -e "${GREEN}✓ npm $(npm -v)${NC}" + echo "" +} + +# Auto-detect Docker availability if not specified +detect_docker() { + echo -e "${BLUE}[3/8] Checking Docker availability...${NC}" + + if [ -z "$USE_DOCKER" ]; then + if command -v docker &> /dev/null && docker ps &> /dev/null; then + USE_DOCKER=true + echo -e "${GREEN}✓ Docker is available and running${NC}" + echo -e "${YELLOW} Will use Docker for services (PostgreSQL, Redis, Temporal)${NC}" + else + USE_DOCKER=false + echo -e "${YELLOW}⚠ Docker not available or not running${NC}" + echo -e "${YELLOW} Will use local services (requires manual setup)${NC}" + fi + else + if [ "$USE_DOCKER" = true ]; then + if ! command -v docker &> /dev/null; then + echo -e "${RED}✗ Docker not found but --docker was specified${NC}" + exit 1 + fi + if ! docker ps &> /dev/null; then + echo -e "${RED}✗ Docker daemon not running${NC}" + echo -e "${YELLOW} Please start Docker and try again${NC}" + exit 1 + fi + echo -e "${GREEN}✓ Docker is available and running${NC}" + else + echo -e "${YELLOW}⚠ Using local services (--no-docker specified)${NC}" + fi + fi + echo "" +} + +# Install dependencies +install_dependencies() { + echo -e "${BLUE}[4/8] Installing dependencies...${NC}" + + if [ "$OFFLINE_MODE" = true ]; then + echo -e "${YELLOW}⚠ Offline mode: Using npm cache only${NC}" + if npm install --offline --prefer-offline 2>/dev/null; then + echo -e "${GREEN}✓ Dependencies installed from cache${NC}" + else + echo -e "${YELLOW}⚠ Some dependencies missing from cache, trying regular install...${NC}" + npm install --prefer-offline + fi + else + npm install + echo -e "${GREEN}✓ Dependencies installed${NC}" + fi + echo "" +} + +# Setup environment variables +setup_env() { + echo -e "${BLUE}[5/8] Setting up environment variables...${NC}" + + if [ -f .env ]; then + echo -e "${YELLOW}⚠ .env file already exists${NC}" + read -p " Overwrite? (y/N): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo -e "${YELLOW} Skipping .env setup${NC}" + echo "" + return + fi + fi + + # Copy template + cp .env.example .env + + # Generate secure secrets + JWT_SECRET=$(openssl rand -base64 32 2>/dev/null || node -e "console.log(require('crypto').randomBytes(32).toString('base64'))") + SSH_KEY=$(openssl rand -base64 32 2>/dev/null || node -e "console.log(require('crypto').randomBytes(32).toString('base64'))") + + # Update .env file + if [[ "$OS" == "macos" ]]; then + sed -i '' "s|JWT_SECRET=.*|JWT_SECRET=$JWT_SECRET|" .env + sed -i '' "s|SSH_ENCRYPTION_KEY=.*|SSH_ENCRYPTION_KEY=$SSH_KEY|" .env + else + sed -i "s|JWT_SECRET=.*|JWT_SECRET=$JWT_SECRET|" .env + sed -i "s|SSH_ENCRYPTION_KEY=.*|SSH_ENCRYPTION_KEY=$SSH_KEY|" .env + fi + + echo -e "${GREEN}✓ Environment file created (.env)${NC}" + echo -e "${GREEN}✓ Generated secure JWT_SECRET${NC}" + echo -e "${GREEN}✓ Generated secure SSH_ENCRYPTION_KEY${NC}" + echo "" +} + +# Start services +start_services() { + echo -e "${BLUE}[6/8] Starting services...${NC}" + + if [ "$USE_DOCKER" = true ]; then + echo -e "${YELLOW} Starting Docker services (PostgreSQL, Redis, Temporal)...${NC}" + docker compose up -d + + # Wait for services to be ready + echo -e "${YELLOW} Waiting for services to be ready...${NC}" + sleep 5 + + # Check PostgreSQL + for i in {1..30}; do + if docker compose exec -T postgres pg_isready -U postgres &> /dev/null; then + echo -e "${GREEN}✓ PostgreSQL is ready${NC}" + break + fi + if [ $i -eq 30 ]; then + echo -e "${RED}✗ PostgreSQL failed to start${NC}" + exit 1 + fi + sleep 1 + done + + # Check Redis + if docker compose exec -T redis redis-cli ping &> /dev/null; then + echo -e "${GREEN}✓ Redis is ready${NC}" + fi + + echo -e "${GREEN}✓ Temporal Server is starting (port 7233)${NC}" + echo -e "${GREEN}✓ Temporal UI will be available at http://localhost:8080${NC}" + else + echo -e "${YELLOW}⚠ Local services mode${NC}" + echo -e "${YELLOW} Please ensure the following services are running:${NC}" + echo -e "${YELLOW} - PostgreSQL (port 5432)${NC}" + echo -e "${YELLOW} - Redis (port 6379)${NC}" + echo -e "${YELLOW} - Temporal Server (port 7233)${NC}" + echo "" + read -p " Press Enter when services are ready..." + fi + echo "" +} + +# Setup database +setup_database() { + echo -e "${BLUE}[7/8] Setting up database...${NC}" + + # Run migrations + echo -e "${YELLOW} Running database migrations...${NC}" + npm run db:migrate + echo -e "${GREEN}✓ Database migrations completed${NC}" + + # Seed database + echo -e "${YELLOW} Seeding database...${NC}" + npm run db:seed + echo -e "${GREEN}✓ Database seeded with initial data${NC}" + echo "" +} + +# Display success message +display_success() { + echo -e "${BLUE}[8/8] Initialization complete!${NC}" + echo "" + echo -e "${GREEN}╔════════════════════════════════════════════╗${NC}" + echo -e "${GREEN}║ CoreStack is ready! ║${NC}" + echo -e "${GREEN}╚════════════════════════════════════════════╝${NC}" + echo "" + echo -e "${BLUE}Default admin credentials:${NC}" + echo -e " Username: ${GREEN}root${NC}" + echo -e " Password: ${YELLOW}Must-Changed${NC}" + echo -e " ${RED}⚠ Please change the password after first login!${NC}" + echo "" + echo -e "${BLUE}To start the application:${NC}" + echo -e " ${GREEN}./run.sh${NC} # Start all services in tmux" + echo -e " ${GREEN}npm run dev${NC} # Start Next.js dev server only" + echo "" + echo -e "${BLUE}Useful commands:${NC}" + echo -e " ${GREEN}docker compose logs -f${NC} # View Docker service logs" + echo -e " ${GREEN}npm run db:studio${NC} # Open database GUI" + echo -e " ${GREEN}npm run lint${NC} # Check code quality" + echo "" + echo -e "${BLUE}Access points:${NC}" + echo -e " Next.js App: ${GREEN}http://localhost:3000${NC}" + echo -e " WebSocket: ${GREEN}ws://localhost:3001${NC}" + echo -e " Temporal UI: ${GREEN}http://localhost:8080${NC}" + echo "" +} + +# Main execution +main() { + detect_os + check_node + detect_docker + install_dependencies + setup_env + start_services + setup_database + display_success +} + +# Run main function +main diff --git a/package.json b/package.json index c98c7d6..e51b7ef 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,8 @@ "version": "0.1.0", "private": true, "scripts": { + "init": "./init.sh", + "run": "./run.sh", "dev": "next dev --turbopack", "build": "next build --turbopack", "start": "next start", @@ -19,6 +21,9 @@ "queue:worker": "tsx server/queue/worker.ts", "temporal:worker": "tsx server/temporal/workers/main.worker.ts", "cli": "tsx cli/index.ts", + "docker:up": "docker compose up -d", + "docker:down": "docker compose down", + "docker:logs": "docker compose logs -f", "prepare": "husky" }, "dependencies": { diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..a7b5691 --- /dev/null +++ b/run.sh @@ -0,0 +1,225 @@ +#!/bin/bash + +# CoreStack Run Script +# Starts all services required for development +# Usage: ./run.sh [--tmux|--no-tmux] [--docker|--no-docker] + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Default options +USE_TMUX="" +USE_DOCKER="" + +# Parse command line arguments +while [[ $# -gt 0 ]]; do + case $1 in + --tmux) + USE_TMUX=true + shift + ;; + --no-tmux) + USE_TMUX=false + shift + ;; + --docker) + USE_DOCKER=true + shift + ;; + --no-docker) + USE_DOCKER=false + shift + ;; + --help) + echo "CoreStack Run Script" + echo "" + echo "Usage: ./run.sh [OPTIONS]" + echo "" + echo "Options:" + echo " --tmux Use tmux to manage services (recommended)" + echo " --no-tmux Run services in foreground (Ctrl+C to stop)" + echo " --docker Start Docker services first" + echo " --no-docker Skip Docker services (assume already running)" + echo " --help Show this help message" + echo "" + echo "Examples:" + echo " ./run.sh # Auto-detect best options" + echo " ./run.sh --tmux --docker # Full setup with tmux" + echo " ./run.sh --no-tmux # Simple foreground mode" + exit 0 + ;; + *) + echo -e "${RED}Unknown option: $1${NC}" + echo "Use --help for usage information" + exit 1 + ;; + esac +done + +echo -e "${BLUE}╔════════════════════════════════════════════╗${NC}" +echo -e "${BLUE}║ CoreStack Service Manager ║${NC}" +echo -e "${BLUE}╚════════════════════════════════════════════╝${NC}" +echo "" + +# Check if .env exists +if [ ! -f .env ]; then + echo -e "${RED}✗ .env file not found${NC}" + echo -e "${YELLOW} Run ./init.sh first to initialize the project${NC}" + exit 1 +fi + +# Auto-detect Docker if not specified +if [ -z "$USE_DOCKER" ]; then + if [ -f docker-compose.yml ] && command -v docker &> /dev/null && docker ps &> /dev/null; then + USE_DOCKER=true + else + USE_DOCKER=false + fi +fi + +# Auto-detect tmux if not specified +if [ -z "$USE_TMUX" ]; then + if command -v tmux &> /dev/null; then + USE_TMUX=true + else + USE_TMUX=false + fi +fi + +# Start Docker services if needed +if [ "$USE_DOCKER" = true ]; then + echo -e "${BLUE}[1/2] Starting Docker services...${NC}" + + # Check if services are already running + if docker compose ps | grep -q "Up"; then + echo -e "${GREEN}✓ Docker services already running${NC}" + else + docker compose up -d + echo -e "${GREEN}✓ Docker services started${NC}" + echo -e "${YELLOW} Waiting for services to be ready...${NC}" + sleep 5 + fi + echo "" +fi + +# Start Node.js services +echo -e "${BLUE}[2/2] Starting Node.js services...${NC}" +echo "" + +# Function to run services in foreground +run_foreground() { + echo -e "${YELLOW}Starting services in foreground mode...${NC}" + echo -e "${YELLOW}Press Ctrl+C to stop all services${NC}" + echo "" + + # Trap Ctrl+C to cleanup + trap 'echo -e "\n${YELLOW}Stopping services...${NC}"; kill 0; exit 0' INT + + # Start services in background + npm run ws:server & + WS_PID=$! + + npm run queue:worker & + QUEUE_PID=$! + + npm run temporal:worker & + TEMPORAL_PID=$! + + # Wait a bit for services to start + sleep 2 + echo -e "${GREEN}✓ WebSocket server started (PID: $WS_PID)${NC}" + echo -e "${GREEN}✓ Queue worker started (PID: $QUEUE_PID)${NC}" + echo -e "${GREEN}✓ Temporal worker started (PID: $TEMPORAL_PID)${NC}" + echo "" + + # Start Next.js in foreground (this is the main process) + echo -e "${GREEN}✓ Starting Next.js dev server...${NC}" + echo "" + npm run dev +} + +# Function to run services in tmux +run_tmux() { + SESSION_NAME="corestack" + + # Check if session already exists + if tmux has-session -t $SESSION_NAME 2>/dev/null; then + echo -e "${YELLOW}⚠ Tmux session '$SESSION_NAME' already exists${NC}" + read -p " Kill existing session and restart? (y/N): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + tmux kill-session -t $SESSION_NAME + else + echo -e "${BLUE} Attaching to existing session...${NC}" + echo -e "${YELLOW} Use 'Ctrl+b d' to detach, 'Ctrl+b [0-3]' to switch windows${NC}" + tmux attach-session -t $SESSION_NAME + exit 0 + fi + fi + + echo -e "${YELLOW}Creating tmux session: $SESSION_NAME${NC}" + + # Create new session with Next.js + tmux new-session -d -s $SESSION_NAME -n "nextjs" + tmux send-keys -t $SESSION_NAME:0 "npm run dev" C-m + + # Create window for WebSocket server + tmux new-window -t $SESSION_NAME:1 -n "websocket" + tmux send-keys -t $SESSION_NAME:1 "npm run ws:server" C-m + + # Create window for Queue worker + tmux new-window -t $SESSION_NAME:2 -n "queue" + tmux send-keys -t $SESSION_NAME:2 "npm run queue:worker" C-m + + # Create window for Temporal worker + tmux new-window -t $SESSION_NAME:3 -n "temporal" + tmux send-keys -t $SESSION_NAME:3 "npm run temporal:worker" C-m + + # Select first window + tmux select-window -t $SESSION_NAME:0 + + echo "" + echo -e "${GREEN}╔════════════════════════════════════════════╗${NC}" + echo -e "${GREEN}║ All services started in tmux! ║${NC}" + echo -e "${GREEN}╚════════════════════════════════════════════╝${NC}" + echo "" + echo -e "${BLUE}Tmux session: ${GREEN}$SESSION_NAME${NC}" + echo "" + echo -e "${BLUE}Windows:${NC}" + echo -e " ${GREEN}0: nextjs${NC} - Next.js dev server (http://localhost:3000)" + echo -e " ${GREEN}1: websocket${NC} - WebSocket server (ws://localhost:3001)" + echo -e " ${GREEN}2: queue${NC} - BullMQ worker" + echo -e " ${GREEN}3: temporal${NC} - Temporal workflow worker" + echo "" + echo -e "${BLUE}Tmux commands:${NC}" + echo -e " ${GREEN}Ctrl+b [0-3]${NC} - Switch between windows" + echo -e " ${GREEN}Ctrl+b d${NC} - Detach from session (services keep running)" + echo -e " ${GREEN}tmux attach -t $SESSION_NAME${NC} - Reattach to session" + echo -e " ${GREEN}tmux kill-session -t $SESSION_NAME${NC} - Stop all services" + echo "" + if [ "$USE_DOCKER" = true ]; then + echo -e "${BLUE}Access points:${NC}" + echo -e " Next.js App: ${GREEN}http://localhost:3000${NC}" + echo -e " WebSocket: ${GREEN}ws://localhost:3001${NC}" + echo -e " Temporal UI: ${GREEN}http://localhost:8080${NC}" + echo "" + fi + echo -e "${YELLOW}Attaching to session...${NC}" + echo "" + + # Attach to session + tmux attach-session -t $SESSION_NAME +} + +# Choose run mode +if [ "$USE_TMUX" = true ]; then + run_tmux +else + run_foreground +fi