Files
roa2web-service-auto/start-dev.sh
Marius Mutu 6b13ffa183 Initial commit: ROA2WEB - FastAPI + Vue.js + Telegram Bot
Modern ERP Reports Application with microservices architecture

Tech Stack:
- Backend: FastAPI + python-oracledb (Oracle DB integration)
- Frontend: Vue.js 3 + PrimeVue + Vite
- Telegram Bot: python-telegram-bot + SQLite
- Infrastructure: Shared database pool, JWT authentication, SSH tunnel

Features:
- FastAPI backend with async Oracle connection pool
- Vue.js 3 responsive frontend with PrimeVue components
- Telegram bot alternative interface
- Microservices architecture with shared components
- Complete deployment support (Linux Docker + Windows IIS)
- Comprehensive testing (Playwright E2E + pytest)

Repository Structure:
- reports-app/ - Main application (backend, frontend, telegram-bot)
- shared/ - Shared components (database pool, auth, utils)
- deployment/ - Deployment scripts (Linux & Windows)
- docs/ - Project documentation
- security/ - Security scanning and git hooks
2025-10-25 14:55:08 +03:00

738 lines
22 KiB
Bash

#!/bin/bash
# ROA2WEB Development Starter Script
# Starts SSH tunnel, backend, and frontend services
set -e # Exit on any error
# 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 messages
print_message() {
echo -e "${BLUE}[ROA2WEB]${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 port is in use
check_port() {
local port=$1
if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then
return 0
else
return 1
fi
}
# Function to cleanup processes on exit
cleanup() {
print_message "Stopping services..."
# Kill background processes
if [[ -n $BACKEND_PID ]]; then
kill $BACKEND_PID 2>/dev/null || true
fi
if [[ -n $FRONTEND_PID ]]; then
kill $FRONTEND_PID 2>/dev/null || true
fi
if [[ -n $TELEGRAM_BOT_PID ]]; then
kill $TELEGRAM_BOT_PID 2>/dev/null || true
fi
# Stop SSH tunnel - try the same paths as in stop_services
SSH_TUNNEL_PATHS=(
"/mnt/d/PROIECTE/roa-flask/roa2web/ssh_tunnel.sh"
"/mnt/e/proiecte/roa2web/roa2web/ssh_tunnel.sh"
"./ssh_tunnel.sh"
)
for tunnel_path in "${SSH_TUNNEL_PATHS[@]}"; do
if [[ -f "$tunnel_path" ]]; then
$tunnel_path stop
break
fi
done
print_success "All services stopped."
exit 0
}
# Function to stop all services
stop_services() {
print_message "Stopping all ROA2WEB services..."
# Stop processes running on specific ports
print_message "Checking for backend processes on port 8001..."
if check_port 8001; then
BACKEND_PIDS=$(lsof -ti:8001)
if [[ -n $BACKEND_PIDS ]]; then
echo $BACKEND_PIDS | xargs kill -TERM 2>/dev/null || true
sleep 2
echo $BACKEND_PIDS | xargs kill -KILL 2>/dev/null || true
print_success "Backend processes stopped"
fi
else
print_message "No backend processes found on port 8001"
fi
print_message "Checking for frontend processes on common ports..."
FRONTEND_STOPPED=false
for port in 3000 3001 3002 3003 3004 3005; do
if check_port $port; then
FRONTEND_PIDS=$(lsof -ti:$port)
if [[ -n $FRONTEND_PIDS ]]; then
# Kill the main process listening on port
echo $FRONTEND_PIDS | xargs kill -TERM 2>/dev/null || true
sleep 2
echo $FRONTEND_PIDS | xargs kill -KILL 2>/dev/null || true
# Also kill parent npm processes that might have spawned vite
for pid in $FRONTEND_PIDS; do
PARENT_PID=$(ps -o ppid= -p $pid 2>/dev/null | tr -d ' ')
if [[ -n $PARENT_PID ]] && [[ $PARENT_PID != "1" ]]; then
PARENT_CMD=$(ps -o comm= -p $PARENT_PID 2>/dev/null)
if [[ $PARENT_CMD == "npm" ]] || [[ $PARENT_CMD == "node" ]]; then
kill -TERM $PARENT_PID 2>/dev/null || true
sleep 1
kill -KILL $PARENT_PID 2>/dev/null || true
fi
fi
done
print_success "Frontend processes stopped on port $port"
FRONTEND_STOPPED=true
fi
fi
done
if [[ $FRONTEND_STOPPED == false ]]; then
print_message "No frontend processes found on common ports"
fi
# Stop Telegram Bot
print_message "Checking for Telegram bot processes on port 8002..."
if check_port 8002; then
TELEGRAM_BOT_PIDS=$(lsof -ti:8002)
if [[ -n $TELEGRAM_BOT_PIDS ]]; then
echo $TELEGRAM_BOT_PIDS | xargs kill -TERM 2>/dev/null || true
sleep 2
echo $TELEGRAM_BOT_PIDS | xargs kill -KILL 2>/dev/null || true
print_success "Telegram bot processes stopped"
fi
else
print_message "No Telegram bot processes found on port 8002"
fi
# Stop SSH tunnel
print_message "Stopping SSH tunnel..."
# Try both possible paths for SSH tunnel
SSH_TUNNEL_PATHS=(
"/mnt/d/PROIECTE/roa-flask/roa2web/ssh_tunnel.sh"
"/mnt/d/proiecte/roa2web/roa2web/ssh_tunnel.sh"
"./ssh_tunnel.sh"
)
SSH_TUNNEL_STOPPED=false
for tunnel_path in "${SSH_TUNNEL_PATHS[@]}"; do
if [[ -f "$tunnel_path" ]]; then
if $tunnel_path stop; then
print_success "SSH tunnel stopped"
SSH_TUNNEL_STOPPED=true
break
fi
fi
done
if [[ $SSH_TUNNEL_STOPPED == false ]]; then
print_warning "SSH tunnel script not found or may not have been running"
fi
# Kill any remaining processes related to ROA2WEB
print_message "Cleaning up any remaining ROA2WEB processes..."
# More comprehensive cleanup patterns
pkill -f "uvicorn.*roa2web" 2>/dev/null || true
pkill -f "uvicorn.*app.main:app" 2>/dev/null || true
pkill -f "node.*roa.*frontend" 2>/dev/null || true
pkill -f "vite.*roa" 2>/dev/null || true
pkill -f "npm.*run.*dev.*roa" 2>/dev/null || true
pkill -f "python.*telegram-bot" 2>/dev/null || true
pkill -f "python.*app.main" 2>/dev/null || true
# Kill processes in the specific directory structure
pkill -f "/mnt/e/proiecte/roa2web/roa2web/reports-app/frontend" 2>/dev/null || true
pkill -f "/mnt/e/proiecte/roa2web/roa2web/reports-app/backend" 2>/dev/null || true
pkill -f "/mnt/e/proiecte/roa2web/roa2web/reports-app/telegram-bot" 2>/dev/null || true
print_success "✅ All ROA2WEB services have been stopped!"
exit 0
}
# Function to stop individual service
stop_service() {
local service=$1
case $service in
tunnel)
print_message "Stopping SSH tunnel..."
SSH_TUNNEL_PATHS=(
"/mnt/d/PROIECTE/roa-flask/roa2web/ssh_tunnel.sh"
"/mnt/e/proiecte/roa2web/roa2web/ssh_tunnel.sh"
"./ssh_tunnel.sh"
)
for tunnel_path in "${SSH_TUNNEL_PATHS[@]}"; do
if [[ -f "$tunnel_path" ]]; then
$tunnel_path stop
print_success "SSH tunnel stopped"
return 0
fi
done
print_warning "SSH tunnel script not found"
;;
backend)
print_message "Stopping backend..."
if check_port 8001; then
BACKEND_PIDS=$(lsof -ti:8001)
if [[ -n $BACKEND_PIDS ]]; then
echo $BACKEND_PIDS | xargs kill -TERM 2>/dev/null || true
sleep 2
echo $BACKEND_PIDS | xargs kill -KILL 2>/dev/null || true
print_success "Backend stopped"
else
print_message "Backend not running"
fi
else
print_message "Backend not running on port 8001"
fi
;;
frontend)
print_message "Stopping frontend..."
for port in 3000 3001 3002 3003 3004 3005; do
if check_port $port; then
FRONTEND_PIDS=$(lsof -ti:$port)
if [[ -n $FRONTEND_PIDS ]]; then
echo $FRONTEND_PIDS | xargs kill -TERM 2>/dev/null || true
sleep 2
echo $FRONTEND_PIDS | xargs kill -KILL 2>/dev/null || true
print_success "Frontend stopped on port $port"
return 0
fi
fi
done
print_message "Frontend not running"
;;
telegram|bot)
print_message "Stopping Telegram bot..."
if check_port 8002; then
TELEGRAM_BOT_PIDS=$(lsof -ti:8002)
if [[ -n $TELEGRAM_BOT_PIDS ]]; then
echo $TELEGRAM_BOT_PIDS | xargs kill -TERM 2>/dev/null || true
sleep 2
echo $TELEGRAM_BOT_PIDS | xargs kill -KILL 2>/dev/null || true
print_success "Telegram bot stopped"
else
print_message "Telegram bot not running"
fi
else
print_message "Telegram bot not running on port 8002"
fi
;;
*)
print_error "Unknown service: $service"
print_message "Valid services: tunnel, backend, frontend, telegram"
exit 1
;;
esac
}
# Function to start individual service
start_service() {
local service=$1
case $service in
tunnel)
print_message "Starting SSH tunnel..."
if ./ssh_tunnel.sh start; then
print_success "SSH Tunnel started successfully"
else
print_error "Failed to start SSH tunnel"
exit 1
fi
;;
backend)
print_message "Starting backend..."
if check_port 8001; then
print_warning "Port 8001 already in use. Backend might be running."
return 1
fi
cd reports-app/backend/
if [ ! -d "venv" ]; then
print_message "Creating Python virtual environment..."
python3 -m venv venv
fi
source venv/bin/activate
if ! python -c "import fastapi, uvicorn" 2>/dev/null; then
print_message "Installing backend dependencies..."
pip install -r requirements.txt
fi
print_message "Starting uvicorn server..."
nohup uvicorn app.main:app --reload --host 0.0.0.0 --port 8001 > /tmp/roa2web_backend.log 2>&1 &
sleep 2
for i in {1..10}; do
if check_port 8001; then
print_success "Backend started on http://localhost:8001"
cd - > /dev/null
return 0
fi
sleep 1
done
print_error "Backend failed to start"
cd - > /dev/null
exit 1
;;
frontend)
print_message "Starting frontend..."
for port in 3000 3001 3002 3003 3004 3005; do
if check_port $port; then
print_warning "Port $port already in use"
fi
done
cd reports-app/frontend/
# Check node_modules
NEED_REINSTALL=false
if [ ! -d "node_modules" ] || [ ! -f "node_modules/.bin/vite" ] || [ -f "node_modules/.bin/vite.cmd" ]; then
NEED_REINSTALL=true
fi
if [ "$NEED_REINSTALL" = true ]; then
print_message "Reinstalling frontend dependencies for WSL..."
rm -rf node_modules package-lock.json
npm install
fi
print_message "Starting Vite development server..."
nohup npm run dev > /tmp/roa2web_frontend.log 2>&1 &
sleep 3
FRONTEND_PORT=""
for i in {1..10}; do
for port in 3000 3001 3002 3003 3004 3005; do
if check_port $port; then
FRONTEND_PORT=$port
break 2
fi
done
sleep 1
done
if [[ -n $FRONTEND_PORT ]]; then
print_success "Frontend started on http://localhost:$FRONTEND_PORT"
cd - > /dev/null
return 0
else
print_error "Frontend failed to start"
cat /tmp/roa2web_frontend.log
cd - > /dev/null
exit 1
fi
;;
telegram|bot)
print_message "Starting Telegram bot..."
if check_port 8002; then
print_warning "Port 8002 already in use. Telegram bot might be running."
return 1
fi
cd reports-app/telegram-bot/
if [ ! -f ".env" ]; then
print_error "Telegram bot .env file not found!"
print_message "Please create .env file from .env.example"
cd - > /dev/null
exit 1
fi
if [ ! -d "venv" ]; then
print_message "Creating Python virtual environment for Telegram bot..."
python3 -m venv venv
fi
source venv/bin/activate
if ! python -c "import telegram" 2>/dev/null; then
print_message "Installing Telegram bot dependencies..."
pip install -r requirements.txt
fi
print_message "Starting Telegram bot..."
nohup python -m app.main > /tmp/roa2web_telegram.log 2>&1 &
sleep 3
for i in {1..10}; do
if check_port 8002; then
print_success "Telegram bot started (Internal API: http://localhost:8002)"
cd - > /dev/null
return 0
fi
sleep 1
done
print_error "Telegram bot failed to start"
cat /tmp/roa2web_telegram.log
cd - > /dev/null
exit 1
;;
*)
print_error "Unknown service: $service"
print_message "Valid services: tunnel, backend, frontend, telegram"
exit 1
;;
esac
}
# Function to restart individual service
restart_service() {
local service=$1
print_message "Restarting $service..."
stop_service $service
sleep 2
start_service $service
print_success "$service restarted successfully"
}
# Function to show service status
show_status() {
echo -e "${BLUE}ROA2WEB Services Status${NC}"
echo
# Check SSH tunnel
if pgrep -f "ssh.*1526.*1521" > /dev/null; then
echo -e " SSH Tunnel: ${GREEN}✓ Running${NC}"
else
echo -e " SSH Tunnel: ${RED}✗ Stopped${NC}"
fi
# Check backend
if check_port 8001; then
echo -e " Backend: ${GREEN}✓ Running${NC} (http://localhost:8001)"
else
echo -e " Backend: ${RED}✗ Stopped${NC}"
fi
# Check frontend
FRONTEND_PORT=""
for port in 3000 3001 3002 3003 3004 3005; do
if check_port $port; then
FRONTEND_PORT=$port
break
fi
done
if [[ -n $FRONTEND_PORT ]]; then
echo -e " Frontend: ${GREEN}✓ Running${NC} (http://localhost:$FRONTEND_PORT)"
else
echo -e " Frontend: ${RED}✗ Stopped${NC}"
fi
# Check Telegram bot
if check_port 8002; then
echo -e " Telegram Bot: ${GREEN}✓ Running${NC} (http://localhost:8002)"
else
echo -e " Telegram Bot: ${RED}✗ Stopped${NC}"
fi
echo
}
# Function to show usage
show_usage() {
echo -e "${BLUE}ROA2WEB Development Script${NC}"
echo
echo "Usage:"
echo " ./start-dev.sh Start all services"
echo " ./start-dev.sh start Start all services"
echo " ./start-dev.sh stop Stop all services"
echo " ./start-dev.sh status Show services status"
echo
echo " ./start-dev.sh restart <service> Restart specific service"
echo " ./start-dev.sh start <service> Start specific service"
echo " ./start-dev.sh stop <service> Stop specific service"
echo
echo "Services:"
echo " tunnel - SSH Tunnel (Oracle DB connection)"
echo " backend - FastAPI (port 8001)"
echo " frontend - Vue.js/Vite (port 3000-3005)"
echo " telegram - Telegram Bot (port 8002)"
echo
echo "Examples:"
echo " ./start-dev.sh restart telegram Restart only Telegram bot"
echo " ./start-dev.sh stop backend Stop only backend"
echo " ./start-dev.sh start frontend Start only frontend"
echo
}
# Check command line arguments
case $1 in
stop)
if [[ -n $2 ]]; then
# Stop specific service
stop_service $2
exit 0
else
# Stop all services
stop_services
fi
;;
start)
if [[ -n $2 ]]; then
# Start specific service
start_service $2
exit 0
else
# Continue with normal start process (start all)
true
fi
;;
restart)
if [[ -z $2 ]]; then
print_error "Please specify which service to restart"
echo
show_usage
exit 1
fi
restart_service $2
exit 0
;;
status)
show_status
exit 0
;;
help|--help|-h)
show_usage
exit 0
;;
"")
# No parameter - start all services
true
;;
*)
print_error "Unknown parameter: $1"
echo
show_usage
exit 1
;;
esac
# Set up signal handlers
trap cleanup SIGINT SIGTERM
print_message "Starting ROA2WEB Development Environment..."
echo
# Step 1: Start SSH Tunnel
print_message "1. Starting SSH Tunnel..."
if ./ssh_tunnel.sh start; then
print_success "SSH Tunnel started successfully"
else
print_error "Failed to start SSH tunnel"
exit 1
fi
# Wait a moment for tunnel to establish
sleep 2
# Step 2: Start Backend
print_message "2. Starting Backend (FastAPI)..."
# Check if backend port is already in use
if check_port 8001; then
print_warning "Port 8001 is already in use. Backend might already be running."
read -p "Continue anyway? (y/n): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
cleanup
fi
fi
cd reports-app/backend/
# Check if virtual environment exists
if [ ! -d "venv" ]; then
print_message "Creating Python virtual environment..."
python3 -m venv venv
fi
# Activate virtual environment
source venv/bin/activate
# Check if dependencies are installed in virtual environment
if ! python -c "import fastapi, uvicorn" 2>/dev/null; then
print_message "Installing backend dependencies in virtual environment..."
pip install -r requirements.txt
fi
# Start backend in background
print_message "Starting uvicorn server..."
uvicorn app.main:app --reload --host 0.0.0.0 --port 8001 &
BACKEND_PID=$!
# Wait for backend to start and check multiple times
sleep 2
for i in {1..10}; do
if check_port 8001; then
print_success "Backend started successfully on http://localhost:8001"
break
fi
if [ $i -eq 10 ]; then
print_error "Backend failed to start after 10 attempts"
cleanup
fi
sleep 1
done
# Step 3: Start Frontend
print_message "3. Starting Frontend (Vue.js)..."
cd ../frontend/
# Check if node_modules exists and is valid for WSL
NEED_REINSTALL=false
if [ ! -d "node_modules" ]; then
print_message "node_modules not found"
NEED_REINSTALL=true
elif [ ! -f "node_modules/.bin/vite" ]; then
print_warning "vite not found (possibly Windows node_modules detected)"
NEED_REINSTALL=true
elif [ -f "node_modules/.bin/vite.cmd" ]; then
print_warning "Windows node_modules detected (contains .cmd files)"
NEED_REINSTALL=true
fi
if [ "$NEED_REINSTALL" = true ]; then
print_message "Reinstalling frontend dependencies for WSL..."
print_message "This happens after Windows deployment builds. Please wait..."
rm -rf node_modules package-lock.json
npm install
print_success "Frontend dependencies installed for WSL"
fi
# Start frontend in background and capture output
print_message "Starting Vite development server..."
npm run dev > /tmp/vite_output.log 2>&1 &
FRONTEND_PID=$!
# Wait for frontend to start and detect the actual port
sleep 3
FRONTEND_PORT=""
for i in {1..10}; do
# Check for common Vite ports
for port in 3000 3001 3002 3003 3004 3005; do
if check_port $port; then
FRONTEND_PORT=$port
break 2
fi
done
sleep 1
done
# Check if frontend is running
if [[ -n $FRONTEND_PORT ]]; then
print_success "Frontend started successfully on http://localhost:$FRONTEND_PORT"
else
print_error "Frontend failed to start"
cat /tmp/vite_output.log
cleanup
fi
# Step 4: Start Telegram Bot
print_message "4. Starting Telegram Bot..."
# Check if telegram bot port is already in use
if check_port 8002; then
print_warning "Port 8002 is already in use. Telegram bot might already be running."
read -p "Continue anyway? (y/n): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
cleanup
fi
fi
cd ../telegram-bot/
# Check if .env file exists
if [ ! -f ".env" ]; then
print_error "Telegram bot .env file not found!"
print_message "Please create .env file from .env.example and configure TELEGRAM_BOT_TOKEN"
cleanup
fi
# Check if virtual environment exists
if [ ! -d "venv" ]; then
print_message "Creating Python virtual environment for Telegram bot..."
python3 -m venv venv
fi
# Activate virtual environment
source venv/bin/activate
# Check if dependencies are installed
if ! python -c "import telegram" 2>/dev/null; then
print_message "Installing Telegram bot dependencies in virtual environment..."
pip install -r requirements.txt
fi
# Start Telegram bot in background
print_message "Starting Telegram bot..."
python -m app.main > /tmp/telegram_bot_output.log 2>&1 &
TELEGRAM_BOT_PID=$!
# Wait for Telegram bot to start
sleep 3
for i in {1..10}; do
if check_port 8002; then
print_success "Telegram bot started successfully (Internal API on http://localhost:8002)"
break
fi
if [ $i -eq 10 ]; then
print_error "Telegram bot failed to start after 10 attempts"
print_message "Check log at /tmp/telegram_bot_output.log for details"
cat /tmp/telegram_bot_output.log
cleanup
fi
sleep 1
done
# Summary
echo
print_success "🚀 ROA2WEB Development Environment is now running!"
echo
echo -e "${BLUE}Services:${NC}"
echo " • SSH Tunnel: Active (Oracle DB connection)"
echo " • Backend: http://localhost:8001"
echo " • Frontend: http://localhost:${FRONTEND_PORT:-3000}"
echo " • Telegram Bot: http://localhost:8002 (Internal API)"
echo " • API Docs: http://localhost:8001/docs"
echo
echo -e "${YELLOW}Press Ctrl+C to stop all services${NC}"
echo
# Keep script running and wait for user interrupt
wait