Перейти к содержимому

Схема — repos/poker-api/apps/server/prisma/schema.prisma: 30 моделей, 476 строк, 23 миграции на 2026-08-24.

Модель Смысл
User аккаунт: телефон (уникален), имя, ник, аватар, город, adminRole?, status (active/banned)
PlayerProfile 1:1 с User: xp, level, skill, gamesPlayed, wins, banUntil?
DealerProfile витрина дилера: фото, био, стаж, gamesDealt
GuestPlayer walk-in без аккаунта: телефон и имя, claimedByUserId?
OtpCode, RefreshToken материал аутентификации: хеши, TTL, счётчики

PlayerProfile держит производные величины (уровень, силу, число игр). Они пересчитываются, а не правятся поверх, — см. рейтинг.

Модель Смысл
Organizer клуб: имя, статус, cancelDeadlineHours (по умолчанию 3)
OrganizerMember членство (organizerId, userId) с ролью owner | td | dealer
DealerInvite приглашение дилера: телефон и одноразовый код с TTL
Location зал: имя, город, адрес, таймзона, координаты, описание, фото
BlindTemplate структура блайндов: levels (JSON), startingStack, lateRegLevel

У BlindTemplate значение organizerId = null означает платформенный шаблон, доступный всем клубам.

Модель Смысл
Season квартал: startsOn/endsOn, статус current | archived
Tournament организатор, зал, сезон, шаблон, тип (mtt | sng), старт, вместимость, статус, призы, чат, баннер и серверные поля часов: currentLevelIdx, levelStartedAt, pausedAt, chipsInPlay
TournamentTranslation заголовок и подпись по локали (ru/en)
TournamentDealer назначение дилера на турнир
Registration запись игрока или гостя: статус, источник app | walk_in, eliminatedAt?
TableSeat посадка: (tournamentId, tableNo, seatNo) уникальна, active гасится при вылете
Result итог: место, очки сезона, xp, сила до и после; (tournamentId, place) уникальна
NoShowStrike страйк за неявку или позднюю отмену, прощаемый

Часы турнира живут на сервере, а не в клиенте. currentLevelIdx, levelStartedAt и pausedAt в Tournament — источник истины; клиент считает оставшееся время сам, но от серверных значений.

Уникальность (tournamentId, place) в Result — та причина, по которой перестановка мест делается перестановкой отметок между игроками, а не переписыванием номеров подряд.

Модель Смысл
City + CityTranslation справочник городов (ru/en), slug — стабильный ключ сида
LevelTier + LevelTierTranslation тиры уровней: minLevel, цвет, картинка, названия
PromoSlide + PromoSlideTranslation слайдер главного экрана: картинка, цель (tournament | url), окно показа, порядок
RatingConfigRow единственная строка с конфигом рейтинга и санкций
Follow, PushToken, Notification, AuditLog подписки, токены устройств, журнал уведомлений, аудит

prisma db seed, идемпотентен. Кладёт:

  • платформенный шаблон блайндов «Стандарт 20 мин» — 13 отрезков, стек 20 000, перерыв 15 минут после шестого уровня;
  • 10 городов, от Москвы до Владивостока;
  • 6 тиров уровней: fish с уровня 1, grinder 3, regular 6, shark 10, pro 15, legend 25.