feat(server): 곡 상세에 외부 링크·Last.fm 좋아요·커버 이미지 - #34
Merged
Conversation
관리자 화면 전용이다. /v1 계약과 앱은 건드리지 않으므로 앱 릴리스가 필요 없다. - 외부 링크 다섯 개(Last.fm·Tunefind·YouTube·Musixmatch·Genius)를 의미 카드가 아니라 머리말 아래로. Tunefind·YouTube는 의미의 출처가 아니라 곡을 더 보러 가는 통로이고, 의미가 비었을 때 카드가 안내하는 "위 링크"가 실제로 위에 있어야 말이 맞는다. - Tunefind API는 쓸 수 없다 — 셀프서비스 가입 창구가 없고 라이선스 계약이 필요하며 무료 티어가 없다. robots.txt는 AI 크롤러를 전면 차단한다. 그래서 검색 링크만 단다. 주소는 /search?q= — /search/site?q=는 실측 404다. - Last.fm 좋아요 표시·토글. 읽기는 지금 키로 되고(track.getInfo + username → userloved), 쓰기는 브라우저 승인 플로우로 세션 키를 받는다. 관리자 쿠키가 SameSite=Strict라 last.fm에서 돌아오는 이동에 실리지 않으므로, 콜백의 신원 증명은 SameSite=Lax인 state 논스 쿠키로 따로 한다. 조회 실패를 "좋아요 안 함" 으로 그리지 않는다 — 이미 켜 둔 것을 끄게 된다. - 커버 이미지. iTunes Search(키 불필요) → Deezer 폴백, 첫 결과를 믿지 않고 MeaningMatch를 통과시킨다. 못 찾은 것도 기억해 열 때마다 다시 부르지 않는다. Last.fm 이미지는 쓰지 않는다 — API 약관이 artwork를 계약 대상에서 명시적으로 제외한다. CSP img-src를 두 호스트로 연다(안 열면 조용히 안 뜬다). - 로그아웃을 네비 우상단으로. 가운데 있어 잘못 눌렀다. 저장은 song_links + app_settings(user_version=7) — 추가뿐이라 롤백해도 안전하다. 테스트 38건 추가(333개 통과), 경고 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
관리자 화면 곡 상세를 보강한다.
/v1계약과 Windows·Android 앱은 건드리지 않으므로 앱 릴리스가 필요 없다.조사로 확정한 것
Tunefind API는 개인이 쓸 수 없다. 셀프서비스 가입 창구가 없고
info@tunefind.com으로 라이선스 계약을 맺어야 하며 무료 티어가 없다. robots.txt는ClaudeBot·anthropic-ai·GPTBot을 전면 차단해 크롤링도 답이 아니다. → 검색 링크만 단다. 주소는 반드시/search?q=다 — 검색 결과에 흔히 나오는/search/site?q=는 실측 404다.Last.fm 좋아요는 공식 API로 읽기·쓰기 모두 된다.
track.getInfo에username을 주면userloved가 실려 오고(지금 키로 충분), 켜고 끄기는 POST +api_sig+ 세션 키가 필요하다.Last.fm 이미지는 쓸 수 없다. API 약관이 audio·audiovisual·artwork를 계약 대상에서 명시적으로 제외한다("expressly excluded from this Agreement"). 커버는 iTunes Search에서 따로 가져온다.
바뀐 것
?cb=로 콜백을 그때그때 넘겨 API 계정에 등록할 필요가 없다). 함정: 관리자 쿠키가SameSite=Strict라 last.fm에서 돌아오는 이동에 실리지 않는다 — 그대로 두면 콜백이 로그인 화면으로 떨어지고 1회용 토큰이 날아간다. 콜백의 신원 증명은SameSite=Lax인 state 논스 쿠키로 따로 한다. 조회 실패는 "좋아요 안 함"으로 그리지 않는다(꺼진 하트를 보고 누르면 이미 켜 둔 것을 끄게 된다).100x100bb.jpg→600x600bb.jpg) → Deezer 폴백. 첫 결과를 믿지 않고MeaningMatch.IsSameSong을 통과시킨다(Genius·Musixmatch에서 이미 겪은 함정). 못 찾은 것도 기억해 열 때마다 다시 부르지 않는다([커버 다시 찾기]로 해제). CSPdefault-src 'none'때문에img-src를 그 두 호스트로 열었다 — 안 열면 이미지가 조용히 안 뜬다.저장·롤백
song_links+app_settings(user_version=7). 테이블 추가뿐이라 구 버전 바이너리로 롤백해도 안전하다.세션 키는 DB에 저장되므로 백업에 Last.fm 쓰기 자격증명이 함께 들어간다 — [연결 해제] 버튼과 last.fm 설정에서의 권한 회수를 문서에 함께 적었다.
새 환경변수
MUSEBASE_LASTFM_SECRET— 없으면 연결 카드와 좋아요 토글이 통째로 사라지고 나머지는 그대로다.검증
img-src반영 · 링크 다섯 개 · 커버를 iTunes에서 실제로 찾아 600x600으로 렌더(is1-ssl.mzstatic.com) · secret 없을 때 Last.fm 카드 숨김 ·/admin/lastfm/connect가 state 쿠키(samesite=lax; path=/admin/lastfm)를 굽고 303 · state 없는 콜백은 안내로 되돌림.🤖 Generated with Claude Code