api/start.sh
2025-11-14 14:47:19 +00:00

419 lines
12 KiB
Bash
Executable File

#!/bin/bash
# ClassroomCopilot Startup Script
# Usage: ./start.sh [start_mode]
# start_mode options: infra, demo-school, demo-users, gais-data, full, dev, prod
set -e
# Function to show help
show_help() {
echo "ClassroomCopilot Startup Script"
echo ""
echo "Usage: ./start.sh [start_mode] [--yes]"
echo ""
echo "Start modes:"
echo " infra - Setup infrastructure (Neo4j schema, calendar, Supabase buckets)"
echo " demo-school - Create demo school (KevlarAI)"
echo " demo-users - Create demo users"
echo " gais-data - Import GAIS data (Edubase, etc.)"
echo " full - Run full initialization (infra → demo-school → demo-users → gais-data)"
echo " nuke - 💥 NUKE Redis - Clear all queue data for fresh start"
echo " dev - Run development server with auto-reload"
echo " prod - Run production server (for Docker/containerized deployment)"
echo ""
echo "Examples:"
echo " ./start.sh # Run in dev mode (default)"
echo " ./start.sh infra # Setup infrastructure"
echo " ./start.sh demo-school # Create demo school"
echo " ./start.sh demo-users # Create demo users"
echo " ./start.sh gais-data # Import GAIS data"
echo " ./start.sh full # Run full initialization"
echo " ./start.sh full --yes # Run full initialization without prompts"
echo " ./start.sh nuke # 💥 NUKE Redis completely"
echo " ./start.sh dev # Run development server"
echo " ./start.sh prod # Run production server"
echo ""
echo "For more information, see README_STARTUP.md"
}
# Check for help flag
if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "help" ]]; then
show_help
exit 0
fi
# Default to dev mode if no argument provided
START_MODE=${1:-dev}
# Non-interactive flag
AUTO_YES=false
if [[ "$2" == "--yes" || "$2" == "-y" ]]; then
AUTO_YES=true
fi
# 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 "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Function to check if Python is available
check_python() {
if command -v python3 &> /dev/null; then
PYTHON_CMD="python3"
elif command -v python &> /dev/null; then
PYTHON_CMD="python"
else
print_error "Python is not installed or not in PATH"
exit 1
fi
print_status "Using Python: $PYTHON_CMD"
}
# Function to check if virtual environment is activated
check_venv() {
if [[ "$VIRTUAL_ENV" == "" ]]; then
print_warning "No virtual environment detected. Consider activating one for production use."
else
print_status "Virtual environment activated: $VIRTUAL_ENV"
fi
}
# Function to check environment variables
check_env() {
if [[ ! -f ".env" ]]; then
print_warning ".env file not found. Make sure environment variables are set."
else
print_status ".env file found"
fi
}
# Function to run infrastructure setup
run_infra() {
print_status "Running infrastructure setup mode..."
print_status "This will set up Neo4j schema, calendar structure, and Supabase buckets."
# Check if we should proceed
if [[ "$AUTO_YES" != true ]]; then
read -p "Do you want to continue with infrastructure setup? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_status "Infrastructure setup cancelled."
exit 0
fi
fi
print_status "Starting infrastructure setup process..."
$PYTHON_CMD main.py --mode infra
if [ $? -eq 0 ]; then
print_success "Infrastructure setup completed successfully!"
else
print_error "Infrastructure setup failed!"
exit 1
fi
}
# Function to run demo school creation
run_demo_school() {
print_status "Running demo school creation mode..."
print_status "This will create the KevlarAI demo school."
# Check if we should proceed
if [[ "$AUTO_YES" != true ]]; then
read -p "Do you want to continue with demo school creation? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_status "Demo school creation cancelled."
exit 0
fi
fi
print_status "Starting demo school creation process..."
$PYTHON_CMD main.py --mode demo-school
if [ $? -eq 0 ]; then
print_success "Demo school creation completed successfully!"
else
print_error "Demo school creation failed!"
exit 1
fi
}
# Function to run demo users creation
run_demo_users() {
print_status "Running demo users creation mode..."
print_status "This will create demo users for testing."
# Check if we should proceed
if [[ "$AUTO_YES" != true ]]; then
read -p "Do you want to continue with demo users creation? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_status "Demo users creation cancelled."
exit 0
fi
fi
print_status "Starting demo users creation process..."
$PYTHON_CMD main.py --mode demo-users
if [ $? -eq 0 ]; then
print_success "Demo users creation completed successfully!"
else
print_error "Demo users creation failed!"
exit 1
fi
}
# Function to run GAIS data import
run_gais_data() {
print_status "Running GAIS data import mode..."
print_status "This will import publicly available school databases (Edubase, etc.) into Neo4j."
# Check if we should proceed
if [[ "$AUTO_YES" != true ]]; then
read -p "Do you want to continue with GAIS data import? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_status "GAIS data import cancelled."
exit 0
fi
fi
print_status "Starting GAIS data import process..."
$PYTHON_CMD main.py --mode gais-data
if [ $? -eq 0 ]; then
print_success "GAIS data import completed successfully!"
else
print_error "GAIS data import failed!"
exit 1
fi
}
# Function to nuke Redis - clear all queue data
run_nuke() {
print_status "💥 NUKING Redis - Clear all queue data for fresh start..."
print_warning "This will DELETE ALL Redis data including queues, tasks, and metrics."
# Check if we should proceed
if [[ "$AUTO_YES" != true ]]; then
read -p "Are you SURE you want to nuke Redis? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_status "Redis nuke cancelled."
exit 0
fi
fi
print_status "Nuking Redis..."
# Kill any running servers first
print_status "Stopping any running API servers..."
pkill -f "python.*main\.py" 2>/dev/null || true
pkill -f "uvicorn" 2>/dev/null || true
sleep 2
# Clear Redis using new manager
$PYTHON_CMD -c "
from modules.redis_manager import get_redis_manager
import redis, os
try:
# Nuke all environments
total_cleared = 0
for env in ['dev', 'prod', 'test']:
try:
manager = get_redis_manager(env)
if manager.ensure_service_running() and manager.connect():
all_keys = manager.client.keys('*')
if all_keys:
manager.client.flushdb()
total_cleared += len(all_keys)
print(f'💥 NUKED {env.upper()}: Cleared {len(all_keys)} keys (db={manager.config.db})')
else:
print(f'✅ {env.upper()}: Already empty (db={manager.config.db})')
manager.client.close()
except Exception as e:
print(f'⚠️ Warning: Could not clear {env} environment: {e}')
print(f'💥 TOTAL NUKED: {total_cleared} keys across all environments')
print('🧹 Redis completely reset - ready for clean start!')
except Exception as e:
print(f'❌ Failed to connect to Redis: {e}')
exit(1)
"
if [ $? -eq 0 ]; then
print_success "💥 Redis NUKED successfully! Fresh slate ready."
else
print_error "Redis nuke failed!"
exit 1
fi
}
# Function to run full initialization (all steps in order)
run_full() {
print_status "Running full initialization (infra → demo-school → demo-users → gais-data)..."
# Single confirmation for the whole flow
if [[ "$AUTO_YES" != true ]]; then
read -p "Do you want to run the full initialization? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_status "Full initialization cancelled."
exit 0
fi
fi
# Run infra
run_infra || { print_error "Full init aborted during infra."; exit 1; }
# Run demo school
run_demo_school || { print_error "Full init aborted during demo-school."; exit 1; }
# Run demo users
run_demo_users || { print_error "Full init aborted during demo-users."; exit 1; }
# Run GAIS data import
run_gais_data || { print_error "Full init aborted during gais-data."; exit 1; }
print_success "Full initialization completed successfully!"
}
# Function to run development mode
run_dev() {
print_status "Running development mode..."
# Stop any running API servers
print_status "🛑 Stopping any running API servers..."
pkill -f "python.*main\.py" 2>/dev/null || true
pkill -f "uvicorn" 2>/dev/null || true
sleep 1
# Ensure Redis service is running and will auto-clear dev database
print_status "🔧 Ensuring Redis service is running for development..."
$PYTHON_CMD -c "
from modules.redis_manager import ensure_redis_running
if ensure_redis_running('dev'):
print('✅ Redis service ready for development (will auto-clear db=0)')
else:
print('❌ Failed to start Redis service')
exit(1)
" || { print_error "Redis setup failed"; exit 1; }
print_status "🎯 Development mode will use clean Redis database (db=0)..."
print_status "Starting uvicorn server with auto-reload..."
export BACKEND_DEV_MODE=true
$PYTHON_CMD main.py --mode dev
if [ $? -eq 0 ]; then
print_success "Development server stopped successfully!"
else
print_error "Development server failed!"
exit 1
fi
}
# Function to run production mode
run_prod() {
print_status "Running production mode..."
# Ensure Redis service is running with data recovery
print_status "🏰 Ensuring Redis service is running for production..."
$PYTHON_CMD -c "
from modules.redis_manager import ensure_redis_running
if ensure_redis_running('prod'):
print('✅ Redis service ready for production (db=1, with task recovery)')
else:
print('❌ Failed to start Redis service')
exit(1)
" || { print_error "Redis setup failed"; exit 1; }
print_status "Starting uvicorn server in production mode..."
export BACKEND_DEV_MODE=false
$PYTHON_CMD main.py --mode prod
if [ $? -eq 0 ]; then
print_success "Production server stopped successfully!"
else
print_error "Production server failed!"
exit 1
fi
}
# Main execution
main() {
print_status "ClassroomCopilot Startup Script"
print_status "Start mode: $START_MODE"
echo
# Pre-flight checks
check_python
check_venv
check_env
echo
# Execute based on start mode
case $START_MODE in
"infra")
run_infra
;;
"demo-school")
run_demo_school
;;
"demo-users")
run_demo_users
;;
"gais-data")
run_gais_data
;;
"full")
run_full
;;
"nuke")
run_nuke
;;
"dev")
run_dev
;;
"prod")
run_prod
;;
*)
print_error "Invalid start mode: $START_MODE"
print_status "Valid modes: infra, demo-school, demo-users, gais-data, nuke, dev, prod"
print_status "Usage: ./start.sh [start_mode]"
print_status "Use './start.sh --help' for more information"
exit 1
;;
esac
}
# Run main function
main "$@"