From 4b89138db5cbabd6023dbab85fb8a6603eeb3503 Mon Sep 17 00:00:00 2001 From: bot-backend Date: Sat, 29 Aug 2026 20:49:49 +0500 Subject: [PATCH] =?UTF-8?q?fix(ops):=20=D0=BA=D0=B0=D0=BD=D0=B0=D1=80?= =?UTF-8?q?=D0=B5=D0=B9=D0=BA=D0=B0=20=D1=81=D0=BC=D0=BE=D1=83=D0=BA=D0=B0?= =?UTF-8?q?=20=D1=81=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=BB=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BC=D0=B5=D1=80=D0=B6=D0=B5=20PR-D3=20?= =?UTF-8?q?=E2=80=94=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D1=8F=D1=8E=20?= =?UTF-8?q?=D0=BE=D0=B6=D0=B8=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=B2=D0=BC?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B5=20=D1=81=20=D0=BD=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit После мержа платёжного роутера (#3231) perimeter-smoke стал красным на проде: FAIL: trade-in payments/notify — 401 anonymous (rbac закрыт до PR-D3) gendsgn.ru/.../payments/notify -> got '405', expected 401 Это НЕ поломка, а срабатывание канарейки, которую сам скрипт и обещал: «осознанно станет красной, когда PR-D3 явно откроет эти пути — тогда ожидания здесь надо обновить вместе с ними». Я смержил PR-D3 и ожидание не обновил. Что изменилось по существу: /payments/notify теперь в rbac._PUBLIC_PATHS — вебхук Т-Банка не умеет присылать X-Authenticated-User, аутентификация там подписью тела. /payments/checkout НЕ открывался и остаётся под 401. Проверка переведена с GET на POST: GET по POST-only маршруту даёт 405 и не говорит ничего ни про rbac, ни про флаг. POST с пустым телом проходит rbac (иначе 401) и упирается в выключенный контур — 503. Заодно закрыты три дыры в покрытии смоука, все замерены на проде: · /stats и /showcase — ручки, из которых лэндинг берёт числа. При их отказе страница по построению рендерится БЕЗ блоков (честная деградация), то есть тихо. Ничем другим это не ловится. · /estimate и /estimate/read — обязаны быть неотличимы от несуществующего пути при выключенном флаге. До #3233 отвечали 422 с перечнем своих полей. Путь длинный (/trade-in/api/public/...) намеренно: короткого на публичном домене нет, а по нему ходит фронт — проба обязана идти рабочим трактом. Следующая канарейка отмечена в комментарии: при включении PAYMENTS_ENABLED 503 станет отказом по подписи, и ожидание надо будет обновить вместе с флагом. Прогон на проде: ALL CHECKS PASSED. --- scripts/smoke-mera-perimeter.sh | 46 ++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/scripts/smoke-mera-perimeter.sh b/scripts/smoke-mera-perimeter.sh index 3ac08d76..149cd7fa 100644 --- a/scripts/smoke-mera-perimeter.sh +++ b/scripts/smoke-mera-perimeter.sh @@ -190,11 +190,51 @@ check "meraocenka.ru payments/notify — must 404 (Caddy не проксируе "$BASE_MERA/trade-in/api/v1/trade-in/payments/notify" 404 check "meraocenka.ru payments/checkout — must 404 (Caddy не проксирует, PR-D4)" \ "$BASE_MERA/trade-in/api/v1/trade-in/payments/checkout" 404 -check "trade-in payments/notify — 401 anonymous (rbac закрыт до PR-D3)" \ - "$BASE_MAIN/trade-in/api/v1/trade-in/payments/notify" 401 -check "trade-in payments/checkout — 401 anonymous (rbac закрыт до PR-D3)" \ +# PR-D3 СМЕРЖЕН 29.08.2026 — канарейка сработала ровно как обещано выше, и её +# ожидания обновлены вместе с ней (иначе смоук остался бы красным навсегда и +# перестал бы что-либо значить). +# +# Что изменилось: `/payments/notify` теперь В `rbac._PUBLIC_PATHS` — иначе +# вебхук Т-Банка получал бы 401, а банк не умеет присылать X-Authenticated-User. +# Аутентификация там — подпись `Token` тела, её проверяет сам хендлер. +# `/payments/checkout` открыт НЕ был и остаётся под 401: его зовёт наш же фронт. +# +# Проверяем POST'ом, а не GET'ом: GET по POST-only маршруту даёт 405, и это +# ничего не говорит ни про rbac, ни про флаг. POST с пустым телом проходит +# rbac (иначе 401) и упирается в выключенный контур — 503. +# +# ⚠️ СЛЕДУЮЩАЯ КАНАРЕЙКА ЗДЕСЬ ЖЕ: когда владелец включит PAYMENTS_ENABLED, +# этот 503 станет отказом по подписи (400/403). Тогда ожидание надо обновить +# ВМЕСТЕ с включением флага — не подгонять задним числом. +check_post "trade-in payments/notify — 503 anonymous (rbac пропускает, контур выключен)" \ + "$BASE_MAIN/trade-in/api/v1/trade-in/payments/notify" '{}' 503 +check "trade-in payments/checkout — 401 anonymous (закрыт, зовёт только наш фронт)" \ "$BASE_MAIN/trade-in/api/v1/trade-in/payments/checkout" 401 +# ── Публичные ручки витрины лэндинга (29.08.2026) ──────────────────────────── +# +# Числа на лэндинге приходят из этих двух ручек. Если они отвалятся, страница +# по построению отрендерится БЕЗ блоков (честная деградация) — то есть тихо и +# незаметно. Поэтому проверяем их здесь: молчаливое исчезновение витрины +# ничем другим не ловится. +# +# Путь длинный (`/trade-in/api/public/...`) НАМЕРЕННО: короткого +# `/api/public/...` на публичном домене нет, и один и тот же адрес обязан +# работать с обоих хостов — см. шапку frontend/src/app/mera-public/public-api.ts. +check "meraocenka.ru /stats — public 200" \ + "$BASE_MERA/trade-in/api/public/mera/stats" 200 +check "meraocenka.ru /showcase — public 200" \ + "$BASE_MERA/trade-in/api/public/mera/showcase" 200 + +# Анонимный расчёт закрыт флагом public_estimate_enabled и обязан быть +# НЕОТЛИЧИМ от несуществующего пути. До 29.08 он отвечал 422 с перечнем своих +# полей: проверка флага стояла в теле хендлера, а FastAPI валидирует тело +# раньше. Гейт переехал в зависимости маршрута; здесь — прод-подтверждение. +check_post "meraocenka.ru /estimate — 404 при выключенном флаге (схема не течёт)" \ + "$BASE_MERA/trade-in/api/public/mera/estimate" '{}' 404 +check_post "meraocenka.ru /estimate/read — 404 при выключенном флаге" \ + "$BASE_MERA/trade-in/api/public/mera/estimate/read" '{}' 404 + echo "========================================" if [ "$fail" -eq 0 ]; then echo "ALL CHECKS PASSED"