init
This commit is contained in:
291
TECHNICAL_SPEC.md
Normal file
291
TECHNICAL_SPEC.md
Normal file
@@ -0,0 +1,291 @@
|
||||
# Техническое задание: Совместное прослушивание музыки
|
||||
|
||||
## 1. Описание продукта
|
||||
|
||||
Веб-приложение для синхронного прослушивания музыки с друзьями в реальном времени. Пользователи создают комнаты, приглашают друзей по ссылке и слушают музыку одновременно.
|
||||
|
||||
## 2. Основные функции
|
||||
|
||||
### 2.1 Комнаты
|
||||
- Создание комнаты (генерация уникального ID/ссылки)
|
||||
- Публичные комнаты с возможностью поиска/списка
|
||||
- Присоединение по ссылке или из списка комнат
|
||||
- Отображение списка участников
|
||||
|
||||
### 2.2 Музыкальный плеер
|
||||
- Воспроизведение MP3 из S3-хранилища
|
||||
- Синхронизация playback между всеми участниками
|
||||
- Управление доступно всем участникам: play/pause, перемотка, следующий/предыдущий трек
|
||||
- Громкость (локальная, у каждого своя)
|
||||
- Очередь воспроизведения (playlist)
|
||||
- Отображение текущего трека, прогресса
|
||||
|
||||
### 2.3 Чат
|
||||
- Текстовый чат внутри комнаты
|
||||
- Сообщения видны всем участникам в реальном времени
|
||||
|
||||
### 2.4 Управление треками
|
||||
- Загрузка MP3 файлов в S3
|
||||
- Общая библиотека треков (доступна всем пользователям во всех комнатах)
|
||||
- Добавление треков в очередь
|
||||
- Базовые метаданные: название, исполнитель
|
||||
|
||||
### 2.5 Пользователи
|
||||
- Обязательная регистрация/авторизация
|
||||
- Профиль пользователя
|
||||
|
||||
## 3. Технические требования
|
||||
|
||||
### 3.1 Стек технологий
|
||||
|
||||
**Frontend:**
|
||||
- Vue 3 (Composition API)
|
||||
- Pinia (state management)
|
||||
- Vue Router
|
||||
- WebSocket клиент для real-time
|
||||
|
||||
**Backend:**
|
||||
- Python
|
||||
- FastAPI (REST API + WebSocket)
|
||||
- SQLAlchemy (ORM)
|
||||
- Alembic (миграции)
|
||||
|
||||
**База данных:**
|
||||
- PostgreSQL
|
||||
|
||||
**Хранилище файлов:**
|
||||
- S3 (FirstVDS)
|
||||
|
||||
### 3.2 Синхронизация
|
||||
- WebSocket для real-time коммуникации
|
||||
- Компенсация сетевой задержки
|
||||
- Периодическая синхронизация позиции трека
|
||||
|
||||
### 3.3 Хранилище
|
||||
- S3 (FirstVDS) для MP3 файлов
|
||||
- Presigned URLs для безопасного доступа к файлам
|
||||
- Ограничение размера файла: 10MB
|
||||
- Лимит общего объёма хранилища: 90GB (проверка перед загрузкой)
|
||||
|
||||
### 3.4 Масштабируемость
|
||||
- Лимит участников на комнату (например, 50)
|
||||
- Автоудаление неактивных комнат
|
||||
|
||||
## 4. Схема базы данных
|
||||
|
||||
### users
|
||||
| Поле | Тип | Описание |
|
||||
|------|-----|----------|
|
||||
| id | UUID | Первичный ключ |
|
||||
| username | VARCHAR(50) | Уникальное имя пользователя |
|
||||
| email | VARCHAR(255) | Email (уникальный) |
|
||||
| password_hash | VARCHAR(255) | Хэш пароля |
|
||||
| created_at | TIMESTAMP | Дата регистрации |
|
||||
|
||||
### rooms
|
||||
| Поле | Тип | Описание |
|
||||
|------|-----|----------|
|
||||
| id | UUID | Первичный ключ |
|
||||
| name | VARCHAR(100) | Название комнаты |
|
||||
| owner_id | UUID (FK) | Создатель комнаты |
|
||||
| current_track_id | UUID (FK) | Текущий трек |
|
||||
| playback_position | INTEGER | Позиция воспроизведения (мс) |
|
||||
| is_playing | BOOLEAN | Играет ли сейчас |
|
||||
| created_at | TIMESTAMP | Дата создания |
|
||||
|
||||
### tracks
|
||||
| Поле | Тип | Описание |
|
||||
|------|-----|----------|
|
||||
| id | UUID | Первичный ключ |
|
||||
| title | VARCHAR(255) | Название трека |
|
||||
| artist | VARCHAR(255) | Исполнитель |
|
||||
| duration | INTEGER | Длительность (мс) |
|
||||
| s3_key | VARCHAR(500) | Путь к файлу в S3 |
|
||||
| uploaded_by | UUID (FK) | Кто загрузил |
|
||||
| created_at | TIMESTAMP | Дата загрузки |
|
||||
|
||||
### room_queue
|
||||
| Поле | Тип | Описание |
|
||||
|------|-----|----------|
|
||||
| id | UUID | Первичный ключ |
|
||||
| room_id | UUID (FK) | Комната |
|
||||
| track_id | UUID (FK) | Трек |
|
||||
| position | INTEGER | Позиция в очереди |
|
||||
| added_by | UUID (FK) | Кто добавил |
|
||||
|
||||
### room_participants
|
||||
| Поле | Тип | Описание |
|
||||
|------|-----|----------|
|
||||
| room_id | UUID (FK) | Комната |
|
||||
| user_id | UUID (FK) | Пользователь |
|
||||
| joined_at | TIMESTAMP | Время входа |
|
||||
|
||||
### messages
|
||||
| Поле | Тип | Описание |
|
||||
|------|-----|----------|
|
||||
| id | UUID | Первичный ключ |
|
||||
| room_id | UUID (FK) | Комната |
|
||||
| user_id | UUID (FK) | Автор |
|
||||
| text | TEXT | Текст сообщения |
|
||||
| created_at | TIMESTAMP | Время отправки |
|
||||
|
||||
## 5. API Endpoints
|
||||
|
||||
### Аутентификация
|
||||
- `POST /api/auth/register` — регистрация
|
||||
- `POST /api/auth/login` — вход
|
||||
- `POST /api/auth/logout` — выход
|
||||
- `GET /api/auth/me` — текущий пользователь
|
||||
|
||||
### Комнаты
|
||||
- `GET /api/rooms` — список публичных комнат
|
||||
- `POST /api/rooms` — создать комнату
|
||||
- `GET /api/rooms/{id}` — информация о комнате
|
||||
- `DELETE /api/rooms/{id}` — удалить комнату (только владелец)
|
||||
- `POST /api/rooms/{id}/join` — присоединиться
|
||||
- `POST /api/rooms/{id}/leave` — покинуть
|
||||
|
||||
### Плеер (через REST + WebSocket)
|
||||
- `POST /api/rooms/{id}/play` — воспроизвести
|
||||
- `POST /api/rooms/{id}/pause` — пауза
|
||||
- `POST /api/rooms/{id}/seek` — перемотка
|
||||
- `POST /api/rooms/{id}/next` — следующий трек
|
||||
- `POST /api/rooms/{id}/prev` — предыдущий трек
|
||||
|
||||
### Очередь
|
||||
- `GET /api/rooms/{id}/queue` — очередь треков
|
||||
- `POST /api/rooms/{id}/queue` — добавить трек в очередь
|
||||
- `DELETE /api/rooms/{id}/queue/{track_id}` — убрать из очереди
|
||||
|
||||
### Треки
|
||||
- `GET /api/tracks` — библиотека треков
|
||||
- `POST /api/tracks/upload` — загрузить трек
|
||||
- `DELETE /api/tracks/{id}` — удалить трек
|
||||
|
||||
### Чат
|
||||
- `GET /api/rooms/{id}/messages` — история сообщений
|
||||
|
||||
### WebSocket
|
||||
- `WS /ws/rooms/{id}` — real-time события комнаты (синхронизация плеера, чат, участники)
|
||||
|
||||
## 6. Структура проекта
|
||||
|
||||
```
|
||||
enigfm/
|
||||
├── backend/
|
||||
│ ├── app/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── main.py # Точка входа FastAPI
|
||||
│ │ ├── config.py # Конфигурация (env переменные)
|
||||
│ │ ├── database.py # Подключение к БД
|
||||
│ │ │
|
||||
│ │ ├── models/ # SQLAlchemy модели
|
||||
│ │ │ ├── __init__.py
|
||||
│ │ │ ├── user.py
|
||||
│ │ │ ├── room.py
|
||||
│ │ │ ├── track.py
|
||||
│ │ │ └── message.py
|
||||
│ │ │
|
||||
│ │ ├── schemas/ # Pydantic схемы
|
||||
│ │ │ ├── __init__.py
|
||||
│ │ │ ├── user.py
|
||||
│ │ │ ├── room.py
|
||||
│ │ │ ├── track.py
|
||||
│ │ │ └── message.py
|
||||
│ │ │
|
||||
│ │ ├── routers/ # API роуты
|
||||
│ │ │ ├── __init__.py
|
||||
│ │ │ ├── auth.py
|
||||
│ │ │ ├── rooms.py
|
||||
│ │ │ ├── tracks.py
|
||||
│ │ │ └── websocket.py
|
||||
│ │ │
|
||||
│ │ ├── services/ # Бизнес-логика
|
||||
│ │ │ ├── __init__.py
|
||||
│ │ │ ├── auth.py
|
||||
│ │ │ ├── room.py
|
||||
│ │ │ ├── track.py
|
||||
│ │ │ ├── s3.py # Работа с S3
|
||||
│ │ │ └── sync.py # Синхронизация плеера
|
||||
│ │ │
|
||||
│ │ └── utils/ # Утилиты
|
||||
│ │ ├── __init__.py
|
||||
│ │ └── security.py # JWT, хэширование
|
||||
│ │
|
||||
│ ├── alembic/ # Миграции БД
|
||||
│ │ ├── versions/
|
||||
│ │ └── env.py
|
||||
│ │
|
||||
│ ├── tests/
|
||||
│ ├── requirements.txt
|
||||
│ ├── alembic.ini
|
||||
│ └── .env.example
|
||||
│
|
||||
├── frontend/
|
||||
│ ├── src/
|
||||
│ │ ├── main.js # Точка входа
|
||||
│ │ ├── App.vue
|
||||
│ │ │
|
||||
│ │ ├── components/ # Vue компоненты
|
||||
│ │ │ ├── player/
|
||||
│ │ │ │ ├── AudioPlayer.vue
|
||||
│ │ │ │ ├── PlayerControls.vue
|
||||
│ │ │ │ ├── ProgressBar.vue
|
||||
│ │ │ │ └── VolumeControl.vue
|
||||
│ │ │ ├── room/
|
||||
│ │ │ │ ├── RoomCard.vue
|
||||
│ │ │ │ ├── RoomList.vue
|
||||
│ │ │ │ ├── ParticipantsList.vue
|
||||
│ │ │ │ └── Queue.vue
|
||||
│ │ │ ├── chat/
|
||||
│ │ │ │ ├── ChatWindow.vue
|
||||
│ │ │ │ └── ChatMessage.vue
|
||||
│ │ │ ├── tracks/
|
||||
│ │ │ │ ├── TrackList.vue
|
||||
│ │ │ │ ├── TrackItem.vue
|
||||
│ │ │ │ └── UploadTrack.vue
|
||||
│ │ │ └── common/
|
||||
│ │ │ ├── Header.vue
|
||||
│ │ │ └── Modal.vue
|
||||
│ │ │
|
||||
│ │ ├── views/ # Страницы
|
||||
│ │ │ ├── HomeView.vue # Список комнат
|
||||
│ │ │ ├── RoomView.vue # Страница комнаты
|
||||
│ │ │ ├── LoginView.vue
|
||||
│ │ │ ├── RegisterView.vue
|
||||
│ │ │ └── TracksView.vue # Библиотека треков
|
||||
│ │ │
|
||||
│ │ ├── stores/ # Pinia stores
|
||||
│ │ │ ├── auth.js
|
||||
│ │ │ ├── room.js
|
||||
│ │ │ ├── player.js
|
||||
│ │ │ └── tracks.js
|
||||
│ │ │
|
||||
│ │ ├── composables/ # Vue composables
|
||||
│ │ │ ├── useWebSocket.js
|
||||
│ │ │ ├── usePlayer.js
|
||||
│ │ │ └── useApi.js
|
||||
│ │ │
|
||||
│ │ ├── router/
|
||||
│ │ │ └── index.js
|
||||
│ │ │
|
||||
│ │ └── assets/
|
||||
│ │ └── styles/
|
||||
│ │
|
||||
│ ├── public/
|
||||
│ ├── package.json
|
||||
│ ├── vite.config.js
|
||||
│ └── .env.example
|
||||
│
|
||||
├── docker-compose.yml # PostgreSQL, Backend, Frontend
|
||||
├── .gitignore
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## 7. Принятые решения
|
||||
|
||||
- **Аутентификация** — обязательная регистрация
|
||||
- **Права управления** — все участники могут управлять плеером
|
||||
- **Чат** — текстовый чат в каждой комнате
|
||||
- **Библиотека музыки** — общая для всех пользователей
|
||||
- **Приватность** — все комнаты публичные
|
||||
Reference in New Issue
Block a user