#!/bin/sh set -eu PROJECT=growqr-backend-staging COMPOSE="docker compose -p $PROJECT -f docker-compose.yml -f docker-compose.override.yml" REQUIRED_NETWORKS="growqr-backend-staging_default interview-service_default roleplay-service_default resume-builder-staging_default course-service_default qscore-service-staging_default matchmaking-v2_default user-service-staging_default" EXTERNAL_NETWORKS="interview-service_default roleplay-service_default resume-builder-staging_default course-service_default qscore-service-staging_default matchmaking-v2_default user-service-staging_default" preflight() { for network in $EXTERNAL_NETWORKS; do docker network inspect "$network" >/dev/null done $COMPOSE config --quiet } verify() { actual=$(docker inspect growqr-backend --format '{{range $name, $_ := .NetworkSettings.Networks}}{{$name}} {{end}}') for network in $REQUIRED_NETWORKS; do case " $actual " in *" $network "*) ;; *) echo "missing backend network: $network" >&2; exit 1 ;; esac done for network in $actual; do case " $REQUIRED_NETWORKS " in *" $network "*) ;; *) echo "unexpected backend network: $network" >&2; exit 1 ;; esac done docker exec growqr-backend node --input-type=module -e ' const checks = [ ["user-service", "http://growqr_user_service:8003/health"], ["qscore", "http://qscore-service-staging-api-1:8000/health"], ["course", "http://growqr-course-service:8010/health"], ["resume", "http://growqr_resume_api:8000/health"], ["interview", "http://interview-service-api-1:8000/health"], ["roleplay", "http://roleplay-service-api-1:8000/health"], ]; let failed = false; for (const [name, url] of checks) { try { const response = await fetch(url, { signal: AbortSignal.timeout(3000) }); console.log(name, response.status); if (response.status !== 200) failed = true; } catch (error) { console.error(name, "ERROR", error.message); failed = true; } } if (failed) process.exit(1); ' docker exec growqr-backend node --input-type=module -e "const response=await fetch('http://127.0.0.1:4000/healthz',{signal:AbortSignal.timeout(3000)});console.log('backend',response.status);if(response.status!==200)process.exit(1)" } action=${1:-} [ "$#" -gt 0 ] && shift case "$action" in preflight) preflight ;; verify) verify ;; up) preflight; $COMPOSE up -d "$@"; verify ;; down) $COMPOSE down "$@" ;; *) echo "Usage: scripts/staging-compose.sh [compose args]" >&2; exit 2 ;; esac