Skip to content

Refactor/crawling#158

Merged
GulSam00 merged 7 commits intodevelopfrom
refactor/crawling
Mar 8, 2026
Merged

Refactor/crawling#158
GulSam00 merged 7 commits intodevelopfrom
refactor/crawling

Conversation

@GulSam00
Copy link
Owner

@GulSam00 GulSam00 commented Mar 8, 2026

📌 PR 제목

refactor : 크롤링 코드 개선

📌 변경 사항

  • @repo/query 패키지 제거 — 미사용 패키지 삭제 및 의존성 정리
  • AI 기반 곡 검증 도입 — isValidKYExistNumber를 Claude AI 기반으로 교체하고, validateSongMatch 유틸 추가
  • 임시 파일 제거 — crawlYoutubeTemp, crawlYoutubeUbuntu 스크립트 및 관련 코드 삭제
  • 크롤링 로그 시스템 정리 — logData 유틸 제거 및 replaceSupabaseFailed 버그 수정
  • DB 기반 체크포인트 전환 — crawlYoutubeVerify의 체크포인트를 파일 기반에서 verify_ky_songs DB 기반으로
    전환
  • CLAUDE.md 추가 — packages/crawling 작업 지침 문서화

💬 추가 참고 사항

GulSam00 and others added 7 commits March 8, 2026 15:17
- updateDataLog 및 log/ 폴더 관련 코드 전체 제거 (DB가 성공/실패 상태 관리)
- saveCrawlYoutubeFailedKYSongs 제거 (crawlYoutube가 DB 방식으로 전환되어 미사용)
- replaceSupabaseFailed에서 loadValidKYSongs → loadCrawlYoutubeFailedKYSongs 버그 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel
Copy link
Contributor

vercel bot commented Mar 8, 2026

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

Project Deployment Actions Updated (UTC)
singcode Ready Ready Preview, Comment Mar 8, 2026 9:55am

@qodo-code-review
Copy link

Review Summary by Qodo

Refactor crawling pipeline with AI validation and database-backed checkpoints

✨ Enhancement 🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Remove unused @repo/query package and clean up dependencies
• Replace file-based checkpoints with database-backed verification in crawlYoutubeVerify
• Introduce AI-powered song validation using OpenAI gpt-4o-mini via validateSongMatch utility
• Eliminate logging system (updateDataLog) and temporary crawling scripts (crawlYoutubeTemp,
  crawlYoutubeUbuntu)
• Fix bug in replaceSupabaseFailed (incorrect function reference)
• Add comprehensive CLAUDE.md documentation for crawling package architecture
Diagram
flowchart LR
  A["Song Data<br/>num_ky=null"] -->|YouTube Scrape| B["Extract KY Number"]
  B -->|Validate| C["validateSongMatch<br/>GPT-4o-mini"]
  C -->|Valid| D["Update DB<br/>songs table"]
  C -->|Invalid| E["Post to<br/>invalid_ky_songs"]
  F["Existing KY Numbers"] -->|Re-verify| G["crawlYoutubeVerify"]
  G -->|Check Match| C
  G -->|Valid| H["Insert to<br/>verify_ky_songs"]
  G -->|Invalid| I["Reset num_ky=null"]
Loading

Grey Divider

File Changes

1. packages/crawling/src/crawling/crawlYoutubeVerify.ts ✨ Enhancement +46/-0

New DB-backed verification script with AI validation

packages/crawling/src/crawling/crawlYoutubeVerify.ts


2. packages/crawling/src/utils/validateSongMatch.ts ✨ Enhancement +46/-0

AI-powered song matching utility using OpenAI

packages/crawling/src/utils/validateSongMatch.ts


3. packages/crawling/src/crawling/isValidKYExistNumber.ts ✨ Enhancement +14/-25

Refactor to use AI validation instead of string parsing

packages/crawling/src/crawling/isValidKYExistNumber.ts


View more (29)
4. packages/crawling/src/utils/logData.ts ✨ Enhancement +0/-50

Remove updateDataLog function and file-based logging

packages/crawling/src/utils/logData.ts


5. packages/crawling/src/crawling/crawlYoutubeTemp.ts Miscellaneous +0/-109

Delete temporary crawling script

packages/crawling/src/crawling/crawlYoutubeTemp.ts


6. packages/crawling/src/crawling/crawlYoutubeUbuntu.ts Miscellaneous +0/-127

Delete Ubuntu-specific temporary crawling script

packages/crawling/src/crawling/crawlYoutubeUbuntu.ts


7. packages/crawling/src/supabase/getDB.ts ✨ Enhancement +10/-0

Add getVerifyKySongsDB function for checkpoint retrieval

packages/crawling/src/supabase/getDB.ts


8. packages/crawling/src/supabase/postDB.ts ✨ Enhancement +17/-1

Add postVerifyKySongsDB function for verified songs

packages/crawling/src/supabase/postDB.ts


9. packages/crawling/src/crawling/crawlYoutubeValid.ts ✨ Enhancement +8/-10

Comment out file-based checkpoint logic

packages/crawling/src/crawling/crawlYoutubeValid.ts


10. packages/crawling/src/crawling/replaceSupabaseFailed.ts 🐞 Bug fix +10/-11

Fix bug and comment out incorrect function reference

packages/crawling/src/crawling/replaceSupabaseFailed.ts


11. packages/crawling/src/crawling/crawlRecentTJ.ts ✨ Enhancement +1/-3

Remove updateDataLog calls for file-based logging

packages/crawling/src/crawling/crawlRecentTJ.ts


12. packages/crawling/src/findKYByOpen.ts ✨ Enhancement +0/-3

Remove updateDataLog calls for file-based logging

packages/crawling/src/findKYByOpen.ts


13. packages/crawling/src/postAllOpenSongs.ts ✨ Enhancement +4/-14

Remove updateDataLog calls and LogData type usage

packages/crawling/src/postAllOpenSongs.ts


14. packages/crawling/src/postByRelease.ts ✨ Enhancement +2/-6

Remove updateDataLog calls and LogData type usage

packages/crawling/src/postByRelease.ts


15. packages/crawling/src/postTransDictionary.ts ✨ Enhancement +10/-14

Comment out file-based checkpoint logic

packages/crawling/src/postTransDictionary.ts


16. packages/crawling/src/updateJpnSongs.ts ✨ Enhancement +0/-9

Remove updateDataLog calls for file-based logging

packages/crawling/src/updateJpnSongs.ts


17. packages/crawling/CLAUDE.md 📝 Documentation +111/-0

Add comprehensive documentation for crawling architecture

packages/crawling/CLAUDE.md


18. packages/crawling/package.json ⚙️ Configuration changes +2/-2

Remove ky-youtube-ubuntu script, add ky-verify command

packages/crawling/package.json


19. apps/web/package.json Dependencies +0/-1

Remove @repo/query dependency

apps/web/package.json


20. packages/query/package.json Miscellaneous +0/-27

Delete entire query package

packages/query/package.json


21. packages/query/src/index.ts Miscellaneous +0/-3

Delete query package exports

packages/query/src/index.ts


22. packages/query/src/open-api/index.ts Miscellaneous +0/-7

Delete query package open-api exports

packages/query/src/open-api/index.ts


23. packages/query/src/types.ts Miscellaneous +0/-8

Delete query package type definitions

packages/query/src/types.ts


24. packages/query/tsconfig.json Miscellaneous +0/-19

Delete query package TypeScript configuration

packages/query/tsconfig.json


25. packages/query/src/open-api/useComposer.ts Additional files +0/-29

...

packages/query/src/open-api/useComposer.ts


26. packages/query/src/open-api/useLyricist.ts Additional files +0/-29

...

packages/query/src/open-api/useLyricist.ts


27. packages/query/src/open-api/useNo.ts Additional files +0/-29

...

packages/query/src/open-api/useNo.ts


28. packages/query/src/open-api/usePopular.ts Additional files +0/-27

...

packages/query/src/open-api/usePopular.ts


29. packages/query/src/open-api/useRelease.ts Additional files +0/-29

...

packages/query/src/open-api/useRelease.ts


30. packages/query/src/open-api/useSinger.ts Additional files +0/-29

...

packages/query/src/open-api/useSinger.ts


31. packages/query/src/open-api/useSong.ts Additional files +0/-29

...

packages/query/src/open-api/useSong.ts


32. pnpm-lock.yaml Additional files +0/-19

...

pnpm-lock.yaml


Grey Divider

Qodo Logo

@qodo-code-review
Copy link

qodo-code-review bot commented Mar 8, 2026

Code Review by Qodo

🐞 Bugs (4) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. ky-update 실패 숨김 🐞 Bug ⛯ Reliability
Description
ky-update&로 3개 스크립트를 백그라운드 병렬 실행해, 일부 작업이 실패해도 전체 명령이 성공으로 보일 수 있습니다(마지막 foreground 프로세스 exit
code만 반영). 결과적으로 크롤링/검증 실패가 탐지되지 않고 데이터 파이프라인이 부분 실패 상태로 남을 수 있습니다.
Code

packages/crawling/package.json[R13-15]

+    "ky-verify": "tsx src/crawling/crawlYoutubeVerify.ts",
+    "ky-update": "pnpm run ky-youtube & pnpm run ky-valid & pnpm run ky-verify",
    "trans": "tsx src/postTransDictionary.ts",
Evidence
ky-updatepnpm run ky-youtube & pnpm run ky-valid & pnpm run ky-verify 형태로 실행되어, 앞의 프로세스들이
백그라운드로 돌며 실패 여부가 상위 프로세스에 제대로 전파되지 않습니다.

packages/crawling/package.json[9-16]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`ky-update` 스크립트가 `&amp;` 백그라운드 실행을 사용하여 일부 작업 실패가 상위 명령의 실패로 전파되지 않을 수 있습니다. 이로 인해 크롤링/검증 파이프라인이 부분 실패해도 성공으로 보이는 문제가 발생합니다.

## Issue Context
현재 `ky-update`는 3개 스크립트를 병렬로 띄우되 실패 집계가 없습니다.

## Fix Focus Areas
- packages/crawling/package.json[9-16]

## Suggested changes
- (옵션 A, 안정) 순차 실행으로 변경: `pnpm run ky-youtube &amp;&amp; pnpm run ky-valid &amp;&amp; pnpm run ky-verify`
- (옵션 B, 병렬 유지) `concurrently`(또는 유사 툴) 도입 후 fail-fast/exit-code 집계 적용
- (옵션 C, 쉘 기반) 백그라운드 실행 후 `wait` 및 각 job의 종료코드 확인 로직 추가(가능하면 B 권장)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. verify 브라우저 정리 누락 🐞 Bug ⛯ Reliability
Description
crawlYoutubeVerify.tsbrowser.close()await하지 않고 try/finally로 감싸지 않아, 에러/중단 시 Chromium
프로세스가 남거나 스크립트가 종료되지 않고 hang될 수 있습니다.
Code

packages/crawling/src/crawling/crawlYoutubeVerify.ts[R12-46]

+const browser = await puppeteer.launch();
+const page = await browser.newPage();
+
+const data = await getSongsKyNotNullDB();
+const verifiedIds = await getVerifyKySongsDB();
+
+console.log('getSongsKyNotNullDB : ', data.length);
+console.log('이미 검증된 곡 수 : ', verifiedIds.size);
+let index = 0;
+
+for (const song of data) {
+  if (verifiedIds.has(song.id!)) {
+    continue;
+  }
+
+  console.log(song.title, ' - ', song.artist + ' : ', song.num_ky);
+  let isValid = true;
+  try {
+    isValid = await isValidKYExistNumber(page, song.num_ky, song.title, song.artist);
+  } catch (error) {
+    index++;
+    continue;
+  }
+
+  if (isValid) {
+    await postVerifyKySongsDB(song);
+  } else {
+    await updateSongsKyDB({ ...song, num_ky: null });
+  }
+
+  index++;
+  console.log('crawlYoutubeVerify : ', index);
+}
+
+browser.close();
Evidence
crawlYoutubeVerify.ts는 top-level에서 browser를 열고 마지막에 browser.close()만 호출합니다(비동기 close를 await하지
않음). 같은 패키지의 crawlYoutube.tsfinally에서 await browser.close()로 안전하게 정리하는 패턴을 이미 사용하고 있어, 새
스크립트의 정리 방식이 일관되지 않고 더 취약합니다.

packages/crawling/src/crawling/crawlYoutubeVerify.ts[12-46]
packages/crawling/src/crawling/crawlYoutube.ts[74-155]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`crawlYoutubeVerify.ts`가 Puppeteer 브라우저를 열고 종료 시 `browser.close()`를 `await`하지 않으며, 예외가 발생해도 항상 닫히도록 보장하는 `try/finally`가 없습니다. 이로 인해 프로세스 hang/리소스 누수가 발생할 수 있습니다.

## Issue Context
동일 패키지의 `crawlYoutube.ts`는 `finally`에서 `await browser.close()`로 안전하게 정리합니다.

## Fix Focus Areas
- packages/crawling/src/crawling/crawlYoutubeVerify.ts[12-46]

## Suggested changes
- 전체 로직을 `try { ... } catch { ... } finally { await browser.close(); }`로 구성
- 마지막 줄을 `await browser.close()`로 변경
- (선택) 예외 catch에서 최소한 song.id/title/artist/num_ky를 로그로 남김

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. OpenAI 응답 파싱 취약 🐞 Bug ⛯ Reliability
Description
validateSongMatch가 모델 응답을 무조건 JSON.parse하여, 응답 포맷이 조금만 어긋나도 예외로 크롤링/검증이 누락되거나 중단될 수 있습니다. 현재
호출부는 예외를 잡고 continue 해버려(특히 verify/valid), 특정 곡이 영구히 검증되지 않는 조용한 데이터 누락이 생길 수 있습니다.
Code

packages/crawling/src/utils/validateSongMatch.ts[R20-45]

+  // 완전 일치 시 API 호출 없이 즉시 반환
+  if (inputTitle === foundTitle && inputArtist === foundArtist) return true;
+
+  const response = await client.chat.completions.create({
+    model: 'gpt-4o-mini',
+    messages: [
+      {
+        role: 'system',
+        content:
+          'Decide if two (title, artist) pairs refer to the same song. Allow spelling variants (spaces, en/kr, case). Return JSON: {"isValid":boolean}',
+      },
+      {
+        role: 'user',
+        content: `"${inputTitle}"(${inputArtist}) vs "${foundTitle}"(${foundArtist})`,
+      },
+    ],
+    response_format: { type: 'json_object' },
+    temperature: 0,
+    max_tokens: 20,
+  });
+
+  const content = response.choices[0].message.content;
+  if (!content) return false;
+
+  const result: { isValid: boolean } = JSON.parse(content);
+  return result.isValid;
Evidence
validateSongMatch.tsresponse.choices[0].message.content를 그대로 JSON.parse하며 실패 시 fallback이
없습니다. isValidKYExistNumber는 이를 await만 하고 자체적으로 처리하지 않으며, 상위 스크립트들은 예외 시 로그 없이(verify/valid) 건너뛰는
흐름이 존재합니다.

packages/crawling/src/utils/validateSongMatch.ts[20-46]
packages/crawling/src/crawling/isValidKYExistNumber.ts[31-38]
packages/crawling/src/crawling/crawlYoutubeVerify.ts[27-34]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`validateSongMatch`가 OpenAI 응답을 무조건 `JSON.parse()`하여 파싱 실패 시 예외가 발생합니다. 상위 호출부는 예외 발생 시 곡을 조용히 `continue`하는 경향이 있어, 검증 누락/데이터 품질 문제가 발생할 수 있습니다.

## Issue Context
- OpenAI 응답은 네트워크/서버/프롬프트 영향으로 예상과 다르게 올 수 있습니다.
- 현재는 파싱 실패에 대한 복구/로그가 부족합니다.

## Fix Focus Areas
- packages/crawling/src/utils/validateSongMatch.ts[20-46]
- packages/crawling/src/crawling/isValidKYExistNumber.ts[31-38]
- packages/crawling/src/crawling/crawlYoutubeVerify.ts[27-34]

## Suggested changes
- `JSON.parse` try/catch + 스키마 검증(`typeof result.isValid === &#x27;boolean&#x27;`)
- 파싱 실패 시 `return false` + 최소한의 에러 로그(입력쌍/응답 content 일부)
- `OPENAI_API_KEY` 없을 때 명확한 에러 메시지 또는 AI 검증 스킵 옵션 제공

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. verify insert 성공 오인 🐞 Bug ✓ Correctness
Description
postVerifyKySongsDB가 Supabase insert에서 에러가 나도 true를 반환하여, 호출자가 성공/실패를 구분할 수 없습니다. 결과적으로 verify
체크포인트가 실제로는 저장되지 않았는데도 파이프라인은 정상처럼 진행되어, 다음 실행에서 동일 곡을 반복 검증하거나 오류 원인이 숨겨질 수 있습니다.
Code

packages/crawling/src/supabase/postDB.ts[R75-88]

+export async function postVerifyKySongsDB(song: Song) {
+  const supabase = getClient();
+
+  try {
+    const { id, title, artist } = song;
+    const { error } = await supabase.from('verify_ky_songs').insert({ id, title, artist }).select();
+    if (error) {
+      console.error('postVerifyKySongsDB error : ', error);
+    }
+    return true;
+  } catch (error) {
+    console.error('catch - postVerifyKySongsDB error : ', error);
+    return error;
+  }
Evidence
postVerifyKySongsDB{ error }가 존재해도 콘솔에만 출력하고 return true로 종료합니다. crawlYoutubeVerify는 반환값을
확인하지 않아 삽입 실패를 감지/재시도/중단하지 못합니다.

packages/crawling/src/supabase/postDB.ts[75-89]
packages/crawling/src/crawling/crawlYoutubeVerify.ts[36-40]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`postVerifyKySongsDB`가 DB insert 실패 시에도 `true`를 반환해 호출자가 성공/실패를 식별할 수 없습니다. 이는 verify 체크포인트(verify_ky_songs)가 실제로 저장되지 않았는데도 파이프라인이 정상처럼 진행되는 문제를 유발합니다.

## Issue Context
`crawlYoutubeVerify`는 반환값을 확인하지 않고 다음 곡으로 진행합니다.

## Fix Focus Areas
- packages/crawling/src/supabase/postDB.ts[75-89]
- packages/crawling/src/crawling/crawlYoutubeVerify.ts[36-40]

## Suggested changes
- `postVerifyKySongsDB` 반환 타입을 `Promise&lt;boolean&gt;`로 고정하고, `error`가 있으면 `return false` 또는 `throw error`
- 호출부에서 실패 시 로그/재시도/중단 정책 결정
- (선택) `upsert` 사용 및 성공 시 `verifiedIds.add(song.id)`로 같은 런 내 중복 작업 최소화

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +13 to 15
"ky-verify": "tsx src/crawling/crawlYoutubeVerify.ts",
"ky-update": "pnpm run ky-youtube & pnpm run ky-valid & pnpm run ky-verify",
"trans": "tsx src/postTransDictionary.ts",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Ky-update 실패 숨김 🐞 Bug ⛯ Reliability

ky-update&로 3개 스크립트를 백그라운드 병렬 실행해, 일부 작업이 실패해도 전체 명령이 성공으로 보일 수 있습니다(마지막 foreground 프로세스 exit
code만 반영). 결과적으로 크롤링/검증 실패가 탐지되지 않고 데이터 파이프라인이 부분 실패 상태로 남을 수 있습니다.
Agent Prompt
## Issue description
`ky-update` 스크립트가 `&` 백그라운드 실행을 사용하여 일부 작업 실패가 상위 명령의 실패로 전파되지 않을 수 있습니다. 이로 인해 크롤링/검증 파이프라인이 부분 실패해도 성공으로 보이는 문제가 발생합니다.

## Issue Context
현재 `ky-update`는 3개 스크립트를 병렬로 띄우되 실패 집계가 없습니다.

## Fix Focus Areas
- packages/crawling/package.json[9-16]

## Suggested changes
- (옵션 A, 안정) 순차 실행으로 변경: `pnpm run ky-youtube && pnpm run ky-valid && pnpm run ky-verify`
- (옵션 B, 병렬 유지) `concurrently`(또는 유사 툴) 도입 후 fail-fast/exit-code 집계 적용
- (옵션 C, 쉘 기반) 백그라운드 실행 후 `wait` 및 각 job의 종료코드 확인 로직 추가(가능하면 B 권장)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +12 to +46
const browser = await puppeteer.launch();
const page = await browser.newPage();

const data = await getSongsKyNotNullDB();
const verifiedIds = await getVerifyKySongsDB();

console.log('getSongsKyNotNullDB : ', data.length);
console.log('이미 검증된 곡 수 : ', verifiedIds.size);
let index = 0;

for (const song of data) {
if (verifiedIds.has(song.id!)) {
continue;
}

console.log(song.title, ' - ', song.artist + ' : ', song.num_ky);
let isValid = true;
try {
isValid = await isValidKYExistNumber(page, song.num_ky, song.title, song.artist);
} catch (error) {
index++;
continue;
}

if (isValid) {
await postVerifyKySongsDB(song);
} else {
await updateSongsKyDB({ ...song, num_ky: null });
}

index++;
console.log('crawlYoutubeVerify : ', index);
}

browser.close();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Verify 브라우저 정리 누락 🐞 Bug ⛯ Reliability

crawlYoutubeVerify.tsbrowser.close()await하지 않고 try/finally로 감싸지 않아, 에러/중단 시 Chromium
프로세스가 남거나 스크립트가 종료되지 않고 hang될 수 있습니다.
Agent Prompt
## Issue description
`crawlYoutubeVerify.ts`가 Puppeteer 브라우저를 열고 종료 시 `browser.close()`를 `await`하지 않으며, 예외가 발생해도 항상 닫히도록 보장하는 `try/finally`가 없습니다. 이로 인해 프로세스 hang/리소스 누수가 발생할 수 있습니다.

## Issue Context
동일 패키지의 `crawlYoutube.ts`는 `finally`에서 `await browser.close()`로 안전하게 정리합니다.

## Fix Focus Areas
- packages/crawling/src/crawling/crawlYoutubeVerify.ts[12-46]

## Suggested changes
- 전체 로직을 `try { ... } catch { ... } finally { await browser.close(); }`로 구성
- 마지막 줄을 `await browser.close()`로 변경
- (선택) 예외 catch에서 최소한 song.id/title/artist/num_ky를 로그로 남김

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@GulSam00 GulSam00 merged commit 2a8f4b4 into develop Mar 8, 2026
2 checks passed
@GulSam00 GulSam00 deleted the refactor/crawling branch March 8, 2026 11:09
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