Skip to content

Conversation

@Jeongchanyeong
Copy link
Collaborator

Motivation

Reference Links
Issue #482

Modification

투표 제작 / 수정 페이지에서 폼 제출 시에 비속어 감지 시 다이어로그 띄워주는 형태.

윤성님 컨펌 받고 수정 예정입니다.


Result

close #482


@github-actions github-actions bot added the feature 피쳐 개발에 사용합니다. label Dec 9, 2025
@Jeongchanyeong Jeongchanyeong force-pushed the feature-482/ai-swear-word-filter branch from f88b8c6 to 8f96213 Compare December 9, 2025 13:49
@github-actions
Copy link

github-actions bot commented Dec 9, 2025

🤖 AI Code Review (OpenAI)

  • src/api/moderation.ts + requestModeration 함수

    • detectedWords가 배열이 아닐 때 문자열을 배열로 변환하는 로직이 있지만, API 스펙이 변경되거나 다른 타입이 올 경우를 대비해 더 엄격한 타입 체크나 변환 로직이 필요해 보입니다.
    • 개선 제안: API 응답 타입을 더 엄격하게 검증하거나, detectedWords가 배열이 아니면 빈 배열로 처리하는 단순화도 고려해볼 수 있습니다.
  • src/hooks/useModerationCheck.tsx + useModerationCheck 훅

    • textsToCheck 배열에 pollData.description이 포함되어 있는데, 만약 description이 빈 문자열 또는 null/undefined일 경우 필터링은 되지만, 이미지 이름(파일명) 검사도 필요하다고 주석에 적혀 있으나 실제로 이미지 이름은 검사 대상에 포함되어 있지 않습니다.
    • 개선 제안: 이미지 이름도 검사 대상에 포함시키려면 pollData.pollChoices의 이미지 URL에서 파일명만 추출해 검사 대상에 추가하는 로직이 필요합니다.
    • useMutationmutationFn 내부에서 다수의 requestModeration 호출 시 에러가 발생해도 무시하고 진행하는데, 네트워크 문제 등으로 모든 요청이 실패할 경우 빈 결과를 반환해 부적절한 내용이 걸러지지 않을 위험이 있습니다.
    • 개선 제안: 실패한 요청에 대한 로깅이나 사용자 알림, 또는 재시도 로직을 추가하는 것이 안전합니다.
  • src/components/poll/edit/PollEditButton/hooks.ts + usePollEditButton 훅

    • handleClickPollEditButton에서 isValid 체크 후 바로 checkModeration 호출하는데, checkModeration이 비동기임에도 불구하고 updatePoll 호출 시점이 onConfirm 콜백에 의존해 있어 UI 상태 관리가 다소 불명확할 수 있습니다.
    • 개선 제안: isPending 상태를 적절히 활용해 버튼 비활성화 처리 및 중복 클릭 방지 로직을 명확히 하는 것이 좋습니다.
  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx

    • useModerationCheck 훅에서 mutate만 받아오고 있는데, isPending 상태를 받아서 제출 버튼 비활성화 처리나 로딩 UI 표시가 없어서 UX 개선 여지가 있습니다.
    • 개선 제안: isPending 상태를 받아서 제출 중임을 사용자에게 명확히 보여주고, 중복 제출을 방지하는 로직 추가를 권장합니다.
  • package.json + yarn.lock

    • chooz-ai-moderation 패키지를 추가했는데, 실제 코드에서는 해당 패키지를 직접 사용하지 않고 있습니다. 불필요한 의존성 추가일 가능성이 있습니다.
    • 개선 제안: 사용하지 않는 의존성은 제거하거나, 해당 패키지를 사용하는 코드가 누락된 것은 아닌지 확인 필요합니다.
  • nit

    • src/api/moderation.ts: 에러 메시지에 마침표가 두 개(..) 붙어 있음. "추가해주세요..""추가해주세요."로 수정 권장
    • src/hooks/useModerationCheck.tsx: useMutation 반환값을 바로 반환하는데, 타입 명시가 없어 가독성 및 유지보수성 향상을 위해 제네릭 타입 명시 권장
    • src/components/poll/edit/PollEditButton/hooks.ts: isPending 변수명을 isUpdatePendingisModerationPending 합친 상태로 재정의하는데, 변수명이 중복되어 혼동될 수 있으므로 명확한 이름 사용 권장 (isAnyPending 등)

자동 생성된 리뷰입니다. 참고용으로만 사용해주세요.

@github-actions
Copy link

🤖 AI Code Review (OpenAI)

  • src/api/moderation.ts + requestModeration 함수

    • 이유: detectedWords가 배열이 아닐 때 배열로 변환하는 로직이 있는데, API 스펙이 바뀌거나 detectedWordsnull 혹은 undefined일 경우를 대비해 좀 더 명확하게 처리하는 것이 좋습니다.
    • 개선 제안: detectedWordsnull 또는 undefined일 때 빈 배열로 초기화하는 로직을 최상단에 두고, 문자열일 경우 배열로 감싸는 식으로 명확히 분기 처리 권장.
  • src/hooks/useModerationCheck.tsx + useMutation 내부 mutationFn

    • 이유: textsToCheck 배열에 pollData.descriptionundefined 혹은 빈 문자열일 경우 필터링은 하지만, 이미지 이름(예: pollChoices 내 이미지 URL 등)도 검사한다고 주석에 명시되어 있으나 실제로는 검사하지 않고 있음.
    • 개선 제안: 이미지 파일명이나 URL도 검사 대상에 포함시키려면 pollChoicesimageUrl 등도 textsToCheck에 추가하는 로직 필요. 만약 의도된 부분이라면 주석 수정 필요.
  • src/hooks/useModerationCheck.tsx + onSuccess 콜백 내 Dialog 컴포넌트

    • 이유: 부적절한 표현이 감지되었을 때 사용자에게 경고 후 '그대로 올리기'를 선택하면 바로 onConfirm 호출하는데, 이 과정에서 다중 클릭 방지나 로딩 상태 관리가 없음.
    • 개선 제안: 다중 클릭 방지 및 사용자 경험 향상을 위해 버튼 클릭 시 로딩 상태를 관리하거나, Dialog 내에서 버튼 비활성화 처리 추가 고려.
  • src/components/poll/edit/PollEditButton/hooks.ts + handleClickPollEditButton 함수

    • 이유: checkModeration 호출 시 pollData를 넘기는데, pollData가 최신 상태인지 확실하지 않음. React Query나 상태 관리 라이브러리 사용 시 stale data 문제 가능성 존재.
    • 개선 제안: pollData가 최신 상태임을 보장하거나, usePollForm에서 반환하는 데이터가 항상 최신인지 확인 필요.
  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx + handleClickSubmitButton 함수

    • 이유: checkModeration 호출 후 onConfirm 콜백에서 registVote 호출 시 pollData를 그대로 사용. 마찬가지로 데이터 최신성 문제 가능성 존재.
    • 개선 제안: pollData가 최신 상태인지 확인하거나, checkModeration 호출 시점에 최신 데이터를 넘기도록 보장 필요.
  • package.json

    • 이유: chooz-ai-moderation 패키지가 추가되었는데, 실제 코드 내에서 해당 패키지를 직접 import 하거나 사용하는 부분이 없음.
    • 개선 제안: 만약 내부적으로 requestModeration 함수가 이 패키지를 사용하는 구조라면 괜찮으나, 그렇지 않다면 불필요한 의존성 추가일 수 있으니 확인 필요.
  • nit (사소한 부분)

    1. src/api/moderation.ts 내 에러 메시지에 마침표가 두 번(..) 찍혀 있음.
    2. src/hooks/useModerationCheck.tsx 내 textsToCheck 필터링 시 filter(Boolean) 대신 명확히 text => text.trim().length > 0 같은 조건으로 빈 문자열도 제거하는 것이 더 안전.
    3. src/components/poll/edit/PollEditButton/hooks.ts 내 isPending 변수명은 두 개의 상태를 합친 것이므로, 좀 더 명확하게 isAnyPending 등으로 명명하면 가독성 향상 가능.

자동 생성된 리뷰입니다. 참고용으로만 사용해주세요.

@Jeongchanyeong Jeongchanyeong force-pushed the feature-482/ai-swear-word-filter branch from 45d78c3 to d462a04 Compare December 30, 2025 23:58
@Jeongchanyeong Jeongchanyeong force-pushed the feature-482/ai-swear-word-filter branch from d462a04 to b707e7e Compare December 30, 2025 23:59
@github-actions
Copy link

🤖 AI Code Review (OpenAI)

  • src/api/moderation.ts + requestModeration 함수

    • 이유: detectedWords가 배열이 아닐 경우 배열로 변환하는 로직이 있으나, API 스펙이 변경되거나 서버에서 빈 문자열, null, undefined 등 다양한 형태가 올 수 있음. 현재는 문자열 한 개만 배열로 감싸는 정도로 처리되어 있는데, 만약 서버가 객체나 다른 타입을 보내면 의도치 않은 동작 가능성 있음.
    • 개선 제안: detectedWords 타입을 좀 더 엄격하게 체크하고, 예상치 못한 타입에 대해 안전하게 빈 배열로 초기화하는 방어 코드를 추가하는 것이 좋음.
  • src/hooks/useModerationCheck.tsx + useModerationCheck 훅

    • 이유: textsToCheck 배열에 pollData.description이 포함되어 있는데, 만약 description이 빈 문자열이나 null일 경우 필터링은 되지만, 이미지 파일명 검사 로직이 빠져 있음. 이미지 이름도 검사해야 한다는 주석과 달리 실제로는 이미지 이름이 검사 대상에서 빠져 있음.
    • 개선 제안: pollData.pollChoices 내 이미지 이름(예: imageUrl에서 파일명 추출)을 텍스트 검사 대상에 포함시키는 로직 추가 필요.
  • src/hooks/useModerationCheck.tsx + useMutation 반환값

    • 이유: useMutation 훅을 반환하면서 내부에서 openDialog를 호출해 UI를 띄우는데, 이 훅을 사용하는 컴포넌트가 unmount 되거나 dialog 상태 관리가 꼬일 경우 메모리 누수나 UI 이상이 발생할 수 있음.
    • 개선 제안: useEffect 등으로 컴포넌트 라이프사이클에 맞춰 dialog 상태를 관리하거나, dialog 상태를 전역 상태관리로 분리하는 방안 고려.
  • src/components/poll/edit/PollEditButton/hooks.ts + handleClickPollEditButton 함수

    • 이유: checkModeration 호출 시 pollData를 넘기고, onConfirm 콜백에서 updatePoll 호출하는데, pollData가 변경될 경우 최신 상태가 반영되지 않을 수 있음.
    • 개선 제안: pollDatacheckModeration 호출 시점에 최신 상태로 보장하거나, onConfirm 내부에서 최신 pollData를 다시 읽어 호출하도록 개선 필요.
  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx + handleClickSubmitButton 함수

    • 이유: checkModeration 호출 후 onConfirm 콜백에서 registVote 호출하는데, registVote 호출 시점에 pollData가 변경될 가능성 있음.
    • 개선 제안: onConfirm 내부에서 pollData를 직접 참조하지 말고, checkModeration 호출 시점의 pollData를 클로저로 유지하거나, onConfirm에 인자로 넘겨서 최신 상태를 보장하는 것이 안전함.
  • package.json + chooz-ai-moderation 패키지 추가

    • 이유: 새 패키지 추가 시 버전 고정이나 peerDependencies 확인이 필요하며, openai 패키지 버전이 4.x에서 6.x로 중복 존재함.
    • 개선 제안: openai 패키지 버전 충돌 가능성 검토 및 필요 시 의존성 정리 필요.
  • nit

    • src/api/moderation.ts: 에러 메시지에 마침표가 두 개(...추가해주세요..) 붙어 있음. 한 개로 정리하면 좋음.
    • src/hooks/useModerationCheck.tsx: useMutation 타입 파라미터 명시가 없는데, 명시적으로 타입을 지정하면 가독성 및 타입 안정성 향상 가능.
    • src/components/poll/edit/PollEditButton/hooks.ts: isPending 변수명을 isLoading 등 React Query 관례에 맞게 통일하면 더 직관적임.

자동 생성된 리뷰입니다. 참고용으로만 사용해주세요.

@github-actions
Copy link

🤖 AI Code Review (OpenAI)

  • src/api/moderation.ts + 전체

    • requestModeration 함수 내에서 detectedWords가 배열이 아닐 경우 문자열을 배열로 변환하는 로직이 있는데, API 스펙이 명확하다면 이 변환 로직을 API 응답 쪽에서 보장하는 편이 더 안전합니다. 클라이언트에서 변환을 계속 유지하면 유지보수성이 떨어질 수 있습니다.
    • withCredentials: false 옵션은 기본값이 false이므로 명시할 필요는 없고, 만약 인증 쿠키를 사용하지 않는 API라면 주석으로 의도를 명확히 하는 것이 좋습니다.
    • useModerateText 훅에서 mutationFn을 인라인으로 작성했는데, requestModeration 함수가 이미 async 함수이므로 mutationFn: requestModeration으로 간결하게 작성해도 무방합니다.
  • src/hooks/useModerationCheck.tsx + 전체

    • useMutation 훅을 반환하는 커스텀 훅인데, 내부에서 openDialog를 호출하는 방식은 UI와 로직이 강하게 결합되어 있습니다. 만약 다른 UI 컴포넌트에서 재사용하거나 테스트하기 어려울 수 있으므로, 모더레이션 결과를 반환하고 호출하는 쪽에서 다이얼로그를 띄우는 구조가 더 유연합니다.
    • textsToCheck 배열에 pollData.description이 있는데, 만약 description이 빈 문자열이나 null일 경우 .filter(Boolean)으로 걸러지긴 하지만, pollChoicestitle도 빈 문자열일 가능성이 있으니 이 부분도 확실히 검증하는 것이 좋습니다.
    • onSuccess 콜백에서 variables.onConfirm() 호출 시점이 다이얼로그 닫기 후인데, 혹시 onConfirm 내부에서 상태 변경이 일어나면 다이얼로그가 제대로 닫히지 않을 위험이 있습니다. closeDialog() 호출을 onConfirm 호출 이후로 옮기거나, onConfirm이 Promise를 반환하면 await 처리하는 방법도 고려해볼 수 있습니다.
  • src/components/poll/edit/PollEditButton/hooks.ts + 전체

    • handleClickPollEditButton 함수 내에서 checkModeration 호출 시 pollData를 넘기고, onConfirm 콜백에서 updatePoll을 호출하는 구조는 좋으나, isValid 체크가 checkModeration 호출 전에만 되어 있습니다. 만약 checkModeration 호출 중에 isValid가 변할 가능성이 있다면 추가 검증이 필요합니다.
    • isPending 변수를 isModerationPending || isUpdatePending으로 합친 것은 직관적이나, UI에서 어떤 작업이 진행 중인지 구분이 필요하면 별도로 관리하는 것이 좋습니다.
  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx + 전체

    • handleClickSubmitButton 내에서 checkModeration 호출 후 onConfirm 콜백에서 registVote를 호출하는 구조는 일관성 있고 좋습니다. 다만 checkModeration 훅에서 isPending 상태를 받아서 버튼 비활성화 등에 활용하면 UX가 더 좋아질 수 있습니다.
    • import 순서가 변경되면서 중복 import가 정리된 점은 좋으나, 상대경로와 절대경로가 섞여 있어 일관된 import 스타일을 유지하는 것이 유지보수에 유리합니다.
  • package.json / yarn.lock

    • chooz-ai-moderation 패키지를 새로 추가했는데, 이 패키지가 실제로 코드 내에서 import 되지 않고 있습니다. 만약 내부적으로 requestModeration에서 사용된다면 명확히 주석이나 문서화가 필요합니다.
    • openai 패키지가 두 버전(^4.0.0^6.9.1)이 중복으로 존재하는데, 충돌이나 번들 크기 증가 우려가 있습니다. 하나의 버전으로 통일하는 것이 좋습니다.
  • nit (사소한 점)

    • src/api/moderation.ts: 에러 메시지에 마침표가 두 개(...추가해주세요..) 붙어있음. 하나만 남기는 것이 깔끔합니다.
    • src/hooks/useModerationCheck.tsx: inlineMessage 생성 시 result.detectedWords.map(...).join(', ') 부분에서 단어가 많으면 UI가 깨질 수 있으니 최대 표시 개수 제한이나 줄임 처리 고려.
    • src/components/poll/edit/PollEditButton/hooks.ts: useParams<{ pollId: string }>() 타입 명시가 있는데, React Router v6에서는 제네릭 타입이 deprecated 되었으니 최신 문서 확인 필요.

자동 생성된 리뷰입니다. 참고용으로만 사용해주세요.

@github-actions
Copy link

🤖 AI Code Review (OpenAI)

  • src/api/moderation.ts + requestModeration 함수

    • detectedWords 처리 로직에서 detectedWords || []를 반환하는 부분이 있는데, 이미 위에서 배열로 변환했으므로 불필요한 중복 검사임.
    • 개선: detectedWords를 확실히 배열로 변환한 후 바로 반환하도록 간결하게 수정 가능.
  • src/hooks/useModerationCheck.tsx

    • 모든 텍스트를 개별적으로 requestModeration 호출하여 검사하는데, 다수의 텍스트가 있을 경우 API 호출이 병렬로 많아져 서버 부하 및 클라이언트 네트워크 비용 증가 우려 있음.
    • 개선: 가능하다면 백엔드에서 여러 텍스트를 한 번에 검사하는 API를 제공하거나, 클라이언트에서 텍스트를 합쳐서 한 번에 검사하는 방식을 고려할 것.
    • 또한 Promise.allSettled 결과 중 실패한 케이스는 무시하고 있는데, 네트워크 오류 등으로 인해 검사 누락이 발생할 수 있으므로 실패 케이스에 대한 로깅이나 재시도 로직 추가 검토 필요.
  • src/hooks/useModerationCheck.tsx + Dialog 컴포넌트 사용

    • 부적절한 표현이 감지되었을 때 사용자에게 보여주는 다이얼로그에서 onConfirm 콜백을 호출하기 전에 closeDialog()를 호출하는데, 만약 onConfirm에서 상태 변경 등 비동기 작업이 있다면 다이얼로그가 너무 빨리 닫혀 UX가 어색할 수 있음.
    • 개선: onConfirm 호출 후 다이얼로그를 닫거나, 다이얼로그 닫힘과 onConfirm 실행 타이밍을 명확히 분리하는 방안 고려.
  • src/components/poll/edit/PollEditButton/hooks.ts + handleClickPollEditButton

    • checkModeration 호출 시 pollData를 넘기고, onConfirm에서 updatePoll 호출하는 구조인데, checkModeration이 비동기 작업임에도 불구하고 버튼 클릭 시 중복 클릭 방지 로직이 없음.
    • 개선: isPending 상태를 활용해 중복 클릭 방지 및 UI 피드백 추가 필요.
  • src/components/poll/regist/PollRegistButton/PollRegistButton.tsx + handleClickSubmitButton

    • 마찬가지로 checkModeration 호출 후 registVote 실행하는데, checkModeration의 로딩 상태를 반영한 UI 상태 관리가 빠져 있음.
    • 개선: 로딩 상태에 따른 버튼 비활성화 또는 로딩 표시 추가 권장.
  • package.json + chooz-ai-moderation 의존성 추가

    • chooz-ai-moderation 패키지가 추가되었는데, 실제 코드에서는 이 패키지를 직접 사용하지 않고 있음.
    • 개선: 불필요한 의존성인지 확인하고, 사용하지 않는다면 제거하거나, 사용 목적에 맞게 코드에 반영할 것.
  • nit

    1. src/api/moderation.ts 내 에러 메시지에 마침표가 두 번(...추가해주세요..) 찍혀 있음.
    2. src/hooks/useModerationCheck.tsx에서 textsToCheck 필터링 시 filter(Boolean)을 사용했는데, pollChoices 배열 내 title이 빈 문자열일 경우도 걸러지므로 의도에 맞는지 확인 필요.
    3. import 순서가 일부 파일에서 섞여 있음(예: PollRegistButton.tsx), 일관성 있게 정리하면 가독성 향상됨.

자동 생성된 리뷰입니다. 참고용으로만 사용해주세요.

@Jeongchanyeong Jeongchanyeong marked this pull request as ready for review December 31, 2025 00:04
@Jeongchanyeong Jeongchanyeong merged commit 5ae0e60 into develop Dec 31, 2025
5 checks passed
@Jeongchanyeong Jeongchanyeong deleted the feature-482/ai-swear-word-filter branch December 31, 2025 00:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature 피쳐 개발에 사용합니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AI 기반 욕설/부적절 표현 감지 기능을 연결한다.

2 participants