Отличный вопрос — вариантов четыре, и у них разные профили. Разложу и дам рекомендацию.

Вариант 1 — SSH-туннель к серверному Postgres (рекомендую для «посмотреть сейчас»). Не копируем ничего: пробрасываем порт (ssh -L 5433:localhost:5432 asus), локальный Scala-бэкенд подключается через туннель, локальный UI dev-сервер ходит в него. Данные настоящие и живые, сетевой трафик шифрован, Postgres наружу не торчит. Read-only эндпоинты — риска для данных практически нет. Две минуты настройки.

Одна честная оговорка: при первом старте Scala-бэкенд выполнит одну запись в серверную базу — Flyway создаст табличку flyway_schema_history и поставит baseline-отметку (мы это специально так спроектировали под будущий деплой, схему он не тронет). Если хотите стерильности — могу подключиться read-only ролью, но для вашей же базы это, на мой взгляд, излишество: отметка всё равно понадобится при деплое Scala-бэкенда.

Вариант 2 — копия базы локально (pg_dump через ssh → локальный контейнер). Правильный выбор, когда начнём фазу 3: гонять тяжёлые агрегатные запросы и эксперименты с индексами по 140k партий лучше на копии, а не на проде. Минусы: разовый снимок устаревает, диск (вероятно, несколько ГБ с учётом turns/positions). Если приживётся — оформлю как mise run db:refresh-from-server, у вас в lab был ровно такой паттерн.

Вариант 3 — просто открыть UI на сервере (порт 8030). Самый быстрый, но именно сейчас — худший: там крутится старый Python-API, в котором жив баг rating_classic — наш новый поиск игроков получит 500-ку. И UI-образ на сервере обновится до фазы 1 только после pull нового latest. Это, кстати, намёк на следующую инфраструктурную задачу: задеплоить Scala-бэкенд на ASUS.

Вариант 4 — Postgres наружу по сети без туннеля. Не рекомендую даже в LAN: привычка плохая, выигрыша перед туннелем никакого.

Итого: сейчас — вариант 1; для фазы 3 — добавим вариант 2 как mise-таск.

Чтобы запустить вариант 1 прямо сейчас, мне нужно от вас одно: как вы ходите на ASUS по ssh — алиас из ~/.ssh/config или user@host? Дальше я сам: туннель → Scala-бэкенд на туннель → dev-сервер UI → и смотрим на настоящие 140 тысяч партий.


Подключаюсь. Сначала проверю ssh-доступ и найду контейнер базы на сервере:

Готово — UI работает на полной базе с сервера. Что сейчас запущено на вашей машине:

  1. SSH-туннель к Postgres на ASUS (локальный порт 5433 → серверный 5432) — база наружу не торчит, трафик шифрован.
  2. Scala-бэкенд на :8000, подключён через туннель. Flyway, как и предупреждал, сделал единственную запись — baseline-отметку (она же пригодится при деплое).
  3. UI dev-сервер на http://localhost:5173 — открывайте и смотрите.

Что показала проверка на настоящих данных:

  • Главный результат: реальная партия из 76 состояний проиграна через движок без единого предупреждения — реконструкция, которую мы построили на синтетике, согласна с данными импортёра. Это первая встреча всей цепочки «импортёр → PostgreSQL → Scala-API → движок в браузере», и она прошла чисто.
  • Список, пагинация, глубокие ссылки, иконки костей — всё живое; поиск находит реальных игроков с честными рейтингами (LinDa 3196, LaBourdonnais 3127 — lateral join работает).
  • Находка для бэклога: поиск игроков на 140k партий — ~1.1s (lateral join без покрывающего индекса). Оформил analytics#74 с двумя вариантами лечения (составной индекс или материализация рейтинга — это прямо milestone v0.4).

Когда насмотритесь, погасить всё одной командой: kill $(cat /tmp/dc_tunnel.pid) (туннель) и lsof -ti :8000 | xargs kill (бэкенд); dev-сервер закроется с панелью предпросмотра. Если такой режим понравится — могу оформить постоянный mise run backend:remote с туннелем в одном таске.


С возвращением! Ситуация после вчерашнего дня сложилась так, что следующий шаг почти выбирает себя сам. Дам рекомендацию с обоснованием.

Рекомендую: задеплоить Scala-бэкенд на ASUS. Три причины:

  1. Назревающая мина. На сервере до сих пор крутится Python-API с живым багом rating_classic. Сейчас это незаметно, потому что серверный UI-образ старый. Но как только сервер подтянет свежий latest (а он уже мультиарх и содержит фазу 1 с поиском игроков) — поиск начнёт получать 500-ку от Python. Новый UI и старый API несовместимы по факту; деплой Scala-бэкенда снимает это до того, как оно выстрелит.
  2. Замыкается цикл переписывания. Вчера мы проверили Scala-бэкенд против полной серверной базы через туннель — он готов; Flyway-отметка в проде уже стоит. После деплоя Python можно выводить из эксплуатации, минус целый стек.
  3. Предпосылка фазы 2. POST /api/games имеет смысл, когда он принимает партии на сервере — ETL и боты будут писать туда, не в локалку.

Объём понятный: Dockerfile для бэкенда (multi-stage: sbt-сборка → лёгкий JRE-образ, токен для Maven-реестра через BuildKit-секрет — образец уже отработан в UI), мультиарх-публикация в ghcr, перевод api-сервиса в docker-compose на новый образ, деплой на сервер по ssh, smoke-проверка. Заодно закрыл бы #74 (индекс для поиска игроков — на проде 1.1s станут заметны сразу).

После этого — фаза 3, позиционная аналитика: агрегаты по позициям, матожидание, эксплорер. Это самая интересная и самая «суждение-ёмкая» работа — для неё советую свежую сессию с чистым контекстом (мой нынешний уже работает на сжатом резюме; для деплоя его хватит с запасом, для дизайна аналитики лучше начать заново — память всё переносит).

Параллельно, по вчерашней схеме маршрутизации: lefthook (#60) и Starlight (#61) — идеальные кандидаты для отдельной Sonnet-сессии, пока мы заняты деплоем.

И мелочь: со вчера могли остаться запущенными туннель, бэкенд и dev-сервер — перед началом приберу.

Если согласны — стартую деплой прямо сейчас.