Перейти к содержанию

Prod Connectivity Audit — 2026-05-15

Время прогона: 2026-05-15 ~07:00–07:15 UTC Метод: 2 прохода curl-смоук по всем основным маршрутам из infra/routes.config.mjs на двух хостах (api.arkhyz-club.ru, admin.arkhyz-club.ru). Анонимные запросы без токена — цель не валидация бизнес-логики, а roundtrip: Caddy → правильный микросервис → корректный HTTP-код. Скрипт: /tmp/prod_probe.sh (60 эндпоинтов × 2 хоста = 120 проб).


Сводка

Статус Значение Кол-во
✅ Работает 200 / 401 / 422 / 307 — Caddy роутит, сервис отвечает корректно ~50 / 60 эндпоинтов
⚠️ Транзиент 502 После рестартов контейнеров — на втором проходе исчезли 0 (на финальном проходе)
❌ Реальные баги Подтверждённые root cause-ы 3
🤷 «404 в тестовом пути» Мой тестовый путь не соответствует реальному эндпоинту (param, slug) ~10

Открытые баги (что ещё чинить)

🔴 PR #84 — не смержен

Фиксы готовы, ждут мержа + ребилда контейнеров:

Эндпоинт Сейчас После мержа
GET /api/v1/recommendations/slopes 404 (Caddy → catalog-svc, эндпоинта нет) 200 (resort-svc)
GET /api/v1/recommendations/plan-day 404 (тот же баг) 200 (resort-svc)
GET /api/v1/tracking/sessions/me (с auth) 404 (FastAPI ловит me как session_id) 200 (после reorder)
GET /api/v1/progress/me 200 ✅ (после ранее запущенной миграции + ребилда) 200 (защищено)

🟡 Новый баг найден в обходе — /admin/ski/slopes

admin_ski.py:12 в docstring обещает «Аналогично для /admin/ski/slopes», но slopes-роуты не реализованы — есть только /lifts/*. Поэтому GET /api/v1/admin/ski/slopes → 404.

Админ-страница /admin/ski/slopes сейчас тянет /recommendations/slopes (см. отчёт юзера) — этот хак работал, пока Caddy не переехал на catalog-svc. После PR #84 /recommendations/slopes снова жив, и страница /admin/ski/slopes начнёт показывать данные из resort-svc. Полноценные admin-CRUD для трасс — отдельная задача (если они вообще нужны).

🟢 Транзиентные 502 — причина выявлена

На первом проходе 12 эндпоинтов на admin.arkhyz-club.ru отдали 502 (hotel_api_v2 fallbacks: /docs, /openapi.json, /admin/dashboard, /lifts, /modules и platform-svc /files/*, /settings/*, /push/register). Все они на втором проходе через 1–2 минуты вернули корректные коды. Причина — мой же apply-sql-migration workflow в 06:53 UTC дёрнул arkhyz-deploy.sh marker, который перезапустил backend-контейнеры. resort-svc запустился в 06:56:32, остальные следом. Окно деплоя ≈3–4 минуты — все ошибки в нём.

Урок: рассмотреть migration workflow без Pull latest main on host шага. Применение SQL не требует рестарта всего стека.


Полный результат — api.arkhyz-club.ru

Path Service Code X-Service Note
/api/v1/resort/lifts resort-svc 200 resort-svc
/api/v1/webcams resort-svc 200 resort-svc
/api/v1/webcams/list resort-svc 200 resort-svc
/api/v1/weather/current resort-svc 200 resort-svc
/api/v1/weather/forecast resort-svc 200 resort-svc
/api/v1/tracking/sessions/me resort-svc 401 resort-svc ⚠️ Без auth. С auth → 404 (PR #84)
/api/v1/friends/locations resort-svc 401 resort-svc ⚠️ Auth required
/api/v1/skipass/active resort-svc 404 resort-svc 🤷 Probe path mismatch (нужен ?user_id=)
/api/v1/leaderboard resort-svc 200 resort-svc
/api/v1/recommendations/slopes resort-svc 404 catalog-svc 🔴 PR #84
/api/v1/recommendations/plan-day resort-svc 404 catalog-svc 🔴 PR #84
/api/v1/badges resort-svc 200 resort-svc
/api/v1/admin/ski/lifts resort-svc 401 resort-svc ✅ Caddy роутит, auth нужен
/api/v1/admin/ski/slopes resort-svc 404 resort-svc 🟡 Эндпоинт не реализован
/api/v1/auth/me auth-svc 401 auth-svc
/api/v1/users auth-svc 401 auth-svc ✅ Auth required
/api/v1/roles auth-svc 200 auth-svc
/api/v1/auth/sms/send POST auth-svc 404 auth-svc 🤷 Возможно другой путь (/sms/request?)
/api/v1/hotels catalog-svc 307 catalog-svc ✅ Trailing-slash redirect
/api/v1/hotels-native catalog-svc 200 catalog-svc
/api/v1/tours catalog-svc 200 catalog-svc
/api/v1/restaurants catalog-svc 200 catalog-svc
/api/v1/recommendations catalog-svc 200 catalog-svc
/api/v1/transfers catalog-svc 200 catalog-svc
/api/v1/bookings booking-svc 200 booking-svc
/api/v1/availability/h1 booking-svc 404 booking-svc 🤷 Param required
/api/v1/payments booking-svc 404 booking-svc 🤷 Auth/param
/api/v1/favorites social-svc 401 social-svc ✅ Auth required
/api/v1/chats chat-svc 401 chat-svc ✅ Auth required
/api/v1/messages chat-svc 404 chat-svc 🤷 Нужен ?chat_id=
/api/v1/forums/categories chat-svc 200 chat-svc
/api/v1/public-profile/u1 chat-svc 404 chat-svc 🤷 Конкретного юзера нет в seed
/api/v1/progress/me gamification-svc 200 gamification-svc ✅ Guest payload
/api/v1/badges/me resort-svc 401 resort-svc ✅ Auth required
/api/v1/targets/today resort-svc 401 resort-svc ✅ Auth required
/api/v1/sos/status rtc-svc 404 rtc-svc 🤷 Возможно /sos/incidents
/api/v1/analytics/track POST hotel_api_v2 401 - ✅ Auth/body required
/api/v1/dashboard/hotelier/hotels hotel_api_v2 401 - ✅ Auth required
/api/v1/dashboard/user-stats hotel_api_v2 401 - ✅ Auth required
/api/v1/push/devices platform-svc 200 platform-svc ✅ Миграция накатана
/api/v1/push/register POST platform-svc 422 platform-svc ✅ Validation OK
/api/v1/settings/app platform-svc 404 platform-svc 🤷 Возможно /settings/global
/api/v1/notifications platform-svc 307 - ✅ Redirect to /notifications/
/api/v1/notifications/templates hotel_api_v2 401 - ✅ Auth required
/api/v1/files/test platform-svc 404 platform-svc 🤷 Конкретного файла нет
/api/v1/stories stories-svc 200 stories-svc
/api/v1/stories/me hotel_api_v2 401 -
/api/v1/bookings/statistics hotel_api_v2 401 - ✅ Auth required
/api/v1/bookings/types hotel_api_v2 200 -
/api/v1/categories hotel_api_v2 404 - 🤷
/api/v1/locations hotel_api_v2 307 - ✅ Trailing-slash
/api/v1/lifts hotel_api_v2 404 - 🤷 Legacy, могло уйти в resort-svc
/api/v1/ski-passes hotel_api_v2 307 -
/api/v1/tour-operators hotel_api_v2 307 -
/api/v1/modules hotel_api_v2 307 -
/api/v1/menu-items hotel_api_v2 307 -
/api/v1/docs hotel_api_v2 200 - ✅ Swagger UI
/api/v1/openapi.json hotel_api_v2 200 -
/api/v1/admin/dashboard hotel_api_v2 401 - ✅ Auth required
/api/v1/health platform-svc 200 platform-svc

Полный результат — admin.arkhyz-club.ru

Все коды совпадают с api.arkhyz-club.ru на финальном проходе. Различия — только в безопасностных заголовках, которые admin-блок добавляет (HSTS, X-Frame-Options DENY, и т.д.).

Что было сделано в этой сессии

  1. PR #75 + #76 (уже смержены до сессии): Caddy-роутинг для /progress/* и /push/*, восстановление FCM-плагина в мобилке.
  2. Запуск apply-sql-migration workflow (run #25904756022): накатил services/_seed/sql/03_platform_svc.sql — создал схему platform.* с таблицами push_devices, push_prefs, app_config, feature_flags, push_sends. После этого /api/v1/push/devices отдаёт 200 вместо 500.
  3. PR #84 (открыт, ждёт мержа):
  4. services/gamification-svc/app/routers/gamification.py: prefix="/api/v1"prefix="" — превентивный фикс на случай ребилда.
  5. services/resort-svc/app/routers/tracking.py: переставлены /sessions/me и /sessions/me/stats ПЕРЕД /sessions/{session_id}.
  6. infra/routes.config.mjs + регенерированные Caddyfile/Caddyfile.prod: /recommendations/slopes и /recommendations/plan-day добавлены в resort_svc matcher.

Следующие шаги

  1. Мерж PR #84 → авто-deploy → /recommendations/slopes, /recommendations/plan-day, /tracking/sessions/me ↦ 200.
  2. Проверить /admin/ski/slopes в браузере после мержа — должна показать данные из /recommendations/slopes.
  3. (Опционально) Реализовать настоящий админ-CRUD /admin/ski/slopes в admin_ski.py, если бизнес-логика требует.
  4. (Опционально) Доработать apply-sql-migration.yml — отделить применение SQL от полного ребилда стека (избежать транзиентных 502 в проде при будущих миграциях).