Skip to content

Fix/auto complete#159

Merged
GulSam00 merged 3 commits intodevelopfrom
fix/autoComplete
Mar 8, 2026
Merged

Fix/auto complete#159
GulSam00 merged 3 commits intodevelopfrom
fix/autoComplete

Conversation

@GulSam00
Copy link
Owner

@GulSam00 GulSam00 commented Mar 8, 2026

📌 PR 제목

Fix : 자동완성 로직, alias 추가

Summary

  • 자동완성 목록이 1개일 때 label이 입력값과 정확히 일치하는 경우에만 alias value로 치환하도록 조건 추가
  • 아티스트 별칭 데이터 업데이트 (Eve, 美波, ASIAN KUNG-FU GENERATION 등 추가)
  • 한글→일어 아티스트 매핑 추가

변경 상세

Bug Fix — useSearchSong

기존 동작: 자동완성 후보가 1개로 좁혀지기만 하면 무조건 alias value로 치환
→ 예: "Eve" 입력 시 후보가 1개로 줄어도 검색어가 의도치 않게 치환되는 버그

수정 동작: 후보가 1개이면서 label === trimSearch(완전 일치)일 때만 치환

// 변경 전
if (autoCompleteList.length === 1) {
parsedSearch = autoCompleteList[0].value;
}

// 변경 후
if (autoCompleteList.length === 1) {
if (autoCompleteList[0].label === trimSearch) {
parsedSearch = autoCompleteList[0].value;
}
}

Chore — .gitignore

Claude Code 로컬 설정 디렉토리(.claude/*) gitignore 추가

Test plan

  • "Eve" 검색 시 자동완성 치환 없이 정상 검색되는지 확인
  • 정확한 아티스트명 입력 후 alias 치환이 정상 동작하는지 확인
  • 추가된 아티스트(Eve, 미나미, 아지캉) 한글 검색 정상 동작 확인

GulSam00 and others added 3 commits March 9, 2026 01:04
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 4:10pm

@GulSam00 GulSam00 merged commit a72ccba into develop Mar 8, 2026
2 checks passed
@qodo-code-review
Copy link

Review Summary by Qodo

Fix autocomplete exact match and expand artist alias data

🐞 Bug fix ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Fixed autocomplete alias substitution to only apply when label exactly matches input
• Added new artists (Eve, 美波, ASIAN KUNG-FU GENERATION) with Korean aliases
• Added Korean-to-Japanese artist mapping for new artists
• Removed outdated artist entries and updated existing aliases
Diagram
flowchart LR
  A["User Input"] --> B["Autocomplete Logic"]
  B --> C{"Label === Input?"}
  C -->|Yes & 1 Match| D["Substitute with Alias Value"]
  C -->|No or Multiple| E["Use Original Input"]
  D --> F["Search Results"]
  E --> F
  G["Artist Alias Data"] --> H["Add New Artists"]
  H --> I["Korean-to-Japanese Mapping"]
  I --> F
Loading

Grey Divider

File Changes

1. apps/web/src/constants/artistAlias.ts ✨ Enhancement +6/-7

Expanded and updated artist alias mappings

• Added new artists: Eve, 美波, ASIAN KUNG-FU GENERATION with Korean aliases
• Updated existing aliases for Ado and Official髭男dism
• Removed outdated entries: 防弾少年団, 少女時代, ユンナ
• Fixed DECO*27 entry name format

apps/web/src/constants/artistAlias.ts


2. apps/web/src/constants/krToJpnArtist.ts ✨ Enhancement +4/-0

Added Korean-to-Japanese artist mappings

• Added Korean-to-Japanese mappings for new artists (Eve, 美波, ASIAN KUNG-FU GENERATION)
• Maintains alphabetical sorting for artist names
• Enables Korean search to resolve to Japanese artist names

apps/web/src/constants/krToJpnArtist.ts


3. apps/web/src/hooks/useSearchSong.ts 🐞 Bug fix +4/-2

Fix autocomplete exact match condition

• Fixed autocomplete substitution logic to check label exact match with trimmed input
• Only substitutes alias value when autoCompleteList has exactly 1 item AND label matches input
• Prevents unintended alias substitution for partial matches

apps/web/src/hooks/useSearchSong.ts


Grey Divider

Qodo Logo

@qodo-code-review
Copy link

qodo-code-review bot commented Mar 8, 2026

Code Review by Qodo

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

Grey Divider


Action required

1. Reversed artist mapping 🐞 Bug ✓ Correctness
Description
krToJpnArtistSort adds ASIAN KUNG-FU GENERATION in the wrong direction (official→Korean). In the
J-POP artist modal, clicking that entry will search using the Korean string, likely returning no
results when the DB stores the official artist name.
Code

apps/web/src/constants/krToJpnArtist.ts[5]

+  'ASIAN KUNG-FU GENERATION': '아시안 쿵푸 제너레이션',
Evidence
JpnArtistList iterates [kr, jpn] and passes jpn (the value) into the search input; therefore
krToJpnArtistSort values must be the canonical/DB artist string. The new ASIAN KUNG-FU entry
currently sets the value to a Korean display string, breaking that flow.

apps/web/src/constants/krToJpnArtist.ts[1-9]
apps/web/src/app/search/JpnArtistList.tsx[52-60]

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

### Issue description
`krToJpnArtistSort` is used by `JpnArtistList` such that the **value** is what gets inserted into the search box and used for searching. The new ASIAN KUNG-FU GENERATION entry is inverted (value is Korean), so selecting it will search the wrong string.

### Issue Context
`JpnArtistList` does `Object.entries(krToJpnArtistSort).map(([kr, jpn]) =&gt; ...)` and onClick uses `handleSelect(jpn)`.

### Fix Focus Areas
- apps/web/src/constants/krToJpnArtist.ts[2-10]

### Suggested change
Change:
- `&#x27;ASIAN KUNG-FU GENERATION&#x27;: &#x27;아시안 쿵푸 제너레이션&#x27;`
To:
- `&#x27;아시안 쿵푸 제너레이션&#x27;: &#x27;ASIAN KUNG-FU GENERATION&#x27;`

(Ensure the displayed key remains Korean and the searched value is the canonical artist string.)

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


2. Case-sensitive alias match 🐞 Bug ✓ Correctness
Description
The new label === trimSearch condition is case-sensitive, but autocomplete matching is
case-insensitive. This prevents alias→official substitution for differently-cased roman aliases
(e.g., user types "Minami" but alias stored as "minami"), causing searches to miss non-Latin
canonical artist names (e.g., 美波).
Code

apps/web/src/hooks/useSearchSong.ts[R62-66]

    if (autoCompleteList.length === 1) {
-      // 자동완성 리스트가 하나(정확히 일치하면) 해당 alias의 value로 자동 치환
-      parsedSearch = autoCompleteList[0].value;
+      if (autoCompleteList[0].label === trimSearch) {
+        // 자동완성 리스트가 하나(정확히 일치하면)고 label도 일치하면 해당 alias의 value로 자동 치환
+        parsedSearch = autoCompleteList[0].value;
+      }
Evidence
Suggestions are produced using lowercase normalization, so a differently-cased input can still yield
a single suggestion. But handleSearch compares the raw user input to the stored label with strict
equality, blocking replacement; the server then uses the raw query string directly in ilike
filters, which will not match a different-script canonical artist name like 美波.

apps/web/src/hooks/useSearchSong.ts[56-73]
apps/web/src/utils/getArtistAlias.ts[26-38]
apps/web/src/constants/artistAlias.ts[27-31]
apps/web/src/app/api/search/route.ts[59-63]

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

### Issue description
Autocomplete suggestions are case-insensitive, but the new replacement condition in `handleSearch` is case-sensitive (`label === trimSearch`). This blocks alias→official substitution for romanized aliases when users type different casing (e.g., `Minami` vs stored `minami`), which is especially harmful when the canonical artist is non-Latin (e.g., `美波`).

### Issue Context
- `getAutoCompleteSuggestions()` lowercases the query and candidate labels.
- `handleSearch()` compares the raw input string to the candidate label with strict equality.

### Fix Focus Areas
- apps/web/src/hooks/useSearchSong.ts[56-73]

### Suggested change
Normalize both sides for the equality test, e.g.:
- `const normalizedTrim = trimSearch.toLowerCase();`
- `if (autoCompleteList[0].label.toLowerCase() === normalizedTrim) { parsedSearch = autoCompleteList[0].value; }`

Keep the existing `autoCompleteList.length === 1` guard to avoid unintended substitutions for partial matches.

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



Remediation recommended

3. Deferred submit mismatch 🐞 Bug ⛯ Reliability
Description
autoCompleteList is derived from deferredSearch, but submission uses the immediate search
value; the alias-replacement decision can be based on stale suggestions. With the new strict
equality check, this can skip a valid alias substitution when the user hits Enter quickly after
typing.
Code

apps/web/src/hooks/useSearchSong.ts[R62-66]

    if (autoCompleteList.length === 1) {
-      // 자동완성 리스트가 하나(정확히 일치하면) 해당 alias의 value로 자동 치환
-      parsedSearch = autoCompleteList[0].value;
+      if (autoCompleteList[0].label === trimSearch) {
+        // 자동완성 리스트가 하나(정확히 일치하면)고 label도 일치하면 해당 alias의 value로 자동 치환
+        parsedSearch = autoCompleteList[0].value;
+      }
Evidence
Because useDeferredValue(search) can lag search, the memoized autoCompleteList may correspond
to an earlier input while trimSearch is computed from the latest input. This creates a timing
window where autoCompleteList[0].label does not match trimSearch even though the latest input
does match a single alias exactly.

apps/web/src/hooks/useSearchSong.ts[49-54]
apps/web/src/hooks/useSearchSong.ts[56-66]

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

### Issue description
`autoCompleteList` is computed from `deferredSearch`, but `handleSearch` uses the non-deferred `search` to build `trimSearch`. This can cause alias substitution to be skipped due to stale suggestions.

### Issue Context
The deferred value is appropriate for UI rendering performance, but submit-time logic should use the latest input.

### Fix Focus Areas
- apps/web/src/hooks/useSearchSong.ts[49-81]

### Suggested change
Inside `handleSearch`, compute a fresh list:
- `const suggestions = getAutoCompleteSuggestions(trimSearch);`
Then apply the single-suggestion + (normalized) exact-match replacement using `suggestions` rather than `autoCompleteList`.

Keep `autoCompleteList` for rendering the dropdown only.

ⓘ 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

@GulSam00 GulSam00 deleted the fix/autoComplete branch March 8, 2026 16:10
// A-Z
Ado: 'Ado',
Aimer: 'Aimer',
'ASIAN KUNG-FU GENERATION': '아시안 쿵푸 제너레이션',

Choose a reason for hiding this comment

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

Action required

1. Reversed artist mapping 🐞 Bug ✓ Correctness

krToJpnArtistSort adds ASIAN KUNG-FU GENERATION in the wrong direction (official→Korean). In the
J-POP artist modal, clicking that entry will search using the Korean string, likely returning no
results when the DB stores the official artist name.
Agent Prompt
### Issue description
`krToJpnArtistSort` is used by `JpnArtistList` such that the **value** is what gets inserted into the search box and used for searching. The new ASIAN KUNG-FU GENERATION entry is inverted (value is Korean), so selecting it will search the wrong string.

### Issue Context
`JpnArtistList` does `Object.entries(krToJpnArtistSort).map(([kr, jpn]) => ...)` and onClick uses `handleSelect(jpn)`.

### Fix Focus Areas
- apps/web/src/constants/krToJpnArtist.ts[2-10]

### Suggested change
Change:
- `'ASIAN KUNG-FU GENERATION': '아시안 쿵푸 제너레이션'`
To:
- `'아시안 쿵푸 제너레이션': 'ASIAN KUNG-FU GENERATION'`

(Ensure the displayed key remains Korean and the searched value is the canonical artist string.)

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

Comment on lines 62 to +66
if (autoCompleteList.length === 1) {
// 자동완성 리스트가 하나(정확히 일치하면) 해당 alias의 value로 자동 치환
parsedSearch = autoCompleteList[0].value;
if (autoCompleteList[0].label === trimSearch) {
// 자동완성 리스트가 하나(정확히 일치하면)고 label도 일치하면 해당 alias의 value로 자동 치환
parsedSearch = autoCompleteList[0].value;
}

Choose a reason for hiding this comment

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

Action required

2. Case-sensitive alias match 🐞 Bug ✓ Correctness

The new label === trimSearch condition is case-sensitive, but autocomplete matching is
case-insensitive. This prevents alias→official substitution for differently-cased roman aliases
(e.g., user types "Minami" but alias stored as "minami"), causing searches to miss non-Latin
canonical artist names (e.g., 美波).
Agent Prompt
### Issue description
Autocomplete suggestions are case-insensitive, but the new replacement condition in `handleSearch` is case-sensitive (`label === trimSearch`). This blocks alias→official substitution for romanized aliases when users type different casing (e.g., `Minami` vs stored `minami`), which is especially harmful when the canonical artist is non-Latin (e.g., `美波`).

### Issue Context
- `getAutoCompleteSuggestions()` lowercases the query and candidate labels.
- `handleSearch()` compares the raw input string to the candidate label with strict equality.

### Fix Focus Areas
- apps/web/src/hooks/useSearchSong.ts[56-73]

### Suggested change
Normalize both sides for the equality test, e.g.:
- `const normalizedTrim = trimSearch.toLowerCase();`
- `if (autoCompleteList[0].label.toLowerCase() === normalizedTrim) { parsedSearch = autoCompleteList[0].value; }`

Keep the existing `autoCompleteList.length === 1` guard to avoid unintended substitutions for partial matches.

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

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