#!/usr/bin/env bash set -euo pipefail if [[ -z "${RAILWAY_API_KEY:-}" ]]; then echo "RAILWAY_API_KEY is missing" exit 1 fi if ! command -v jq >/dev/null 2>&1; then echo "jq is required for tools/railway/setup-project.sh" exit 1 fi PROJECT_NAME="${RAILWAY_PROJECT_NAME:-ghostfolio-ai-mvp}" API_IMAGE="${RAILWAY_API_IMAGE:-docker.io/ghostfolio/ghostfolio:latest}" POSTGRES_IMAGE="${RAILWAY_POSTGRES_IMAGE:-docker.io/library/postgres:15-alpine}" REDIS_IMAGE="${RAILWAY_REDIS_IMAGE:-docker.io/library/redis:alpine}" ENDPOINT="https://backboard.railway.app/graphql/v2" ACCESS_TOKEN_SALT_VALUE="${ACCESS_TOKEN_SALT:-$(openssl rand -hex 24)}" JWT_SECRET_KEY_VALUE="${JWT_SECRET_KEY:-$(openssl rand -hex 24)}" POSTGRES_DB_VALUE="${POSTGRES_DB:-ghostfolio-db}" POSTGRES_USER_VALUE="${POSTGRES_USER:-user}" POSTGRES_PASSWORD_VALUE="${POSTGRES_PASSWORD:-$(openssl rand -hex 24)}" REDIS_PASSWORD_VALUE="${REDIS_PASSWORD:-$(openssl rand -hex 24)}" call_gql() { local query="$1" local payload payload=$(jq -n --arg query "$query" '{query: $query}') curl -sS \ -H "Authorization: Bearer ${RAILWAY_API_KEY}" \ -H "Content-Type: application/json" \ -d "$payload" \ "$ENDPOINT" } extract_or_fail() { local response="$1" local path="$2" local value value=$(echo "$response" | jq -r "$path") if [[ -z "$value" || "$value" == "null" ]]; then echo "$response" exit 1 fi echo "$value" } workspace_response=$(call_gql 'query { apiToken { workspaces { id name } } }') workspace_id=$(extract_or_fail "$workspace_response" '.data.apiToken.workspaces[0].id') projects_response=$(call_gql 'query { projects { edges { node { id name environments { edges { node { id name } } } services { edges { node { id name } } } } } } }') project_id=$(echo "$projects_response" | jq -r --arg name "$PROJECT_NAME" '.data.projects.edges[]?.node | select(.name == $name) | .id' | head -n 1) if [[ -z "${project_id:-}" || "${project_id}" == "null" ]]; then create_project_query=$(cat <