Skip to content

[Feat] : 포인트 투표 기반 이달의 아티스트 선정 기능 (#307) - #309

Open
GulSam00 wants to merge 20 commits into
developfrom
feat/307-monthlyArtistVoting
Open

[Feat] : 포인트 투표 기반 이달의 아티스트 선정 기능 (#307)#309
GulSam00 wants to merge 20 commits into
developfrom
feat/307-monthlyArtistVoting

Conversation

@GulSam00

Copy link
Copy Markdown
Owner

📌 PR 제목

[Feat] : 포인트 투표 기반 이달의 아티스트 선정 기능 (#307)

📌 변경 사항

투표 · 집계

  • artists / artist_votes / monthly_artist_rankings 테이블 + RLS 정책 (apps/web/artist-vote-schema.sql)
    • 최초 버전엔 enable row level security만 있고 정책이 없어 앱(anon 키)에서 모든 조회가 조용히 빈 배열로 돌아왔다. 정책을 추가하고, 파일 전체를 재실행해도 안전하도록 if not exists / drop policy if exists로 정리
    • 남의 투표는 이미 확정된 (월, 아티스트)만 공개 — 집계 전 실시간 득표 현황이 새지 않게
  • 포인트 투표 API (등록/수정/삭제, 이번 달만 수정 가능)
  • 월간 확정: 득표 합산 → 상위 30명 저장. 동점은 그달에 먼저 득표를 모으기 시작한 쪽 우선

확정 배치를 크롤링 패키지로 이관 (엔드포인트 제거)

  • /api/artist-vote/finalize(공개 POST)를 삭제하고 packages/crawlingpnpm finalize-artist로 이관
    • 인증 없는 공개 URL이 순위를 지우고 다시 쓰는 구조라 공유 시크릿으로 잠가야 했다. 문 자체를 없애 ARTIST_VOTE_FINALIZE_SECRET과 Vercel SUPABASE_SERVICE_ROLE_KEY가 모두 불필요해짐
    • 투표가 0건이면 기존 순위를 지우지 않고 종료 — 조회가 일시적으로 비어 돌아온 날 확정 결과가 날아가지 않도록
  • 집계 규칙(rankArtistVotes.ts)과 KST 월 계산(kstMonth.ts)을 @repo/constants로 이동. 배치와 웹이 갈리면 화면에 적힌 순위와 저장된 순위가 어긋난다. 웹은 utils/kst.ts 재수출로 import 경로 유지

랭킹 화면

  • 1~3위 액자 카드(1위 금 / 2·3위 황동) + 카드 상단에 통산 우승 (프로 스포츠 방식), 별 클릭 시 그달 상세
  • 우승 이력은 조회 중인 달까지만 집계 — 지난 달을 볼 때 그 시점의 개수가 나오도록 (lte)
  • 430위 막대, 득표 비중 파이(110위 개별 조각)
  • 파이 색: 검증 통과한 카테고리 팔레트 8칸으로 확장(--chart-6~8). 9·10위는 새 색을 만들지 않고 앞선 색을 빗금으로 재사용 — 색만으로는 구분이 무너지므로 색+질감으로 나눔
  • 범례가 순위·이름·득표·비중을 모두 적어 표 역할 겸함(색 단독 구분 회피)

아티스트 사진

  • artists.image_url 추가. finalize_artist_of_month.yml 마지막 단계가 확정된 시상대 1~3위 중 사진이 없는 사람만 채움(ARTIST_IMAGE_PODIUM=3)
  • 이름 매칭: MusicBrainz(별칭 사전) → Deezer(사진). DB는 TJ 표기(한글·원어)인데 음원 서비스 등록은 로마자라("방탄소년단" ↔ "BTS") 이 다리가 없으면 사진이 있어도 못 찾음
  • 이름이 정확히 일치하는 후보만 채택. 검색 API는 무엇을 넣든 결과를 주므로 느슨하게 받으면 1위 액자에 다른 사람 얼굴이 걸린다
  • 사진 실패가 확정을 망치지 않도록 continue-on-error

기타

  • 곡 카드 배지가 "IU(Feat.최백호)" 같은 원문에서 빠지던 문제 수정(주 아티스트 추출 후 비교)
  • 아티스트 이름 정규화 규칙을 @repo/constants로 이동(백필·웹 공유)
  • recharts 도입, 최신곡 카드 구분선 통일, "신고 내역" → "수정 요청 내역" 문구 변경

💬 추가 참고 사항

⚠️ 머지 전 필요한 설정

  • GitHub Actions repo secret: SUPABASE_URL, SUPABASE_KEY(service_role)
    finalize_artist_of_month.yml이 확정·사진 백필 양쪽에 사용. 다른 크롤링 워크플로가 쓰는 이름이지만 이 워크플로에서는 처음 참조한다. anon 키면 RLS에 막혀 에러 없이 0행 처리되므로 반드시 service_role
  • Vercel 추가 환경변수 없음
  • Supabase SQL Editor에서 apps/web/artist-vote-schema.sql 실행 완료

검증 상태

확정 스크립트는 실 DB로 1회 실행해 월 계산·조회·가드 동작을 확인했고, 집계 함수는 동점 케이스로 정렬·최다 투표자를 확인했다. 다만 실데이터로 끝까지 흘려본 적은 없다.

  • 확정 쓰기 경로(delete → insert) — 투표 데이터가 0건이라 미실행
  • RLS 정책 실동작 — 아티스트 검색 자동완성으로 확인 가능
  • 투표 → 포인트 차감 → 랭킹 반영 — 카카오 로그인 필요, 자동 검증 불가
  • artists(name_ko, image_url) 임베드 — 실패 시 PGRST200
  • 사진 백필 podium 모드 — 확정 데이터가 없어 드라이런만 수행

알려진 사항

  • 태연·잔나비·폴킴 사진은 MusicBrainz 다리를 붙이기 전에 채워져 팬 수 20~60짜리 중복 등록에서 온 것이다. 정품으로 바꾸려면 해당 행을 null로 되돌린 뒤 다시 돌려야 한다(image_url is null인 행만 대상)

  • 테스트 스위트 없음(packages/crawlingtest 스크립트는 vitest 미설치로 실행 불가) — 기존 상태 그대로

  • close 포인트 투표 기반 이달의 아티스트 선정 기능 추가 #307

GulSam00 and others added 20 commits August 20, 2026 20:00
포인트로 아티스트에 투표하는 artist_votes, 월별 1~10위를 확정하는
monthly_artist_rankings, 그리고 두 테이블이 FK로 참조하는 artists
마스터 테이블 스키마를 추가한다. 투표 증감/삭제(PUT), 랭킹/투표자
조회, 매일 00:10 KST에 전월을 확정하는 finalize 배치(GitHub Actions +
service role 전용 라우트)까지 백엔드 전체를 구성한다.
songs 테이블을 순회하며 artistAlias로 표기를 정규화하고, song_tags
언어 태그로 country_code를, artist_ko/artistAlias로 name_ko를
추정해 artists 테이블을 채우는 backfillArtists.ts를 추가한다.
ARTIST_BACKFILL_SINCE_DAYS로 최초(전체) 백필과 매달 증분 백필을
구분하며, 매달 1일 자동 실행되는 GitHub Actions 워크플로우를 함께 둔다.
artists 테이블을 name/name_ko로 검색하는 GET /api/artists/search와
클라이언트 훅을 추가한다. 이달의 아티스트 투표 모달의 아티스트
자동완성이 이 API를 쓴다.
하단 내비게이션 '인기곡'을 '인기 차트'로 바꾸고 /popular를 노래방
인기곡/이달의 아티스트 탭으로 재구성한다. 이달의 아티스트 탭은 월
선택, 1~3위 포디움과 4~10위 리스트, 투표자 상세, 투표 모달(검색 +
내 투표 증감/삭제)로 구성된다. 월 선택 UI는 기존 인기차트와
공유하도록 MonthSelector로 분리했다. 곡 카드 공통 컴포넌트
SongSummary에는 이번 달 1위 아티스트 배지(★ 누적 선정 횟수 포함)를
추가한다.
SQL 실행, artists 최초 백필, 환경변수/시크릿 등록 등 코드 완성 후
남은 수동 작업을 진행 중인 작업 섹션에 정리한다.
artists.country_code(임의 문자열)를 기존 tags 테이블을 참조하는
language_tag_id FK로 교체하고, 스키마를 정책 없이 테이블·RLS enable만
남기도록 정리한다.

백필 정규화는 애매하게 잘라 쓰는 대신 명확한 기준으로 무효 처리하는
쪽으로 단순화한다 — 쉼표, &/&, ×/・, feat, with, 앞뒤 단어가 있는
x-콜라보(예: "지코 X 아이유")가 하나라도 있으면 그 곡의 artist는
백필 대상에서 제외한다. 살아남은 값은 첫 괄호 앞부분만 남기되(내용
무관), 잘랐을 때 빈 문자열이 되면("(여자)아이들"처럼 이름 자체가
괄호로 시작하는 경우) 원문을 유지한다. songs.updated_at도 증분
스캔 조건에 포함해 기존 곡의 artist 오타 수정 같은 걸 놓치지
않게 한다.

백필 실행 로그를 파일로 남기고(packages/crawling/src/assets/
artistBackfillLog.txt) GitHub Actions에서도 아티팩트로 업로드한다.
오작동하던 언어 태그 필터(LanguageTagFilter)를 검색 화면과
api/search에서 걷어낸다. UI 컴포넌트, 관련 훅(useSearchSong,
useSaveSongModal)과 쿼리(searchSongQuery)의 languageTag 파라미터,
api/search의 song_tags 조인 필터링 로직, 가이드 투어 스텝을 모두
제거한다.
언어 태그 필터 오작동을 계기로 태그 기능 자체를 끈다. artists 백필에서
language_tag_id 산출 로직과 스키마 컬럼 정의를 제거하고, tags/song_tags를
등록하거나 참조하던 taggingSongs.ts와 translationJpn.ts는 삭제 대신
전체 주석처리한다. 연결된 GitHub Actions 스케줄(tagging_song.yml,
translation_jpn.yml)도 schedule 트리거만 주석처리해 자동 실행을
멈추고, workflow_dispatch로 필요하면 수동 실행은 가능하게 남긴다.
tags/song_tags 테이블 자체는 DB에서 지우지 않는다.
태그 기능 제거 배경을 참고용으로 남기고, 이달의 아티스트 잔여 작업
목록에 아티스트 투표/검색 기능 동작 검증 항목을 추가한다.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPpnfzdUzPYFQZrjzNL65k
@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@vercel

vercel Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
singcode Ready Ready Preview Aug 23, 2026 3:00pm

@GulSam00

Copy link
Copy Markdown
Owner Author

/describe

@GulSam00

Copy link
Copy Markdown
Owner Author

/review

@GulSam00

Copy link
Copy Markdown
Owner Author

/improve

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

포인트 투표 기반 이달의 아티스트 선정 기능 추가

1 participant