sto-k-odnomu/README.md
2026-01-05 01:11:25 +03:00

312 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 100 к 1 - Multiplayer Game
Интерактивная веб-игра "100 к 1" с поддержкой мультиплеера и локальной игры.
## 🎮 Возможности
### 🌐 Мультиплеер (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 фреймворк
- **PostgreSQL** - база данных (запускается отдельно в Coolify)
- **Prisma ORM** - работа с БД
- **Socket.IO** - WebSocket сервер
- **JWT** - авторизация
- **ConfigModule** - управление переменными окружения
## 📁 Структура проекта
```
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
**Требования:**
- 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`.
```bash
cd backend
# Установить зависимости
npm install
# Выполнить миграции
npx prisma migrate dev --name init
# Заполнить демо-данными (опционально)
npm run prisma:seed
# Запустить backend
npm run start:dev
```
Backend: http://localhost:3000
### 2. Frontend
```bash
# В корне проекта
npm install
npm run dev
```
Frontend: http://localhost:5173
## 🎯 Как играть
### Мультиплеер
1. **Главная страница** → Выберите действие
2. **Создать комнату**:
- Выберите пак вопросов
- Настройте параметры
- Поделитесь кодом/QR с игроками
3. **Присоединиться**:
- Введите 6-значный код комнаты
- Или отсканируйте QR-код
4. **Начать игру** (ведущий)
5. Игроки открывают ответы в реальном времени
### Локальная игра
1. Главная → **Локальная игра**
2. Добавьте участников (👥)
3. Играйте на одном устройстве
## 📊 API Endpoints
### REST API
- **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`
### WebSocket Events
**Client → Server:**
- `joinRoom`, `startGame`, `revealAnswer`, `updateScore`, `nextQuestion`, `endGame`
**Server → Client:**
- `roomUpdate`, `gameStarted`, `answerRevealed`, `scoreUpdated`, `questionChanged`, `gameEnded`
## 🗄️ База данных
### Модели (Prisma)
- **User** - пользователи (анонимные/зарегистрированные)
- **Room** - игровые комнаты
- **Participant** - участники (HOST/PLAYER/SPECTATOR)
- **QuestionPack** - паки вопросов
- **GameHistory** - история игр
### Seed данные
- Демо пользователь
- 2 пака вопросов (общие, семейные)
## ⚙️ Переменные окружения
Приложение использует переменные окружения напрямую через `@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`
**Поддержка нескольких origins:** Можно указать несколько доменов через запятую:
```
CORS_ORIGIN=https://party-games.online,https://www.party-games.online,http://localhost:5173
```
### 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.
### 🔑 Как сгенерировать JWT_SECRET?
`JWT_SECRET` - это секретный ключ для подписи и проверки JWT токенов. Он должен быть:
- **Случайным** и криптографически стойким
- **Длинным** (минимум 32 символа, рекомендуется 64+)
- **Уникальным** для каждого приложения
- **Секретным** - никогда не коммитьте в Git!
#### Способы генерации:
**1. Используя Node.js:**
```bash
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
```
**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
```
#### Где использовать:
1. **В Coolify**: Добавьте переменную окружения `JWT_SECRET` в настройках приложения
2. **Локально для разработки**: Можно использовать `.env` файл (но не коммитить его!)
**⚠️ ВАЖНО:**
- Используйте **разные** `JWT_SECRET` для development и production
- Если измените `JWT_SECRET`, все существующие токены станут недействительными
- Храните секрет в безопасности - это критически важно для безопасности приложения
## 📝 Разработка
### Backend
```bash
cd backend
npm run start:dev # Dev режим
npm run build # Сборка
npm run test # Тесты
npx prisma studio # DB GUI
```
### Frontend
```bash
npm run dev # Dev сервер
npm run build # Сборка
npm run preview # Preview build
```
## 🔐 Безопасность
- 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
- [TROUBLESHOOTING.md](TROUBLESHOOTING.md) - решение проблем с деплоем (502 ошибки, CORS и т.д.)
## 🎨 Особенности
- ❄️ Новогодняя анимация снежинок
- 🎨 Адаптивный дизайн
- 💾 Автосохранение прогресса
- 🔄 Real-time синхронизация
- 📱 QR-коды для присоединения
- 📊 Статистика и история игр
## 🚧 Roadmap
- [x] Backend инфраструктура
- [x] Frontend интеграция
- [x] WebSocket real-time
- [x] Игровые комнаты
- [x] QR-коды
- [ ] Таймер ответов
- [ ] Экспорт статистики (PDF)
- [ ] Публичные комнаты
- [ ] Рейтинг игроков
## 📜 Лицензия
Private project
---
**Сделано с ❤️ для семейных праздников**