Architecture cleanup after migration to ultrathin monolith: - Remove INTERNAL_API_PORT from .env files (was port 8002) - Clean up bot_main.py: remove uvicorn, Thread, run_internal_api() - Update validate.md to check /api/telegram/health instead of port 8002 - Add deprecation notices to old Windows deployment docs - Update docs/telegram/README.md with architecture note The Telegram internal API is now served at /api/telegram/internal/* on the main backend port (8000/8001) instead of separate port 8002. Also includes: menu updates, ServerLogsView improvements, script fixes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
243 lines
6.4 KiB
Bash
Executable File
243 lines
6.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# Unified Backend Service Control Script for ROA2WEB
|
|
# Manages the unified FastAPI backend on port 8000 (Reports + Data Entry + Telegram)
|
|
|
|
# Script directory
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
ROOT_DIR="$SCRIPT_DIR"
|
|
|
|
# Source helper functions
|
|
source "$SCRIPT_DIR/scripts/service-helpers.sh"
|
|
|
|
# Service configuration
|
|
SERVICE_NAME="Unified Backend"
|
|
PORT=8000
|
|
LOGS_DIR="$ROOT_DIR/logs"
|
|
LOG_FILE_STDOUT="$LOGS_DIR/backend-stdout.log"
|
|
LOG_FILE_STDERR="$LOGS_DIR/backend-stderr.log"
|
|
LOG_FILE="$LOG_FILE_STDERR" # Default for status/logs commands
|
|
BACKEND_DIR="$ROOT_DIR/backend"
|
|
VENV_DIR="$BACKEND_DIR/venv"
|
|
ENV_FILE="$BACKEND_DIR/.env"
|
|
|
|
# Function to start backend
|
|
start_backend() {
|
|
print_header "Starting $SERVICE_NAME"
|
|
|
|
# Check if port is already in use
|
|
if ! check_port_available $PORT "$SERVICE_NAME"; then
|
|
print_warning "$SERVICE_NAME may already be running"
|
|
print_info "Use './start-backend.sh status' to check or './start-backend.sh stop' to stop it"
|
|
return 1
|
|
fi
|
|
|
|
# Check backend directory
|
|
if [ ! -d "$BACKEND_DIR" ]; then
|
|
print_error "Backend directory not found: $BACKEND_DIR"
|
|
return 1
|
|
fi
|
|
|
|
# Check virtual environment
|
|
if [ ! -d "$VENV_DIR" ]; then
|
|
print_info "Creating virtual environment..."
|
|
cd "$BACKEND_DIR"
|
|
python3 -m venv venv
|
|
source venv/bin/activate
|
|
print_info "Installing dependencies (this may take 3-5 minutes for ML packages)..."
|
|
pip install -r requirements.txt
|
|
cd "$ROOT_DIR"
|
|
fi
|
|
|
|
# Check .env file
|
|
if [ ! -f "$ENV_FILE" ]; then
|
|
print_warning ".env file not found: $ENV_FILE"
|
|
print_info "Using backend/.env.example as template"
|
|
if [ -f "$BACKEND_DIR/.env.example" ]; then
|
|
cp "$BACKEND_DIR/.env.example" "$ENV_FILE"
|
|
print_info "Created $ENV_FILE - please configure it"
|
|
fi
|
|
fi
|
|
|
|
# Start backend
|
|
print_info "Starting unified backend on port $PORT..."
|
|
cd "$BACKEND_DIR"
|
|
|
|
# Create logs directory if it doesn't exist
|
|
mkdir -p "$LOGS_DIR"
|
|
|
|
# Clear old log files
|
|
> "$LOG_FILE_STDOUT"
|
|
> "$LOG_FILE_STDERR"
|
|
|
|
# Activate virtual environment and start uvicorn
|
|
# stdout → backend-stdout.log, stderr → backend-stderr.log
|
|
nohup bash -c "source venv/bin/activate && uvicorn main:app --host 0.0.0.0 --port $PORT --reload" > "$LOG_FILE_STDOUT" 2> "$LOG_FILE_STDERR" &
|
|
|
|
BACKEND_PID=$!
|
|
cd "$ROOT_DIR"
|
|
|
|
# Wait for backend to start
|
|
print_info "Waiting for backend to initialize (Oracle pool + cache + databases)..."
|
|
MAX_WAIT=30
|
|
ELAPSED=0
|
|
while [ $ELAPSED -lt $MAX_WAIT ]; do
|
|
if check_port_in_use $PORT; then
|
|
print_success "$SERVICE_NAME started successfully on http://localhost:$PORT"
|
|
print_info "Process ID: $BACKEND_PID"
|
|
print_info "Log file: $LOG_FILE"
|
|
print_info "API Documentation: http://localhost:$PORT/docs"
|
|
print_info "Health Check: http://localhost:$PORT/health"
|
|
echo
|
|
print_info "Modules:"
|
|
echo " • Reports API: http://localhost:$PORT/api/reports/*"
|
|
echo " • Data Entry API: http://localhost:$PORT/api/data-entry/*"
|
|
echo " • Telegram API: http://localhost:$PORT/api/telegram/*"
|
|
echo " • Auth API: http://localhost:$PORT/api/auth/*"
|
|
|
|
# Check health endpoint
|
|
sleep 2
|
|
if command -v curl &> /dev/null; then
|
|
print_info "Checking health endpoint..."
|
|
curl -s http://localhost:$PORT/health | python3 -m json.tool || echo "(health check pending)"
|
|
fi
|
|
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
ELAPSED=$((ELAPSED + 1))
|
|
if [ $((ELAPSED % 5)) -eq 0 ]; then
|
|
print_info "Still waiting... ($ELAPSED/${MAX_WAIT}s)"
|
|
fi
|
|
done
|
|
|
|
print_error "$SERVICE_NAME failed to start within ${MAX_WAIT}s"
|
|
print_info "Check log file: $LOG_FILE"
|
|
tail -n 20 "$LOG_FILE"
|
|
return 1
|
|
}
|
|
|
|
# Function to stop backend
|
|
stop_backend() {
|
|
print_header "Stopping $SERVICE_NAME"
|
|
|
|
if check_port_in_use $PORT; then
|
|
print_info "Stopping processes on port $PORT..."
|
|
|
|
# Get PIDs
|
|
PIDS=$(lsof -ti:$PORT)
|
|
|
|
if [ -n "$PIDS" ]; then
|
|
# Try graceful shutdown first
|
|
echo "$PIDS" | xargs kill -TERM 2>/dev/null || true
|
|
sleep 2
|
|
|
|
# Force kill if still running
|
|
if check_port_in_use $PORT; then
|
|
print_warning "Graceful shutdown failed, forcing..."
|
|
echo "$PIDS" | xargs kill -KILL 2>/dev/null || true
|
|
sleep 1
|
|
fi
|
|
|
|
if check_port_in_use $PORT; then
|
|
print_error "Failed to stop $SERVICE_NAME"
|
|
return 1
|
|
else
|
|
print_success "$SERVICE_NAME stopped"
|
|
return 0
|
|
fi
|
|
fi
|
|
else
|
|
print_info "$SERVICE_NAME is not running"
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
# Function to restart backend
|
|
restart_backend() {
|
|
print_header "Restarting $SERVICE_NAME"
|
|
stop_backend
|
|
sleep 2
|
|
start_backend
|
|
}
|
|
|
|
# Function to check backend status
|
|
status_backend() {
|
|
print_header "$SERVICE_NAME Status"
|
|
|
|
if check_port_in_use $PORT; then
|
|
print_success "$SERVICE_NAME is running on port $PORT"
|
|
|
|
# Get process info
|
|
PIDS=$(lsof -ti:$PORT)
|
|
print_info "Process IDs: $PIDS"
|
|
|
|
# Show recent log
|
|
if [ -f "$LOG_FILE" ]; then
|
|
echo
|
|
print_info "Recent log entries (last 10 lines):"
|
|
tail -n 10 "$LOG_FILE"
|
|
fi
|
|
|
|
# Check health endpoint
|
|
echo
|
|
if command -v curl &> /dev/null; then
|
|
print_info "Health check:"
|
|
curl -s http://localhost:$PORT/health | python3 -m json.tool || echo "(health endpoint not responding)"
|
|
fi
|
|
|
|
return 0
|
|
else
|
|
print_warning "$SERVICE_NAME is not running"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to show logs
|
|
logs_backend() {
|
|
if [ ! -f "$LOG_FILE" ]; then
|
|
print_warning "Log file not found: $LOG_FILE"
|
|
return 1
|
|
fi
|
|
|
|
if [ "$1" = "follow" ] || [ "$1" = "-f" ]; then
|
|
print_info "Following $SERVICE_NAME logs (Ctrl+C to stop)..."
|
|
tail -f "$LOG_FILE"
|
|
else
|
|
print_info "Showing last 50 lines of $SERVICE_NAME logs:"
|
|
tail -n 50 "$LOG_FILE"
|
|
fi
|
|
}
|
|
|
|
# Main script logic
|
|
case "$1" in
|
|
start)
|
|
start_backend
|
|
;;
|
|
stop)
|
|
stop_backend
|
|
;;
|
|
restart)
|
|
restart_backend
|
|
;;
|
|
status)
|
|
status_backend
|
|
;;
|
|
logs)
|
|
logs_backend "$2"
|
|
;;
|
|
*)
|
|
echo "Usage: $0 {start|stop|restart|status|logs [follow]}"
|
|
echo
|
|
echo "Commands:"
|
|
echo " start - Start the unified backend (port $PORT)"
|
|
echo " stop - Stop the unified backend"
|
|
echo " restart - Restart the unified backend"
|
|
echo " status - Check if backend is running"
|
|
echo " logs - Show recent logs"
|
|
echo " logs follow - Follow logs in real-time"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
exit $?
|