2026-01-03 14:07:04 +00:00
# 100 к 1 - Multiplayer Game
2025-12-31 16:49:50 +00:00
2026-01-03 14:07:04 +00:00
Интерактивная веб-игра "100 к 1" с поддержкой мультиплеера и локальной игры.
2025-12-31 16:49:50 +00:00
2026-01-03 14:07:04 +00:00
## 🎮 Возможности
### 🌐 Мультиплеер (NEW!)
- **Игровые комнаты** с уникальными кодами
- **QR-коды** для быстрого присоединения
- **Real-time синхронизация** через WebSocket
- **Роли**: Ведущий, Игрок, Зритель
- **Статистика игр** с историей
### 🏠 Локальная игра
- Оригинальная версия для одного устройства
- Управление участниками
- Редактирование вопросов
- Автосохранение прогресса
## 🛠 Технологический стек
### Frontend
- **React 18.2** + **Vite 5.0**
- **React Router v6** - маршрутизация
- **Socket.IO Client** - WebSocket
- **Axios** - HTTP клиент
- **QRCode** - генерация QR-кодов
### Backend
- **NestJS** - TypeScript фреймворк
2026-01-04 21:48:55 +00:00
- **PostgreSQL** - база данных (запускается отдельно в Coolify)
2026-01-03 14:07:04 +00:00
- **Prisma ORM** - работа с БД
- **Socket.IO** - WebSocket сервер
- **JWT** - авторизация
2026-01-04 21:48:55 +00:00
- **ConfigModule** - управление переменными окружения
2026-01-03 14:07:04 +00:00
## 📁 Структура проекта
```
sto_k_odnomu/
├── backend/ # NestJS Backend
│ ├── src/
│ │ ├── auth/ # Авторизация (JWT, анонимные)
│ │ ├── rooms/ # Модуль комнат
│ │ ├── questions/ # Паки вопросов
│ │ ├── game/ # WebSocket игра
│ │ ├── stats/ # Статистика
│ │ └── prisma/ # Prisma сервис
│ ├── prisma/
│ │ ├── schema.prisma # Схема БД
│ │ └── seed.ts # Seed данные
│
├── src/ # React Frontend
│ ├── pages/ # Страницы
│ │ ├── Home.jsx # Главная
│ │ ├── CreateRoom.jsx # Создание комнаты
│ │ ├── JoinRoom.jsx # Присоединение
│ │ ├── RoomPage.jsx # Лобби комнаты
│ │ └── LocalGame.jsx # Локальная игра
│ ├── services/ # API & WebSocket
│ ├── context/ # React Context
│ ├── hooks/ # Custom hooks
│ └── components/ # Компоненты игры
│
└── PLAN.md # Детальный план разработки
```
## 🚀 Быстрый старт
### 1. Backend
2025-12-31 16:49:50 +00:00
2026-01-04 21:48:55 +00:00
**Требования:**
- PostgreSQL должен быть запущен отдельно (например, в Coolify)
- Переменные окружения должны быть настроены в системе или через Coolify
**Переменные окружения:**
- `DATABASE_URL` - строка подключения к PostgreSQL
- `JWT_SECRET` - секретный ключ для JWT токенов
- `PORT` - порт для backend (по умолчанию 3000)
- `HOST` - хост для backend (по умолчанию 0.0.0.0)
- `CORS_ORIGIN` - домен frontend приложения, с которого разрешены запросы к backend (по умолчанию http://localhost:5173)
**Важно:** `CORS_ORIGIN` - это домен, где работает frontend, а не backend. Например, если frontend на `https://example.com` , а backend на `https://api.example.com` , то `CORS_ORIGIN` должен быть `https://example.com` .
2025-12-31 16:49:50 +00:00
```bash
2026-01-03 14:07:04 +00:00
cd backend
# Установить зависимости
2025-12-31 16:49:50 +00:00
npm install
2026-01-03 14:07:04 +00:00
# Выполнить миграции
npx prisma migrate dev --name init
2026-01-04 21:48:55 +00:00
# Заполнить демо-данными (опционально)
2026-01-03 14:07:04 +00:00
npm run prisma:seed
# Запустить backend
npm run start:dev
2025-12-31 16:49:50 +00:00
```
2026-01-03 14:07:04 +00:00
Backend: http://localhost:3000
### 2. Frontend
2025-12-31 16:49:50 +00:00
```bash
2026-01-03 14:07:04 +00:00
# В корне проекта
npm install
2025-12-31 16:49:50 +00:00
npm run dev
```
2026-01-03 14:07:04 +00:00
Frontend: http://localhost:5173
## 🎯 Как играть
### Мультиплеер
1. **Главная страница** → Выберите действие
2. **Создать комнату** :
- Выберите пак вопросов
- Настройте параметры
- Поделитесь кодом/QR с игроками
3. **Присоединиться** :
- Введите 6-значный код комнаты
- Или отсканируйте QR-код
4. **Начать игру** (ведущий)
5. Игроки открывают ответы в реальном времени
### Локальная игра
2025-12-31 16:49:50 +00:00
2026-01-03 14:07:04 +00:00
1. Главная → **Локальная игра**
2. Добавьте участников (👥)
3. Играйте на одном устройстве
2025-12-31 16:49:50 +00:00
2026-01-03 14:07:04 +00:00
## 📊 API Endpoints
2025-12-31 16:49:50 +00:00
2026-01-03 14:07:04 +00:00
### REST API
2025-12-31 16:49:50 +00:00
2026-01-03 14:07:04 +00:00
- **Auth**: `/auth/anonymous` , `/auth/register` , `/auth/login`
- **Rooms**: `/rooms` (POST, GET), `/rooms/:code` , `/rooms/:id/join`
- **Questions**: `/questions/packs` (CRUD)
- **Stats**: `/stats/game-history/:userId` , `/stats/user/:userId`
2025-12-31 17:05:48 +00:00
2026-01-03 14:07:04 +00:00
### WebSocket Events
2025-12-31 17:05:48 +00:00
2026-01-03 14:07:04 +00:00
**Client → Server:**
- `joinRoom` , `startGame` , `revealAnswer` , `updateScore` , `nextQuestion` , `endGame`
2025-12-31 17:05:48 +00:00
2026-01-03 14:07:04 +00:00
**Server → Client:**
- `roomUpdate` , `gameStarted` , `answerRevealed` , `scoreUpdated` , `questionChanged` , `gameEnded`
2025-12-31 17:05:48 +00:00
2026-01-03 14:07:04 +00:00
## 🗄️ База данных
### Модели (Prisma)
- **User** - пользователи (анонимные/зарегистрированные)
- **Room** - игровые комнаты
- **Participant** - участники (HOST/PLAYER/SPECTATOR)
- **QuestionPack** - паки вопросов
- **GameHistory** - история игр
### Seed данные
- Демо пользователь
- 2 пака вопросов (общие, семейные)
2026-01-04 21:48:55 +00:00
## ⚙️ Переменные окружения
Приложение использует переменные окружения напрямую через `@nestjs/config` . В с е переменные должны быть настроены в системе или через Coolify:
### Backend переменные:
- `DATABASE_URL` - строка подключения к PostgreSQL (например: `postgresql://user:password@host:5432/dbname` )
- `JWT_SECRET` - секретный ключ для JWT токенов (см. ниже как сгенерировать)
- `PORT` - порт для backend (по умолчанию 3000)
- `HOST` - хост для backend (по умолчанию 0.0.0.0)
- `CORS_ORIGIN` - **домен frontend приложения** , с которого разрешены запросы к backend (по умолчанию http://localhost:5173)
**Важно:** `CORS_ORIGIN` - это домен, где работает frontend, а не backend. Это настройка безопасности, которая говорит backend, с каких доменов принимать запросы. Например:
- Frontend: `https://example.com`
- Backend: `https://api.example.com`
- `CORS_ORIGIN` должен быть: `https://example.com`
### Frontend переменные:
- `VITE_API_URL` - URL backend API (по умолчанию http://localhost:3000)
- `VITE_WS_URL` - URL WebSocket сервера (по умолчанию http://localhost:3000)
**Почему префикс `VITE_` ?**
Vite (инструмент сборки) требует префикс `VITE_` для переменных окружения, которые должны быть доступны в клиентском коде. Это сделано для безопасности — только переменные с этим префиксом встраиваются в собранный JavaScript код.
**Как это работает:**
- В коде используется `import.meta.env.VITE_API_URL` (см. `src/services/api.js` )
- Vite заменяет эти значения на этапе сборки
- Без префикса `VITE_` переменная не будет доступна в браузере
**Пример использования:**
```javascript
// В коде frontend
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3000';
```
**Примечание:** PostgreSQL должен быть запущен отдельно как отдельное приложение в Coolify.
2026-01-03 14:07:04 +00:00
2026-01-04 21:48:55 +00:00
### 🔑 Как сгенерировать JWT_SECRET?
`JWT_SECRET` - это секретный ключ для подписи и проверки JWT токенов. Он должен быть:
- **Случайным** и криптографически стойким
- **Длинным** (минимум 32 символа, рекомендуется 64+)
- **Уникальным** для каждого приложения
- **Секретным** - никогда не коммитьте в Git!
#### Способы генерации:
**1. Используя Node.js:**
2026-01-03 14:07:04 +00:00
```bash
2026-01-04 21:48:55 +00:00
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
```
2026-01-03 14:07:04 +00:00
2026-01-04 21:48:55 +00:00
**2. Используя OpenSSL:**
```bash
openssl rand -hex 64
```
**3. Используя Python:**
```bash
python3 -c "import secrets; print(secrets.token_hex(64))"
```
**4. Онлайн генераторы:**
- Можно использовать, но не рекомендуется для production
- Пример: https://generate-secret.vercel.app/64
#### Пример сгенерированного ключа:
```
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2g3h4i5j6k7l8m9n0o1p2q3r4s5t6u7v8w9x0y1z2
2026-01-03 14:07:04 +00:00
```
2026-01-04 21:48:55 +00:00
#### Где использовать:
1. **В Coolify** : Добавьте переменную окружения `JWT_SECRET` в настройках приложения
2. **Локально для разработки** : Можно использовать `.env` файл (но не коммитить е г о !)
**⚠️ ВАЖНО:**
- Используйте **разные** `JWT_SECRET` для development и production
- Если измените `JWT_SECRET` , все существующие токены станут недействительными
- Храните секрет в безопасности - это критически важно для безопасности приложения
2026-01-03 14:07:04 +00:00
## 📝 Разработка
### Backend
2025-12-31 17:05:48 +00:00
```bash
2026-01-03 14:07:04 +00:00
cd backend
npm run start:dev # Dev режим
npm run build # Сборка
npm run test # Тесты
npx prisma studio # DB GUI
```
### Frontend
2025-12-31 17:05:48 +00:00
2026-01-03 14:07:04 +00:00
```bash
npm run dev # Dev сервер
npm run build # Сборка
npm run preview # Preview build
2025-12-31 17:05:48 +00:00
```
2026-01-03 14:07:04 +00:00
## 🔐 Безопасность
- JWT токены для авторизации
- CORS настройка
- Валидация данных (class-validator)
- PostgreSQL для надёжного хранения
## 📄 Документация
- [Backend README ](backend/README.md ) - детальная документация backend
- [PLAN.md ](PLAN.md ) - полный план разработки
- [API Documentation ](backend/README.md#-api-endpoints ) - REST и WebSocket API
## 🎨 Особенности
- ❄️ Новогодняя анимация снежинок
- 🎨 Адаптивный дизайн
- 💾 Автосохранение прогресса
- 🔄 Real-time синхронизация
- 📱 QR-коды для присоединения
- 📊 Статистика и история игр
## 🚧 Roadmap
- [x] Backend инфраструктура
- [x] Frontend интеграция
- [x] WebSocket real-time
- [x] Игровые комнаты
- [x] QR-коды
- [ ] Таймер ответов
- [ ] Экспорт статистики (PDF)
- [ ] Публичные комнаты
- [ ] Рейтинг игроков
## 📜 Лицензия
2025-12-31 17:05:48 +00:00
2026-01-03 14:07:04 +00:00
Private project
2025-12-31 16:49:50 +00:00
2026-01-03 14:07:04 +00:00
---
2025-12-31 16:49:50 +00:00
2026-01-03 14:07:04 +00:00
**Сделано с ❤️ для семейных праздников**