63 lines
1.5 KiB
Go
63 lines
1.5 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
|
|
"watch-party-backend/internal/repo"
|
|
)
|
|
|
|
var ErrInvalidTime = errors.New("invalid start_time (expected HH:MM or HH:MM:SS)")
|
|
|
|
type EpisodeService interface {
|
|
GetCurrent(ctx context.Context) (repo.Episode, error)
|
|
SetCurrent(ctx context.Context, id int64, start string) (repo.Episode, error)
|
|
}
|
|
|
|
type episodeService struct {
|
|
repo repo.EpisodeRepository
|
|
}
|
|
|
|
func NewEpisodeService(r repo.EpisodeRepository) EpisodeService {
|
|
return &episodeService{repo: r}
|
|
}
|
|
|
|
func (s *episodeService) GetCurrent(ctx context.Context) (repo.Episode, error) {
|
|
c, cancel := context.WithTimeout(ctx, 3*time.Second)
|
|
defer cancel()
|
|
return s.repo.GetCurrent(c)
|
|
}
|
|
|
|
func (s *episodeService) SetCurrent(ctx context.Context, id int64, start string) (repo.Episode, error) {
|
|
// normalize and validate time as HH:MM:SS
|
|
normalized, err := normalizeHHMMSS(start)
|
|
if err != nil {
|
|
return repo.Episode{}, ErrInvalidTime
|
|
}
|
|
|
|
c, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
defer cancel()
|
|
|
|
// do the transaction
|
|
if err := s.repo.SetCurrent(c, id, normalized); err != nil {
|
|
return repo.Episode{}, err
|
|
}
|
|
// return the new current row
|
|
return s.repo.GetCurrent(c)
|
|
}
|
|
|
|
func normalizeHHMMSS(s string) (string, error) {
|
|
s = strings.TrimSpace(s)
|
|
if len(s) == 5 { // HH:MM → append seconds
|
|
s += ":00"
|
|
}
|
|
// Strict parse/format to 24h
|
|
t, err := time.Parse("15:04:05", s)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return t.Format("15:04:05"), nil
|
|
}
|