HEAVY: finish music service migration, tidy up services, more tests

This commit is contained in:
ari melody 2026-08-01 00:29:31 +01:00
parent 9e311df462
commit 90a671982c
Signed by: ari
GPG key ID: CF99829C92678188
47 changed files with 2698 additions and 902 deletions

180
service/music/release.go Normal file
View file

@ -0,0 +1,180 @@
package music
import (
"arimelody-web/errors"
"arimelody-web/model"
"arimelody-web/service/validator"
"fmt"
"time"
)
// Hydrates a release with its additional data (credits, tracks, links)
func (s *MusicService) fillRelease(release *model.Release) error {
credits, err := s.GetReleaseCredits(release.ID)
if err != nil { return fmt.Errorf("credits: %s", err) }
release.Credits = append(release.Credits, credits...)
tracks, err := s.GetReleaseTracks(release.ID)
if err != nil { return fmt.Errorf("tracks: %s", err) }
release.Tracks = append(release.Tracks, tracks...)
links, err := s.GetReleaseLinks(release.ID)
if err != nil { return fmt.Errorf("links: %s", err) }
release.Links = append(release.Links, links...)
return nil
}
func (s *MusicService) GetAllReleases(onlyVisible bool, limit int) ([]*model.Release, error) {
return s.repo.GetAllReleases(onlyVisible, limit)
}
func (s *MusicService) GetAllFullReleases(onlyVisible bool, limit int) ([]*model.Release, error) {
releases, err := s.repo.GetAllReleases(onlyVisible, limit)
if err != nil { return nil, err }
for _, release := range releases {
if err := s.fillRelease(release); err != nil { return nil, err }
}
return releases, nil
}
func (s *MusicService) GetReleaseCount(onlyVisible bool) (int, error) {
return s.repo.GetReleaseCount(onlyVisible)
}
func (s *MusicService) GetReleaseByID(id string) (*model.Release, error) {
release, err := s.repo.GetReleaseByID(id)
if err != nil { return nil, err }
if release == nil { return nil, errors.NewNotExistError("Release does not exist") }
return release, nil
}
func (s *MusicService) GetFullReleaseByID(id string) (*model.Release, error) {
release, err := s.GetReleaseByID(id)
if err != nil { return nil, err }
if err := s.fillRelease(release); err != nil { return nil, err }
return release, nil
}
func (s *MusicService) GetReleaseTracks(id string) ([]*model.Track, error) {
return s.repo.GetReleaseTracks(id)
}
func (s *MusicService) GetReleaseCredits(id string) ([]*model.Credit, error) {
return s.repo.GetReleaseCredits(id)
}
func (s *MusicService) GetReleaseLinks(id string) ([]*model.Link, error) {
return s.repo.GetReleaseLinks(id)
}
func (s *MusicService) CreateRelease(
id string,
title string,
releaseType string,
releaseDate time.Time,
artworkURL string,
) error {
if len(id) == 0 { return errors.NewValidationError("Release ID cannot be empty") }
if !validator.ValidateID(id) { return errors.NewValidationError("Release ID contains invalid characters") }
if len(title) == 0 { return errors.NewValidationError("Release title cannot be empty") }
validReleaseType, ok := model.ValidReleaseType(releaseType)
if !ok { return errors.NewValidationError("Invalid release type") }
if err := s.repo.CreateRelease(id, title, validReleaseType, releaseDate, artworkURL); err != nil { return err }
s.log.Printf("Created new release '%s' (%s)", title, id)
return nil
}
func (s *MusicService) UpdateRelease(release *model.Release) error {
if len(release.ID) == 0 { return errors.NewValidationError("Release ID cannot be empty") }
if !validator.ValidateID(release.ID) { return errors.NewValidationError("Release ID contains invalid characters") }
if len(release.Title) == 0 { return errors.NewValidationError("Release title cannot be empty") }
if err := s.repo.UpdateRelease(release); err != nil { return err }
s.log.Printf("Updated release '%s' (%s)", release.Title, release.ID)
return nil
}
func (s *MusicService) UpdateReleaseID(oldID string, newID string) error {
if len(newID) == 0 { return errors.NewValidationError("Release ID cannot be empty") }
if !validator.ValidateID(newID) { return errors.NewValidationError("Release ID contains invalid characters") }
if err := s.repo.UpdateReleaseID(oldID, newID); err != nil { return err }
s.log.Printf("Updated release ID %s to %s", oldID, newID)
return nil
}
func (s *MusicService) UpdateReleaseVisibility(id string, visible bool) error {
if err := s.repo.UpdateReleaseVisibility(id, visible); err != nil { return err }
s.log.Printf("Updated release '%s' visibility to %t", id, visible)
return nil
}
func (s *MusicService) UpdateReleaseTitle(id string, title string) error {
if len(title) == 0 { return errors.NewValidationError("Release title cannot be empty") }
if err := s.repo.UpdateReleaseTitle(id, title); err != nil { return err }
s.log.Printf("Updated release '%s' title to %s", id, title)
return nil
}
func (s *MusicService) UpdateReleaseDescription(id string, description string) error {
if err := s.repo.UpdateReleaseDescription(id, description); err != nil { return err }
s.log.Printf("Updated release '%s' description to %s", id, description)
return nil
}
func (s *MusicService) UpdateReleaseType(id string, releaseType string) error {
validReleaseType, ok := model.ValidReleaseType(releaseType)
if !ok { return errors.NewValidationError("Invalid release type") }
if err := s.repo.UpdateReleaseType(id, validReleaseType); err != nil { return err }
s.log.Printf("Updated release '%s' type to %s", id, releaseType)
return nil
}
func (s *MusicService) UpdateReleaseDate(id string, releaseDate time.Time) error {
if err := s.repo.UpdateReleaseDate(id, releaseDate); err != nil { return err }
s.log.Printf("Updated release '%s' date to %s", id, releaseDate.Format(time.RFC3339))
return nil
}
func (s *MusicService) UpdateReleaseArtwork(id string, artwork string) error {
if err := s.repo.UpdateReleaseArtwork(id, artwork); err != nil { return err }
s.log.Printf("Updated release '%s' artwork to %s", id, artwork)
return nil
}
func (s *MusicService) UpdateReleaseBuyInfo(id string, buyName string, buyLink string) error {
if err := s.repo.UpdateReleaseBuyInfo(id, buyName, buyLink); err != nil { return err }
s.log.Printf("Updated release '%s' buy info (name='%s', link='%s')", id, buyName, buyLink)
return nil
}
func (s *MusicService) UpdateReleaseCopyright(id string, copyright string, url string) error {
if err := s.repo.UpdateReleaseCopyright(id, copyright, url); err != nil { return err }
s.log.Printf("Updated release '%s' copyright (copyright='%s', url='%s')", id, copyright, url)
return nil
}
func (s *MusicService) UpdateReleaseTracks(id string, newTrackIDs []string) error {
for _, id := range newTrackIDs {
if len(id) == 0 { return errors.NewValidationError("Track IDs cannot be empty") }
}
if err := s.repo.UpdateReleaseTracks(id, newTrackIDs); err != nil { return err }
s.log.Printf("Updated release '%s' tracks (%d tracks)", id, len(newTrackIDs))
return nil
}
func (s *MusicService) UpdateReleaseCredits(id string, newCredits []*model.Credit) error {
if err := s.repo.UpdateReleaseCredits(id, newCredits); err != nil { return err }
s.log.Printf("Updated release '%s' credits (%d credits)", id, len(newCredits))
return nil
}
func (s *MusicService) UpdateReleaseLinks(id string, newLinks []*model.Link) error {
for _, link := range newLinks {
if len(link.Name) == 0 { return errors.NewValidationError("Link names cannot be empty") }
if len(link.URL) == 0 { return errors.NewValidationError("Link URLs cannot be empty") }
}
if err := s.repo.UpdateReleaseLinks(id, newLinks); err != nil { return err }
s.log.Printf("Updated release '%s' links (%d links)", id, len(newLinks))
return nil
}
func (s *MusicService) DeleteRelease(id string) error {
deletedID, err := s.repo.DeleteRelease(id)
if err != nil { return err }
if deletedID == "" { return errors.NewNotExistError("Release does not exist") }
s.log.Printf("Deleted release '%s'", id)
return nil
}