👩🏻‍💻 Develop/TroubleShooting

[Next.js] ENUM 키워드 매핑 실패로 인해 발생한 한글 변환 오류 해결하기

dev.daisy 2025. 11. 25. 14:24
ENUM 키워드 매핑 실패 문제를 겪고 enum value가 중복될 수 있는 구조라서 prefix를 붙여야겠다는 생각까지는 했지만 이것만으로 문제를 해결할 수 없었습니다. 카테고리별 포맷을 camelCase에서 SNAKE_CASE로 통일해야 했고, 매핑 객체의 key 규칙이 명확하게 정의되지 않은 상태에서는 구조와 포맷이 어긋날 때마다 오류가 반복적으로 발생했습니다. 또한 포맷 불일치로 매핑이 실패할 경우 내부 영문 키가 그대로 노출되는 fallback은 사용자 경험 측면에서도 안좋은 문제라고 생각이 들었습니다.

이번 문제를 해결하며 다시 한 번 느낀 점은 “사용자에게 보이는 한 줄의 텍스트도 그 이면에는 데이터 구조, enum 설계, 포맷 규칙 등 전체 시스템이 유기적으로 연결되어 있어야 한다”는 사실입니다. 이 경험으로 단순한 이슈 해결을 넘어서, prefixEnum과 포맷 정규화(normalize)를 기반으로 한 라이브러리를 설계해봐야겠다는 생각을 하는 계기가 되었습니다. 앞으로 Tuning 서비스뿐 아니라 이후 다른 프로젝트에서도 재사용 가능한 구조로 확장할 수 있는 기반을 마련해보려고 합니다.

개발 중인 Tuning 프로젝트에서는 유저 성향과 공통 관심사를 기반으로 매칭을 해주는 서비스이기 때문에 유저 정보를 담은 프로필 카드가 있는데, 이때 백엔드에서 내려온 enum 값을 프론트에서 한글 라벨로 변환해 UI에 렌더링하는 과정이 필요합니다. 하지만 특정 상황에서 영문 enum 값이 그대로 노출되는 문제가 발생했습니다.

(유저 프로필카드 - ENUM 키워드 선택 페이지)

 

서비스에서 실제 사용자에게 보여야 할 라벨은 다음과 같습니다.

  • RELIGION (카테고리) → NON_RELIGIOUS (라벨) → “종교 없음”
  • PREFERRED_PEOPLE (카테고리) → RELIABLE (라벨) → “믿음직한 사람”

하지만 실제 화면에는 다음처럼 내부 키가 그대로 나타났습니다. 중복되는 라벨을 다루기 위해 카테고리명으로 prefix를 붙여서 보여줬는데, 실제 백엔드에서 사용하는 ENUM값으로 매핑하는 과정에서 잘못된 문자열로 넘겨주고 있었습니다.

 

(아래 글에서 더 자세한 내용을 확인할 수 있습니다!)

https://dani1552.tistory.com/84

 

[TroubleShooting] 중복 ENUM 값 충돌로 인해 발생한 키워드 매핑 오류 해결하기

ENUM에서 value가 같으면 동일한 의미일 것이라는 가정으로 키워드 매핑 오류가 발생했습니다. 렌더링 단계에서는 value만 보고 매칭하기 때문에 구분이 불가능했고, 이 때문에 UI에 잘못된 정보가

dani1552.tistory.com

MBTI_ISTJ
RELIGION_NON_RELIGIOUS
PREFERREDPEOPLE_RELIABLE

 

사용자 입장에서는 어떤 의미인지 알 수 없기 때문에 UX에 직접적인 악영향을 끼쳤고, 바로 원인 분석과 구조 개선이 필요한 상황이였습니다.


문제 원인 분석하기 - 매핑 객체의 key 구조 문제

해당 문제를 해결하기 위해 코드를 살펴봤을 때 enum 구조 설계부터 포맷 일관성, 키워드 생성 규칙까지 여러 요소에서 복합적으로 얽힌 문제로 보였습니다. 

 

키워드 매핑을 위해 선언해둔 ENUM값은 '언더스코어 + SNAKE_CASE' 기준으로 구조화되어 있어서 기준을 맞춰 라벨을 조회해야만 정상적으로 매핑이 됩니다.

{
  RELIGION_CHRISTIANITY: '기독교',
  DRINKING_SOMETIMES: '가끔 마심',
}

 

하지만 실제 렌더링 시 생성한 키는 포맷이 달랐는데, 문제는 공통 관심사 키워드를 조합하는 부분에서 발생했습니다.

정상적으로 동작한 경우:

TuningKeywords(개인 키워드)는 이미 ${카테고리}_${값} 형태로 조합되어 문제가 없었습니다.

문제 발생한 경우:

하지만 sameInterests(공통 관심사)에서는 다음과 같이 조합하고 있었습니다.

preferredPeople + RELIABLE  
→ PREFERREDPEOPLE_RELIABLE  // ❌ 언더스코어 없음

 

이 때 매핑 객체에는 아래 형태로 존재하므로,

PREFERRED_PEOPLE_RELIABLE

결과적으로 포맷이 불일치하여 매핑이 실패하고, 매핑 실패하니 라벨이 아닌 영문 키 그대로 출력되는 문제가 발생되어 그대로 UI까지 전달되고 있는 상황이였습니다!

 

정리하자면 이번 문제는 다음 세 가지가 문제가 맞물려 발생했는데,

  1. enum value 중복
  2. 카테고리 이름 포맷(camelCase vs SNAKE_CASE) 불일치
  3. 키 조합 규칙의 일관성 부족

이로 인해 ALL_KEYWORD_MAP에 존재하지 않는 key가 만들어지고, 결국 매핑 실패 → UI에 영문 키 노출이라는 UX 문제가 발생한 것입니다.


해결 방법

문제를 해결하기 위해 다음과 같은 구조 개선을 진행했습니다.

1) 카테고리 이름을 자동으로 스네이크케이스로 변환하기

function normalizeCategory(category: string) {
  return category
    .replace(/([a-z])([A-Z])/g, '$1_$2')
    .toUpperCase();
}

camelCase → SNAKE_CASE로 자동 변환하여 포맷 일관성을 확보했습니다.

2) 공통 관심사 키워드 생성 시 normalize 적용하기

const commonInterestList = Object.entries(sameInterests).flatMap(
  ([category, keys]) => {
    const normalizedCategory = normalizeCategory(category);
    return keys.map((key) => `${normalizedCategory}_${key}`);
  }
);

이제 항상 PREFERRED_PEOPLE_RELIABLE 형태로 키가 생성되어 ALL_KEYWORD_MAP과 정확히 매핑됩니다.


회고

표면적으로는 “키 이름이 달라서 발생한 오류”처럼 보였지만, 실제 원인은 생각보다 더 복잡했습니다. enum value가 중복될 수 있는 구조라서 prefix를 붙여야겠다는 생각까지는 했지만 이것만으로 문제를 해결할 수 있는 것은 아니었습니다. 카테고리별 포맷을 camelCase에서 SNAKE_CASE로 통일해야 했고, 매핑 객체의 key 규칙이 명확하게 정의되지 않은 상태에서는 구조와 포맷이 어긋날 때마다 오류가 반복적으로 발생했습니다. 또한 포맷 불일치로 매핑이 실패할 경우 내부 영문 키가 그대로 노출되는 fallback은 사용자 경험 측면에서도 안좋은 문제라고 생각이 들었습니다.

 

이번 문제를 해결하며 다시 한 번 느낀 점은 “사용자에게 보이는 한 줄의 텍스트도 그 이면에는 데이터 구조, enum 설계, 포맷 규칙 등 전체 시스템이 유기적으로 연결되어 있어야 한다”는 사실입니다. 이 경험으로 단순한 이슈 해결을 넘어서, prefixEnum과 포맷 정규화(normalize)를 기반으로 한 라이브러리를 설계해봐야겠다는 생각을 하는 계기가 되었습니다. 앞으로 Tuning 서비스뿐 아니라 이후 다른 프로젝트에서도 재사용 가능한 구조로 확장할 수 있는 기반을 마련해보려고 합니다.


(튜닝 프론트엔드 레포지토리 보러가기)

https://github.com/100-hours-a-week/2-hertz-fe

 

GitHub - 100-hours-a-week/2-hertz-fe: ⚡️ 2조 튜닝 FE 레포지토리

⚡️ 2조 튜닝 FE 레포지토리. Contribute to 100-hours-a-week/2-hertz-fe development by creating an account on GitHub.

github.com