Сейчас посмотрю, что у вас есть в репозиториях, и сделаю обзор всех четырёх проектов.
Все четыре обзора готовы. Перед тем как писать итог, проверю одно критичное утверждение — что в dicechess-lab закоммичен .env с секретами.
Баг подтверждён: Player.rating_classic используется в players.py:28, но в модели Player такого поля нет — эндпоинт GET /api/players упадёт с AttributeError при первом же вызове.
Вот итоговое ревью всех четырёх проектов.
Ревью экосистемы Dice Chess
Общий вердикт: у вас сложилась цельная и грамотно спроектированная экосистема из четырёх проектов с ясным разделением ролей: lab (продукт-тренажёр + ETL с dicechess.com) → engine (правила и боты) → analytics (PostgreSQL-хранилище для массового анализа) → analytics-ui (визуализация). Инженерная культура высокая: типизация везде, CI/CD, документация, миграции. Главные слабые места — аналитика без тестов и со сломанным эндпоинтом игроков, дублирование FEN-логики между проектами и отсутствие глубокого стохастического поиска в движке.
Кстати, в Repositories есть ещё dicechess-bots и dicechess-extension — их я не смотрел, скажите, если нужно.
1. dicechess-lab — зрелый, активный, в хорошей форме
Самый большой проект: ~1500 коммитов с марта, FastAPI + SQLite (WAL) + Svelte 5 PWA, деплой на Raspberry Pi, гейтированный пайплайн staging → production. Бэкенд ~5.5k строк с паттерном Repository, ~2.8k строк тестов; фронтенд с Vitest + Playwright. Документация на Astro/Starlight, версия v0.2.0 с роадмапом до v1.0.
Что стоит поправить:
- Высокая цикломатическая сложность в game_sync.py (CC≈14) и
routers/share.py(CC≈12) — это ваш ETL и шаринг, самые рискованные места для багов. - Конфликт peer-зависимостей
vite-plugin-pwa↔ Vite 8 закрыт флагом--legacy-peer-deps— мина под будущие обновления. - Возможные N+1-запросы в роутере игроков (на Raspberry Pi с SD-картой это чувствительно) — стоит проверить
selectinloadвrepositories/players.py.
Один из агентов заявил «критическую утечку секретов в git» — я это проверил, и это неправда: backend-api/.env корректно игнорируется, в репозитории только .env.example и .env.staging с плейсхолдерами. Тревога ложная, но добавить detect-secrets в pre-commit всё равно дёшево и полезно.
2. dicechess-engine-scala — технически сильный, но поиск пока «жадный»
Scala 3.8, кросс-компиляция JVM + Scala.js, magic bitboards, opaque types, 85% покрытия с жёстким порогом в CI, JMH-бенчмарки, тест/код ≈ 0.94. Полная генерация ходов, правило максимума микро-ходов, DFEN-парсер, JS API из 10 функций, интегрированный с PWA на dc.jc.id.lv. Очень добротная работа.
Слабые места:
- Все 6 ботов — жадные эвристики. Expectiminimax/MCTS из роадмапа (Phase 4) не реализован. Самый умный бот (
PrudentSearch, экспериментальный) лишь оценивает вероятность взятия короля/ферзя по 216 исходам костей на один ход вперёд. sys.errorв TurnGenerator.scala:99 — защитная паника роняет движок (в том числе в браузере) вместо graceful-ошибки. Стоит заменить наEitherдо массового self-play.queenCaptureProbabilityне учитывает правило максимума микро-ходов и завышает вероятность —PrudentSearchиз-за этого может недооценивать ферзя.
3. dicechess-analytics — правильная архитектура, но v0.2 не дотянута
PostgreSQL 18 + FastAPI + Alembic, грамотная схема: games / turns / positions (дедупликация по нормализованному FEN + xxhash64) / players / game_events. Импортёр из SQLite лаборатории работает батчами с ON CONFLICT. Документация и роадмап (v0.1 готов, v0.2 в работе) — на месте.
Проблемы по убыванию важности:
- Сломан
GET /api/players— сортировка по несуществующемуPlayer.rating_classic(players.py:28, schemas.py:25). Подтверждено мной — это рантайм-AttributeError. Рейтинги живут вgames.white_rating/black_rating, у игрока поля нет. - Тестов нет вообще — для проекта, чья ценность в корректности данных, это главный риск. Баг №1 как раз иллюстрация: один smoke-тест на каждый эндпоинт его бы поймал.
- Импортёр — монолит на 749 строк (importer.py) с хрупкими эвристиками: границы ходов определяются по броскам костей, события (дабл/ничья) реконструируются догадками,
terminationзахардкожен как"unknown". Парсинг FEN без валидации. - Три отдельных database engine (
database.py,api/dependencies.py, синхронный в импортёре) — стоит централизовать. - Нет
POST /api/games— без него движок и боты не смогут лить партии напрямую (заявлено в v0.2).
4. dicechess-analytics-ui — бодрый старт, правильный скелет
Svelte 5 + Vite + Tailwind 4, Chessground, 7 тем, Docker с nginx-прокси на API. За первый день: рабочий список партий с пагинацией и полноценный просмотрщик — доска, кости с отметкой использованных, история ходов, плейбек с клавиатуры. Для одного дня — отличный результат, ~1.9k строк.
Риски:
activeGameStoreна 493 строки без тестов — реконструкция состояний из turns/events (многоэтапный парсинг, интерливинг событий) — самое сложное и самое непокрытое место. Сюда первым делом нужны юнит-тесты с проверкой непрерывности:state[i].fen == applyMove(state[i-1].fen, move).- Собственный
fenHelper.tsприменяет ходы псевдолегально без валидации — если бэкенд пришлёт кривые данные, доска молча покажет неверную позицию. И это уже третья реализация FEN/ходов в экосистеме (после движка и lab). - Нет retry/восстановления при ошибках API, заглушки вместо Openings/Players/Analytics.
Сквозные наблюдения
- Логика правил Dice Chess размазана по четырём местам: Scala-движок (эталон),
@rabestro/dicechess-enginenpm-пакет в lab,fenHelper.tsв UI, FEN-эвристики в импортёре analytics. Движок уже компилируется в Scala.js — UI и импортёр могли бы валидировать через него, а не дублировать. - Данные текут через хрупкое звено: SQLite лаборатории → синхронный импортёр с догадками → PostgreSQL. Любая ошибка эвристики тиражируется на миллионы строк и потом ломает UI.
- Тесты распределены обратно пропорционально риску: движок — 85%+, lab — ~50%, а analytics (источник истины для всей аналитики) — 0%.
Если коротко, что чинить первым
rating_classicв analytics (минуты) + базовый pytest-набор на API и импортёр.sys.error→EitherвTurnGeneratorдвижка.- Тесты на
activeGameStore.reconstructStates()в UI. - Решить стратегически: движок как единственный источник правил (через Scala.js-пакет) для UI и валидации в импортёре.
Это было ревью «что есть». Следующий ваш вопрос — «как двигаться дальше» — заслуживает отдельного разговора: тут есть развилка между «углубить аналитику» (позиционная статистика v0.3, opening explorer — то, ради чего БД и затевалась) и «поумнить движок» (expectiminimax), и они друг друга усиливают: сильному боту нужна статистика позиций, а аналитике — оценка движка. Скажите, в какую сторону вам интереснее, и я помогу спланировать.