Плейлисты
Relevant source files
The following files were used as context for generating this wiki page:
- internal/features/playlists/model/playlist.go
- internal/features/playlists/service/create.go
- internal/features/playlists/service/service.go
- internal/features/playlists/repository/postgres/playlist_repository.go
- internal/features/playlists/transport/http/transport.go
- internal/features/playlists/transport/http/create.go
- migrations/001_init.up.sql
Модуль "Плейлисты" является ключевым компонентом музыкального сервиса, позволяющим пользователям организовывать свои музыкальные коллекции. Он предоставляет функциональность для создания, управления, обновления и удаления персонализированных списков треков. Система реализует бизнес-ограничения в зависимости от типа подписки пользователя, в частности, ограничивая количество создаваемых плейлистов для пользователей с бесплатным тарифом (FREE).
Sources: README.md, internal/features/playlists/service/service.go:11-12, internal/features/playlists/service/create.go:13-16
Архитектура и компоненты
Модуль построен с использованием многослойной архитектуры, разделяющей транспортный уровень (HTTP), уровень бизнес-логики (Service) и уровень доступа к данным (Repository).
Слой транспорта (HTTP)
Обрабатывает входящие HTTP-запросы, извлекает параметры из путей (например, playlist_id) и тел запросов, проверяет аутентификацию пользователя через JWT-токены и делегирует выполнение сервисному слою.
Sources: internal/features/playlists/transport/http/transport.go:27-31, internal/features/playlists/transport/http/create.go:34-45
Слой сервиса (Business Logic)
Содержит основную логику валидации и соблюдения бизнес-правил. Основные функции включают:
- Проверку лимитов на количество плейлистов для FREE-пользователей.
- Проверку прав собственности (Ownership) перед модификацией или удалением.
Sources: internal/features/playlists/service/service.go:24-27, internal/features/playlists/service/create.go:13-28
Слой репозитория (PostgreSQL)
Выполняет прямые SQL-запросы к базе данных PostgreSQL с использованием библиотеки sqlx. Он управляет сохранением данных в таблицах playlists и playlist_tracks.
Sources: internal/features/playlists/repository/postgres/playlist_repository.go:21-25, migrations/001_init.up.sql:71-84
Схема взаимодействия компонентов
Ниже представлена диаграмма процесса создания плейлиста, иллюстрирующая взаимодействие слоев и проверку лимитов.
Модель данных
Сущность Playlist
Основная структура данных, представляющая плейлист в системе.
| Поле | Тип | Описание |
|---|---|---|
ID | int64 | Уникальный идентификатор плейлиста |
UserID | int64 | ID владельца плейлиста |
Title | string | Название (обязательно) |
Description | *string | Необязательное описание |
CreatedAt | time.Time | Время создания |
Sources: internal/features/playlists/model/playlist.go:5-11
Структура БД
Связь между плейлистами и треками реализована через таблицу связи playlist_tracks, что позволяет реализовать отношение многие-ко-многим.
Sources: migrations/001_init.up.sql:71-84
API Эндпоинты
Модуль предоставляет стандартный RESTful интерфейс для управления ресурсами.
| Метод | Путь | Описание |
|---|---|---|
GET | /playlists | Получить список плейлистов текущего пользователя |
POST | /playlists | Создать новый плейлист |
GET | /playlists/{id} | Получить детали плейлиста по ID |
PUT | /playlists/{id} | Обновить название или описание |
DELETE | /playlists/{id} | Удалить плейлист |
POST | /playlists/{pid}/tracks/{tid} | Добавить трек в плейлист |
DELETE | /playlists/{pid}/tracks/{tid} | Удалить трек из плейлиста |
Sources: internal/features/playlists/transport/http/transport.go:41-75, README.md
Бизнес-правила и ограничения
- Лимит для FREE подписки: Пользователи с типом подписки
FREEограничены созданием не более чем 3 плейлистов. Это значение конфигурируется через параметрFREE_PLAYLIST_LIMIT.
Sources: internal/features/playlists/service/create.go:15-28, README.md:58 - Проверка владения (Ownership): Любая операция модификации (
Update,Delete,AddTrack,RemoveTrack) или получения деталей по ID проверяет, совпадает лиUserIDвладельца плейлиста с ID текущего аутентифицированного пользователя. В противном случае возвращается ошибкаErrForbiddenPlaylist.
Sources: internal/features/playlists/service/update.go:15-17, internal/features/playlists/service/get.go:14-16 - Дубликаты треков: Система предотвращает добавление одного и того же трека в один и тот же плейлист дважды с использованием первичного ключа на паре
(playlist_id, track_id)в базе данных.
Sources: internal/features/playlists/repository/postgres/playlist_repository.go:115-118, migrations/001_init.up.sql:83
Реализация репозитория
Пример реализации добавления трека в плейлист с обработкой конфликтов:
func (r *PlaylistRepository) AddTrack(ctx context.Context, playlistID, trackID int64) error {
query := `INSERT INTO playlist_tracks (playlist_id, track_id, added_at) VALUES ($1, $2, NOW())`
_, err := r.db.ExecContext(ctx, query, playlistID, trackID)
if err != nil {
// Проверка на ошибку дублирования ключа (Postgres код 23505)
if strings.Contains(err.Error(), "duplicate key") || strings.Contains(err.Error(), "23505") {
return ErrTrackAlreadyInPlaylist
}
return fmt.Errorf("add track to playlist: %w", err)
}
return nil
}
Sources: internal/features/playlists/repository/postgres/playlist_repository.go:112-123
Заключение
Система плейлистов спроектирована с учетом масштабируемости и строгого соблюдения прав доступа. Использование Postgres индексов и ограничений целостности данных на уровне схемы гарантирует надежность хранения музыкальных подборок пользователей, а сервисный слой обеспечивает гибкое применение бизнес-логики подписок.