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

Архыз.CLUB — дальнейшие задачи и источники сигналов

Документ ведётся вместе с PROJECT_ACCESS.md. Когда задача закрывается — переносится в CHANGELOG / удаляется отсюда.


0. CHANGELOG (закрытые задачи)

2026-05-27 — Sprint #3 (medium-priority из client report): - ✅ B1 CookieConsent в 5 ролевых кабинетах (hotelier/restaurant/instructor/touroperator/transfer). - ✅ B2 GDPR кнопки: «Скачать данные» (GET /me/export) и «Удалить аккаунт» (DELETE /me) в SettingsScreen. - ✅ B3 Картинки в постах беседки. ALTER TABLE forum_posts ADD image_url; /attachments/upload?folder=besedka; UI 📎 + thumbnail. - ✅ B4 Edit/delete своих постов (Phase N — было реализовано раньше; verified). - ✅ B5+B6 Поиск + категории беседок: chip-row + /forums/categories. - ✅ B7 Запись голосовых бесед — schema + endpoints + UI shell готовы. Для активации нужно деплойнуть LiveKit Egress контейнер (см. ниже). - ✅ B8 Фильтр сторис по подъёмникам: GET /lifts → chip-row в SkiStoriesScreen. - ✅ B9 Follow/unfollow (Phase Follow — было реализовано раньше; verified). - ✅ Fix pre-existing TS errors в 3 кабинетах (Settings duplicate import; CreditMountainSnowd/CreditMountaind mass-rename артефакт).

2026-05-27 — Sprint #2 closed: - ✅ F1 OAuth merge by email — уже реализовано в hotel-api/server/app/routers/auth_oauth.py:191-205. Дубликатов в БД нет. - ✅ F2 YooKassa edge-fn → FastAPI bypass (bookingPaymentService.ts invoker для всех типов). - ✅ F3 /news, /promotions, /ski-pass/tariffs — handlers созданы. - ✅ F4 PSP routing yookassa ↔ arkhyzpay — psp.py + arkhyzpay.py + legacy_booking_compat.py для всех 5 commission-first типов (restaurant/tour/transfer/instructor/hotel). Hotel идёт через _finalize_commission_response. - ✅ F5 UI nominal-account fields в HotelierPaymentSettingsPage.tsx. - ✅ U1-U6 GC worker stuck_payment_canceller_loop + /ski-pass alias + /auth/sms/status routing + pass.passes schema. - ✅ R1 gen-routes.mjsrewrite_to + method matchers. - ✅ R2 tourist-app/vite.config.ts — minify + 10 manualChunks. - ✅ R3 5 workflows: push-trigger off (services, deploy-supabase-functions) + self-hosted (routes-drift, tests, ui-visual-regression). - ✅ R4 auto-deploy-watcher.sh уже делает docker restart arkhyz-supabase-functions на изменения supabase/functions/**. - ✅ Healthcheck arkhyzpay-apiwget --spider (HEAD 404) → wget -qO- (GET 200). - ✅ Alembic migration loop в hotel-api — alembic stamp head проставил версию e93cd6e8e846.


1. ОТКРЫТЫЕ ЗАДАЧИ

🟡 Инфра (требует ops-вмешательства)

  • LiveKit Egress контейнер для реальной записи голосовых бесед.
  • Схема БД (forum_voice_rooms.is_recording/recording_url/egress_id) готова.
  • Backend endpoints /forums/{id}/voice/recording/start|stop готовы.
  • UI кнопка в VoiceRoomBar готова.
  • Что нужно: deploy livekit-egress контейнер, задать env vars: LIVEKIT_EGRESS_URL=http://egress:8081, LIVEKIT_RECORDINGS_BUCKET, S3_*. Подключить LiveKit webhook на egress_ended/egress_updated.
  • Документация: https://docs.livekit.io/realtime/egress/deployment/

  • B10 Ротация JWT secret — теперь zero-downtime через dual-key:

Процедура (без maintenance window):

# 1. На прод-сервере, .env.prod:
HOTEL_API_JWT_SECRET_PREV=<текущий ключ>   # оставляем как PREV
HOTEL_API_JWT_SECRET=<новый случайный>     # генерим новый
# 2. docker compose up -d --no-deps hotel_api_v2 auth-svc
# 3. Ждём 30 дней (REFRESH_TTL) пока плавающие refresh-токены протухнут
# 4. Убираем HOTEL_API_JWT_SECRET_PREV из env → ротация завершена

Что сделано (Phase B10-prep): - services/auth-svc/app/jwt_utils.py — decode пробует JWT_SECRET, потом JWT_SECRET_PREV - api-admin/app/utils/jwt_utils.py + token.py — то же поведение - Encode всегда использует JWT_SECRET (новый ключ)

🟢 Кандидаты на будущее (низкий приоритет)

  • U2 SMS-логин: поиск по users.phone ДО создания нового user. Сейчас может создать дубликат если телефон в users есть, а в auth.users нет.
  • /payments/process legacy endpoint в booking-svc/routers/payments.py всё ещё на прямом yookassa.create_payment (не через PSP). Manual repay flow, риск переключать.
  • Mobile app — Capacitor build не пересобирался с момента F2 patch. Нужен EAS rebuild чтобы deep-link arkhyz://payment-result ловил arkhyzpay redirects.

🔴 Задачи заказчика (1-2 минуты каждая)

  • GitHub Actions billing — Settings → Billing → set spending limit $1 — разблокирует cloud CI.
  • Apple-сертификаты — загрузить из Apple Developer Account (7 секретов в repo Settings).
  • Пополнить sms.ru — иначе SMS-коды не отправляются (демо-код 1111 для +7999000XXXX работает).
  • VPN на сервере для Telegramapi.telegram.org заблокирован РКН, нужен outbound VPN.

2. ИСТОЧНИКИ СИГНАЛОВ — куда смотреть, чтобы найти новые баги

Каждое утро (или после каждого деплоя) — пройтись по этим 6 источникам.

🔥 A. Внутренний Sentry — public.error_events table

Команда (быстрая):

ssh root@arkhyz-club.ru "docker exec arkhyz-supabase-db psql -U postgres -c \"SELECT service, severity, COUNT(*), LEFT(message, 80) FROM public.error_events WHERE created_at > NOW() - INTERVAL '24 hours' GROUP BY service, severity, LEFT(message, 80) ORDER BY 3 DESC LIMIT 15;\""

UI: https://errors.arkhyz-club.ru (Sentry-lite). Фильтры в _drop_internal_sentry_errors: - PermissionDeniedError unsupported_country (OpenAI) - ConnectTimeoutError errors.arkhyz-club.ru (internal loop) - Supabase health check Connection refused (transient)

Действие: count >= 5 → stacktrace → root cause → fix или новый filter.

🟧 B. Caddy 5xx логи

ssh root@arkhyz-club.ru "docker logs --since 1h arkhyz-caddy 2>&1 | grep -E ' (5[0-9][0-9]) '" | head -30

🟨 C. Backend Python tracebacks

for svc in booking catalog resort platform chat auth rtc analytics social stories gamification pass; do
  cnt=$(ssh root@arkhyz-club.ru "docker logs --since 24h arkhyz-$svc-svc 2>&1 | grep -cE 'ERROR|Exception|Traceback'")
  [ "$cnt" -gt 20 ] && echo "$svc: $cnt"
done

🟩 D. БД integrity checks

-- Broken bookings (commission > 0 без YK payment_id, >30 дней)
SELECT 'room', COUNT(*) FROM public.room_bookings WHERE status='pending_payment' AND created_at < NOW() - INTERVAL '30 days' UNION ALL
SELECT 'tour', COUNT(*) FROM public.tour_bookings WHERE status='pending_payment' AND created_at < NOW() - INTERVAL '30 days' UNION ALL
SELECT 'restaurant', COUNT(*) FROM public.restaurant_bookings WHERE status='pending_payment' AND created_at < NOW() - INTERVAL '30 days' UNION ALL
SELECT 'transfer', COUNT(*) FROM public.transfer_bookings WHERE status='pending_payment' AND created_at < NOW() - INTERVAL '30 days' UNION ALL
SELECT 'instructor', COUNT(*) FROM public.instructor_bookings WHERE status='pending_payment' AND created_at < NOW() - INTERVAL '30 days';

-- Stuck payments (worker должен чистить)
SELECT COUNT(*) FROM public.payments WHERE status='pending' AND created_at < NOW() - INTERVAL '24 hours';

-- Orphan auth.users
SELECT COUNT(*) FROM auth.users au LEFT JOIN public.users pu ON pu.id = au.id WHERE pu.id IS NULL;

Норма: broken_*_30d = 0, stuck_payments = 0, orphan_auth = 0. На 2026-05-27 всё в норме.

🟦 E. Disk + RAM

ssh root@arkhyz-club.ru "df -h / && free -h | head -2"

Норма: диск < 75%, RAM свободно > 6GB. Auto-cleanup: arkhyz-disk-cleanup.timer (Sun 03:00).

🟪 F. Container health

ssh root@arkhyz-club.ru "docker ps -a --format '{{.Names}}|{{.Status}}' | grep -v healthy | grep -v 'Up '"

Норма: 0 unhealthy. Если arkhyz-supabase-functions пересоздан < 5 мин назад — частые crash.

🟫 G. PSP arkhyzpay-api

ssh root@arkhyz-club.ru "curl -s http://localhost:8092/v1/health"

Ожидаемо: {"status":"ok","tbank_mode":"mock",...}. Когда T-Bank переключится в production — tbank_mode:"production".


3. ПРИЗНАКИ ЧТО НАДО БРАТЬ ЗАДАЧУ

🔴 Срочно: 1. Прямая жалоба пользователя — drop everything 2. count >= 10 за час в Sentry 3. 5xx на главных страницах 4. Disk > 80%, RAM < 1GB

🟡 Накопительно: 5. count >= 50 за сутки в Sentry 6. Backend микросервис генерит >100 ERROR/день 7. stuck_payments > 100 8. broken_bookings > 50

🟢 Refactor: 9. TODO/FIXME > N дней 10. Дублирование кода (5+ мест) 11. Файлы > 1000 строк 12. Циклические импорты


4. ПРОЦЕСС РЕШЕНИЯ ЗАДАЧ

1. Sentry/жалоба → что сломано
2. Воспроизвести через curl/SQL на проде
3. Root cause (grep по сообщению)
4. Fix → smoke на проде
5. Commit + push (detailed message)
6. Auto-deploy подхватит через ~1-2 мин (или ручной deploy-svc.sh <svc>)
7. Verify smoke
8. Закрыть таску / записать в CHANGELOG

Формат commit message:

<тип>: краткое (< 70 символов)

Корень: 1-3 предложения почему было сломано.
Fix: что именно поменяли + почему так.
Затронуто: список файлов.

Co-Authored-By: Claude <noreply@anthropic.com>


5. ДИАГНОСТИКА — cheat-sheet

Симптом Команда
502/503 на URL docker logs arkhyz-caddy \| grep <url> + docker logs arkhyz-<svc>
Пустой UI DevTools Network → 4xx/5xx; Console → ErrorBoundary stacktrace
Бронь не создаётся SQL свежий <table>_bookings + booking-svc logs
«role does not exist» pg_roles (tourist/hotelier/admin/etc)
PostgREST 404 на таблицу NOTIFY pgrst, 'reload schema'
Kong 502 «Host unreachable» docker restart arkhyz-supabase-kong (DNS stale)
Alembic migration loop docker exec <api> alembic stamp head
PSP outage curl localhost:8092/v1/health (arkhyzpay) + YK env

6. ТЕКУЩЕЕ СОСТОЯНИЕ (2026-05-27)

  • 0 ошибок в error_events за 7 дней
  • 0 stuck/broken bookings
  • arkhyzpay-api healthy (GET /v1/health)
  • Все 5 PSP-flow роутятся через psp.py
  • 5 cabinet-доменов отвечают 200
  • CI billing экономия: 5 workflows на self-hosted + 2 push triggers off

Документ обновлять при каждой новой задаче / закрытой проблеме.