cms.c2sgmbh/scripts/db-direct.sh
Martin Porwoll da735cab46 feat: add Products and ProductCategories collections with CI/CD pipeline
- Add Products collection with comprehensive fields (pricing, inventory, SEO, CTA)
- Add ProductCategories collection with hierarchical structure
- Implement CI/CD pipeline with GitHub Actions (lint, typecheck, test, build, e2e)
- Add access control test utilities and unit tests
- Fix Posts API to include category field for backwards compatibility
- Update ESLint config with ignores for migrations and admin components
- Add centralized access control functions in src/lib/access
- Add db-direct.sh utility script for database access

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-12 21:36:26 +00:00

187 lines
5.4 KiB
Bash
Executable file

#!/bin/bash
#
# db-direct.sh - Direkte PostgreSQL-Verbindung (umgeht PgBouncer)
#
# Verwendung:
# ./scripts/db-direct.sh migrate # Migrationen ausführen
# ./scripts/db-direct.sh migrate:create # Migration erstellen
# ./scripts/db-direct.sh psql # Interaktive psql-Session
# ./scripts/db-direct.sh query "SQL" # SQL-Query ausführen
#
# Credentials werden aus ~/.pgpass gelesen (Format: host:port:database:user:password)
# Alternativ: DB_PASSWORD Umgebungsvariable setzen
#
set -e
# Konfiguration (keine Secrets hier!)
DB_HOST="${DB_HOST:-10.10.181.101}"
DB_PORT="${DB_PORT:-5432}"
DB_NAME="${DB_NAME:-payload_db}"
DB_USER="${DB_USER:-payload}"
# Farbige Ausgabe
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
error() { echo -e "${RED}ERROR: $1${NC}" >&2; exit 1; }
info() { echo -e "${GREEN}$1${NC}"; }
warn() { echo -e "${YELLOW}$1${NC}"; }
# Passwort aus ~/.pgpass oder Umgebungsvariable lesen
get_password() {
if [[ -n "${DB_PASSWORD:-}" ]]; then
echo "$DB_PASSWORD"
return
fi
local pgpass="$HOME/.pgpass"
if [[ -f "$pgpass" ]]; then
# Format: host:port:database:user:password
local password
password=$(grep "^${DB_HOST}:${DB_PORT}:${DB_NAME}:${DB_USER}:" "$pgpass" 2>/dev/null | cut -d: -f5)
if [[ -n "$password" ]]; then
echo "$password"
return
fi
# Fallback: Wildcard-Einträge prüfen
password=$(grep "^\*:\*:\*:${DB_USER}:" "$pgpass" 2>/dev/null | cut -d: -f5)
if [[ -n "$password" ]]; then
echo "$password"
return
fi
fi
error "Kein Passwort gefunden. Setze DB_PASSWORD oder erstelle ~/.pgpass"
}
# URL-Encode für Passwörter mit Sonderzeichen
urlencode() {
local string="$1"
local strlen=${#string}
local encoded=""
local pos c o
for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="$c" ;;
* ) printf -v o '%%%02X' "'$c" ;;
esac
encoded+="$o"
done
echo "$encoded"
}
# Temporäre .env-Datei für sichere Credential-Übergabe
# Vermeidet Credential-Leak via `ps` command
run_with_direct_db() {
local cmd="$1"
shift
local password
password=$(get_password)
local encoded_password
encoded_password=$(urlencode "$password")
# Temporäre Datei mit restriktiven Permissions
local temp_env
temp_env=$(mktemp)
chmod 600 "$temp_env"
# Trap für Cleanup bei Abbruch
trap "rm -f '$temp_env'" EXIT
# Nur DATABASE_URI in temp file, Rest aus Umgebung
echo "DATABASE_URI=postgresql://${DB_USER}:${encoded_password}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=require" > "$temp_env"
# Führe Befehl mit env aus temp file aus (nicht sichtbar in ps)
env $(cat "$temp_env") "$cmd" "$@"
local exit_code=$?
# Cleanup
rm -f "$temp_env"
trap - EXIT
return $exit_code
}
# Hauptlogik
case "${1:-help}" in
migrate)
info "Führe Migrationen direkt auf PostgreSQL aus (umgeht PgBouncer)..."
warn "Host: ${DB_HOST}:${DB_PORT}"
run_with_direct_db pnpm payload migrate
info "Migrationen abgeschlossen."
;;
migrate:create)
info "Erstelle neue Migration..."
run_with_direct_db pnpm payload migrate:create
;;
migrate:status)
info "Migrations-Status..."
run_with_direct_db pnpm payload migrate:status
;;
psql)
info "Öffne interaktive psql-Session..."
warn "Host: ${DB_HOST}:${DB_PORT}"
# psql nutzt PGPASSWORD - nicht in ps sichtbar wenn via env gesetzt
PGPASSWORD="$(get_password)" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME"
;;
query)
if [[ -z "${2:-}" ]]; then
error "SQL-Query erforderlich: ./scripts/db-direct.sh query \"SELECT ...\""
fi
PGPASSWORD="$(get_password)" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "$2"
;;
test)
info "Teste direkte Verbindung zu PostgreSQL..."
if PGPASSWORD="$(get_password)" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "SELECT 1;" > /dev/null 2>&1; then
info "Verbindung erfolgreich!"
PGPASSWORD="$(get_password)" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "SELECT version();"
else
error "Verbindung fehlgeschlagen!"
fi
;;
help|--help|-h|*)
cat << EOF
db-direct.sh - Direkte PostgreSQL-Verbindung (umgeht PgBouncer)
Verwendung:
./scripts/db-direct.sh <command>
Commands:
migrate Migrationen ausführen
migrate:create Neue Migration erstellen
migrate:status Migrations-Status anzeigen
psql Interaktive psql-Session
query "SQL" SQL-Query ausführen
test Verbindung testen
help Diese Hilfe anzeigen
Konfiguration:
DB_HOST PostgreSQL Host (default: 10.10.181.101)
DB_PORT PostgreSQL Port (default: 5432)
DB_NAME Datenbank (default: payload_db)
DB_USER Benutzer (default: payload)
DB_PASSWORD Passwort (oder ~/.pgpass verwenden)
Beispiel ~/.pgpass (chmod 600):
10.10.181.101:5432:payload_db:payload:DEIN_PASSWORT
Sicherheit:
- Credentials werden URL-encoded (Sonderzeichen-safe)
- DATABASE_URI wird via temp file übergeben (nicht in ps sichtbar)
- Temp files haben chmod 600 und werden sofort gelöscht
EOF
;;
esac