#!/bin/bash # TekDek Command Center - Deployment Script # For: Hephaestus, Operations Engineer # Date: 2026-04-13 set -e # Colors for output GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuration BACKEND_PORT=3000 FRONTEND_DIR="/var/www/tekdek-command-center" BACKEND_DIR="/opt/tekdek-command-center" DB_NAME="tekdek_command_center" DB_USER="tekdek" # Functions print_header() { echo -e "${BLUE}========================================${NC}" echo -e "${BLUE}$1${NC}" echo -e "${BLUE}========================================${NC}" } print_success() { echo -e "${GREEN}✓ $1${NC}" } print_error() { echo -e "${RED}✗ $1${NC}" } print_warning() { echo -e "${YELLOW}⚠ $1${NC}" } check_requirements() { print_header "Checking Requirements" # Check Node.js if ! command -v node &> /dev/null; then print_error "Node.js not found" exit 1 fi NODE_VERSION=$(node -v) print_success "Node.js: $NODE_VERSION" # Check npm if ! command -v npm &> /dev/null; then print_error "npm not found" exit 1 fi NPM_VERSION=$(npm -v) print_success "npm: $NPM_VERSION" # Check PostgreSQL if ! command -v psql &> /dev/null; then print_warning "PostgreSQL client not found (may already be installed on server)" else print_success "PostgreSQL client installed" fi # Check Nginx if ! command -v nginx &> /dev/null; then print_warning "Nginx not found (may already be installed on server)" else print_success "Nginx installed" fi } deploy_backend() { print_header "Deploying Backend" # Create directories print_warning "Creating backend directory: $BACKEND_DIR" mkdir -p "$BACKEND_DIR" # Copy code print_warning "Copying backend code..." cp -r src/ "$BACKEND_DIR/" cp -r scripts/ "$BACKEND_DIR/" cp package.json "$BACKEND_DIR/" cp package-lock.json "$BACKEND_DIR/" 2>/dev/null || true cp .env.example "$BACKEND_DIR/.env.example" cd "$BACKEND_DIR" # Install dependencies print_warning "Installing dependencies (npm install)..." npm install --production print_success "Dependencies installed" # Check for .env if [ ! -f ".env" ]; then print_warning "No .env file found - using .env.example as template" cp .env.example .env print_warning "⚠️ IMPORTANT: Edit .env with your database credentials" print_warning "📝 Edit: $BACKEND_DIR/.env" read -p "Press enter after editing .env..." fi # Setup database print_warning "Setting up database..." npm run db:setup print_success "Database schema created" print_warning "Seeding initial data..." npm run db:seed print_success "Database seeded" # Test API print_warning "Testing API locally..." timeout 5 npm start & BACKEND_PID=$! sleep 2 if curl -s http://localhost:$BACKEND_PORT/health | grep -q "ok"; then print_success "Backend health check passed" else print_warning "Backend health check might have timed out (expected in this test)" fi # Kill test process kill $BACKEND_PID 2>/dev/null || true print_success "Backend deployed" } deploy_frontend() { print_header "Deploying Frontend" # Create directories print_warning "Creating frontend directory: $FRONTEND_DIR" mkdir -p "$FRONTEND_DIR" # Copy files print_warning "Copying frontend files..." cp ui/index.html "$FRONTEND_DIR/" cp ui/styles.css "$FRONTEND_DIR/" cp ui/api.js "$FRONTEND_DIR/" cp ui/ui.js "$FRONTEND_DIR/" cp ui/app.js "$FRONTEND_DIR/" # Update API URL if provided if [ -n "$API_URL" ]; then print_warning "Updating API URL to: $API_URL" sed -i "s|const BASE_URL = .*|const BASE_URL = '$API_URL';|" "$FRONTEND_DIR/api.js" else print_warning "⚠️ Update API URL in: $FRONTEND_DIR/api.js" fi # Set permissions chmod 755 "$FRONTEND_DIR" chmod 644 "$FRONTEND_DIR"/* print_success "Frontend deployed" } verify_backend() { print_header "Verifying Backend" # Check PM2 if command -v pm2 &> /dev/null; then print_warning "Checking PM2 processes..." pm2 list | grep tekdek-api || print_warning "API not running via PM2" else print_warning "PM2 not installed globally (install with: npm install -g pm2)" fi # Check Node process if pgrep -f "node.*src/index.js" > /dev/null; then print_success "Node.js API process running" else print_warning "Node.js API process not running - start with: npm start or pm2 start src/index.js" fi # Test health endpoint if curl -s http://localhost:$BACKEND_PORT/health 2>/dev/null | grep -q "ok"; then print_success "Backend health check passed" else print_warning "Backend not responding (may not be started yet)" fi } verify_frontend() { print_header "Verifying Frontend" if [ -f "$FRONTEND_DIR/index.html" ]; then print_success "Frontend files deployed" # Check API URL configured if grep -q "BASE_URL" "$FRONTEND_DIR/api.js"; then print_success "API client configured" else print_warning "API client not configured" fi else print_error "Frontend files not found" fi } verify_database() { print_header "Verifying Database" # Try to connect if psql -U "$DB_USER" -d "$DB_NAME" -c "SELECT 1;" 2>/dev/null; then print_success "Database connection successful" # Check tables TABLE_COUNT=$(psql -U "$DB_USER" -d "$DB_NAME" -t -c "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='public';") print_success "Found $TABLE_COUNT tables" else print_warning "Cannot connect to database - verify DATABASE_URL in .env" fi } test_endpoints() { print_header "Testing API Endpoints" BASE_URL="http://localhost:$BACKEND_PORT/api/v1" # Test 1: Create Project print_warning "1. Testing POST /projects..." PROJECT=$(curl -s -X POST "$BASE_URL/projects" \ -H "Content-Type: application/json" \ -d '{"name":"Test Project","description":"Deployment test","color_hex":"#3498db"}') if echo "$PROJECT" | grep -q "\"status\":\"success\""; then PROJECT_ID=$(echo "$PROJECT" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) print_success "Created test project (ID: $PROJECT_ID)" else print_warning "Could not create test project (API may not be running)" return fi # Test 2: List Projects print_warning "2. Testing GET /projects..." if curl -s "$BASE_URL/projects" | grep -q "\"status\":\"success\""; then print_success "Listed projects" fi # Test 3: Create Task print_warning "3. Testing POST /projects/{id}/tasks..." TASK=$(curl -s -X POST "$BASE_URL/projects/$PROJECT_ID/tasks" \ -H "Content-Type: application/json" \ -d '{"title":"Test Task","status":"backlog"}') if echo "$TASK" | grep -q "\"status\":\"success\""; then TASK_ID=$(echo "$TASK" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2) print_success "Created test task (ID: $TASK_ID)" fi print_success "Endpoint tests completed" } main() { print_header "TekDek Command Center - Deployment" echo "For: Hephaestus, Operations Engineer" echo "Date: $(date)" echo "" # Check what to deploy DEPLOY_BACKEND=${1:-"yes"} DEPLOY_FRONTEND=${2:-"yes"} # Run deployment check_requirements if [ "$DEPLOY_BACKEND" != "no" ]; then deploy_backend verify_backend fi if [ "$DEPLOY_FRONTEND" != "no" ]; then deploy_frontend verify_frontend fi verify_database print_header "Deployment Complete" echo "" echo -e "${GREEN}✓ Backend: $BACKEND_DIR${NC}" echo -e "${GREEN}✓ Frontend: $FRONTEND_DIR${NC}" echo "" echo "Next steps:" echo "1. Start backend with: cd $BACKEND_DIR && npm start" echo "2. Or use PM2: npm install -g pm2 && pm2 start src/index.js" echo "3. Configure Nginx with backend URL and frontend directory" echo "4. Setup SSL with Let's Encrypt: certbot certonly --nginx" echo "" echo "See DEPLOYMENT_STRATEGY.md for complete instructions" } # Run if executed directly if [ "${BASH_SOURCE[0]}" == "${0}" ]; then main "$@" fi