Files
enigFM/TECHNICAL_SPEC.md
2025-12-12 13:30:09 +03:00

12 KiB
Raw Permalink Blame History

Техническое задание: Совместное прослушивание музыки

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. Принятые решения

  • Аутентификация — обязательная регистрация
  • Права управления — все участники могут управлять плеером
  • Чат — текстовый чат в каждой комнате
  • Библиотека музыки — общая для всех пользователей
  • Приватность — все комнаты публичные