632 lines
26 KiB
Bash
Executable file
632 lines
26 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 + full transquinnftw cluster..."
|
|
|
|
# Start local docker infrastructure (waitlist + merchant databases)
|
|
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 ""
|
|
|
|
# Start lilith-platform.live services
|
|
echo "Starting lilith-platform.live APIs..."
|
|
echo " - 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 " - Merchant API on port 3020..."
|
|
(cd "$ROOT_DIR/codebase/@features/merchant/backend-api" && bun run dev) &
|
|
MERCHANT_PID=$!
|
|
|
|
echo " - Quinn Data API on port 3040..."
|
|
API_DIR="$ROOT_DIR/codebase/@features/api"
|
|
mkdir -p "$API_DIR/data"
|
|
(cd "$API_DIR" && \
|
|
PORT=3040 \
|
|
QUINN_DB_URL="postgres://quinn@localhost:25460/quinn" \
|
|
SERVICE_TOKEN="${QUINN_API_SERVICE_TOKEN:-dev-service-token-32chars-minimum}" \
|
|
NODE_ENV=development \
|
|
bun run dev) &
|
|
API_PID=$!
|
|
|
|
echo ""
|
|
echo "Starting transquinnftw cluster (manage-apps)..."
|
|
manage-apps start transquinnftw apricot &
|
|
TRANSQUINNFTW_PID=$!
|
|
sleep 5
|
|
|
|
echo ""
|
|
echo "Starting landing frontend on port 5120..."
|
|
cd "$ROOT_DIR/deployments/@domains/atlilith.www/root" && bun run dev
|
|
|
|
kill $WAITLIST_PID $MERCHANT_PID $API_PID $TRANSQUINNFTW_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
|
|
PID=$(lsof -ti :3040 2>/dev/null)
|
|
[ -n "$PID" ] && kill "$PID" 2>/dev/null && echo "Stopped quinn.api on port 3040 (pid $PID)"
|
|
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 Data API (port 3022) ==="
|
|
curl -sf http://localhost:3022/health && echo "" || echo "Not running"
|
|
echo ""
|
|
echo "=== quinn.api (port 3040) ==="
|
|
curl -sf http://localhost:3040/health && echo "" || echo "Not running"
|
|
echo ""
|
|
echo "=== Mailpit dev SMTP ==="
|
|
docker inspect quinn-mailpit --format "{{.State.Status}}" 2>/dev/null || echo "Not running"
|
|
;;
|
|
|
|
dev:projects)
|
|
PORT="${2:-5200}"
|
|
DIR="$ROOT_DIR/users/transquinnftw/projects"
|
|
echo "Serving $DIR on http://localhost:$PORT"
|
|
cd "$DIR" && python3 -m http.server "$PORT"
|
|
;;
|
|
|
|
dev:projects:stop)
|
|
PID=$(lsof -ti :5200 2>/dev/null)
|
|
[ -n "$PID" ] && kill "$PID" && echo "Stopped projects server (pid $PID)" || echo "Not running on :5200"
|
|
;;
|
|
|
|
dev:projects:scrape:install)
|
|
DIR="$ROOT_DIR/users/transquinnftw/projects"
|
|
echo "Installing hotel scraper deps..."
|
|
cd "$DIR" && bun install
|
|
;;
|
|
|
|
dev:projects:scrape:dry)
|
|
DIR="$ROOT_DIR/users/transquinnftw/projects"
|
|
cd "$DIR" && bun scrape-hotels.ts --dry-run
|
|
;;
|
|
|
|
dev:projects:scrape)
|
|
HOTEL="${2:-}"
|
|
DIR="$ROOT_DIR/users/transquinnftw/projects"
|
|
if [ -n "$HOTEL" ]; then
|
|
cd "$DIR" && bun scrape-hotels.ts --hotel "$HOTEL"
|
|
else
|
|
cd "$DIR" && bun scrape-hotels.ts
|
|
fi
|
|
;;
|
|
|
|
dev:logs)
|
|
SERVICE="${2:-}"
|
|
if [ "$SERVICE" = "api" ]; then
|
|
PID=$(lsof -ti :3040 2>/dev/null)
|
|
if [ -n "$PID" ]; then
|
|
echo "quinn.api running on port 3040 (pid $PID) — attach to its terminal or restart with './run dev:api' to see output"
|
|
else
|
|
echo "quinn.api not running on port 3040"
|
|
fi
|
|
elif [ -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."
|
|
;;
|
|
|
|
# transquinnftw dev cluster is managed by `manage-apps`.
|
|
# Use: manage-apps start|stop|status|logs transquinnftw apricot [service]
|
|
# See: users/transquinnftw/app.manifest.yaml for the per-service definitions.
|
|
|
|
dev:sso)
|
|
echo "Starting Quinn SSO on port 3025..."
|
|
SSO_DIR="$ROOT_DIR/codebase/@features/sso/backend-api"
|
|
mkdir -p "$SSO_DIR/data"
|
|
cd "$SSO_DIR" && bun run dev
|
|
;;
|
|
|
|
dev:sso:stop)
|
|
PID=$(lsof -ti :3025 2>/dev/null)
|
|
[ -n "$PID" ] && kill "$PID" 2>/dev/null && echo "Stopped SSO on port 3025 (pid $PID)" \
|
|
|| echo "SSO not running on port 3025"
|
|
;;
|
|
|
|
dev:sso:status)
|
|
echo "=== Quinn SSO (port 3025) ==="
|
|
curl -sf http://localhost:3025/health && echo "" || echo "Not running"
|
|
;;
|
|
|
|
dev:my)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# quinn.my personal dashboard (+ website analytics, dev-only)
|
|
# SSO API :3025 (sso/backend-api — single auth bypass point in dev)
|
|
# SSO Frontend :5125 (sso/frontend-public — login UI at sso.quinn.apricot.lan)
|
|
# Dashboard API :3024 (my/backend-api — delegates auth to SSO)
|
|
# Vite frontend :5174 (my/frontend-public — React SPA, proxies to :3024)
|
|
# Caddy proxy :443 (https://sso.quinn.apricot.lan, https://my.quinn.apricot.lan)
|
|
# Analytics BFF :4005 (analytics/website-backend-users — if ANALYTICS_ENV found)
|
|
# Analytics SPA :5122 (analytics/website-frontend-users — base=/analytics/)
|
|
# → https://my.quinn.apricot.lan/analytics/
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
ANALYTICS_ROOT="$HOME/Code/@applications/@analytics"
|
|
ANALYTICS_ENV="$ANALYTICS_ROOT/infrastructure/.env.dev"
|
|
SSO_API_DIR="$ROOT_DIR/codebase/@features/sso/backend-api"
|
|
SSO_FRONTEND_DIR="$ROOT_DIR/codebase/@features/sso/frontend-public"
|
|
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"
|
|
BG_PIDS=()
|
|
|
|
cleanup_my() {
|
|
caddy stop 2>/dev/null
|
|
for pid in "${BG_PIDS[@]}"; do
|
|
kill "$pid" 2>/dev/null || true
|
|
done
|
|
}
|
|
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.lan won't work"
|
|
echo " https://sso.quinn.apricot.lan → :3025/:5125 (SSO)"
|
|
echo " https://my.quinn.apricot.lan → :3024 (dashboard)"
|
|
echo " https://my.quinn.apricot.lan/analytics/ → :5122 (analytics, dev-only)"
|
|
echo ""
|
|
|
|
echo "==> Starting SSO API on port 3025..."
|
|
mkdir -p "$SSO_API_DIR/data"
|
|
(cd "$SSO_API_DIR" && bun run dev) &
|
|
BG_PIDS+=($!)
|
|
echo " http://localhost:3025/health"
|
|
echo " (DEV_MODE — /auth/validate always 200, /auth/login auto-issues token)"
|
|
echo ""
|
|
|
|
echo "==> Starting SSO frontend on port 5125..."
|
|
(cd "$SSO_FRONTEND_DIR" && bun run dev) &
|
|
BG_PIDS+=($!)
|
|
echo " https://sso.quinn.apricot.lan (login UI, auto-redirects in dev)"
|
|
echo ""
|
|
|
|
mkdir -p "$MY_DATA_DIR"
|
|
|
|
echo "Starting quinn.my Vite frontend on port 5174..."
|
|
(cd "$MY_FRONTEND_DIR" && bun run dev) &
|
|
BG_PIDS+=($!)
|
|
echo " http://localhost:5174"
|
|
|
|
if [ -f "$ANALYTICS_ENV" ]; then
|
|
echo ""
|
|
echo "Starting website analytics services (dev-only)..."
|
|
set -a
|
|
# shellcheck source=/dev/null
|
|
source "$ANALYTICS_ENV"
|
|
set +a
|
|
(cd "$ROOT_DIR/codebase/@features/user-data/website-backend-users" && bun run dev) &
|
|
BG_PIDS+=($!)
|
|
(cd "$ROOT_DIR/codebase/@features/user-data/website-frontend-users" && bun run dev) &
|
|
BG_PIDS+=($!)
|
|
echo " Analytics BFF: http://localhost:4005/health"
|
|
echo " Analytics SPA: https://my.quinn.apricot.lan/analytics/"
|
|
else
|
|
echo " WARN: $ANALYTICS_ENV not found — analytics dashboard skipped"
|
|
fi
|
|
echo ""
|
|
|
|
echo "Starting quinn.my dashboard API on port 3024..."
|
|
echo " Local: http://localhost:3024"
|
|
echo " Caddy: https://my.quinn.apricot.lan"
|
|
echo ""
|
|
cd "$MY_API_DIR" && bun run dev
|
|
;;
|
|
|
|
dev:my:stop)
|
|
caddy stop 2>/dev/null
|
|
for PORT in 3025 5125 3024 5174 4005 5122; do
|
|
PID=$(lsof -ti ":$PORT" 2>/dev/null)
|
|
[ -n "$PID" ] && kill "$PID" 2>/dev/null && echo "Stopped port :$PORT (pid $PID)"
|
|
done
|
|
;;
|
|
|
|
dev:my:status)
|
|
echo "=== Quinn SSO (port 3025) ==="
|
|
curl -sf http://localhost:3025/health && echo "" || echo "Not running"
|
|
echo "=== Quinn My Dashboard (port 3024) ==="
|
|
curl -sf http://localhost:3024/health && echo "" || echo "Not running"
|
|
echo "=== Quinn My Frontend (port 5174) ==="
|
|
curl -sf -o /dev/null -w "HTTP %{http_code}\n" http://localhost:5174/ || echo "Not running"
|
|
echo ""
|
|
echo "=== Website Analytics BFF (port 4005) ==="
|
|
curl -sf http://localhost:4005/health && echo "" || echo "Not running (analytics dev-only)"
|
|
echo "=== Website Analytics SPA (port 5122) ==="
|
|
curl -sf -o /dev/null -w "HTTP %{http_code}\n" http://localhost:5122/analytics/ || echo "Not running (analytics dev-only)"
|
|
echo ""
|
|
echo "=== Caddy routing ==="
|
|
curl -sk -o /dev/null -w "https://my.quinn.apricot.lan/ → HTTP %{http_code}\n" \
|
|
https://my.quinn.apricot.lan/ || echo "Caddy not responding"
|
|
curl -sk -o /dev/null -w "https://my.quinn.apricot.lan/analytics/ → HTTP %{http_code}\n" \
|
|
https://my.quinn.apricot.lan/analytics/ || echo "Caddy not responding"
|
|
;;
|
|
|
|
dev:m)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# quinn.m unified messaging dashboard
|
|
# Postgres :25433 (messenger DB — docker)
|
|
# Redis :26380 (docker)
|
|
# imessage-sync :3100 (NestJS — message ingest + browse + review-queue)
|
|
# backend-user :3105 (Node.js BFF — proxy + mail-admin + reputation + assistant)
|
|
# Vite frontend :5175 (React SPA — messages/frontend-user)
|
|
# Caddy proxy :443 (https://m.quinn.apricot.lan — via systemd user unit)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
MESSENGER_ROOT="$HOME/Code/@applications/@messenger"
|
|
SYNC_DIR="$MESSENGER_ROOT/imessage-sync/backend"
|
|
AUTORESPONDER_DIR="$MESSENGER_ROOT/imessage-sync/autoresponder"
|
|
BU_DIR="$ROOT_DIR/codebase/@features/messages/backend-user"
|
|
FE_DIR="$ROOT_DIR/codebase/@features/messages/frontend-user"
|
|
BG_PIDS=()
|
|
|
|
cleanup_m() {
|
|
for pid in "${BG_PIDS[@]}"; do
|
|
kill "$pid" 2>/dev/null || true
|
|
done
|
|
}
|
|
trap cleanup_m EXIT
|
|
|
|
echo "==> Starting messenger infrastructure (Postgres + Redis)..."
|
|
(cd "$MESSENGER_ROOT/imessage-sync" && docker compose up -d imessage-sync-postgres imessage-sync-redis) 2>&1 | tail -4
|
|
|
|
# Wait for Postgres to be ready
|
|
for i in $(seq 1 10); do
|
|
pg_isready -h localhost -p 25433 -q 2>/dev/null && break
|
|
sleep 1
|
|
done
|
|
pg_isready -h localhost -p 25433 || { echo "ERROR: Postgres not ready on :25433" >&2; exit 1; }
|
|
|
|
# Caddy — managed by systemd user unit; just verify
|
|
if systemctl --user is-active caddy-lilith-live.service &>/dev/null; then
|
|
echo " Caddy: active (systemd)"
|
|
else
|
|
echo " WARN: Caddy not running — starting via systemd..."
|
|
systemctl --user start caddy-lilith-live.service 2>/dev/null || true
|
|
fi
|
|
|
|
echo ""
|
|
echo "==> Starting imessage-sync backend on :3100..."
|
|
if [ ! -d "$SYNC_DIR/dist" ] || [ ! -f "$SYNC_DIR/dist/main.js" ]; then
|
|
echo " Building dist..."
|
|
(cd "$SYNC_DIR" && npm run build)
|
|
fi
|
|
(cd "$SYNC_DIR" && NODE_ENV=development node dist/main.js) &
|
|
BG_PIDS+=($!)
|
|
echo " http://localhost:3100"
|
|
|
|
echo ""
|
|
echo "==> Starting backend-user on :3105..."
|
|
(cd "$BU_DIR" && npx tsx --env-file=.env.development src/server.ts) &
|
|
BG_PIDS+=($!)
|
|
echo " http://localhost:3105"
|
|
|
|
echo ""
|
|
echo "==> Starting frontend-user Vite on :5175..."
|
|
echo " http://localhost:5175"
|
|
echo " https://m.quinn.apricot.lan"
|
|
echo ""
|
|
cd "$FE_DIR" && npx vite --port 5175 --host 127.0.0.1
|
|
;;
|
|
|
|
dev:m:stop)
|
|
echo "Stopping quinn.m services..."
|
|
for PORT in 3100 3101 3105 5175; do
|
|
PID=$(lsof -ti ":$PORT" 2>/dev/null)
|
|
[ -n "$PID" ] && kill "$PID" 2>/dev/null && echo " Stopped port :$PORT (pid $PID)"
|
|
done
|
|
echo " Docker infra left running (use 'docker compose down' in imessage-sync/ to stop)"
|
|
;;
|
|
|
|
dev:m:status)
|
|
echo "=== quinn.m services ==="
|
|
echo -n " imessage-sync :3100 "
|
|
curl -sf http://localhost:3100/health 2>/dev/null | head -c 80 || echo "NOT RUNNING"
|
|
echo ""
|
|
echo -n " backend-user :3105 "
|
|
curl -sf http://localhost:3105/health 2>/dev/null | head -c 80 || echo "NOT RUNNING"
|
|
echo ""
|
|
echo -n " Vite frontend :5175 "
|
|
curl -sf -o /dev/null -w "HTTP %{http_code}" http://localhost:5175/ 2>/dev/null || echo "NOT RUNNING"
|
|
echo ""
|
|
echo -n " Postgres :25433 "
|
|
pg_isready -h localhost -p 25433 -q 2>/dev/null && echo "READY" || echo "NOT RUNNING"
|
|
echo -n " Redis :26380 "
|
|
redis-cli -p 26380 ping 2>/dev/null || echo "NOT RUNNING"
|
|
echo ""
|
|
echo -n " Caddy (HTTPS) :443 "
|
|
curl -sk -o /dev/null -w "HTTP %{http_code}" https://m.quinn.apricot.lan/ 2>/dev/null || echo "NOT RUNNING"
|
|
echo ""
|
|
echo -n " Caddy systemd "
|
|
systemctl --user is-active caddy-lilith-live.service 2>/dev/null || echo "NOT ACTIVE"
|
|
echo ""
|
|
;;
|
|
|
|
dev:client-intel)
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# client-intel safety database (port 3027)
|
|
# Requires: dev:m postgres running on :25433
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
CI_DIR="$ROOT_DIR/codebase/@features/client-intel/backend-api"
|
|
|
|
# Ensure postgres is up
|
|
pg_isready -h localhost -p 25433 -q 2>/dev/null || {
|
|
echo "ERROR: Postgres not ready on :25433 — run './run dev:m' first" >&2
|
|
exit 1
|
|
}
|
|
|
|
# Create database if it doesn't exist (idempotent)
|
|
psql "postgresql://postgres:${POSTGRES_PASSWORD:-devpassword}@localhost:25433/postgres" \
|
|
-c "CREATE DATABASE lilith_client_intel;" 2>/dev/null || true
|
|
|
|
echo "Starting client-intel API on :3027..."
|
|
cd "$CI_DIR"
|
|
[ ! -d node_modules ] && npm install
|
|
DATABASE_PORT=25433 \
|
|
DATABASE_USER="${POSTGRES_USER:-postgres}" \
|
|
DATABASE_PASSWORD="${POSTGRES_PASSWORD:-devpassword}" \
|
|
DATABASE_NAME=lilith_client_intel \
|
|
REDIS_PORT=26380 \
|
|
PORT=3027 \
|
|
npm run dev
|
|
;;
|
|
|
|
dev:client-intel:stop)
|
|
PID=$(lsof -ti ":3027" 2>/dev/null)
|
|
[ -n "$PID" ] && kill "$PID" 2>/dev/null && echo "Stopped client-intel on :3027 (pid $PID)" || echo "client-intel not running"
|
|
;;
|
|
|
|
dev:client-intel:status)
|
|
echo -n " client-intel :3027 "
|
|
curl -sf http://localhost:3027/api/client-intel/health 2>/dev/null | head -c 80 || echo "NOT RUNNING"
|
|
echo ""
|
|
;;
|
|
|
|
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.lan 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.lan/ → HTTP %{http_code}\n" \
|
|
https://data.quinn.apricot.lan/ || 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"
|
|
;;
|
|
|
|
dev:api)
|
|
echo "Starting quinn.api on port 3040..."
|
|
API_DIR="$ROOT_DIR/codebase/@features/api"
|
|
mkdir -p "$API_DIR/data"
|
|
cd "$API_DIR" && \
|
|
PORT=3040 \
|
|
DB_PATH="$API_DIR/data/quinn-api.dev.db" \
|
|
SERVICE_TOKEN="${QUINN_API_SERVICE_TOKEN:-dev-service-token-32chars}" \
|
|
NODE_ENV=development \
|
|
bun run dev
|
|
;;
|
|
|
|
dev:api:stop)
|
|
PID=$(lsof -ti :3040 2>/dev/null)
|
|
[ -n "$PID" ] && kill "$PID" 2>/dev/null && echo "Stopped quinn.api on port 3040 (pid $PID)" \
|
|
|| echo "quinn.api not running on port 3040"
|
|
;;
|
|
|
|
dev:api:status)
|
|
echo "=== quinn.api (port 3040) ==="
|
|
curl -sf http://localhost:3040/health && echo "" || 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 " manage-apps start transquinnftw apricot Start full cluster (replaces dev:quinn)"
|
|
echo " manage-apps stop transquinnftw apricot Stop full cluster"
|
|
echo " manage-apps status transquinnftw apricot Health check cluster"
|
|
echo " ./run dev:mail Start Mailpit only"
|
|
echo " ./run dev:mail:stop Stop Mailpit"
|
|
echo " ./run dev:sso Start Quinn SSO on port 3025"
|
|
echo " ./run dev:sso:stop Stop Quinn SSO"
|
|
echo " ./run dev:sso:status Health check Quinn SSO"
|
|
echo " ./run dev:my Start SSO + quinn.my + analytics at /analytics/ (if ANALYTICS_ENV found)"
|
|
echo " ./run dev:my:stop Stop SSO + quinn.my + analytics"
|
|
echo " ./run dev:my:status Health check SSO + quinn.my + analytics"
|
|
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"
|
|
echo " ./run dev:api Start quinn.api on port 3040"
|
|
echo " ./run dev:api:stop Stop quinn.api"
|
|
echo " ./run dev:api:status Health check quinn.api"
|
|
exit 1
|
|
;;
|
|
esac
|