From 05b1d81d30cbb68c68749cafefae6c5f135101b9 Mon Sep 17 00:00:00 2001 From: senke Date: Thu, 30 Apr 2026 22:27:14 +0200 Subject: [PATCH] fix(scripts): payment-e2e walkthrough safety guards (DRY_RUN + prod confirm) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three holes in the v1.0.9 W6 Day 27 walkthrough that an operator under stress could fall into : 1. Typo'd STAGING_URL pointing at production. The script accepted any URL with no sanity check, so `STAGING_URL=https://veza.fr ...` would happily POST /orders and charge a real card on the first run. Fix: heuristic detection (URL doesn't contain "staging", "localhost" or "127.0.0.1" → treat as prod) refuses to run unless CONFIRM_PRODUCTION=1 is explicitly set. 2. No way to rehearse the flow without spending money. Added DRY_RUN=1 that exits cleanly after step 2 (product listing) — exercises auth, API plumbing, and the staging product fixture without creating an order. 3. No final confirm before the actual charge. On a prod target, after the product is picked and before the POST /orders fires, the script now prints the {product_id, price, operator, endpoint} block and demands the operator type the literal word `CHARGE`. Any other answer aborts with exit code 2. Together these turn "STAGING_URL typo = burnt 5 EUR" into "STAGING_URL typo = exit code 3 with explanation". The wrapper docs in docs/PAYMENT_E2E_LIVE_REPORT.md already mention card-charge risk in prose; these guards enforce it at exec time. Co-Authored-By: Claude Opus 4.7 (1M context) --- scripts/payment-e2e-walkthrough.sh | 79 ++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/scripts/payment-e2e-walkthrough.sh b/scripts/payment-e2e-walkthrough.sh index 8de3ce22e..b924ee5b8 100755 --- a/scripts/payment-e2e-walkthrough.sh +++ b/scripts/payment-e2e-walkthrough.sh @@ -42,6 +42,17 @@ OPERATOR_EMAIL=${OPERATOR_EMAIL:-?} OPERATOR_PASSWORD=${OPERATOR_PASSWORD:-?} ORDER_POLL_TIMEOUT=${ORDER_POLL_TIMEOUT:-300} ORDER_POLL_INTERVAL=${ORDER_POLL_INTERVAL:-5} +# v1.0.10 polish safety guards: +# DRY_RUN=1 — skip the POST /orders + payment steps; rehearse +# the login + product-listing + license-poll path +# end-to-end on staging without spending a euro. +# CONFIRM_PRODUCTION=1 — required when STAGING_URL points at the live +# environment. Without it the script refuses to +# run, so a typo (`STAGING_URL=https://veza.fr` +# on a sandbox-targeted command) can't accidentally +# charge a real card. +DRY_RUN=${DRY_RUN:-0} +CONFIRM_PRODUCTION=${CONFIRM_PRODUCTION:-0} SESSION_DATE="$(date +%Y%m%d-%H%M)" SESSION_LOG="${REPO_ROOT}/docs/PAYMENT_E2E_LIVE_REPORT.md.session-${SESSION_DATE}.log" @@ -64,6 +75,43 @@ require jq [ "$OPERATOR_EMAIL" = "?" ] && fail "OPERATOR_EMAIL env var required" 3 [ "$OPERATOR_PASSWORD" = "?" ] && fail "OPERATOR_PASSWORD env var required" 3 +# Heuristic: any URL that doesn't include the substring "staging" is +# treated as production. Operators on a non-veza-domain (custom env) +# can still run the script; they just have to pass CONFIRM_PRODUCTION=1. +TARGET_LOOKS_LIKE_PROD=0 +if [[ ! "$STAGING_URL" =~ staging ]] && [[ ! "$STAGING_URL" =~ localhost ]] && [[ ! "$STAGING_URL" =~ 127\.0\.0\.1 ]]; then + TARGET_LOOKS_LIKE_PROD=1 +fi + +if [ "$TARGET_LOOKS_LIKE_PROD" = "1" ] && [ "$CONFIRM_PRODUCTION" != "1" ]; then + cat >&2 </dev/null) ORDER_ID=$(echo "$order_resp" | jq -r '.data.order.id // .data.id // .id // ""')