Архыз.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.mjs — rewrite_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-api — wget --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ловилarkhyzpayredirects.
🔴 Задачи заказчика (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 на сервере для Telegram —
api.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
Документ обновлять при каждой новой задаче / закрытой проблеме.