Refactor episode service and handlers to use UseCases interface

This commit is contained in:
Nik Afiq 2025-12-02 20:56:45 +09:00
parent f8837fed9f
commit ab7f919d0e
4 changed files with 29 additions and 26 deletions

View File

@ -0,0 +1,12 @@
package episode
import "context"
// UseCases captures the inbound port for episode-related interactions.
type UseCases interface {
GetCurrent(ctx context.Context) (Episode, error)
SetCurrent(ctx context.Context, id int64, start string) (Episode, error)
MoveToArchive(ctx context.Context, ids []int64) (MoveResult, error)
ListAll(ctx context.Context) ([]Episode, error)
Delete(ctx context.Context, id int64) error
}

View File

@ -7,12 +7,11 @@ import (
"time"
"watch-party-backend/internal/core/episode"
"watch-party-backend/internal/service"
"github.com/gin-gonic/gin"
)
func NewRouter(svc service.EpisodeService) *gin.Engine {
func NewRouter(svc episode.UseCases) *gin.Engine {
r := gin.New()
r.Use(gin.Logger(), gin.Recovery())
@ -54,7 +53,7 @@ func timeHandler(c *gin.Context) {
// @Failure 404 {object} HTTPError "no current row found"
// @Failure 500 {object} HTTPError "query failed"
// @Router /api/v1/current [get]
func getCurrentHandler(svc service.EpisodeService) gin.HandlerFunc {
func getCurrentHandler(svc episode.UseCases) gin.HandlerFunc {
return func(c *gin.Context) {
cur, err := svc.GetCurrent(c.Request.Context())
if err != nil {
@ -81,7 +80,7 @@ func getCurrentHandler(svc service.EpisodeService) gin.HandlerFunc {
// @Failure 404 {object} HTTPError "id not found"
// @Failure 500 {object} HTTPError "update failed"
// @Router /api/v1/current [post]
func setCurrentHandler(svc service.EpisodeService) gin.HandlerFunc {
func setCurrentHandler(svc episode.UseCases) gin.HandlerFunc {
return func(c *gin.Context) {
var req SetCurrentReq
if err := c.ShouldBindJSON(&req); err != nil {
@ -117,7 +116,7 @@ func setCurrentHandler(svc service.EpisodeService) gin.HandlerFunc {
// @Failure 400 {object} HTTPError "empty ids"
// @Failure 500 {object} HTTPError "move failed"
// @Router /api/v1/archive [post]
func moveToArchiveHandler(svc service.EpisodeService) gin.HandlerFunc {
func moveToArchiveHandler(svc episode.UseCases) gin.HandlerFunc {
return func(c *gin.Context) {
var req MoveReq
if err := c.ShouldBindJSON(&req); err != nil {
@ -158,7 +157,7 @@ func moveToArchiveHandler(svc service.EpisodeService) gin.HandlerFunc {
// @Success 200 {array} CurrentResponse
// @Failure 500 {object} HTTPError "list failed"
// @Router /api/v1/shows [get]
func listShowsHandler(svc service.EpisodeService) gin.HandlerFunc {
func listShowsHandler(svc episode.UseCases) gin.HandlerFunc {
return func(c *gin.Context) {
items, err := svc.ListAll(c.Request.Context())
if err != nil {
@ -180,7 +179,7 @@ func listShowsHandler(svc service.EpisodeService) gin.HandlerFunc {
// @Failure 404 {object} HTTPError "id not found"
// @Failure 500 {object} HTTPError "delete failed"
// @Router /api/v1/shows [delete]
func deleteShowsHandler(svc service.EpisodeService) gin.HandlerFunc {
func deleteShowsHandler(svc episode.UseCases) gin.HandlerFunc {
return func(c *gin.Context) {
idStr := c.Query("id")
id, err := strconv.ParseInt(idStr, 10, 64)

View File

@ -11,12 +11,11 @@ import (
"watch-party-backend/internal/core/episode"
httpapi "watch-party-backend/internal/http"
"watch-party-backend/internal/service"
"github.com/gin-gonic/gin"
)
// ---- fake service implementing service.EpisodeService ----
// ---- fake service implementing episode.UseCases ----
type fakeSvc struct {
cur episode.Episode
@ -55,7 +54,7 @@ func (f *fakeSvc) Delete(ctx context.Context, id int64) error {
// ---- helpers ----
func newRouterWithSvc(svc service.EpisodeService) *gin.Engine {
func newRouterWithSvc(svc episode.UseCases) *gin.Engine {
gin.SetMode(gin.TestMode)
return httpapi.NewRouter(svc)
}

View File

@ -8,29 +8,22 @@ import (
"watch-party-backend/internal/core/episode"
)
type EpisodeService interface {
GetCurrent(ctx context.Context) (episode.Episode, error)
SetCurrent(ctx context.Context, id int64, start string) (episode.Episode, error)
MoveToArchive(ctx context.Context, ids []int64) (episode.MoveResult, error)
ListAll(ctx context.Context) ([]episode.Episode, error)
Delete(ctx context.Context, id int64) error
}
type episodeService struct {
// Service implements the episode.UseCases port.
type Service struct {
repo episode.Repository
}
func NewEpisodeService(r episode.Repository) EpisodeService {
return &episodeService{repo: r}
func NewEpisodeService(r episode.Repository) *Service {
return &Service{repo: r}
}
func (s *episodeService) ListAll(ctx context.Context) ([]episode.Episode, error) {
func (s *Service) ListAll(ctx context.Context) ([]episode.Episode, error) {
c, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
return s.repo.ListAll(c)
}
func (s *episodeService) GetCurrent(ctx context.Context) (episode.Episode, error) {
func (s *Service) GetCurrent(ctx context.Context) (episode.Episode, error) {
c, cancel := context.WithTimeout(ctx, 3*time.Second)
defer cancel()
return s.repo.GetCurrent(c)
@ -38,7 +31,7 @@ func (s *episodeService) GetCurrent(ctx context.Context) (episode.Episode, error
var hhmmss = regexp.MustCompile(`^(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d$`)
func (s *episodeService) SetCurrent(ctx context.Context, id int64, start string) (episode.Episode, error) {
func (s *Service) SetCurrent(ctx context.Context, id int64, start string) (episode.Episode, error) {
if !hhmmss.MatchString(start) {
return episode.Episode{}, episode.ErrInvalidStartTime
}
@ -50,7 +43,7 @@ func (s *episodeService) SetCurrent(ctx context.Context, id int64, start string)
return s.repo.GetCurrent(c)
}
func (s *episodeService) MoveToArchive(ctx context.Context, ids []int64) (episode.MoveResult, error) {
func (s *Service) MoveToArchive(ctx context.Context, ids []int64) (episode.MoveResult, error) {
uniq := make([]int64, 0, len(ids))
seen := make(map[int64]struct{}, len(ids))
for _, id := range ids {
@ -68,7 +61,7 @@ func (s *episodeService) MoveToArchive(ctx context.Context, ids []int64) (episod
return s.repo.MoveToArchive(c, uniq)
}
func (s *episodeService) Delete(ctx context.Context, id int64) error {
func (s *Service) Delete(ctx context.Context, id int64) error {
c, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
return s.repo.Delete(c, id)