feat: add employee management, backend health check, and UI improvements
This commit is contained in:
133
start.sh
133
start.sh
@@ -1,6 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
export MSYS_NO_PATHCONV=1
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ENV_FILE="$SCRIPT_DIR/.env"
|
||||
ENV_EXAMPLE_FILE="$SCRIPT_DIR/.env.example"
|
||||
@@ -31,6 +33,69 @@ set +a
|
||||
SERVER_STARTUP_TIMEOUT="${SERVER_STARTUP_TIMEOUT:-300}"
|
||||
SETUP_COMPLETED="${SETUP_COMPLETED:-false}"
|
||||
|
||||
server_probe_url() {
|
||||
echo "http://${SERVER_HOST:-127.0.0.1}:${SERVER_PORT:-8000}${API_V1_PREFIX:-/api/v1}/health"
|
||||
}
|
||||
|
||||
server_smoke_url() {
|
||||
echo "http://${SERVER_HOST:-127.0.0.1}:${SERVER_PORT:-8000}${API_V1_PREFIX:-/api/v1}/employees/meta"
|
||||
}
|
||||
|
||||
server_probe_python() {
|
||||
if [ -x "$SCRIPT_DIR/server/.venv/Scripts/python.exe" ]; then
|
||||
echo "$SCRIPT_DIR/server/.venv/Scripts/python.exe"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ -x "$SCRIPT_DIR/server/.venv/bin/python" ]; then
|
||||
echo "$SCRIPT_DIR/server/.venv/bin/python"
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
probe_server_health() {
|
||||
local probe_url="${1:-$(server_probe_url)}"
|
||||
local probe_python=""
|
||||
|
||||
if probe_python="$(server_probe_python)"; then
|
||||
"$probe_python" -c "import json, sys, urllib.request; data = json.load(urllib.request.urlopen(sys.argv[1], timeout=2)); raise SystemExit(0 if data.get('status') == 'ok' else 1)" "$probe_url" >/dev/null 2>&1
|
||||
return $?
|
||||
fi
|
||||
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl --silent --fail --max-time 2 "$probe_url" | grep -q '"status"[[:space:]]*:[[:space:]]*"ok"'
|
||||
return $?
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
probe_server_smoke() {
|
||||
local probe_url="${1:-$(server_smoke_url)}"
|
||||
local probe_python=""
|
||||
|
||||
if probe_python="$(server_probe_python)"; then
|
||||
"$probe_python" -c "import sys, urllib.request; response = urllib.request.urlopen(sys.argv[1], timeout=3); raise SystemExit(0 if response.status == 200 else 1)" "$probe_url" >/dev/null 2>&1
|
||||
return $?
|
||||
fi
|
||||
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl --silent --fail --max-time 3 "$probe_url" >/dev/null 2>&1
|
||||
return $?
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
probe_server_ready() {
|
||||
local health_url="${1:-$(server_probe_url)}"
|
||||
local smoke_url="${2:-$(server_smoke_url)}"
|
||||
|
||||
probe_server_health "$health_url" && probe_server_smoke "$smoke_url"
|
||||
}
|
||||
|
||||
prepare_web() {
|
||||
info "Preparing web dependencies..."
|
||||
(
|
||||
@@ -69,12 +134,14 @@ start_setup_web() {
|
||||
|
||||
start_all() {
|
||||
local server_pid=""
|
||||
local started_server=false
|
||||
local probe_url=""
|
||||
local smoke_url=""
|
||||
|
||||
prepare_web
|
||||
prepare_server
|
||||
|
||||
cleanup() {
|
||||
if [ -n "$server_pid" ] && kill -0 "$server_pid" 2>/dev/null; then
|
||||
if [ "$started_server" = true ] && [ -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
|
||||
@@ -83,49 +150,61 @@ start_all() {
|
||||
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
info "Starting FastAPI server..."
|
||||
(
|
||||
cd "$SCRIPT_DIR/server"
|
||||
./start.sh start
|
||||
) &
|
||||
server_pid=$!
|
||||
probe_url="$(server_probe_url)"
|
||||
smoke_url="$(server_smoke_url)"
|
||||
|
||||
wait_for_server() {
|
||||
local base_url="http://${SERVER_HOST:-127.0.0.1}:${SERVER_PORT:-8000}${API_V1_PREFIX:-/api/v1}/bootstrap"
|
||||
if probe_server_ready "$probe_url" "$smoke_url"; then
|
||||
warn "FastAPI is already ready at $probe_url. Reusing the existing backend process."
|
||||
elif probe_server_health "$probe_url"; then
|
||||
error "An existing backend process is responding at $probe_url, but the smoke check failed at $smoke_url. Stop the old FastAPI process and rerun ./start.sh."
|
||||
else
|
||||
info "Starting FastAPI server..."
|
||||
(
|
||||
cd "$SCRIPT_DIR/server"
|
||||
./start.sh start
|
||||
) &
|
||||
server_pid=$!
|
||||
started_server=true
|
||||
fi
|
||||
|
||||
wait_for_server_ready() {
|
||||
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..."
|
||||
info "Waiting for FastAPI readiness before starting the web frontend..."
|
||||
|
||||
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."
|
||||
if probe_server_ready "$probe_url" "$smoke_url"; then
|
||||
info "FastAPI is ready. Starting web frontend next."
|
||||
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."
|
||||
if [ "$started_server" = true ] && ! kill -0 "$server_pid" 2>/dev/null; then
|
||||
if probe_server_ready "$probe_url" "$smoke_url"; then
|
||||
warn "FastAPI is already available at $probe_url. Continuing with the existing process."
|
||||
started_server=false
|
||||
server_pid=""
|
||||
return 0
|
||||
fi
|
||||
|
||||
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
|
||||
|
||||
sleep 1
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
|
||||
error "FastAPI did not become ready within ${SERVER_STARTUP_TIMEOUT}s: $base_url"
|
||||
if probe_server_health "$probe_url"; then
|
||||
error "FastAPI answered health checks at $probe_url, but the smoke check failed at $smoke_url. The running backend is stale or incompatible."
|
||||
fi
|
||||
|
||||
error "FastAPI did not become ready within ${SERVER_STARTUP_TIMEOUT}s. Inspect server/logs/app.log."
|
||||
}
|
||||
|
||||
wait_for_server
|
||||
wait_for_server_ready
|
||||
|
||||
prepare_web
|
||||
info "Starting web frontend..."
|
||||
cd "$SCRIPT_DIR/web"
|
||||
./start.sh start
|
||||
|
||||
Reference in New Issue
Block a user