diff --git a/backend/scripts/verify-and-test.sh b/backend/scripts/verify-and-test.sh new file mode 100755 index 0000000..7bea4cf --- /dev/null +++ b/backend/scripts/verify-and-test.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +# +# دورة تحقّق واحدة: افحص البيئة → أقلِع → **انتظر الصحة فعلاً** → اختبر. +# +# سبب وجوده: تسلسل `up -d --build && restart && <اختبار>` كان يشغّل الاختبار +# بينما الـapi ساقطة، فيظهر الفشل كـ`EAI_AGAIN` في الاختبار — أي في المكان +# الخطأ تماماً. ضاعت دورتان كاملتان على تشخيص خاطئ لهذا السبب وحده. +# البوابة هنا تمنع تكراره: لا اختبار قبل ردّ /health الفعلي. +# +# التشغيل من backend/: bash scripts/verify-and-test.sh +# بلا اختبار (نشر فقط): bash scripts/verify-and-test.sh --deploy-only +# مع إعادة بناء: bash scripts/verify-and-test.sh --build + +set -uo pipefail + +BUILD=0 +DEPLOY_ONLY=0 +for arg in "$@"; do + case "$arg" in + --build) BUILD=1 ;; + --deploy-only) DEPLOY_ONLY=1 ;; + *) echo "خيار غير معروف: $arg"; exit 2 ;; + esac +done + +cd "$(dirname "$0")/.." || exit 1 +ENV_FILE=".env" +FAILED=0 + +hr() { printf '%s\n' "────────────────────────────────────────────────"; } + +# ── 1) فحص البيئة قبل أي إقلاع ─────────────────────────────────────── +hr; echo "1) فحص البيئة" + +if [[ ! -f "$ENV_FILE" ]]; then + echo "❌ لا يوجد $ENV_FILE"; exit 1 +fi + +NODE_ENV_VAL=$(grep -E '^NODE_ENV=' "$ENV_FILE" | cut -d= -f2- | tr -d '"'"'"'\r ' || true) +OTP_DEV_VAL=$(grep -E '^OTP_DEV_MODE=' "$ENV_FILE" | cut -d= -f2- | tr -d '"'"'"'\r ' || true) +echo " NODE_ENV=${NODE_ENV_VAL:-<غير مضبوط>} OTP_DEV_MODE=${OTP_DEV_VAL:-<غير مضبوط>}" + +# التعارض القاتل: الحارس في main.ts ينهي العملية (exit 1) لا يحذّر فقط، +# فالحاوية تدخل حلقة إعادة تشغيل ويظهر العطل لاحقاً كفشل شبكة مضلِّل. +if [[ "$NODE_ENV_VAL" == "production" && "$OTP_DEV_VAL" == "true" ]]; then + echo " ⚠️ تعارض قاتل: OTP_DEV_MODE=true مع NODE_ENV=production → الـapi لن تقلع." + echo " ↪︎ أطفئ OTP_DEV_MODE تلقائياً (الاختبار لا يحتاجه — يقرأ الرمز من Redis)." + sed -i.bak 's/^OTP_DEV_MODE=.*/OTP_DEV_MODE=false/' "$ENV_FILE" + echo " ✅ OTP_DEV_MODE=false (نسخة احتياطية: ${ENV_FILE}.bak)" +fi + +if ! grep -qE '^PLATFORM_SECRET=.+' "$ENV_FILE"; then + echo " ❌ PLATFORM_SECRET غير مضبوط — نقاط السوبر-أدمن مغلقة والاختبار يحتاجها." + exit 1 +fi + +# ── 2) الإقلاع ─────────────────────────────────────────────────────── +hr; echo "2) الإقلاع" +if [[ "$BUILD" == "1" ]]; then + echo " بناء (الاختبارات تعمل داخل مرحلة البناء وتحجب النشر عند الفشل)…" + docker compose up -d --build || { echo "❌ فشل البناء"; exit 1; } +else + docker compose up -d || { echo "❌ فشل الإقلاع"; exit 1; } +fi + +# ── 3) بوابة الصحة — لا اختبار قبلها ───────────────────────────────── +hr; echo "3) انتظار /health" +HEALTH_OK=0 +for i in $(seq 1 30); do + STATUS=$(docker compose ps --format '{{.Name}} {{.Status}}' | grep '^tripz-api' || true) + # الحاوية في حلقة إعادة تشغيل = خطأ إقلاع، والانتظار لن يصلحه. + if [[ "$STATUS" == *Restarting* ]]; then + echo " ❌ tripz-api في حلقة إعادة تشغيل — خطأ إقلاع، لا مشكلة شبكة." + hr; echo "سبب السقوط (آخر أخطاء):" + docker compose logs api --tail=200 2>/dev/null | grep -E 'ERROR|⛔|Error:' | tail -15 + exit 1 + fi + if docker run --rm --network tripz-net curlimages/curl:latest \ + -fsS --max-time 3 http://tripz-api:4010/api/health >/dev/null 2>&1; then + HEALTH_OK=1 + echo " ✅ الـapi تستجيب (بعد ${i} محاولة)" + break + fi + sleep 2 +done + +if [[ "$HEALTH_OK" != "1" ]]; then + echo " ❌ لم تستجب /health خلال 60 ثانية." + hr; docker compose ps + hr; docker compose logs api --tail=40 + exit 1 +fi + +docker compose ps --format 'table {{.Name}}\t{{.Status}}' + +if [[ "$DEPLOY_ONLY" == "1" ]]; then + hr; echo "✅ النشر سليم (بلا اختبار)."; exit 0 +fi + +# ── 4) اختبار التسعير ──────────────────────────────────────────────── +hr; echo "4) اختبار التسعير" +SECRET=$(grep -E '^PLATFORM_SECRET=' "$ENV_FILE" | cut -d= -f2- | tr -d '"'"'"'\r ') +docker run --rm --network tripz-net \ + -e BASE=http://tripz-api:4010/api \ + -e PLATFORM_SECRET="$SECRET" \ + -v "$(pwd)/scripts:/s" \ + node:22-alpine node /s/pricing-test.mjs +FAILED=$? + +hr +if [[ "$FAILED" == "0" ]]; then echo "✅ تمّت الدورة بنجاح."; else echo "❌ فشل الاختبار (رمز $FAILED)."; fi +exit $FAILED