#!/bin/bash # ================================================================================================ # ENHANCED TECH STACK SELECTOR - MIGRATED VERSION STARTUP SCRIPT # Uses PostgreSQL data migrated to Neo4j with proper price-based relationships # ================================================================================================ set -e # Parse command line arguments FORCE_MIGRATION=false if [ "$1" = "--force-migration" ] || [ "$1" = "-f" ]; then FORCE_MIGRATION=true echo "🔄 Force migration mode enabled" elif [ "$1" = "--help" ] || [ "$1" = "-h" ]; then echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" echo " --force-migration, -f Force re-run all migrations" echo " --help, -h Show this help message" echo "" echo "Examples:" echo " $0 # Normal startup with auto-migration detection" echo " $0 --force-migration # Force re-run all migrations" exit 0 fi echo "="*60 echo "🚀 ENHANCED TECH STACK SELECTOR v15.0 - MIGRATED VERSION" echo "="*60 echo "✅ PostgreSQL data migrated to Neo4j" echo "✅ Price-based relationships" echo "✅ Real data from PostgreSQL" echo "✅ Comprehensive pricing analysis" echo "="*60 # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Function to print colored output print_status() { echo -e "${GREEN}✅ $1${NC}" } print_warning() { echo -e "${YELLOW}âš ī¸ $1${NC}" } print_error() { echo -e "${RED}❌ $1${NC}" } print_info() { echo -e "${BLUE}â„šī¸ $1${NC}" } # Check if Python is available if ! command -v python3 &> /dev/null; then print_error "Python3 is not installed or not in PATH" exit 1 fi print_status "Python3 found: $(python3 --version)" # Check if pip is available if ! command -v pip3 &> /dev/null; then print_error "pip3 is not installed or not in PATH" exit 1 fi print_status "pip3 found: $(pip3 --version)" # Check if psql is available if ! command -v psql &> /dev/null; then print_error "psql is not installed or not in PATH" print_info "Please install PostgreSQL client tools:" print_info " Ubuntu/Debian: sudo apt-get install postgresql-client" print_info " CentOS/RHEL: sudo yum install postgresql" print_info " macOS: brew install postgresql" exit 1 fi print_status "psql found: $(psql --version)" # Check if createdb is available if ! command -v createdb &> /dev/null; then print_error "createdb is not installed or not in PATH" print_info "Please install PostgreSQL client tools:" print_info " Ubuntu/Debian: sudo apt-get install postgresql-client" print_info " CentOS/RHEL: sudo yum install postgresql" print_info " macOS: brew install postgresql" exit 1 fi print_status "createdb found: $(createdb --version)" # Install/upgrade required packages print_info "Installing/upgrading required packages..." pip3 install --upgrade fastapi uvicorn neo4j psycopg2-binary anthropic loguru pydantic # Function to create database if it doesn't exist create_database_if_not_exists() { print_info "Checking if database 'dev_pipeline' exists..." # Try to connect to the specific database if python3 -c " import psycopg2 try: conn = psycopg2.connect( host='localhost', port=5432, user='pipeline_admin', password='secure_pipeline_2024', database='dev_pipeline' ) conn.close() print('Database dev_pipeline exists') except Exception as e: print(f'Database dev_pipeline does not exist: {e}') exit(1) " 2>/dev/null; then print_status "Database 'dev_pipeline' exists" return 0 else print_warning "Database 'dev_pipeline' does not exist - creating it..." # Try to create the database if createdb -h localhost -p 5432 -U pipeline_admin dev_pipeline 2>/dev/null; then print_status "Database 'dev_pipeline' created successfully" return 0 else print_error "Failed to create database 'dev_pipeline'" print_info "Please create the database manually:" print_info " createdb -h localhost -p 5432 -U pipeline_admin dev_pipeline" return 1 fi fi } # Check if PostgreSQL is running print_info "Checking PostgreSQL connection..." if ! python3 -c " import psycopg2 try: conn = psycopg2.connect( host='localhost', port=5432, user='pipeline_admin', password='secure_pipeline_2024', database='postgres' ) conn.close() print('PostgreSQL connection successful') except Exception as e: print(f'PostgreSQL connection failed: {e}') exit(1) " 2>/dev/null; then print_error "PostgreSQL is not running or not accessible" print_info "Please ensure PostgreSQL is running and accessible" exit 1 fi print_status "PostgreSQL is running and accessible" # Create database if it doesn't exist if ! create_database_if_not_exists; then exit 1 fi # Function to check if database needs migration check_database_migration() { print_info "Checking if database needs migration..." # Check if price_tiers table exists and has data if ! python3 -c " import psycopg2 try: conn = psycopg2.connect( host='localhost', port=5432, user='pipeline_admin', password='secure_pipeline_2024', database='dev_pipeline' ) cursor = conn.cursor() # Check if price_tiers table exists cursor.execute(\"\"\" SELECT EXISTS ( SELECT FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'price_tiers' ); \"\"\") table_exists = cursor.fetchone()[0] if not table_exists: print('price_tiers table does not exist - migration needed') exit(1) # Check if price_tiers has data cursor.execute('SELECT COUNT(*) FROM price_tiers;') count = cursor.fetchone()[0] if count == 0: print('price_tiers table is empty - migration needed') exit(1) # Check if stack_recommendations has sufficient data (should have more than 8 records) cursor.execute('SELECT COUNT(*) FROM stack_recommendations;') rec_count = cursor.fetchone()[0] if rec_count < 30: # Expect at least 30 domain recommendations print(f'stack_recommendations has only {rec_count} records - migration needed for additional domains') exit(1) # Check for specific new domains cursor.execute(\"\"\" SELECT COUNT(DISTINCT business_domain) FROM stack_recommendations WHERE business_domain IN ('healthcare', 'finance', 'gaming', 'education', 'media', 'iot', 'social', 'elearning', 'realestate', 'travel', 'manufacturing', 'ecommerce', 'saas') \"\"\") new_domains_count = cursor.fetchone()[0] if new_domains_count < 12: # Expect at least 12 domains print(f'Only {new_domains_count} domains found - migration needed for additional domains') exit(1) print('Database appears to be fully migrated with all domains') cursor.close() conn.close() except Exception as e: print(f'Error checking database: {e}') exit(1) " 2>/dev/null; then return 1 # Migration needed else return 0 # Migration not needed fi } # Function to run PostgreSQL migrations run_postgres_migrations() { print_info "Running PostgreSQL migrations..." # Migration files in order migration_files=( "db/001_schema.sql" "db/002_tools_migration.sql" "db/003_tools_pricing_migration.sql" "db/004_comprehensive_stacks_migration.sql" "db/005_comprehensive_ecommerce_stacks.sql" "db/006_comprehensive_all_domains_stacks.sql" ) # Set PGPASSWORD to avoid password prompts export PGPASSWORD="secure_pipeline_2024" for migration_file in "${migration_files[@]}"; do if [ ! -f "$migration_file" ]; then print_error "Migration file not found: $migration_file" exit 1 fi print_info "Running migration: $migration_file" # Run migration with error handling if psql -h localhost -p 5432 -U pipeline_admin -d dev_pipeline -f "$migration_file" -q 2>/dev/null; then print_status "Migration completed: $migration_file" else print_error "Migration failed: $migration_file" print_info "Check the error logs above for details" print_info "You may need to run the migration manually:" print_info " psql -h localhost -p 5432 -U pipeline_admin -d dev_pipeline -f $migration_file" exit 1 fi done # Unset password unset PGPASSWORD print_status "All PostgreSQL migrations completed successfully" } # Check if migration is needed and run if necessary if [ "$FORCE_MIGRATION" = true ]; then print_warning "Force migration enabled - running migrations..." run_postgres_migrations # Verify migration was successful print_info "Verifying migration..." if check_database_migration; then print_status "Migration verification successful" else print_error "Migration verification failed" exit 1 fi elif check_database_migration; then print_status "Database is already migrated" else print_warning "Database needs migration - running migrations..." run_postgres_migrations # Verify migration was successful print_info "Verifying migration..." if check_database_migration; then print_status "Migration verification successful" else print_error "Migration verification failed" exit 1 fi fi # Show migration summary print_info "Migration Summary:" python3 -c " import psycopg2 try: conn = psycopg2.connect( host='localhost', port=5432, user='pipeline_admin', password='secure_pipeline_2024', database='dev_pipeline' ) cursor = conn.cursor() # Get table counts tables = ['price_tiers', 'frontend_technologies', 'backend_technologies', 'database_technologies', 'cloud_technologies', 'testing_technologies', 'mobile_technologies', 'devops_technologies', 'ai_ml_technologies', 'tools', 'price_based_stacks', 'stack_recommendations'] print('📊 Database Statistics:') for table in tables: try: cursor.execute(f'SELECT COUNT(*) FROM {table};') count = cursor.fetchone()[0] print(f' {table}: {count} records') except Exception as e: print(f' {table}: Error - {e}') cursor.close() conn.close() except Exception as e: print(f'Error getting migration summary: {e}') " 2>/dev/null # Check if Neo4j is running print_info "Checking Neo4j connection..." if ! python3 -c " from neo4j import GraphDatabase try: driver = GraphDatabase.driver('bolt://localhost:7687', auth=('neo4j', 'password')) driver.verify_connectivity() print('Neo4j connection successful') driver.close() except Exception as e: print(f'Neo4j connection failed: {e}') exit(1) " 2>/dev/null; then print_error "Neo4j is not running or not accessible" print_info "Please start Neo4j first:" print_info " docker run -d --name neo4j -p 7474:7474 -p 7687:7687 -e NEO4J_AUTH=neo4j/password neo4j:latest" print_info " Wait for Neo4j to start (check http://localhost:7474)" exit 1 fi print_status "Neo4j is running and accessible" # Check if migration has been run print_info "Checking if migration has been completed..." if ! python3 -c " from neo4j import GraphDatabase try: driver = GraphDatabase.driver('bolt://localhost:7687', auth=('neo4j', 'password')) with driver.session() as session: result = session.run('MATCH (p:PriceTier) RETURN count(p) as count') price_tiers = result.single()['count'] if price_tiers == 0: print('No data found in Neo4j - migration needed') exit(1) else: print(f'Found {price_tiers} price tiers - migration appears complete') driver.close() except Exception as e: print(f'Error checking migration status: {e}') exit(1) " 2>/dev/null; then print_warning "No data found in Neo4j - running migration..." # Run migration if python3 migrate_postgres_to_neo4j.py; then print_status "Migration completed successfully" else print_error "Migration failed" exit 1 fi else print_status "Migration appears to be complete" fi # Set environment variables export NEO4J_URI="bolt://localhost:7687" export NEO4J_USER="neo4j" export NEO4J_PASSWORD="password" export POSTGRES_HOST="localhost" export POSTGRES_PORT="5432" export POSTGRES_USER="pipeline_admin" export POSTGRES_PASSWORD="secure_pipeline_2024" export POSTGRES_DB="dev_pipeline" export CLAUDE_API_KEY="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" print_status "Environment variables set" # Create logs directory if it doesn't exist mkdir -p logs # Start the migrated application print_info "Starting Enhanced Tech Stack Selector (Migrated Version)..." print_info "Server will be available at: http://localhost:8002" print_info "API documentation: http://localhost:8002/docs" print_info "Health check: http://localhost:8002/health" print_info "Diagnostics: http://localhost:8002/api/diagnostics" print_info "" print_info "Press Ctrl+C to stop the server" print_info "" # Run TSS namespace migration print_info "Running TSS namespace migration..." cd src if python3 migrate_to_tss_namespace.py; then print_status "TSS namespace migration completed successfully" else print_error "TSS namespace migration failed" exit 1 fi # Start the application print_info "Starting Tech Stack Selector application..." python3 main_migrated.py