Skip to content

[fix] 셋리스트 재수집 시 트랙 미저장 수정 및 누락분 재수집 - #89

Merged
You-Hyuk merged 3 commits into
mainfrom
fix/#88-setlist-track-resave
Oct 6, 2026
Merged

You-Hyuk merged 3 commits into
mainfrom
fix/#88-setlist-track-resave

Conversation

@You-Hyuk

@You-Hyuk You-Hyuk commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

관련 이슈

Closes #88


변경 개요

트랙 0개로 먼저 저장된 셋리스트는 이후 setlist.fm에 곡이 채워져 재수집해도 트랙이 DB에 저장되지 않았다. ON CONFLICT (setlist_fm_id) DO NOTHING으로 RETURNING 결과가 없어 트랙 INSERT를 건너뛰었고, 어드민 단건 수집은 저장 결과와 무관하게 성공으로 응답해 화면에는 보이지만 공연 상세 셋리스트는 비어 있었다. 또 06시 배치는 setlist 행이 없는 공연만 조회해, 이미 트랙 0개로 저장된 셋리스트(운영 74건)는 자동으로 복구되지 않았다.

변경사항

파일 변경 내용
db/repository.py save_setlists: ON CONFLICT DO UPDATE ... RETURNING id로 변경, 새 tracks가 있으면 기존 트랙 DELETE 후 INSERT(빈 tracks면 기존 트랙 유지), raise_on_error 옵션 추가
db/repository.py get_completed_concerts: 대상 조건을 "setlist 행 없음"에서 "setlist 행 없음 또는 트랙 0개"로 확장 (fetch_attempted_at 7일 재시도 간격 유지)
scheduler.py collect_and_save_setlist: raise_on_error=True로 저장, 실패 시 예외 전파 → 내부 API 500 응답
docs/pipeline.md ⑤ setlist.fm 수집 대상 조건·트랙 교체 규칙 보강
tests/test_repository.py 재현 테스트(트랙 0개 저장 → 같은 setlist_fm_id + 트랙으로 재저장), 빈 tracks 시 기존 트랙 유지, 저장 실패 전파, get_completed_concerts 조건 테스트
tests/test_scheduler.py raise_on_error=True 호출 검증, 저장 실패 시 예외 전파 테스트

주요 구현 내용

  • 재저장 동작: 같은 setlist_fm_id면 attribution_url·collected_at을 갱신하고 id를 항상 받는다. 새 결과에 트랙이 있을 때만 같은 트랜잭션에서 트랙을 교체하므로, setlist.fm에서 곡이 일시적으로 비어도 기존 트랙이 지워지지 않는다.
  • 실패 처리 분리: 배치 경로(run_setlist_collect)는 기존대로 실패 건만 로그 후 건너뛰고, 어드민 단건 경로만 예외를 올린다.
  • 복구 방식: 별도 recover 명령 대신 06시 배치 대상 조건을 확장했다. 74건 대부분은 fetch_attempted_at이 7일 이상 지나 배포 후 첫 실행에서 재조회되고, 이후 새로 생기는 빈 셋리스트도 주 1회 재확인된다.

테스트

  • 로컬 실행 확인 (pytest 415 passed, ruff check . 통과)
  • 단위 테스트 추가/수정
  • 예외 케이스 확인 (재현 테스트가 수정 전 코드에서 실패함을 확인, 빈 tracks·저장 실패 케이스)

리뷰어 참고사항

  • Backend 변경 불필요: Data 5xx → PipelineServerException → 어드민 화면 "수집에 실패했습니다." 표시 확인됨. ConcertService.getSetlist는 collected_at 최신 setlist를 읽으므로 재수집 결과가 바로 반영된다.
  • setlist_track.id를 참조하는 테이블이 없어(Backend Flyway V1·V2 확인) 트랙 DELETE 후 INSERT가 안전하다.
  • setlist.fm에 곡이 끝내 올라오지 않는 공연은 주 1회 계속 재조회된다 (상한 미적용).
  • 배포 후 확인: python scheduler.py run-job --job setlist로 즉시 실행하거나 06시 실행 뒤 아래 쿼리로 트랙 0개 건수 감소 확인
    SELECT s.id, s.concert_id, s.setlist_fm_id, count(t.id) AS tracks
    FROM setlist s LEFT JOIN setlist_track t ON t.setlist_id = s.id
    GROUP BY s.id HAVING count(t.id) = 0;

코드 리뷰

변경사항 요약

  • db/repository.py: save_setlists upsert + 트랙 교체, raise_on_error 옵션 / get_completed_concerts 대상 조건 확장
  • scheduler.py: 단건 셋리스트 수집 저장 실패 전파
  • tests/test_repository.py, tests/test_scheduler.py: 재현·예외 케이스 테스트
  • /data-review 결과 🔴 0건 / 🟡 0건 / 🔵 0건 (DML-only, print 없음, Python 3.9 문법, setlist.fm 요청 코드 변경 없음)

✅ 특이사항 없음. 변경사항이 깔끔하게 구현되었습니다.

Summary by CodeRabbit

  • Bug Fixes
    • Completed performances with missing or empty setlists are now eligible for collection, with repeat attempts still limited by the seven-day backoff.
    • Re-collecting a performance replaces its existing tracks when new tracks are available, while empty results preserve existing tracks.
    • Collection errors now surface instead of being silently skipped during scheduled collection.

You-Hyuk and others added 3 commits October 6, 2026 16:35
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@You-Hyuk You-Hyuk added the Bug 🐛 버그 수정 label Oct 6, 2026
@You-Hyuk You-Hyuk self-assigned this Oct 6, 2026
@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: affaf53c-ba23-4597-822d-e0044ca2c24f
📥 Commits

Reviewing files that changed from the base of the PR and between 061f542 and 2370f12.

📒 Files selected for processing (5)
  • db/repository.py
  • docs/pipeline.md
  • scheduler.py
  • tests/test_repository.py
  • tests/test_scheduler.py

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The completed-concert query now includes performances with no setlist tracks. Setlist saves update existing records and replace tracks when incoming tracks are nonempty. The single-setlist scheduler requests error propagation from saves.

Changes

Setlist recollection

Layer / File(s) Summary
Select eligible performances
db/repository.py, docs/pipeline.md, tests/test_repository.py
The query includes ended concerts with no setlist tracks, including concerts with an empty setlist. It retains the seven-day fetch-attempt condition. Tests cover the query filters and returned concert data.
Refresh setlist data and propagate save errors
db/repository.py, scheduler.py, tests/test_repository.py, tests/test_scheduler.py
Conflicting setlist IDs update attribution and collection time. Nonempty incoming tracks replace existing tracks; empty track lists leave existing tracks unchanged. The scheduler requests that save errors be re-raised, and tests cover the save and propagation behavior.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 2370f

No established issue remains that needs to be resolved before merge; normal checks can proceed.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: save tracks when recollecting a setlist and recollect missing setlists.
Linked Issues check ✅ Passed Issue #88 requires setlist upsert and recovery of tracks on re-collection, preservation of existing tracks when the new result is empty, save-error propagation for single-item collection, and batch se…
Out of Scope Changes check ✅ Passed The reported changes are limited to issue #88 implementation and its supporting tests and pipeline documentation. The repository inspection could not retrieve the diff, but the available PR and file-c…
Docstring Coverage ✅ Passed Docstring coverage is 88.89% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 4 files. (1 skipped: 1 …
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@You-Hyuk
You-Hyuk merged commit 364c792 into main Oct 6, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug 🐛 버그 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[fix] 셋리스트 재수집 시 트랙 미저장 수정 및 누락분 재수집

1 participant