Files
roa2web-service-auto/start-backend.sh
Marius Mutu c5e051ad80 feat: Migrate to ultrathin monolith architecture
Consolidate 3 separate applications (reports-app, data-entry-app, telegram-bot) into a unified
architecture with single backend and frontend:

Backend Changes:
- Unified FastAPI backend at backend/ with modular structure
- Modules: reports, data_entry, telegram in backend/modules/
- Centralized config.py and main.py with all routers registered
- Single worker mode (--workers 1) for Telegram bot compatibility
- Shared Oracle connection pool and JWT authentication
- Unified requirements.txt and environment configuration

Frontend Changes:
- Single Vue.js SPA with module-based routing
- Unified frontend at src/ with modules in src/modules/{reports,data-entry}/
- Shared components and stores in src/shared/
- Error boundaries for module isolation
- Dual API proxy in Vite for module communication

Infrastructure:
- New unified startup scripts: start-prod.sh, start-test.sh, start-backend.sh
- Environment templates: .env.dev.example, .env.test.example, .env.prod.example
- Updated deployment scripts for Windows IIS
- Simplified SSH tunnel management

Documentation:
- Comprehensive CLAUDE.md with architecture overview
- Module-specific docs in docs/{data-entry,telegram}/
- Architecture decision records in docs/ARCHITECTURE-DECISIONS.md
- Deployment guides consolidated in deployment/windows/docs/

This migration reduces complexity, improves maintainability, and enables easier
deployment while maintaining all existing functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-29 23:48:14 +02:00

232 lines
6.0 KiB
Bash

#!/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
LOG_FILE="/tmp/unified-backend.log"
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"
# Activate virtual environment and start uvicorn
nohup bash -c "source venv/bin/activate && uvicorn main:app --host 0.0.0.0 --port $PORT --reload" > "$LOG_FILE" 2>&1 &
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 $?