fix: reduce watchlist update complexity

This commit is contained in:
2026-06-27 15:46:18 +02:00
parent ae1b323732
commit 490b2e3ed5

View File

@@ -22,38 +22,38 @@ func NewWatchlistService(repo domain.WatchlistRepository, jikan *jikan.Client, i
} }
func (s *watchlistService) UpdateEntry(ctx context.Context, userID string, animeID int64, status string) error { func (s *watchlistService) UpdateEntry(ctx context.Context, userID string, animeID int64, status string) error {
var anime jikan.Anime anime, fetchedAnime := s.fetchAnimeForWatchlist(ctx, animeID)
var fetchErr error
if s.jikan != nil {
anime, fetchErr = s.jikan.GetAnimeByID(ctx, int(animeID))
}
if fetchErr != nil {
// still allow status updates for already-known anime rows
anime = jikan.Anime{}
}
if err := s.repo.InTx(ctx, func(txCtx context.Context, repo domain.WatchlistRepository) error { if err := s.repo.InTx(ctx, func(txCtx context.Context, repo domain.WatchlistRepository) error {
_, err := repo.GetAnime(txCtx, animeID) return s.updateEntryInTx(txCtx, repo, userID, animeID, status, anime, fetchedAnime)
if err != nil && fetchErr == nil && anime.MalID > 0 {
durationSeconds := anime.DurationSeconds()
duration := sql.NullFloat64{Valid: durationSeconds > 0}
if duration.Valid {
duration.Float64 = durationSeconds
}
if _, err := repo.UpsertAnime(txCtx, db.UpsertAnimeParams{
ID: int64(anime.MalID),
TitleOriginal: anime.Title,
TitleEnglish: sql.NullString{String: anime.TitleEnglish, Valid: anime.TitleEnglish != ""},
TitleJapanese: sql.NullString{String: anime.TitleJapanese, Valid: anime.TitleJapanese != ""},
ImageUrl: anime.Images.Webp.LargeImageURL,
Airing: sql.NullBool{Bool: anime.Airing, Valid: true},
DurationSeconds: duration,
}); err != nil { }); err != nil {
return err return err
} }
s.invalidateTopPicks(userID)
return nil
}
func (s *watchlistService) fetchAnimeForWatchlist(ctx context.Context, animeID int64) (jikan.Anime, bool) {
if s.jikan == nil {
return jikan.Anime{}, false
}
anime, err := s.jikan.GetAnimeByID(ctx, int(animeID))
if err != nil {
// still allow status updates for already-known anime rows
return jikan.Anime{}, false
}
return anime, anime.MalID > 0
}
func (s *watchlistService) updateEntryInTx(ctx context.Context, repo domain.WatchlistRepository, userID string, animeID int64, status string, anime jikan.Anime, fetchedAnime bool) error {
_, err := repo.GetAnime(ctx, animeID)
if err != nil && fetchedAnime {
if _, err := repo.UpsertAnime(ctx, watchlistAnimeParams(anime)); err != nil {
return err
}
} }
existing, err := repo.GetWatchListEntry(txCtx, db.GetWatchListEntryParams{ existing, err := repo.GetWatchListEntry(ctx, db.GetWatchListEntryParams{
UserID: userID, UserID: userID,
AnimeID: animeID, AnimeID: animeID,
}) })
@@ -61,7 +61,7 @@ func (s *watchlistService) UpdateEntry(ctx context.Context, userID string, anime
return err return err
} }
_, err = repo.UpsertWatchListEntry(txCtx, db.UpsertWatchListEntryParams{ _, err = repo.UpsertWatchListEntry(ctx, db.UpsertWatchListEntryParams{
ID: uuid.New().String(), ID: uuid.New().String(),
UserID: userID, UserID: userID,
AnimeID: animeID, AnimeID: animeID,
@@ -70,11 +70,23 @@ func (s *watchlistService) UpdateEntry(ctx context.Context, userID string, anime
CurrentTimeSeconds: existing.CurrentTimeSeconds, CurrentTimeSeconds: existing.CurrentTimeSeconds,
}) })
return err return err
}); err != nil {
return err
} }
s.invalidateTopPicks(userID)
return nil func watchlistAnimeParams(anime jikan.Anime) db.UpsertAnimeParams {
durationSeconds := anime.DurationSeconds()
duration := sql.NullFloat64{Valid: durationSeconds > 0}
if duration.Valid {
duration.Float64 = durationSeconds
}
return db.UpsertAnimeParams{
ID: int64(anime.MalID),
TitleOriginal: anime.Title,
TitleEnglish: sql.NullString{String: anime.TitleEnglish, Valid: anime.TitleEnglish != ""},
TitleJapanese: sql.NullString{String: anime.TitleJapanese, Valid: anime.TitleJapanese != ""},
ImageUrl: anime.Images.Webp.LargeImageURL,
Airing: sql.NullBool{Bool: anime.Airing, Valid: true},
DurationSeconds: duration,
}
} }
func (s *watchlistService) RemoveEntry(ctx context.Context, userID string, animeID int64) error { func (s *watchlistService) RemoveEntry(ctx context.Context, userID string, animeID int64) error {