#!/usr/bin/env bash set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" PROFILE_ROOT="$ROOT/dev/production-like" PROFILE_ENV="${GOVOPLAN_PRODUCTION_LIKE_ENV:-$PROFILE_ROOT/.env}" if [ ! -f "$PROFILE_ENV" ]; then PROFILE_ENV="$PROFILE_ROOT/.env.example" fi PYTHON="${PYTHON:-$ROOT/.venv/bin/python}" DOCKER="${DOCKER:-docker}" usage() { cat <<'EOF' Usage: scripts/production-like-dev.sh [--yes] Commands: start Start the production-like API, worker, WebUI, PostgreSQL, and Redis profile. stop Stop PostgreSQL and Redis profile containers. status Show profile container status and validate the effective environment. seed Run migrations and seed development data against the profile database. reset --yes Stop containers, remove profile volumes, and remove runtime/production-like data. validate-config Validate the profile environment only. The start command delegates to scripts/launch-production-like-dev.sh. Stop/reset operate on Docker dependencies; API/WebUI/worker processes started by the launcher are stopped with Ctrl+C in that launcher terminal. EOF } fail() { printf 'production-like-dev: %s\n' "$*" >&2 exit 1 } command="${1:-}" if [ -z "$command" ] || [ "$command" = "-h" ] || [ "$command" = "--help" ]; then usage exit 0 fi shift || true yes=0 for arg in "$@"; do case "$arg" in --yes) yes=1 ;; *) fail "unknown argument: $arg" ;; esac done [ -f "$PROFILE_ENV" ] || fail "profile env file not found: $PROFILE_ENV" [ -x "$PYTHON" ] || fail "Python virtualenv not found at $PYTHON. Run: cd $ROOT && ./.venv/bin/python -m pip install -r requirements-dev.txt" set -a # shellcheck disable=SC1090 . "$PROFILE_ENV" set +a export APP_ENV="${APP_ENV:-staging}" export GOVOPLAN_INSTALL_PROFILE="${GOVOPLAN_INSTALL_PROFILE:-production-like}" export DATABASE_URL="${DATABASE_URL:-${GOVOPLAN_PRODUCTION_LIKE_DATABASE_URL:-postgresql+psycopg://govoplan:govoplan-dev@127.0.0.1:55433/govoplan}}" export GOVOPLAN_DATABASE_URL_PGTOOLS="${GOVOPLAN_DATABASE_URL_PGTOOLS:-${GOVOPLAN_PRODUCTION_LIKE_DATABASE_URL_PGTOOLS:-postgresql://govoplan:govoplan-dev@127.0.0.1:55433/govoplan}}" export REDIS_URL="${REDIS_URL:-${GOVOPLAN_PRODUCTION_LIKE_REDIS_URL:-redis://127.0.0.1:56379/0}}" export CELERY_ENABLED="${CELERY_ENABLED:-true}" export ENABLED_MODULES="${ENABLED_MODULES:-tenancy,organizations,identity,access,admin,dashboard,policy,audit,campaigns,files,mail,calendar,docs,ops}" export FILE_STORAGE_BACKEND="${FILE_STORAGE_BACKEND:-local}" export FILE_STORAGE_LOCAL_ROOT="${FILE_STORAGE_LOCAL_ROOT:-$ROOT/runtime/production-like/files}" export DEV_AUTO_MIGRATE_ENABLED="${DEV_AUTO_MIGRATE_ENABLED:-false}" export DEV_BOOTSTRAP_ENABLED="${DEV_BOOTSTRAP_ENABLED:-true}" export CORS_ORIGINS="${CORS_ORIGINS:-http://127.0.0.1:5173,http://localhost:5173}" if [ -z "${MASTER_KEY_B64:-}" ]; then MASTER_KEY_B64="$("$PYTHON" -m govoplan_core.commands.config env-template --profile production-like --generate-secrets | sed -n 's/^MASTER_KEY_B64=//p' | head -n 1)" export MASTER_KEY_B64 fi compose() { "$DOCKER" compose --env-file "$PROFILE_ENV" -f "$PROFILE_ROOT/docker-compose.yml" "$@" } validate_config() { "$PYTHON" -m govoplan_core.commands.config validate --profile production-like } case "$command" in start) exec "$ROOT/scripts/launch-production-like-dev.sh" ;; stop) compose down ;; status) compose ps validate_config ;; seed) validate_config "$PYTHON" -m govoplan_core.commands.init_db --database-url "$DATABASE_URL" --with-dev-data ;; reset) [ "$yes" = "1" ] || fail "reset is destructive; rerun with --yes" compose down -v rm -rf "$ROOT/runtime/production-like" ;; validate-config) validate_config ;; *) usage >&2 fail "unknown command: $command" ;; esac