Commit Graph
4 Commits
Author SHA1 Message Date
NotBigGhostandClaude Opus 5 bdd07e8103 SSE: событие партии несёт участников, клиент не дёргает лишних
Событие о партии рассылается всей группе, и клиент по нему инвалидировал историю
игр, публичные профили и личную статистику получателя. В группе из шести человек
любая партия двоих заставляла остальные четыре вкладки перезапрашивать свою
историю и открытый профиль, хотя у них ничего не изменилось.

Теперь событие несёт participant_ids. Общие витрины (карточка партии, списки и
статистика группы, топ и главная) обновляются у всех — рейтинг глобальный, чужая
партия действительно двигает топ. История, публичный профиль и личная статистика
обновляются только у тех, кто играл, и у зрителей их профилей.

При удалении партии участники собираются ДО удаления: каскад уносит их строки
вместе с партией, и собранный после список всегда был бы пустым. Это же
поведение закреплено тестом.

Событие без participant_ids (вкладка открыта до обновления сервера) обрабатывается
по-старому, широко: обновление бэкенда не ломает уже открытые страницы.

#33

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BoiJK9ux8peeyjLb8TYjFf
2026-09-09 20:47:32 +03:00
NotBigGhostandClaude Opus 5 8be9a23c0c Партия: общий черновик завершения и запрет результатов до финиша
Результаты (места и причина победы) теперь пишутся только в завершённую партию.
Раньше их можно было проставить идущей: партия оставалась in_progress, висела в
«Незавершённых», в статистику не попадала и очков не приносила — победитель есть,
а игры как бы не было. Дату и общий комментарий по ходу партии править по-прежнему
можно: двойственного состояния они не создают.

Форма завершения получила общий черновик (match_finish_drafts): раскладка мест,
ничьи, выбывшие, комментарии и причина победы видны всем, кто заполняет партию.
Отдельная таблица, а не колонки в matches, намеренно — запись в строку партии
дёргает onupdate у updated_at, то есть версию для оптимистичной блокировки, и
«Завершить» у второго участника ловил бы STALE_WRITE на каждую чужую правку.
Черновик удаляется при завершении и уходит каскадом при удалении партии.

Черновик разъезжается отдельным типом SSE-события: он меняется на каждое движение
тайла, и полная инвалидация (лидерборд, история, профили) по нему была бы
расточительной. Автору правки событие не шлётся.

#28

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BoiJK9ux8peeyjLb8TYjFf
2026-09-09 19:39:31 +03:00
NotBigGhostandClaude Opus 4.8 f4286ffa6c Уведомления: persistent + live (push-to-invalidate → pull)
Новая система уведомлений поверх готовой SSE-шины: события пишутся в БД,
живут 72 часа и чистятся (при чтении списка + фоновой задачей), всплывают
сверху экрана в момент прихода, доступны через колокольчик в правом верхнем
углу (бейдж непрочитанных + панель).

Типы: приглашение в группу (→ /group), старт/финиш партии участникам кроме
инициатора (→ /match/{id}). Титулы — готовый хелпер-задел (не подключён, т.к.
выдача титулов игрокам ещё не реализована).

Бэкенд: модель Notification + миграция 0008 (идемпотентная), notification_service,
notify.notifications_changed, роутер /api/notifications (GET + /read), триггеры
в groups/matches, фоновая чистка в lifespan, защита hub.publish от закрытого loop.
Фронт: useNotifications/useMarkNotificationsRead, NotificationBell/Panel/Toaster,
перекомпоновка top-bar, стили; useServerEvents знает тип notifications.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 15:16:40 +03:00
NotBigGhostandClaude Opus 4.8 2500ca575b Реал-тайм через SSE (push-to-invalidate): живые приглашения/партии, авто-обновление без перезагрузки
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 22:52:41 +03:00