#!/usr/bin/env bash set -euo pipefail PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$PROJECT_DIR" ACTION="${1:-status}" ENV_FILE="${PROJECT_DIR}/.env" COMPOSE_FILE="${COMPOSE_FILE_PATH:-docker-compose.yml}" require_cmd() { command -v "$1" >/dev/null 2>&1 || { echo "[ERROR] missing command: $1" exit 1 } } require_cmd docker require_cmd curl if ! docker info >/dev/null 2>&1; then echo "[ERROR] Docker daemon is not running." exit 1 fi if [[ ! -f "$ENV_FILE" && -f "${PROJECT_DIR}/.env.example" ]]; then cp "${PROJECT_DIR}/.env.example" "$ENV_FILE" echo "[INFO] .env created from .env.example" fi compose() { docker compose -f "$COMPOSE_FILE" "$@" } backend_health() { curl -fsS "http://127.0.0.1:${BACKEND_PORT:-8000}/healthz" >/dev/null } redis_health() { local redis_password redis_password="$(grep -E '^REDIS_PASSWORD=' "$ENV_FILE" | cut -d'=' -f2- || true)" compose exec -T redis redis-cli -a "${redis_password:-pmflow_redis_pass}" ping | grep -q PONG } db_health() { local db_user db_name db_user="$(grep -E '^POSTGRES_USER=' "$ENV_FILE" | cut -d'=' -f2- || true)" db_name="$(grep -E '^POSTGRES_DB=' "$ENV_FILE" | cut -d'=' -f2- || true)" compose exec -T db pg_isready -U "${db_user:-pmflow}" -d "${db_name:-pmflow}" >/dev/null } case "$ACTION" in start) echo "[INFO] compose file: ${COMPOSE_FILE}" compose up -d echo "[OK] stack started" ;; restart) echo "[INFO] compose file: ${COMPOSE_FILE}" compose down compose up -d echo "[OK] stack restarted" ;; stop) echo "[INFO] compose file: ${COMPOSE_FILE}" compose down echo "[OK] stack stopped" ;; status|ps) echo "[INFO] compose file: ${COMPOSE_FILE}" compose ps ;; logs) echo "[INFO] compose file: ${COMPOSE_FILE}" compose logs --tail=200 "${2:-}" ;; health) backend_health && echo "[OK] backend healthz" db_health && echo "[OK] db pg_isready" redis_health && echo "[OK] redis ping" ;; dev-start) COMPOSE_FILE="docker-compose.dev.yml" echo "[INFO] compose file: ${COMPOSE_FILE}" compose up -d echo "[OK] dev stack started" ;; dev-restart) COMPOSE_FILE="docker-compose.dev.yml" echo "[INFO] compose file: ${COMPOSE_FILE}" compose down compose up -d echo "[OK] dev stack restarted" ;; dev-stop) COMPOSE_FILE="docker-compose.dev.yml" echo "[INFO] compose file: ${COMPOSE_FILE}" compose down echo "[OK] dev stack stopped" ;; dev-status|dev-ps) COMPOSE_FILE="docker-compose.dev.yml" echo "[INFO] compose file: ${COMPOSE_FILE}" compose ps ;; dev-logs) COMPOSE_FILE="docker-compose.dev.yml" echo "[INFO] compose file: ${COMPOSE_FILE}" compose logs --tail=200 "${2:-}" ;; dev-health) COMPOSE_FILE="docker-compose.dev.yml" backend_health && echo "[OK] backend healthz" db_health && echo "[OK] db pg_isready" redis_health && echo "[OK] redis ping" ;; *) echo "Usage: $0 {start|restart|stop|status|ps|logs [service]|health|dev-start|dev-restart|dev-stop|dev-status|dev-ps|dev-logs [service]|dev-health}" exit 1 ;; esac