-
Notifications
You must be signed in to change notification settings - Fork 0
feat : artistAlias 공용 패키지 분리 및 J-POP 번역 시 artist_ko 고정 적용 (#195) #196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| { | ||
| "name": "@repo/constants", | ||
| "version": "1.0.0", | ||
| "description": "Shared domain constants across apps/packages", | ||
| "main": "./src/index.ts", | ||
| "exports": { | ||
| ".": "./src/index.ts" | ||
| }, | ||
| "type": "module", | ||
| "scripts": { | ||
| "build": "tsup src/index.ts --format esm,cjs --dts" | ||
| }, | ||
| "devDependencies": { | ||
| "@types/node": "^22.13.10", | ||
| "tsup": "^8.4.0", | ||
| "typescript": "^5.8.2" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| export const artistAlias = { | ||
| // 나무위키 데이터 추가 | ||
|
|
||
| Aimer: ["에메", "에이머"], | ||
| amazarashi: ["아마자라시"], | ||
| "Bump of Chicken": ["범프 오브 치킨"], | ||
| ELLEGARDEN: ["엘레가든"], | ||
| "King Gnu": ["킹 누"], | ||
| LISA: ["리사"], | ||
| "Mrs. GREEN APPLE": ["미세스 그린 애플"], | ||
| RADWIMPS: ["래드윔프스"], | ||
| "SEKAI NO OWARI": ["세카이노 오와리", "세카오와"], | ||
| SPYAIR: ["스파이에어"], | ||
| Vaundy: ["바운디"], | ||
| YOASOBI: ["요아소비"], | ||
| "Creepy Nuts": ["크리피 너츠"], | ||
|
|
||
| // [Gemini 추천 아티스트 추가] 한국 인기 최상위 | ||
| Ado: ["아도", "우세와", "신시대"], | ||
| imase: ["이마세", "나이트댄서"], | ||
| "ONE OK ROCK": ["원오크락", "원오크", "원옥"], | ||
| "X JAPAN": ["엑스재팬", "엑스제팬"], | ||
| "tuki.": ["츠키", "투키", "만찬가"], | ||
| HoneyWorks: ["허니웍스"], | ||
| "L'Arc~en~Ciel": ["라르크 앙 시엘", "라르크"], | ||
| 松田聖子: ["마츠다 세이코"], | ||
| 椎名林檎: ["시이나 링고"], | ||
| Eve: ["이브", "eve"], | ||
| 美波: ["미나미", "minami", "373"], | ||
| "ASIAN KUNG-FU GENERATION": ["아시안 쿵푸 제너레이션", "아지캉", "아쿵제"], | ||
|
|
||
| // 기존 데이터 | ||
| 嵐: ["아라시"], | ||
| あいみょん: ["아이묭"], | ||
| 米津玄師: ["요네즈 켄시"], | ||
| 浜崎あゆみ: ["하마사키 아유미"], | ||
| 水樹奈々: ["미즈키 나나"], | ||
| "モーニング娘。": ["모닝구 무스메"], | ||
| Official髭男dism: ["오피셜히게단디즘", "히게단", "프리텐더"], | ||
| ヨルシカ: ["요루시카"], | ||
| 中島美嘉: ["나카시마 미카"], | ||
| 宇多田ヒカル: ["우타다 히카루"], | ||
| 西野カナ: ["니시노 카나"], | ||
| "関ジャニ∞": ["칸쟈니 에이트"], | ||
| "ずっと真夜中でいいのに。": ["즛토마요", "계속 한밤중이면 좋을텐데."], | ||
| 倉木麻衣: ["쿠라키 마이"], | ||
| 安室奈美惠: ["아무로 나미에"], | ||
| いきものがかり: ["이키모노가카리"], | ||
| 星野源: ["호시노 겐"], | ||
| 倖田來未: ["코다 쿠미"], | ||
| 緑黄色社会: ["녹황색사회"], | ||
| 坂本真綾: ["사카모토 마아야"], | ||
| 結束バンド: ["결속 밴드"], | ||
| 乃木坂46: ["노기자카46"], | ||
| 林原めぐみ: ["하야시바라 메구미"], | ||
| ポルノグラフィティ: ["포르노그라피티"], | ||
| 初音ミク: ["하츠네 미쿠"], | ||
| "DECO*27": ["DECO27", "데코니나"], | ||
| 松浦亜弥: ["마츠우라 아야"], | ||
| 堀江由衣: ["호리에 유이"], | ||
| コブクロ: ["코부쿠로"], | ||
| きゃりーぱみゅぱみゅ: ["캬리 파뮤파뮤"], | ||
| ももいろクローバーZ: ["모모이로 클로버 Z"], | ||
| キタニタツヤ: ["키타니 타츠야"], | ||
| 優里: ["유우리"], | ||
| 鈴木このみ: ["스즈키 코노미"], | ||
| 菅田将暉: ["스다 마사키"], | ||
| スキマスイッチ: ["스키마스위치"], | ||
| "『ユイカ』": ["유이카"], | ||
| 福山雅治: ["후쿠야마 마사하루"], | ||
| 大塚愛: ["오오츠카 아이"], | ||
| 米倉千尋: ["요네쿠라 치히로"], | ||
| "平井 堅": ["히라이 켄"], | ||
| 藤井風: ["후지이 카제"], | ||
| 田村ゆかり: ["타무라 유카리"], | ||
| オーイシマサヨシ: ["오이시 마사요시"], | ||
| ちゃんみな: ["챤미나"], | ||
| なとり: ["나토리"], | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { artistAlias } from './artistAlias'; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "compilerOptions": { | ||
| "target": "ESNext", | ||
| "module": "ESNext", | ||
| "lib": ["ESNext"], | ||
| "moduleResolution": "node", | ||
| "esModuleInterop": true, | ||
| "skipLibCheck": true, | ||
| "strict": true, | ||
| "forceConsistentCasingInFileNames": true, | ||
| "outDir": "dist", | ||
| "rootDir": "src", | ||
| "declaration": true, | ||
| "declarationDir": "./dist/types", | ||
| "declarationMap": true | ||
| }, | ||
| "include": ["**/*.ts"], | ||
| "exclude": ["node_modules", "dist"] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| import { artistAlias } from '@repo/constants'; | ||
|
|
||
| import { getJpopSongsForTranslationDB } from '@/supabase/getDB'; | ||
| import { updateSongKoTranslationDB } from '@/supabase/updateDB'; | ||
| import { translateJpnToKo } from '@/utils/translateJpnToKo'; | ||
|
|
@@ -6,6 +8,7 @@ const resultsLog = { | |
| success: 0, | ||
| failed: 0, | ||
| skipped: 0, | ||
| usedAlias: 0, | ||
| }; | ||
|
|
||
| // 히라가나, 카타카나, CJK 한자 범위로 일본어 포함 여부 판단 | ||
|
|
@@ -15,14 +18,18 @@ function containsJapanese(text: string): boolean { | |
| return JAPANESE_REGEX.test(text); | ||
| } | ||
|
|
||
| // 1. J-POP 곡 조회 | ||
| // artistAlias 로부터 artist 원어 → 한국어 대표 표기(별명 배열의 0번째) 맵 생성 | ||
| const artistAliasMap = new Map<string, string>( | ||
| Object.entries(artistAlias).map(([artist, aliases]) => [artist, aliases[0]]), | ||
| ); | ||
|
|
||
| const songs = await getJpopSongsForTranslationDB(); | ||
|
|
||
| console.log('J-POP 곡 수:', songs.length); | ||
|
|
||
| let processedCount = 0; | ||
| for (const song of songs) { | ||
| if (processedCount >= 5000) break; | ||
| if (processedCount >= 10000) break; | ||
|
|
||
| // 이미 번역된 곡 스킵 | ||
| if (song.title_ko && song.artist_ko) { | ||
|
|
@@ -46,15 +53,26 @@ for (const song of songs) { | |
| continue; | ||
| } | ||
|
|
||
| console.log(result); | ||
| // artistAlias 에 등록된 아티스트면 artist_ko 를 고정 값(alias 배열 0번째)으로 덮어쓰기 | ||
| // title_ko 는 AI 번역 결과를 그대로 사용 | ||
| const aliasArtistKo = artistAliasMap.get(song.artist); | ||
| const finalArtistKo = aliasArtistKo ?? result.artist_ko; | ||
|
|
||
| const success = await updateSongKoTranslationDB(song.id, result.title_ko, result.artist_ko); | ||
| if (success) { | ||
| resultsLog.success++; | ||
| console.log(`[OK] ${song.title} → ${result.title_ko} / ${song.artist} → ${result.artist_ko}`); | ||
| } else { | ||
| const success = await updateSongKoTranslationDB(song.id, result.title_ko, finalArtistKo); | ||
|
Comment on lines
+56
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2. artistaliasmap applied after translation translationJpn.ts calls translateJpnToKo(song.title, song.artist) before checking the alias map, so OpenAI is still used even when a fixed artist alias exists. This violates the requirement to resolve artist via alias first and avoid translating the artist when an alias is present. Agent Prompt
|
||
| if (!success) { | ||
| resultsLog.failed++; | ||
| continue; | ||
| } | ||
|
|
||
| if (aliasArtistKo) { | ||
| resultsLog.usedAlias++; | ||
| } else { | ||
| resultsLog.success++; | ||
| } | ||
| const logPrefix = aliasArtistKo ? '[ALIAS]' : '[OK]'; | ||
| console.log( | ||
| `${logPrefix} ${song.title} → ${result.title_ko} / ${song.artist} → ${finalArtistKo}`, | ||
| ); | ||
| } catch (error) { | ||
| resultsLog.failed++; | ||
| console.error(`[ERROR] ${song.title} - ${song.artist}:`, error); | ||
|
|
@@ -70,6 +88,7 @@ for (const song of songs) { | |
| console.log(` | ||
| 총 ${songs.length}곡 중: | ||
| - 스킵 (이미 번역됨): ${resultsLog.skipped}곡 | ||
| - 성공: ${resultsLog.success}곡 | ||
| - 성공 (AI 번역): ${resultsLog.success}곡 | ||
| - 성공 (artist_ko alias 적용): ${resultsLog.usedAlias}곡 | ||
| - 실패: ${resultsLog.failed}곡 | ||
| `); | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. Missing artistalias loader utility
📎 Requirement gap⚙ MaintainabilityAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools