Skip to content

[FIX] 테스트 등록 글자 수 제한 삭제 - #163

Merged
Lee-Sunho merged 6 commits into
mainfrom
fix/#162
Aug 24, 2026
Merged

Lee-Sunho merged 6 commits into
mainfrom
fix/#162

Conversation

@Lee-Sunho

Copy link
Copy Markdown
Member

🛠 작업 내용

  • 테스트 등록 텍스트 필드 글자수 제한 삭제(주관식 답변 등 미사용 로직 정리 포함)
  • 임시저장 실패 시 빈 초안("제목 없는 테스트")이 서버에 계속 쌓이지 않도록 롤백 처리 추가
    • updateDraft까지 성공해야 draftId를 로컬 상태에 반영
    • 이번 호출에서 새로 만든 초안인데 저장이 실패하면 deleteDraft로 즉시 롤백
  • 임시저장 실패 토스트에 백엔드 code/message를 그대로 노출(원인 파악 쉽게)

💡 참고 사항

  • 백엔드 dev 브랜치에서 title/description 글자수 제한(DB 컬럼 제약 + @Size) 제거됨 (PR #296)
  • serviceName(서비스 이름)은 아직 17자 제한 유지 — 의도된 것으로 보임

Lee-Sunho and others added 4 commits August 24, 2026 00:16
- updateDraft까지 성공해야 draftId를 로컬 상태에 반영
- 이번 호출에서 새로 생성한 초안인데 저장이 실패하면 deleteDraft로 즉시 롤백
  (재시도마다 '제목 없는 테스트'가 쌓이던 문제 수정)
- 저장 실패 토스트에 백엔드 code/message를 그대로 노출

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🤖 Gemini Code Review

안녕하세요, MATE-FE 프로젝트의 시니어 프론트엔드 개발자입니다. PR diff를 꼼꼼히 리뷰했습니다.

이번 PR의 주요 변경사항은 클라이언트 측의 maxLength 속성 및 관련 유효성 검사 로직을 제거하는 것으로 보입니다. 이는 유효성 검사 책임을 백엔드로 완전히 이전하려는 의도로 해석됩니다. useSaveDraft의 에러 처리 개선은 긍정적입니다.

✅ 잘된 점

  • useSaveDraft의 에러 처리 개선: src/features/test-create/model/useSaveDraft.ts 파일에서 초안 생성 후 업데이트 실패 시, 새로 생성된 초안을 롤백(deleteDraft)하는 로

powered by gemini-2.5-flash — MATE-FE 코딩 규칙

@Lee-Sunho Lee-Sunho changed the title [FIX] 글자 수 제한 삭제 [FIX] 테스트 등록 글자 수 제한 삭제 Aug 23, 2026
@github-actions

Copy link
Copy Markdown

🤖 Gemini Code Review

안녕하세요, MATE-FE 프로젝트의 시니어 프론트엔드 개발자입니다.
PR diff를 꼼꼼히 리뷰했습니다. 전반적으로 maxLength 관련 로직을 프론트엔드에서 제거하고 백엔드에서 관리하도록 전환하려는 의도가 엿보이며, useSaveDraft 훅의 에러 처리 로직 개선은 매우 긍정적입니다.


✅ 잘된 점

  • useSaveDraft 훅의 에러 처리 및 롤백 로직 개선:
    • src/features/test-create/model/useSaveDraft.ts 파일에서 초안 생성 후 updateDraft 실패 시, 새로 생성된 초안을 deleteDraft로 롤백하는 로직이 추가되어 데이터 일관성을 높였습니다. 이는 매우 견고한 에러 처리 방식입니다.
    • 에러 메시지를 await toMessage(e)를 통해 사용자에게 더 친화적이고 구체적인 메시지로 전달하려는 시도도 좋습니다.
    • onDraftCreated 콜백 호출 시점을 updateDraft 성공 후로 변경하여 논리적인 흐름을 개선했습니다.
  • FSD 레이어 규칙 준수:
    • features 내에서 각 도메인(question-cardsort, question-fivesec, test-create 등)의 책임이 명확하게 분리되어 있으며, shared 레이어의 API를 적절히 활용하고 있습니다. maxLength 관련 타입 및 로직 제거도 각 레이어의 역할에 맞게 수정되었습니다.
  • TDS 컴포넌트 사용:
    • TextField, TextArea, BottomSheet 등 TDS 컴포넌트를 일관되게 사용하고 있습니다. maxLength 속성 제거는 TDS 컴포넌트 사용 자체를 위반하는 것이 아니며, 백엔드 주도 유효성 검사로의 전환 의도로 보입니다.

⚠️ 개선 필요

  • maxLength 제거에 따른 사용자 경험 고려 (글자 수 제한 피드백 부재):

    • 위치: src/features/question-cardsort/create/CardSortItemBottomSheet.tsx (Line 77), src/features/question-fivesec/create/FivesecCreatePage.tsx (Line 446), src/features/question-multiple/create/MultipleChoiceEditorOverlay.tsx (Line 65), src/features/question-scale/create/ScaleLabelEditSheet.tsx (Line 69), src/features/question-tree/create/TreeNodeAddSheet.tsx (Line 67), src/features/test-create/ui/BasicInfoEditPage.tsx (Line 71, 85), src/features/test-create/ui/QuestionCreateTopSection.tsx (Line 286, 331), src/features/test-create/ui/QuestionEditSheet.tsx (Line 64), src/features/test-create/ui/ServiceDescriptionEditPage.tsx (Line 54, 58), src/features/test-create/ui/ServiceDescriptionStep.tsx (Line 30, 34), src/features/test-create/ui/TestBasicInfoStep.tsx (Line 110) 등 maxLength prop과 onChange 핸들러 내의 클라이언트 측 글자 수 제한 로직이 제거된 모든 곳.
    • 이유: maxLength prop과 onChange 핸들러 내의 slice 로직을 제거함으로써, 사용자가 입력 필드에 글자 수 제한을 초과하여 계속 입력할 수 있게 됩니다. 백엔드에서 글자 수 유효성 검사를 수행하더라도, 사용자는 입력 시점에 즉각적인 피드백(예: 글자 수 카운터, 제한 초과 시 입력 불가 또는 경고 메시지)을 받지 못해 혼란을 겪을 수 있습니다. 이는 모바일/웹뷰 환경에서 특히 중요한 사용자 경험 요소입니다.
    • 권고:
      1. TDS TextField/TextArea 컴포넌트의 maxLength prop 활용: TDS 컴포넌트가 HTML maxLength 속성을 지원한다면, 이를 다시 추가하여 브라우저 수준에서 1차적인 입력 제한을 두는 것을 고려해 주세요.
      2. 글자 수 카운터 추가: TextField 하단에 현재 글자 수 / 최대 글자 수를 표시하는 UI를 추가하여 사용자에게 시각적인 피드백을 제공하는 것이 좋습니다. (예: 15/17자)
      3. 백엔드 에러 메시지 활용: 백엔드에서 글자 수 제한 위반 시 내려주는 에러 메시지를 TextFieldhelp prop이나 별도의 에러 메시지 UI를 통해 사용자에게 명확하게 보여줄 수 있도록 useSaveDraft에서 toMessage(e)를 통해 받은 메시지를 활용하는 방안을 고려해 주세요.
  • src/features/test-create/ui/TestRegisterStep.tsx - 테스트 한 줄 소개 문구:

    • 위치: src/features/test-create/ui/TestRegisterStep.tsx (Line 291)
    • 이유: bottom={form.summary || "테스트 한 줄 소개 최대 60자"}에서 "최대 60자" 문구가 제거되었습니다. maxLength 제거와 일관된 변경이지만, 사용자가 테스트를 등록하기 전 "한 줄 소개" 필드의 의도와 제한을 인지할 수 있도록 돕는 문구였습니다.
    • 권고: "테스트 한 줄 소개"만으로는 정보가 부족할 수 있습니다. BasicInfoEditPageTestBasicInfoStep에서 글자 수 카운터 등을 통해 제한을 명확히 보여준다면 괜찮지만, 그렇지 않다면 이 부분에 "테스트 한 줄 소개 (선택)" 또는 "테스트 한 줄 소개를 입력해주세요"와 같이 좀 더 명확한 가이드 문구를 고려해 주세요.

🚫 필수 수정

  • 현재 PR diff만으로는 명확한 규칙 위반이나 버그는 발견되지 않았습니다. 위에 언급된 '개선 필요' 사항들이 사용자 경험에 큰 영향을 미칠 수 있으므로, 팀 내에서 논의 후 우선순위를 정해 반영하는 것을 권고합니다.

💡 제안

  • toMessage 함수 타입 정의 및 위치:
    • 위치: src/features/test-create/model/useSaveDraft.ts (Line 42)
    • 이유: await toMessage(e) 함수가 사용되었는데, 이 함수의 정의가 PR diff에 포함되어 있지 않습니다. e의 타입이 HTTPError 또는 Error 인스턴스임을 명시하고, `

powered by gemini-2.5-flash — MATE-FE 코딩 규칙

@github-actions

Copy link
Copy Markdown

🤖 Gemini Code Review

안녕하세요, MATE-FE 프로젝트 시니어 프론트엔드 개발자입니다.
PR diff를 꼼꼼히 리뷰했습니다. 전반적으로 백엔드 API 변경사항에 맞춰 프론트엔드 유효성 검사 및 UI를 잘 조정한 PR이라고 생각합니다. 특히 maxLength 속성 활용과 useSaveDraft의 에러 처리 개선은 긍정적입니다. 몇 가지 개선 사항과 필수 수정 사항이 있으니 확인 부탁드립니다.


✅ 잘된 점

  • 백엔드 변경사항 반영 및 maxLength 속성 활용:
    • 백엔드 글자수 제한 완화에 맞춰 TextField, TextArea 컴포넌트의 maxLength 속성을 250자로 일관되게 업데이트한 점이 좋습니다.
    • TextFieldTextAreamaxLength 속성을 사용하면서 onChange 핸들러 내에서 e.target.value.slice(0, MAX_LENGTH)와 같이 수동으로 길이를 자르던 중복 로직을 제거한 점도 깔끔합니다.
    • ScaleLabelEditSheet.tsx에서 백엔드 제한(100자)을 명확히 주석으로 언급하고 MAX_LENGTH를 설정한 점도 좋습니다.
  • 주관식 질문 maxLength 제거:
    • SubjectiveQuestionData 모델 및 관련 로직(SubjectiveCreatePage.tsx, model/types.ts, model/draftMapper.ts, api/mappers.ts, api/types.ts, model/mock.ts, model/validation.ts, test-result/model/mock.ts, shared/api/question.ts)에서 maxLength 필드를 일관되게 제거하여 백엔드 정책 변화에 잘 대응했습니다.
  • useSaveDraft 에러 처리 개선:
    • 새로운 초안 생성 중 updateDraft 실패 시, 서버에 "제목 없는 테스트"가 방치되지 않도록 deleteDraft를 호출하여 롤백하는 로직을 추가한 점은 매우 훌륭한 에러 처리입니다.
    • 에러 메시지를 await toMessage(e)를 통해 백엔드 응답을 더 상세하게 노출하도록 개선한 점도 사용자 경험 측면에서 좋습니다.
  • FSD 및 프로젝트 컨텍스트 준수:
    • FSD 레이어 규칙을 위반하는 변경사항은 보이지 않습니다.
    • TDS 컴포넌트를 일관되게 사용하고 있으며, ky를 통한 API 로직 분리, TanStack Query 사용 등 프로젝트 컨텍스트를 잘 준수하고 있습니다.
    • any 타입 남용이나 useEffect를 통한 데이터 페칭도 발견되지 않았습니다.

⚠️ 개선 필요

  • QuestionCreateTopSection.tsxonChangeDescription 중복 로직:

    • TextArea 컴포넌트에 maxLength={50}이 설정되어 있으므로, onChange 핸들러 내에서 e.target.value.slice(0, 50)로 다시 길이를 자르는 로직은 중복됩니다. maxLength prop이 이미 이 역할을 수행합니다.
    • 파일: src/features/test-create/ui/QuestionCreateTopSection.tsx
    • 위치: L283, L328
    • 수정 제안: onChange={(e) => onChangeTitle(e.target.value.slice(0, 250))} -> onChange={(e) => onChangeTitle(e.target.value)}
    • 수정 제안: onChange={(e) => onChangeDescription(e.target.value.slice(0, 50))} -> onChange={(e) => onChangeDescription(e.target.value)}
  • ServiceDescriptionEditPage.tsxServiceDescriptionStep.tsxTextArea maxLength 누락:

    • ServiceDescriptionEditPage.tsxTextAreaServiceDescriptionStep.tsxTextAreaDESCRIPTION_MAX_LENGTHmaxLength prop으로 명시적으로 추가하는 것이 좋습니다. onChange 핸들러에서 길이를 체크하고 있지만, maxLength prop을 사용하면 TDS 컴포넌트 자체에서 시각적인 피드백(예: 글자수 카운터)을 제공하거나 입력 자체를 제한할 수 있어 더 견고합니다.
    • 파일: src/features/test-create/ui/ServiceDescriptionEditPage.tsx
    • 위치: L87
    • 수정 제안: <TextArea ... onChange={handleDescriptionChange} enterKeyHint="done" /> -> <TextArea ... onChange={handleDescriptionChange} enterKeyHint="done" maxLength={DESCRIPTION_MAX_LENGTH} />
    • 파일: src/features/test-create/ui/ServiceDescriptionStep.tsx
    • 위치: L68
    • 수정 제안: <TextArea ... onBlur={onBlur} enterKeyHint="done" /> -> `<TextArea ... onBlur={onBlur} enterKeyHint="done" maxLength={DESCRIPTION

powered by gemini-2.5-flash — MATE-FE 코딩 규칙

- 테스트 이름/한줄소개, 서비스 이름/소개, 질문 제목/추가 설명, 선택지/카드/카테고리,
  트리 기능명: 250자로 통일 (백엔드 @SiZe 제한 삭제에 맞춤)
- 척도 최소/최대 라벨만 100자 유지 — 백엔드가 minLabel/maxLabel에 아직
  @SiZe(max=100)을 걸어두고 있어 250으로 풀면 400이 남

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🤖 Gemini Code Review

MATE-FE 프로젝트의 시니어 프론트엔드 개발자로서 PR diff를 리뷰합니다.


✅ 잘된 점

  • 백엔드 변경사항에 대한 적절한 대응: 백엔드의 글자수 제한 완화/삭제에 맞춰 프론트엔드의 maxLength 속성을 조정하고, 불필요한 클라이언트 측 slice 로직을 제거한 점이 좋습니다. 특히 ScaleLabelEditSheet.tsx에서 백엔드 제한이 유지되는 경우를 명시적으로 처리한 점은 꼼꼼한 작업으로 보입니다.
  • 개선된 초안 저장 에러 처리: src/features/test-create/model/useSaveDraft.ts에서 초안 생성 후 내용 저장에 실패했을 때, 새로 생성된 초안이 서버에 "제목 없는 테스트"로 방치되지 않도록 deleteDraft를 통해 롤백하는 로직을 추가한 점은 매우 훌륭한 에러 처리 개선입니다. 또한, 백엔드 에러 메시지를 toMessage 헬퍼를 통해 사용자에게 더 명확하게 전달하려는 시도도 좋습니다.
  • FSD 원칙 준수: API 로직이 shared/api에서 분리되어 사용되고, 각 features 내에서 관련 로직과 UI가 관리되는 등 FSD 레이어 규칙을 잘 준수하고 있습니다.
  • TDS 컴포넌트 활용: TextField, TextArea, BottomSheet 등 TDS 컴포넌트를 일관되게 사용하여 디자인 시스템 가이드라인을 따르고 있습니다.
  • TanStack Query 및 Zustand 사용 원칙 준수: 서버 상태는 useMutation을 통해 관리하고, useTestCreateForm과 같은 Zustand는 순수하게 클라이언트 측 폼 상태 관리에 사용되어 원칙을 잘 지키고 있습니다.

⚠️ 개선 필요

  • toMessage(e) 헬퍼 함수 정의 확인:
    • 위치: src/features/test-create/model/useSaveDraft.ts
    • 이유: await toMessage(e)가 사용되었으나, toMessage 함수의 정의가 PR diff에 포함되어 있지 않습니다. 이 함수가 kyHTTPError를 포함한 다양한 에러 타입을 안정적으로 처리하여 사용자에게 의미 있는 메시지를 반환하는지 확인이 필요합니다. 만약 shared/utils나 다른 공통 모듈에 이미 정의되어 있다면 괜찮지만, 그렇지 않다면 정의를 추가하거나 임포트 경로를 명시해야 합니다.
    • 제안: toMessage 함수가 kyHTTPError에서 response.json()을 통해 백엔드 에러 메시지(예: code, message)를 추출하는 로직을 포함하고 있는지 확인하고, 필요하다면 해당 로직을 포함하는 shared/utils/error.ts와 같은 파일을 생성하여 관리하는 것을 권장합니다.

🚫 필수 수정

  • 없음. 현재 PR은 전반적으로 잘 구현되었으며, 필수적으로 수정해야 할 규칙 위반이나 버그는 발견되지 않았습니다.

💡 제안

  • MAX_LENGTH 상수 관리:
    • 위치: src/features/question-cardsort/create/CardSortItemBottomSheet.tsx, src/features/test-create/ui/BasicInfoEditPage.tsx, `src/

powered by gemini-2.5-flash — MATE-FE 코딩 규칙

@github-actions

Copy link
Copy Markdown

🤖 Gemini Code Review

안녕하세요, MATE-FE 프로젝트 시니어 프론트엔드 개발자입니다.
PR diff를 꼼꼼히 리뷰했습니다. 백엔드 글자수 제한 완화에 따른 프론트엔드 반영 및 초안 저장 로직 개선 등 전반적으로 잘 작성된 PR입니다.


✅ 잘된 점

  • 백엔드 변경사항에 대한 적절한 대응: 백엔드의 글자수 제한 완화(@Size 제거)에 맞춰 프론트엔드의 maxLength250으로 일괄 조정하고, 여전히 제한이 있는 경우(ScaleLabelEditSheet.tsx100)는 해당 제한을 유지한 점이 좋습니다.
  • **maxLength 속성 활용 및

powered by gemini-2.5-flash — MATE-FE 코딩 규칙

@Lee-Sunho
Lee-Sunho merged commit 6b49087 into main Aug 24, 2026
3 checks passed
@Lee-Sunho
Lee-Sunho deleted the fix/#162 branch August 24, 2026 14:03
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.

2 participants