530 lines
24 KiB
Bash
Executable file
530 lines
24 KiB
Bash
Executable file
#!/bin/bash
|
|
# Dev environment commands for lilith-platform.live
|
|
# Sourced by the top-level ./run script — do not execute directly.
|
|
# SCRIPT_DIR and ROOT_DIR are set by the caller.
|
|
|
|
COMMAND="${1:-dev}"
|
|
|
|
case "$COMMAND" in
|
|
dev)
|
|
echo "Starting lilith-platform.live dev environment..."
|
|
docker compose -f "$ROOT_DIR/deployments/docker/docker-compose.yml" up -d
|
|
echo "PostgreSQL (waitlist) running on port 25460"
|
|
echo "PostgreSQL (merchant) running on port 25445"
|
|
echo ""
|
|
|
|
echo "Starting waitlist API on port 3070..."
|
|
(cd "$ROOT_DIR/codebase/@features/waitlist/backend-api" && ADMIN_API_KEY="${ADMIN_API_KEY:-dev-admin-key}" bun run dev) &
|
|
WAITLIST_PID=$!
|
|
|
|
echo "Starting merchant API on port 3020..."
|
|
(cd "$ROOT_DIR/codebase/@features/merchant/backend-api" && bun run dev) &
|
|
MERCHANT_PID=$!
|
|
|
|
echo ""
|
|
echo "Starting frontend..."
|
|
cd "$ROOT_DIR/deployments/@domains/atlilith.www/root" && bun run dev
|
|
|
|
kill $WAITLIST_PID $MERCHANT_PID 2>/dev/null
|
|
;;
|
|
|
|
dev:infra)
|
|
docker compose -f "$ROOT_DIR/deployments/docker/docker-compose.yml" up -d
|
|
echo "Infrastructure running."
|
|
echo " PostgreSQL (waitlist): port 25460"
|
|
echo " PostgreSQL (merchant): port 25445"
|
|
;;
|
|
|
|
dev:waitlist)
|
|
echo "Starting waitlist API on port 3070..."
|
|
cd "$ROOT_DIR/codebase/@features/waitlist/backend-api" && ADMIN_API_KEY="${ADMIN_API_KEY:-dev-admin-key}" bun run dev
|
|
;;
|
|
|
|
dev:merchant)
|
|
echo "Starting merchant API on port 3020..."
|
|
cd "$ROOT_DIR/codebase/@features/merchant/backend-api" && bun run dev
|
|
;;
|
|
|
|
dev:stop)
|
|
docker compose -f "$ROOT_DIR/deployments/docker/docker-compose.yml" down
|
|
echo "All services stopped."
|
|
;;
|
|
|
|
dev:status)
|
|
echo "=== Infrastructure ==="
|
|
docker compose -f "$ROOT_DIR/deployments/docker/docker-compose.yml" ps
|
|
echo ""
|
|
echo "=== Waitlist API (port 3070) ==="
|
|
curl -sf http://localhost:3070/api/health && echo "" || echo "Not running"
|
|
echo ""
|
|
echo "=== Merchant API (port 3020) ==="
|
|
curl -sf http://localhost:3020/api/health && echo "" || echo "Not running"
|
|
echo ""
|
|
echo "=== Quinn Contact API (port 3021) ==="
|
|
curl -sf http://localhost:3021/health && echo "" || echo "Not running"
|
|
echo ""
|
|
echo "=== Quinn Data API (port 3022) ==="
|
|
curl -sf http://localhost:3022/health && echo "" || echo "Not running"
|
|
echo ""
|
|
echo "=== Mailpit dev SMTP ==="
|
|
docker inspect quinn-mailpit --format "{{.State.Status}}" 2>/dev/null || echo "Not running"
|
|
;;
|
|
|
|
dev:logs)
|
|
SERVICE="${2:-}"
|
|
if [ -n "$SERVICE" ]; then
|
|
docker compose -f "$ROOT_DIR/deployments/docker/docker-compose.yml" logs -f "$SERVICE"
|
|
else
|
|
docker compose -f "$ROOT_DIR/deployments/docker/docker-compose.yml" logs -f
|
|
fi
|
|
;;
|
|
|
|
dev:mail)
|
|
echo "Starting Mailpit dev SMTP..."
|
|
docker compose -f "$ROOT_DIR/deployments/@domains/quinn.www/docker/compose.mail.dev.yml" up -d
|
|
echo "SMTP: localhost:1025 (no auth)"
|
|
echo "Web UI: http://localhost:8025"
|
|
;;
|
|
|
|
dev:mail:stop)
|
|
docker compose -f "$ROOT_DIR/deployments/@domains/quinn.www/docker/compose.mail.dev.yml" down
|
|
echo "Mailpit stopped."
|
|
;;
|
|
|
|
dev:quinn)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# transquinnftw full cluster
|
|
# Mailpit :1025/:8025 (docker — dev SMTP + web UI)
|
|
# Contact API :3021 (provider-website/backend-api)
|
|
# Data API :3022 (provider-website/data-api)
|
|
# Frontend :5120 (quinn.www Vite app)
|
|
# TimescaleDB :25434 (@analytics/infrastructure)
|
|
# Redis :26379 (@analytics/infrastructure)
|
|
# Collector :4001 (@applications/@analytics/services/collector)
|
|
# Query API :4003 (@applications/@analytics/services/api)
|
|
# Backend API :4110 (lilith-platform/platform-analytics/backend-api)
|
|
# Analytics UI :5111 (lilith-platform/platform-analytics/frontend-provider)
|
|
# Web Ana. BE :4005 (analytics/website-backend-users)
|
|
# Web Ana. FE :5122 (analytics/website-frontend-users)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
ANALYTICS_ROOT="$HOME/Code/@applications/@analytics"
|
|
PLATFORM_ROOT="$HOME/Code/@projects/@lilith/lilith-platform"
|
|
ANALYTICS_ENV="$ANALYTICS_ROOT/infrastructure/.env.dev"
|
|
BG_PIDS=()
|
|
|
|
cleanup() {
|
|
for pid in "${BG_PIDS[@]}"; do
|
|
kill "$pid" 2>/dev/null
|
|
done
|
|
caddy stop 2>/dev/null
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
echo "==> [0/4] Starting Caddy reverse proxy..."
|
|
caddy start --config "$ROOT_DIR/infrastructure/Caddyfile.local" 2>/dev/null \
|
|
|| echo " WARN: Caddy failed to start — https://*.apricot.local won't work"
|
|
echo " https://quinn.apricot.local → :5120"
|
|
echo " https://my.quinn.apricot.local → :3024"
|
|
echo " https://data.quinn.apricot.local → :5111/:4110/:4001"
|
|
echo " https://admin.quinn.apricot.local → :5121/:3023"
|
|
echo ""
|
|
|
|
echo "==> [1/4] Starting docker services (Mailpit + TimescaleDB + Redis)..."
|
|
docker compose -f "$ROOT_DIR/deployments/@domains/quinn.www/docker/compose.mail.dev.yml" up -d
|
|
echo " Mailpit SMTP on :1025, web UI at http://localhost:8025"
|
|
|
|
if [ -f "$ANALYTICS_ENV" ]; then
|
|
docker compose -f "$ANALYTICS_ROOT/infrastructure/docker-compose.dev.yaml" up -d
|
|
echo " Waiting for TimescaleDB to be healthy..."
|
|
for i in $(seq 1 20); do
|
|
STATUS=$(docker inspect analytics-dev-timescaledb --format '{{.State.Health.Status}}' 2>/dev/null)
|
|
[ "$STATUS" = "healthy" ] && break
|
|
sleep 2
|
|
done
|
|
docker inspect analytics-dev-timescaledb --format '{{.State.Health.Status}}' | grep -q healthy \
|
|
|| { echo "ERROR: TimescaleDB failed to become healthy"; exit 1; }
|
|
else
|
|
echo " WARN: $ANALYTICS_ENV not found — skipping analytics infrastructure"
|
|
fi
|
|
echo ""
|
|
|
|
echo "==> [2/4] Starting quinn APIs..."
|
|
(cd "$ROOT_DIR/codebase/@features/provider-website/backend-api" && SMTP_HOST=localhost SMTP_PORT=1025 SMTP_REQUIRE_TLS=false bun run dev) &
|
|
BG_PIDS+=($!)
|
|
(cd "$ROOT_DIR/codebase/@features/provider-website/data-api" && DB_PATH="$ROOT_DIR/codebase/@features/admin/backend-api/data/quinn.db" bun run dev) &
|
|
BG_PIDS+=($!)
|
|
|
|
# quinn.my personal dashboard API (:3024)
|
|
# Shared service token — admin backend uses this to authenticate its proxy requests to quinn.my.
|
|
# Must match QUINN_MY_SERVICE_TOKEN on the admin backend. In production, set via systemd env.
|
|
QUINN_MY_SERVICE_TOKEN="${QUINN_MY_SERVICE_TOKEN:-dev-quinn-my-service-token}"
|
|
MY_API_DIR="$ROOT_DIR/codebase/@features/my/backend-api"
|
|
MY_DATA_DIR="$MY_API_DIR/data"
|
|
mkdir -p "$MY_DATA_DIR"
|
|
if [ ! -f "$MY_DATA_DIR/quinn-my.db" ]; then
|
|
echo " Seeding quinn.my passphrase (set ADMIN_PASSPHRASE or enter interactively)..."
|
|
(cd "$MY_API_DIR" && bun run seed-passphrase)
|
|
fi
|
|
(cd "$MY_API_DIR" && DEV_BYPASS_AUTH=true QUINN_MY_SERVICE_TOKEN="$QUINN_MY_SERVICE_TOKEN" bun run dev) &
|
|
BG_PIDS+=($!)
|
|
|
|
# image-protection API (:3030)
|
|
(cd "$ROOT_DIR/codebase/@features/image-protection/backend-api" && mkdir -p data && IMAGE_PROTECTION_URL=http://localhost:3030 bun run dev) &
|
|
BG_PIDS+=($!)
|
|
|
|
# quinn admin API (:3023) + frontend (:5121)
|
|
(cd "$ROOT_DIR/codebase/@features/admin/backend-api" && IMAGE_PROTECTION_URL=http://localhost:3030 QUINN_MY_SERVICE_TOKEN="$QUINN_MY_SERVICE_TOKEN" bun run dev) &
|
|
BG_PIDS+=($!)
|
|
(cd "$ROOT_DIR/codebase/@features/admin/frontend-public" && bun run dev) &
|
|
BG_PIDS+=($!)
|
|
|
|
# comm-newsletter API (:3026) + frontend (:5126)
|
|
(cd "$ROOT_DIR/codebase/@features/comm-newsletter/backend-api" && mkdir -p data && SMTP_HOST=localhost SMTP_PORT=1025 SMTP_REQUIRE_TLS=false bun run dev) &
|
|
BG_PIDS+=($!)
|
|
(cd "$ROOT_DIR/codebase/@features/comm-newsletter/frontend-admin" && bun run dev) &
|
|
BG_PIDS+=($!)
|
|
echo ""
|
|
|
|
if [ -f "$ANALYTICS_ENV" ]; then
|
|
echo "==> [3/4] Starting analytics services..."
|
|
set -a
|
|
# shellcheck source=/dev/null
|
|
source "$ANALYTICS_ENV"
|
|
set +a
|
|
(cd "$ANALYTICS_ROOT/services/collector" && bun run dev) &
|
|
BG_PIDS+=($!)
|
|
(cd "$ANALYTICS_ROOT/services/api" && PORT=4003 bun run dev) &
|
|
BG_PIDS+=($!)
|
|
(cd "$ANALYTICS_ROOT/services/processor" && PORT=4002 bun run dev) &
|
|
BG_PIDS+=($!)
|
|
(cd "$PLATFORM_ROOT/codebase/features/platform-analytics/backend-api" && \
|
|
LILITH_PROJECT_ROOT="$PLATFORM_ROOT" \
|
|
PORT=4110 \
|
|
REDIS_PASSWORD="${REDIS_PASSWORD:-analytics_dev_password}" \
|
|
bun run dev) &
|
|
BG_PIDS+=($!)
|
|
(cd "$PLATFORM_ROOT/codebase/features/platform-analytics/frontend-provider" && bun run dev) &
|
|
BG_PIDS+=($!)
|
|
(cd "$ROOT_DIR/codebase/@features/analytics/website-backend-users" && bun run dev) &
|
|
BG_PIDS+=($!)
|
|
(cd "$ROOT_DIR/codebase/@features/analytics/website-frontend-users" && bun run dev) &
|
|
BG_PIDS+=($!)
|
|
else
|
|
echo "==> [3/4] Analytics skipped (no .env.dev)"
|
|
fi
|
|
echo ""
|
|
|
|
echo "==> [4/4] Starting quinn.www frontend on port 5120..."
|
|
cd "$ROOT_DIR/deployments/@domains/quinn.www/root" && VITE_DATA_API_URL=http://localhost:3022 bun run dev
|
|
;;
|
|
|
|
dev:quinn:stop)
|
|
echo "Stopping transquinnftw cluster..."
|
|
caddy stop 2>/dev/null
|
|
ANALYTICS_ROOT="$HOME/Code/@applications/@analytics"
|
|
docker compose -f "$ROOT_DIR/deployments/@domains/quinn.www/docker/compose.mail.dev.yml" down
|
|
docker compose -f "$ANALYTICS_ROOT/infrastructure/docker-compose.dev.yaml" down 2>/dev/null
|
|
for PORT in 3021 3022 3023 3024 3026 3030 5120 5121 5122 5126 5130 4001 4002 4003 4005 4110 5111; do
|
|
PID=$(lsof -ti :$PORT 2>/dev/null)
|
|
[ -n "$PID" ] && kill $PID 2>/dev/null && echo "Stopped process on port $PORT (pid $PID)"
|
|
done
|
|
echo "Transquinnftw cluster stopped."
|
|
;;
|
|
|
|
dev:quinn:status)
|
|
echo "=== Quinn Frontend (port 5120) ==="
|
|
curl -sf -o /dev/null -w "HTTP %{http_code}\n" http://localhost:5120/ || echo "Not running"
|
|
echo "=== Quinn Contact API (port 3021) ==="
|
|
curl -sf http://localhost:3021/health && echo "" || echo "Not running"
|
|
echo "=== Quinn Data API (port 3022) ==="
|
|
curl -sf http://localhost:3022/health && echo "" || echo "Not running"
|
|
echo "=== Quinn My Dashboard (port 3024) ==="
|
|
curl -sf http://localhost:3024/health && echo "" || echo "Not running"
|
|
echo "=== Mailpit dev SMTP ==="
|
|
docker inspect quinn-mailpit --format "{{.State.Status}}" 2>/dev/null || echo "Not running"
|
|
echo ""
|
|
echo "=== Analytics Collector (port 4001) ==="
|
|
curl -sf http://localhost:4001/analytics/health/live && echo "" || echo "Not running"
|
|
echo "=== Analytics Processor (port 4002) ==="
|
|
curl -sf http://localhost:4002/health && echo "" || echo "Not running"
|
|
echo "=== Analytics Query API (port 4003) ==="
|
|
curl -sf http://localhost:4003/health && echo "" || echo "Not running"
|
|
echo "=== Website Analytics Backend (port 4005) ==="
|
|
curl -sf http://localhost:4005/health && echo "" || echo "Not running"
|
|
echo "=== Analytics API (port 4110) ==="
|
|
curl -sf http://localhost:4110/health && echo "" || echo "Not running"
|
|
echo "=== Analytics Frontend (port 5111) ==="
|
|
curl -sf -o /dev/null -w "HTTP %{http_code}\n" http://localhost:5111/ || echo "Not running"
|
|
echo "=== Website Analytics (port 5122) ==="
|
|
curl -sf -o /dev/null -w "HTTP %{http_code}\n" http://localhost:5122/ || echo "Not running"
|
|
echo ""
|
|
echo "=== Analytics Infrastructure ==="
|
|
docker inspect analytics-dev-timescaledb --format "{{.State.Status}}" 2>/dev/null || echo "TimescaleDB: Not running"
|
|
docker inspect analytics-dev-redis --format "{{.State.Status}}" 2>/dev/null || echo "Redis: Not running"
|
|
echo ""
|
|
echo "=== Admin API (port 3023) ==="
|
|
curl -sf http://localhost:3023/health && echo "" || echo "Not running"
|
|
echo "=== Admin Frontend (port 5121) ==="
|
|
curl -sf -o /dev/null -w "HTTP %{http_code}\n" http://localhost:5121/ || echo "Not running"
|
|
echo ""
|
|
echo "=== Newsletter API (port 3026) ==="
|
|
curl -sf http://localhost:3026/health && echo "" || echo "Not running"
|
|
echo "=== Newsletter Frontend (port 5126) ==="
|
|
curl -sf -o /dev/null -w "HTTP %{http_code}\n" http://localhost:5126/ || echo "Not running"
|
|
echo ""
|
|
echo "=== Image Protection API (port 3030) ==="
|
|
curl -sf http://localhost:3030/health && echo "" || echo "Not running"
|
|
echo ""
|
|
echo "=== Caddy reverse proxy ==="
|
|
curl -sk -o /dev/null -w "https://quinn.apricot.local/ → HTTP %{http_code}\n" \
|
|
https://quinn.apricot.local/ || echo " quinn.apricot.local — Caddy not responding"
|
|
curl -sk -o /dev/null -w "https://data.quinn.apricot.local/ → HTTP %{http_code}\n" \
|
|
https://data.quinn.apricot.local/ || echo " data.quinn.apricot.local — Caddy not responding"
|
|
curl -sk -o /dev/null -w "https://my.quinn.apricot.local/ → HTTP %{http_code}\n" \
|
|
https://my.quinn.apricot.local/ || echo " my.quinn.apricot.local — Caddy not responding"
|
|
curl -sk -o /dev/null -w "https://admin.quinn.apricot.local/ → HTTP %{http_code}\n" \
|
|
https://admin.quinn.apricot.local/ || echo " admin.quinn.apricot.local — Caddy not responding"
|
|
;;
|
|
|
|
dev:my)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# quinn.my personal dashboard
|
|
# Dashboard API :3024 (my/backend-api — passphrase auth + static file server)
|
|
# Vite frontend :5174 (my/frontend-public — React SPA, proxies to :3024)
|
|
# Caddy proxy :443 (https://my.quinn.apricot.local → :3024)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
MY_API_DIR="$ROOT_DIR/codebase/@features/my/backend-api"
|
|
MY_FRONTEND_DIR="$ROOT_DIR/codebase/@features/my/frontend-public"
|
|
MY_DATA_DIR="$MY_API_DIR/data"
|
|
MY_FRONTEND_PID=""
|
|
|
|
cleanup_my() {
|
|
caddy stop 2>/dev/null
|
|
if [ -n "$MY_FRONTEND_PID" ]; then
|
|
kill "$MY_FRONTEND_PID" 2>/dev/null || true
|
|
fi
|
|
}
|
|
trap cleanup_my EXIT
|
|
|
|
if [ ! -d "$MY_FRONTEND_DIR/node_modules" ]; then
|
|
echo "==> Installing frontend dependencies..."
|
|
(cd "$MY_FRONTEND_DIR" && bun install)
|
|
fi
|
|
|
|
echo "==> Starting Caddy reverse proxy..."
|
|
caddy start --config "$ROOT_DIR/infrastructure/Caddyfile.local" 2>/dev/null \
|
|
|| echo " WARN: Caddy failed to start — https://my.quinn.apricot.local won't work"
|
|
echo " https://my.quinn.apricot.local → :3024"
|
|
echo ""
|
|
|
|
mkdir -p "$MY_DATA_DIR"
|
|
|
|
if [ ! -f "$MY_DATA_DIR/quinn-my.db" ]; then
|
|
echo "No passphrase DB found. Seeding..."
|
|
echo " (Set ADMIN_PASSPHRASE env var or enter interactively)"
|
|
(cd "$MY_API_DIR" && bun run seed-passphrase)
|
|
fi
|
|
|
|
echo "Starting quinn.my Vite frontend on port 5174..."
|
|
(cd "$MY_FRONTEND_DIR" && bun run dev) &
|
|
MY_FRONTEND_PID=$!
|
|
echo " http://localhost:5174"
|
|
echo ""
|
|
|
|
echo "Starting quinn.my dashboard API on port 3024..."
|
|
echo " Local: http://localhost:3024"
|
|
echo " Caddy: https://my.quinn.apricot.local"
|
|
echo ""
|
|
cd "$MY_API_DIR" && DEV_BYPASS_AUTH=true bun run dev
|
|
;;
|
|
|
|
dev:my:stop)
|
|
caddy stop 2>/dev/null
|
|
PID=$(lsof -ti :3024 2>/dev/null)
|
|
if [ -n "$PID" ]; then
|
|
kill "$PID" 2>/dev/null
|
|
echo "Stopped quinn.my dashboard API (pid $PID)"
|
|
else
|
|
echo "quinn.my dashboard API not running"
|
|
fi
|
|
;;
|
|
|
|
dev:my:status)
|
|
echo "=== Quinn My Dashboard (port 3024) ==="
|
|
curl -sf http://localhost:3024/health && echo "" || echo "Not running"
|
|
echo ""
|
|
echo "=== Caddy routing ==="
|
|
curl -sk -o /dev/null -w "https://my.quinn.apricot.local/ → HTTP %{http_code}\n" \
|
|
https://my.quinn.apricot.local/ || echo "Caddy not responding"
|
|
;;
|
|
|
|
dev:newsletter)
|
|
echo "Starting comm-newsletter API on port 3026..."
|
|
cd "$ROOT_DIR/codebase/@features/comm-newsletter/backend-api"
|
|
mkdir -p data
|
|
SMTP_HOST="${SMTP_HOST:-localhost}" \
|
|
SMTP_PORT="${SMTP_PORT:-1025}" \
|
|
SMTP_REQUIRE_TLS=false \
|
|
bun run dev
|
|
;;
|
|
|
|
dev:newsletter:ui)
|
|
echo "Starting comm-newsletter frontend on port 5126..."
|
|
echo " http://localhost:5126"
|
|
cd "$ROOT_DIR/codebase/@features/comm-newsletter/frontend-admin" && bun run dev
|
|
;;
|
|
|
|
dev:newsletter:stop)
|
|
for PORT in 3026 5126; do
|
|
PID=$(lsof -ti ":$PORT" 2>/dev/null)
|
|
if [ -n "$PID" ]; then
|
|
kill "$PID" 2>/dev/null
|
|
echo "Stopped process on port $PORT (pid $PID)"
|
|
fi
|
|
done
|
|
;;
|
|
|
|
dev:newsletter:status)
|
|
echo "=== Newsletter API (port 3026) ==="
|
|
curl -sf http://localhost:3026/health && echo "" || echo "Not running"
|
|
echo "=== Newsletter Frontend (port 5126) ==="
|
|
curl -sf -o /dev/null -w "HTTP %{http_code}\n" http://localhost:5126/ || echo "Not running"
|
|
;;
|
|
|
|
dev:analytics)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# transquinnftw analytics cluster
|
|
# Brings up the full data.quinn.apricot.local stack:
|
|
# TimescaleDB :25434 (@analytics/infrastructure)
|
|
# Redis :26379 (@analytics/infrastructure)
|
|
# Collector :4001 (@applications/@analytics/services/collector)
|
|
# Backend API :4110 (lilith-platform/platform-analytics/backend-api)
|
|
# Frontend :5111 (lilith-platform/platform-analytics/frontend-provider)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
ANALYTICS_ROOT="$HOME/Code/@applications/@analytics"
|
|
PLATFORM_ROOT="$HOME/Code/@projects/@lilith/lilith-platform"
|
|
ANALYTICS_ENV="$ANALYTICS_ROOT/infrastructure/.env.dev"
|
|
|
|
if [ ! -f "$ANALYTICS_ENV" ]; then
|
|
echo "ERROR: $ANALYTICS_ENV not found."
|
|
echo " cp $ANALYTICS_ROOT/infrastructure/.env.dev.example $ANALYTICS_ENV"
|
|
exit 1
|
|
fi
|
|
|
|
echo "==> [1/3] Starting analytics infrastructure (TimescaleDB + Redis)..."
|
|
docker compose -f "$ANALYTICS_ROOT/infrastructure/docker-compose.dev.yaml" up -d
|
|
|
|
echo " Waiting for TimescaleDB to be healthy..."
|
|
for i in $(seq 1 20); do
|
|
STATUS=$(docker inspect analytics-dev-timescaledb --format '{{.State.Health.Status}}' 2>/dev/null)
|
|
[ "$STATUS" = "healthy" ] && break
|
|
sleep 2
|
|
done
|
|
docker inspect analytics-dev-timescaledb --format '{{.State.Health.Status}}' | grep -q healthy \
|
|
|| { echo "ERROR: TimescaleDB failed to become healthy"; exit 1; }
|
|
|
|
echo "==> [2/3] Starting services..."
|
|
|
|
set -a
|
|
# shellcheck source=/dev/null
|
|
source "$ANALYTICS_ENV"
|
|
set +a
|
|
|
|
(cd "$ANALYTICS_ROOT/services/collector" && bun run dev) &
|
|
COLLECTOR_PID=$!
|
|
|
|
(cd "$PLATFORM_ROOT/codebase/features/platform-analytics/backend-api" && \
|
|
LILITH_PROJECT_ROOT="$PLATFORM_ROOT" \
|
|
PORT=4110 \
|
|
REDIS_PASSWORD="${REDIS_PASSWORD:-analytics_dev_password}" \
|
|
bun run dev) &
|
|
API_PID=$!
|
|
|
|
echo "==> [3/3] Starting analytics frontend (:5111)..."
|
|
(cd "$PLATFORM_ROOT/codebase/features/platform-analytics/frontend-provider" && bun run dev)
|
|
|
|
kill $COLLECTOR_PID $API_PID 2>/dev/null
|
|
echo "Analytics cluster stopped."
|
|
;;
|
|
|
|
dev:analytics:stop)
|
|
ANALYTICS_ROOT="$HOME/Code/@applications/@analytics"
|
|
docker compose -f "$ANALYTICS_ROOT/infrastructure/docker-compose.dev.yaml" down
|
|
echo "Analytics infrastructure stopped."
|
|
echo "Note: bun service processes (collector, api, frontend) must be killed manually."
|
|
;;
|
|
|
|
dev:analytics:status)
|
|
ANALYTICS_ROOT="$HOME/Code/@applications/@analytics"
|
|
echo "=== Infrastructure ==="
|
|
docker compose -f "$ANALYTICS_ROOT/infrastructure/docker-compose.dev.yaml" ps
|
|
echo ""
|
|
echo "=== Collector (port 4001) ===" && \
|
|
curl -sf http://localhost:4001/health/live && echo "" || echo "Not running"
|
|
echo "=== Backend API (port 4110) ===" && \
|
|
curl -sf http://localhost:4110/health && echo "" || echo "Not running"
|
|
echo "=== Frontend (port 5111) ===" && \
|
|
curl -sf -o /dev/null -w "HTTP %{http_code}\n" http://localhost:5111/ || echo "Not running"
|
|
echo ""
|
|
echo "=== Caddy routing ==="
|
|
curl -sk -o /dev/null -w "https://data.quinn.apricot.local/ → HTTP %{http_code}\n" \
|
|
https://data.quinn.apricot.local/ || echo "Caddy not responding"
|
|
;;
|
|
|
|
dev:image-protection)
|
|
PROTECT_API="$ROOT_DIR/codebase/@features/image-protection/backend-api"
|
|
mkdir -p "$PROTECT_API/data"
|
|
echo "Starting image-protection API on port 3030..."
|
|
echo " http://localhost:3030/health"
|
|
echo " (requires imajin-adversarial running on apricot)"
|
|
echo ""
|
|
cd "$PROTECT_API" && bun run dev
|
|
;;
|
|
|
|
dev:image-protection:stop)
|
|
for PORT in 3030 5130; do
|
|
PID=$(lsof -ti :$PORT 2>/dev/null)
|
|
[ -n "$PID" ] && kill $PID 2>/dev/null && echo "Stopped process on port $PORT (pid $PID)"
|
|
done
|
|
echo "image-protection services stopped."
|
|
;;
|
|
|
|
dev:image-protection:status)
|
|
echo "=== Image Protection API (port 3030) ==="
|
|
curl -sf http://localhost:3030/health && echo "" || echo "Not running"
|
|
echo "=== Image Protection Frontend (port 5130) ==="
|
|
curl -sf -o /dev/null -w "HTTP %{http_code}\n" http://localhost:5130/ || echo "Not running"
|
|
;;
|
|
|
|
*)
|
|
echo "Unknown dev command: $COMMAND"
|
|
echo ""
|
|
echo "Dev commands:"
|
|
echo " ./run dev Start full dev (docker + frontend + APIs)"
|
|
echo " ./run dev:infra Start infrastructure only (PostgreSQL)"
|
|
echo " ./run dev:waitlist Start waitlist API"
|
|
echo " ./run dev:merchant Start merchant API"
|
|
echo " ./run dev:stop Stop all services"
|
|
echo " ./run dev:status Health check all services"
|
|
echo " ./run dev:logs [svc] View service logs"
|
|
echo " ./run dev:quinn Start quinn.www full cluster"
|
|
echo " ./run dev:quinn:stop Stop quinn.www cluster"
|
|
echo " ./run dev:quinn:status Health check quinn.www cluster"
|
|
echo " ./run dev:mail Start Mailpit only"
|
|
echo " ./run dev:mail:stop Stop Mailpit"
|
|
echo " ./run dev:my Start quinn.my dashboard"
|
|
echo " ./run dev:my:stop Stop quinn.my"
|
|
echo " ./run dev:my:status Health check quinn.my"
|
|
echo " ./run dev:analytics Start analytics cluster"
|
|
echo " ./run dev:analytics:stop Stop analytics cluster"
|
|
echo " ./run dev:analytics:status Health check analytics cluster"
|
|
echo " ./run dev:newsletter Start comm-newsletter API"
|
|
echo " ./run dev:newsletter:ui Start comm-newsletter frontend"
|
|
echo " ./run dev:newsletter:stop Stop comm-newsletter"
|
|
echo " ./run dev:newsletter:status Health check comm-newsletter"
|
|
echo " ./run dev:image-protection Start image-protection API"
|
|
echo " ./run dev:image-protection:stop Stop image-protection"
|
|
echo " ./run dev:image-protection:status Health check image-protection"
|
|
exit 1
|
|
;;
|
|
esac
|