lilith-platform.live/scripts/run/dev.sh
2026-04-07 14:08:55 -07:00

559 lines
25 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" SMTP_HOST=localhost SMTP_PORT=1025 SMTP_REQUIRE_TLS=false 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 (+ website analytics, dev-only)
# 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)
# Analytics BFF :4005 (analytics/website-backend-users — if ANALYTICS_ENV found)
# Analytics SPA :5122 (analytics/website-frontend-users — base=/analytics/)
# → https://my.quinn.apricot.local/analytics/
# ─────────────────────────────────────────────────────────────────────────────
ANALYTICS_ROOT="$HOME/Code/@applications/@analytics"
ANALYTICS_ENV="$ANALYTICS_ROOT/infrastructure/.env.dev"
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.local won't work"
echo " https://my.quinn.apricot.local → :3024 (dashboard)"
echo " https://my.quinn.apricot.local/analytics/ → :5122 (analytics, dev-only)"
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) &
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/analytics/website-backend-users" && bun run dev) &
BG_PIDS+=($!)
(cd "$ROOT_DIR/codebase/@features/analytics/website-frontend-users" && bun run dev) &
BG_PIDS+=($!)
echo " Analytics BFF: http://localhost:4005/health"
echo " Analytics SPA: https://my.quinn.apricot.local/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.local"
echo ""
cd "$MY_API_DIR" && DEV_BYPASS_AUTH=true bun run dev
;;
dev:my:stop)
caddy stop 2>/dev/null
for PORT in 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 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.local/ → HTTP %{http_code}\n" \
https://my.quinn.apricot.local/ || echo "Caddy not responding"
curl -sk -o /dev/null -w "https://my.quinn.apricot.local/analytics/ → HTTP %{http_code}\n" \
https://my.quinn.apricot.local/analytics/ || 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 + analytics at /analytics/ (if ANALYTICS_ENV found)"
echo " ./run dev:my:stop Stop quinn.my + analytics"
echo " ./run dev:my:status Health check 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"
exit 1
;;
esac