#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ENV_FILE="$SCRIPT_DIR/.env" ENV_EXAMPLE_FILE="$SCRIPT_DIR/.env.example" MODE="${1:-all}" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; } if [ ! -f "$ENV_FILE" ]; then if [ -f "$ENV_EXAMPLE_FILE" ]; then warn ".env not found. Creating it from .env.example" cp "$ENV_EXAMPLE_FILE" "$ENV_FILE" else error ".env and .env.example are both missing." fi fi set -a . "$ENV_FILE" set +a SERVER_STARTUP_TIMEOUT="${SERVER_STARTUP_TIMEOUT:-300}" SETUP_COMPLETED="${SETUP_COMPLETED:-false}" prepare_web() { info "Preparing web dependencies..." ( cd "$SCRIPT_DIR/web" ./start.sh deps ) } prepare_server() { info "Preparing server dependencies..." ( cd "$SCRIPT_DIR/server" ./start.sh deps ) } start_web() { prepare_web cd "$SCRIPT_DIR/web" exec ./start.sh start } start_server() { prepare_server cd "$SCRIPT_DIR/server" exec ./start.sh start } start_setup_web() { warn "Initial setup is not completed. Starting web only." warn "Finish the setup form first. After setup is saved, run ./start.sh again to launch FastAPI as well." prepare_web cd "$SCRIPT_DIR/web" exec ./start.sh start } start_all() { local server_pid="" prepare_web prepare_server cleanup() { if [ -n "$server_pid" ] && kill -0 "$server_pid" 2>/dev/null; then warn "Stopping FastAPI server..." kill "$server_pid" 2>/dev/null || true wait "$server_pid" 2>/dev/null || true fi } trap cleanup EXIT INT TERM info "Starting FastAPI server..." ( cd "$SCRIPT_DIR/server" ./start.sh start ) & server_pid=$! wait_for_server() { local base_url="http://${SERVER_HOST:-127.0.0.1}:${SERVER_PORT:-8000}${API_V1_PREFIX:-/api/v1}/bootstrap" local attempt=1 local max_attempts="$SERVER_STARTUP_TIMEOUT" if ! command -v curl >/dev/null 2>&1; then warn "curl not found, skipping backend readiness check." return 0 fi info "Waiting for FastAPI bootstrap endpoint..." while [ "$attempt" -le "$max_attempts" ]; do if ! kill -0 "$server_pid" 2>/dev/null; then wait "$server_pid" 2>/dev/null || true error "FastAPI process exited before becoming ready. Run ./server/start.sh start directly to inspect the backend error." fi if curl --silent --fail "$base_url" >/dev/null 2>&1; then info "FastAPI bootstrap endpoint is ready." return 0 fi if [ $((attempt % 15)) -eq 0 ]; then warn "FastAPI is still starting. First run may take longer while .venv and dependencies are prepared." fi sleep 1 attempt=$((attempt + 1)) done error "FastAPI did not become ready within ${SERVER_STARTUP_TIMEOUT}s: $base_url" } wait_for_server info "Starting web frontend..." cd "$SCRIPT_DIR/web" ./start.sh start } case "$MODE" in web) start_web ;; server) start_server ;; all) if [ "$SETUP_COMPLETED" = "true" ]; then start_all else start_setup_web fi ;; *) error "Unknown mode: $MODE. Use one of: web, server, all" ;; esac