File size: 2,857 Bytes
9e89154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env bash
# Start local dev stack: Flask API + Next.js (default) or CRA.
#
# Usage:
#   chmod +x scripts/dev.sh
#   ./scripts/dev.sh              # API (background) + Next on :3000
#   ./scripts/dev.sh --cra        # API + CRA React (:3000)
#   ./scripts/dev.sh --api-only   # Flask only (PORT or 5000)
#   ./scripts/dev.sh --next-only  # Next only — run API separately
#
# Env:
#   PORT          API port (default 5000) — same as api.py
#   NEXT_PORT     Next / CRA dev port (default 3000)
#   VENV          Path to venv (default .venv in repo root)

set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"

MODE="next"
API_ONLY=false
UI_ONLY=false

for arg in "$@"; do
  case "$arg" in
    --cra) MODE="cra" ;;
    --next) MODE="next" ;;
    --api-only) API_ONLY=true ;;
    --ui-only|--next-only) UI_ONLY=true ;;
    -h|--help)
      sed -n '2,18p' "$0" | cat
      exit 0
      ;;
    *)
      echo "Unknown option: $arg" >&2
      exit 1
      ;;
  esac
done

VENV="${VENV:-$ROOT/.venv}"
if [[ -f "$VENV/bin/activate" ]]; then
  # shellcheck source=/dev/null
  source "$VENV/bin/activate"
fi

API_PORT="${PORT:-5000}"
NEXT_PORT="${NEXT_PORT:-3000}"
export PORT="$API_PORT"

API_PID=""
cleanup() {
  if [[ -n "${API_PID}" ]] && kill -0 "$API_PID" 2>/dev/null; then
    echo ""
    echo "[dev] Stopping API (pid $API_PID)..."
    kill "$API_PID" 2>/dev/null || true
    wait "$API_PID" 2>/dev/null || true
  fi
}
trap cleanup EXIT INT TERM

if [[ "$UI_ONLY" != true ]]; then
  echo "[dev] Starting Flask API on 0.0.0.0:${API_PORT}..."
  python api.py &
  API_PID=$!

  echo "[dev] Waiting for /api/health..."
  for _ in $(seq 1 45); do
    if curl -sf "http://127.0.0.1:${API_PORT}/api/health" >/dev/null 2>&1; then
      echo "[dev] API is up."
      break
    fi
    sleep 1
  done
  if ! curl -sf "http://127.0.0.1:${API_PORT}/api/health" >/dev/null 2>&1; then
    echo "[dev] WARNING: API did not respond on ${API_PORT}. Check logs above." >&2
  fi
fi

if [[ "$API_ONLY" == true ]]; then
  echo "[dev] API-only mode; press Ctrl+C to stop."
  wait "${API_PID:-}"
  exit 0
fi

if [[ "$MODE" == "next" ]]; then
  if [[ ! -d "$ROOT/web/node_modules" ]]; then
    echo "[dev] Installing web dependencies (npm install)..."
    (cd "$ROOT/web" && npm install)
  fi
  echo "[dev] Starting Next.js on http://127.0.0.1:${NEXT_PORT} (rewrites /api → :${API_PORT})"
  # No exec: keeps shell alive so EXIT trap stops the API when you quit Next
  (cd "$ROOT/web" && npx next dev -p "${NEXT_PORT}")
else
  if [[ ! -d "$ROOT/frontend/node_modules" ]]; then
    echo "[dev] Installing frontend dependencies (npm install)..."
    (cd "$ROOT/frontend" && npm install)
  fi
  echo "[dev] Starting CRA on http://127.0.0.1:${NEXT_PORT} (proxy → :${API_PORT})"
  (cd "$ROOT/frontend" && env PORT="${NEXT_PORT}" npm start)
fi