Skip to content

feat: SP1 닉네임 중복확인 api 연결#336

Merged
heesunee merged 6 commits intodevelopfrom
feat/#327/duplicate-check
Sep 4, 2025
Merged

feat: SP1 닉네임 중복확인 api 연결#336
heesunee merged 6 commits intodevelopfrom
feat/#327/duplicate-check

Conversation

@heesunee
Copy link
Contributor

@heesunee heesunee commented Sep 4, 2025

#️⃣ Related Issue

Closes #327

☀️ New-insight

  • 추후 추가하겠습니다..

💎 PR Point

📸 Screenshot

Summary by CodeRabbit

  • 신기능
    • 회원가입·프로필 수정에 “닉네임 중복 확인” 기능 추가: 전용 버튼으로 사용 가능 여부 확인, 결과에 따른 안내 메시지/시각 상태 반영, 사용 가능 시에만 제출 활성화
  • 리팩터
    • 내부 소유 속성 확인 로직을 최신 표준 API로 정리
  • 잡무(Chores)
    • VS Code 편집기 설정 정리 및 언어별 포맷터 구성 개선
    • 타입스크립트 표준 라이브러리 타깃을 ES2022로 상향하여 최신 내장 API 타입 지원

@coderabbitai
Copy link

coderabbitai bot commented Sep 4, 2025

Walkthrough

닉네임 중복 확인 로직을 도입하고, 가입/프로필수정 화면에 확인 버튼과 상태 흐름을 추가했습니다. 이를 위해 사용자 쿼리, 엔드포인트, 쿼리 키를 신설했으며, 관련 상수/타입을 확장했습니다. 부가적으로 VSCode 설정 정리, TS lib 타겟(ES2022) 상향, hasOwn 사용 교체가 포함되었습니다.

Changes

Cohort / File(s) Summary
닉네임 중복확인 기능 도입
src/pages/sign-up/components/signup-step.tsx, src/pages/edit-profile/edit-profile.tsx
닉네임 상태(idle/checking/available/duplicate) 추가, “중복 확인” 버튼 도입, 서버 확인 결과에 따른 메시지/유효성/버튼 게이팅 반영
닉네임 체크 쿼리/키/엔드포인트
src/shared/apis/user/user-queries.ts, src/shared/constants/query-key.ts, src/shared/constants/api.ts
userQueries.NICKNAME_CHECK 추가(수동 트리거, CONFLICT 처리), USER_KEY.NICKNAME_CHECK 키 빌더 추가, END_POINT.GET_NICKNAME_CHECK(nickname) 추가
상수/타입 보강
src/pages/sign-up/constants/NOTICE.ts, src/pages/sign-up/types/nickname-types.ts
NICKNAME_DUPLICATED, NicknameStatus 추가
유틸 개선
src/pages/match/utils/match-status.ts
hasOwnProperty 체크를 Object.hasOwn으로 교체
빌드/에디터 설정
.vscode/settings.json, tsconfig.app.json
Biome 포맷터 언어별 설정 및 정리, TS lib를 ES2022로 상향

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as 사용자
  participant V as 가입/프로필 화면(UI)
  participant RQ as react-query
  participant API as /v2/users/info?nickname=...
  participant S as 서버

  U->>V: 닉네임 입력
  V->>V: nicknameStatus = idle

  U->>V: "중복 확인" 클릭
  V->>V: nicknameStatus = checking
  V->>RQ: refetch(NICKNAME_CHECK(nickname))
  RQ->>API: GET
  API->>S: 요청 전달
  alt 닉네임 사용 가능 (200)
    S-->>API: 200 OK
    API-->>RQ: true
    RQ-->>V: true
    V->>V: nicknameStatus = available
  else 닉네임 중복 (409)
    S-->>API: 409 CONFLICT
    API-->>RQ: false
    RQ-->>V: false
    V->>V: nicknameStatus = duplicate
  else 기타 오류
    S-->>API: 5xx/네트워크 오류
    API-->>RQ: throw
    RQ-->>V: error
    V->>V: nicknameStatus = idle
  end

  U->>V: 제출 버튼 클릭
  V->>V: nicknameStatus === 'available' 인 경우만 진행
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Assessment against linked issues

Objective Addressed Explanation
닉네임 중복확인 로직을 추가합니다. [#327]

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
VSCode 포맷터/설정 정리 (.vscode/settings.json) 이슈 #327의 닉네임 중복확인 기능 범위를 벗어난 에디터 설정 변경입니다.
TypeScript lib 타겟 ES2022로 상향 (tsconfig.app.json) 기능 요구와 무관한 컴파일러 환경 변경입니다.
Object.hasOwn로 체크 방식 변경 (src/pages/match/utils/match-status.ts) 매칭 유틸 내 소유 속성 체크 리팩터링으로, 닉네임 중복확인과 직접 관련이 없습니다.

Possibly related PRs

Suggested labels

feat, 희선

Suggested reviewers

  • Dubabbi
  • bongtta
  • yeeeww

Poem

새 이름 톡톡, 토끼 발로 톡!
중복이면 멈칫, 초록불이면 쏙—GO!
버튼은 살포시, 상태는 또렷이,
닉네임 달빛에 반짝 반짝 빛나니,
오늘도 깔끔 저장! (ฅ•̀㉨•́)ฅ✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#327/duplicate-check

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link

github-actions bot commented Sep 4, 2025

MATEBALL-STORYBOOK
⚾ Storybook 배포가 완료되었습니다!

@heesunee heesunee changed the title feat: 닉네임 중복확인 api 연결 feat: SP1 닉네임 중복확인 api 연결 Sep 4, 2025
@heesunee heesunee merged commit ffbbe69 into develop Sep 4, 2025
6 of 7 checks passed
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (12)
src/pages/sign-up/constants/NOTICE.ts (1)

19-19: 메시지 마침표 일관성 맞추기

동일한 톤 유지 차원에서 성공 메시지(NICKNAME_SUCCESS_MESSAGE)처럼 마침표를 붙이는 것이 좋아 보입니다.

-export const NICKNAME_DUPLICATED = '이미 존재하는 닉네임이에요';
+export const NICKNAME_DUPLICATED = '이미 존재하는 닉네임이에요.';
src/pages/sign-up/types/nickname-types.ts (1)

5-5: 네트워크 실패 표현을 위한 상태 추가 고려

API 오류를 구분할 수 있도록 'error' 상태를 추가하면 UI 분기(재시도, 토스트 등)에 유용합니다.

-export type NicknameStatus = 'idle' | 'checking' | 'available' | 'duplicate';
+export type NicknameStatus = 'idle' | 'checking' | 'available' | 'duplicate' | 'error';
tsconfig.app.json (1)

6-6: Object.hasOwn 사용 위치(src/pages/match/utils/match-status.ts:45) 런타임 호환성 검토

  • 옵션 A: 브라우저 지원이 충분하다면 target을 ES2022로 상향
  • 옵션 B: 공용 유틸에 폴리필/헬퍼 적용
export const hasOwn = (obj: object, key: PropertyKey) =>
  // @ts-ignore
  Object.hasOwn ? Object.hasOwn(obj, key) : Object.prototype.hasOwnProperty.call(obj, key);
src/shared/constants/api.ts (1)

15-16: 엔드포인트 의미 명확성 및 인코딩 처리

encodeURIComponent 사용은 적절합니다. 다만 동일 경로(/v2/users/info)가 USER_INFO와 중복되어 있어, 서버에서 nickname 쿼리 유무에 따라 서로 다른 의미를 제공한다는 전제가 필요합니다. 백엔드 계약을 한 번만 확인해 주세요(상태 코드/응답 스키마 포함).

가독성 측면의 대안(선호 시):

-    `/v2/users/info?nickname=${encodeURIComponent(nickname)}`,
+    `/v2/users/info?${new URLSearchParams({ nickname }).toString()}`,
src/shared/constants/query-key.ts (1)

8-8: 키 정규화 여부 확인(대소문자/공백 민감도)

API가 닉네임을 대소문자 구분 없이 처리하거나 공백을 금지한다면, 캐시 키에 trim()(및 필요 시 toLowerCase())을 적용해 중복 캐시를 줄일 수 있습니다. 서버 규칙에 따라 결정 부탁드립니다.

-  NICKNAME_CHECK: (nickname: string) => [...USER_KEY.ALL, 'nickname-check', nickname] as const,
+  NICKNAME_CHECK: (nickname: string) => [...USER_KEY.ALL, 'nickname-check', nickname.trim()] as const,
.vscode/settings.json (1)

2-26: Biome 고정 설정 👍, JSON/JSONC 포맷터 범위 보완 제안

팀 일관성 확보에는 좋아 보입니다. 추가로 일반 JSON도 Biome/빌트인 포맷터로 명시하면 혼선을 줄일 수 있습니다.

아래처럼 JSON도 명시 추가 제안:

   "[javascriptreact]": {
     "editor.defaultFormatter": "biomejs.biome",
     "editor.formatOnSave": true
   },
+  "[json]": {
+    "editor.defaultFormatter": "vscode.json-language-features"
+  },
   "[jsonc]": {
     "editor.defaultFormatter": "vscode.json-language-features"
   }

또한 .vscode/extensions.json에 Biome 추천 확장을 추가하면 새 참가자 환경 일관성이 좋아집니다:

{
  "recommendations": ["biomejs.biome"]
}
src/shared/apis/user/user-queries.ts (1)

30-50: 닉네임 트림/취소 가능 신호 적용으로 레이스·메모리 개선 제안

  • 입력 공백 트림을 쿼리 레이어에서 강제해 UI별 상이한 처리로 인한 오탐을 방지.
  • React Query가 주는 signal을 axios에 전달해 탭 이탈/재요청 시 안전하게 취소.
  • 타자마다 새 키가 생기는 캐시를 짧게 유지(gcTime)해 메모리 발자국 축소.
-  NICKNAME_CHECK: (nickname: string) =>
-    queryOptions<boolean>({
-      queryKey: USER_KEY.NICKNAME_CHECK(nickname),
-      enabled: false,
-      queryFn: async () => {
+  NICKNAME_CHECK: (nickname: string) => {
+    const nick = nickname.trim();
+    return queryOptions<boolean>({
+      queryKey: USER_KEY.NICKNAME_CHECK(nick),
+      enabled: false,
+      gcTime: 30_000,
+      queryFn: async ({ signal }) => {
         try {
-          await get<void>(END_POINT.GET_NICKNAME_CHECK(nickname));
+          await get<void>(END_POINT.GET_NICKNAME_CHECK(nick), { signal });
           return true;
         } catch (e) {
           if (axios.isAxiosError(e) && e.response?.status === HTTP_STATUS.CONFLICT) {
             return false;
           }
           throw e;
         }
       },
-      retry: (failureCount, error) => {
-        if (axios.isAxiosError(error) && error.response?.status === HTTP_STATUS.CONFLICT)
-          return false;
-        return failureCount < 2;
-      },
-    }),
+      retry: 2,
+    });
+  },
src/pages/sign-up/components/signup-step.tsx (3)

92-101: 중복확인 시 트림/레이스 가드 및 버튼 중복클릭 방지

  • 요청 전 trim()으로 서버 체크 값 일치.
  • 응답 도착 시 현재 입력값이 바뀌었으면 상태 갱신 스킵해 플리커 방지.
  • 체크 중엔 버튼 비활성화.
 const handleCheckNickname = async () => {
-  if (!isNicknameValid) return;
+  if (!isNicknameValid) return;
+  const current = nicknameValue.trim();
   setNicknameStatus('checking');
   try {
     const { data } = await refetchNicknameCheck();
-    setNicknameStatus(data ? 'available' : 'duplicate');
+    // 입력값이 바뀌었으면 결과 반영하지 않음
+    if (watch('nickname').trim() !== current) return;
+    setNicknameStatus(data ? 'available' : 'duplicate');
   } catch {
     setNicknameStatus('idle');
   }
 };
 
 ...
 <Button
   label="중복 확인"
   type="button"
   className="cap_14_sb ml-auto w-fit px-[1.6rem] py-[0.6rem]"
   onClick={handleCheckNickname}
-  disabled={!isNicknameValid}
+  disabled={!isNicknameValid || nicknameStatus === 'checking'}
 />

Also applies to: 134-140


121-130: 스키마 에러 메시지 연동으로 UX 개선

현재 duplicate/available만 표시합니다. 스키마 에러(errors.nickname)도 노출되도록 합치면 사용자가 더 빠르게 수정할 수 있습니다. 에러일 땐 isError도 true로.

-  validationMessage={
-    nicknameStatus === 'duplicate'
-      ? NICKNAME_DUPLICATED
-      : nicknameStatus === 'available'
-        ? NICKNAME_SUCCESS_MESSAGE
-        : undefined
-  }
-  isError={nicknameStatus === 'duplicate'}
+  validationMessage={
+    nicknameStatus === 'duplicate'
+      ? NICKNAME_DUPLICATED
+      : errors.nickname?.message ?? (nicknameStatus === 'available' ? NICKNAME_SUCCESS_MESSAGE : undefined)
+  }
+  isError={!!errors.nickname || nicknameStatus === 'duplicate'}
   isValid={nicknameStatus === 'available'}

53-55: 타이핑마다 새로운 쿼리 키 생성에 따른 캐시 증가 고려

enabled: false라도 닉네임이 바뀔 때마다 각 키가 5분 동안 남습니다. 상단 제안처럼 gcTime을 짧게 두면 완화됩니다.

src/pages/edit-profile/edit-profile.tsx (2)

112-121: 중복확인 트림/레이스 가드 및 로딩 중 버튼 비활성화

사인업 쪽과 동일한 개선을 권장합니다.

 const handleCheckNickname = async () => {
-  if (errors.nickname || nicknameVal.trim().length < 2) return;
+  if (errors.nickname || nicknameVal.trim().length < 2) return;
+  const current = nicknameVal.trim();
   setNicknameStatus('checking');
   try {
     const { data } = await refetchNicknameCheck();
-    setNicknameStatus(data ? 'available' : 'duplicate');
+    if (watch('nickname').trim() !== current) return;
+    setNicknameStatus(data ? 'available' : 'duplicate');
   } catch {
     setNicknameStatus('idle');
   }
 };
 
 ...
 <Button
   type="button"
   variant="skyblue"
   label="중복 확인"
   onClick={handleCheckNickname}
-  disabled={!!errors.nickname || nicknameVal.trim().length === 0 || isSubmitting}
+  disabled={!!errors.nickname || nicknameVal.trim().length === 0 || isSubmitting || nicknameStatus === 'checking'}
   className="cap_14_sb mt-[0.8rem] w-auto px-[1.6rem] py-[0.6rem] disabled:text-white"
 />

Also applies to: 151-158


138-146: 닉네임 입력의 스키마 에러 메시지도 표시

중복만이 아니라 유효성 에러도 함께 보여주면 수정이 빠릅니다.

-  validationMessage={
-    nicknameStatus === 'duplicate'
-      ? NICKNAME_DUPLICATED
-      : nicknameStatus === 'available'
-        ? NICKNAME_SUCCESS_MESSAGE
-        : undefined
-  }
-  isError={nicknameStatus === 'duplicate'}
+  validationMessage={
+    nicknameStatus === 'duplicate'
+      ? NICKNAME_DUPLICATED
+      : (errors.nickname?.message ?? (nicknameStatus === 'available' ? NICKNAME_SUCCESS_MESSAGE : undefined))
+  }
+  isError={!!errors.nickname || nicknameStatus === 'duplicate'}
   isValid={nicknameStatus === 'available'}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e6cca86 and 27a519e.

📒 Files selected for processing (10)
  • .vscode/settings.json (1 hunks)
  • src/pages/edit-profile/edit-profile.tsx (5 hunks)
  • src/pages/match/utils/match-status.ts (1 hunks)
  • src/pages/sign-up/components/signup-step.tsx (6 hunks)
  • src/pages/sign-up/constants/NOTICE.ts (1 hunks)
  • src/pages/sign-up/types/nickname-types.ts (1 hunks)
  • src/shared/apis/user/user-queries.ts (2 hunks)
  • src/shared/constants/api.ts (1 hunks)
  • src/shared/constants/query-key.ts (1 hunks)
  • tsconfig.app.json (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: heesunee
PR: MATEBALL/MATEBALL-CLIENT#95
File: src/pages/sign-up/components/nickname-step.tsx:28-30
Timestamp: 2025-07-09T18:07:41.693Z
Learning: heesunee는 src/pages/sign-up/components/nickname-step.tsx의 onSubmit 핸들러 API 호출을 쿼리와 함께 통합해서 처리할 예정이므로, 이 부분에 대해 다시 언급하지 않아야 합니다.
Learnt from: heesunee
PR: MATEBALL/MATEBALL-CLIENT#94
File: src/pages/sign-up/sign-up.tsx:4-4
Timestamp: 2025-07-09T17:24:19.755Z
Learning: heesunee는 src/pages/sign-up/sign-up.tsx의 isNicknameStep 하드코딩된 값을 퍼널 패턴으로 카카오 통합과 함께 나중에 처리할 예정이므로, 이 부분에 대해 다시 언급하지 않아야 합니다.
Learnt from: heesunee
PR: MATEBALL/MATEBALL-CLIENT#78
File: src/pages/sign-up/utils/age-calculate.ts:1-4
Timestamp: 2025-07-09T09:08:46.371Z
Learning: heesunee는 나이 계산 시 한국식 나이 시스템을 사용하므로, 정확한 생일 기반 계산보다는 출생연도 기준의 간단한 계산 방식을 선호합니다.
📚 Learning: 2025-07-09T17:24:19.755Z
Learnt from: heesunee
PR: MATEBALL/MATEBALL-CLIENT#94
File: src/pages/sign-up/sign-up.tsx:4-4
Timestamp: 2025-07-09T17:24:19.755Z
Learning: heesunee는 src/pages/sign-up/sign-up.tsx의 isNicknameStep 하드코딩된 값을 퍼널 패턴으로 카카오 통합과 함께 나중에 처리할 예정이므로, 이 부분에 대해 다시 언급하지 않아야 합니다.

Applied to files:

  • src/pages/sign-up/constants/NOTICE.ts
  • src/pages/edit-profile/edit-profile.tsx
  • src/pages/sign-up/components/signup-step.tsx
📚 Learning: 2025-07-09T18:07:41.693Z
Learnt from: heesunee
PR: MATEBALL/MATEBALL-CLIENT#95
File: src/pages/sign-up/components/nickname-step.tsx:28-30
Timestamp: 2025-07-09T18:07:41.693Z
Learning: heesunee는 src/pages/sign-up/components/nickname-step.tsx의 onSubmit 핸들러 API 호출을 쿼리와 함께 통합해서 처리할 예정이므로, 이 부분에 대해 다시 언급하지 않아야 합니다.

Applied to files:

  • src/pages/edit-profile/edit-profile.tsx
  • src/pages/sign-up/components/signup-step.tsx
🧬 Code graph analysis (4)
src/pages/match/utils/match-status.ts (1)
src/shared/components/chip/styles/chip-variants.ts (1)
  • chipVariantOptions (3-36)
src/shared/apis/user/user-queries.ts (4)
src/shared/constants/query-key.ts (1)
  • USER_KEY (2-13)
src/shared/apis/base/http.ts (1)
  • get (3-5)
src/shared/constants/api.ts (1)
  • END_POINT (3-46)
src/shared/constants/response.ts (1)
  • HTTP_STATUS (1-11)
src/pages/edit-profile/edit-profile.tsx (4)
src/pages/sign-up/types/nickname-types.ts (1)
  • NicknameStatus (5-5)
src/shared/apis/user/user-queries.ts (1)
  • userQueries (9-51)
src/pages/sign-up/constants/validation.ts (1)
  • NICKNAME_PLACEHOLDER (21-21)
src/pages/sign-up/constants/NOTICE.ts (3)
  • NICKNAME_RULE_MESSAGE (9-9)
  • NICKNAME_DUPLICATED (19-19)
  • NICKNAME_SUCCESS_MESSAGE (11-11)
src/pages/sign-up/components/signup-step.tsx (3)
src/pages/sign-up/types/nickname-types.ts (1)
  • NicknameStatus (5-5)
src/shared/apis/user/user-queries.ts (1)
  • userQueries (9-51)
src/pages/sign-up/constants/NOTICE.ts (3)
  • NICKNAME_RULE_MESSAGE (9-9)
  • NICKNAME_DUPLICATED (19-19)
  • NICKNAME_SUCCESS_MESSAGE (11-11)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: chromatic
🔇 Additional comments (2)
src/pages/match/utils/match-status.ts (1)

45-45: Object.hasOwn 사용은 OK, 런타임 지원만 확인 부탁

ES2022 이상의 런타임(또는 폴리필)이 보장되는지 확인해 주세요. 구형 브라우저 타깃이 섞여 있다면 폴리필이나 기존 hasOwnProperty.call로의 폴백이 필요할 수 있습니다.

src/shared/apis/user/user-queries.ts (1)

45-49: retry 횟수 의도 확인 필요

failureCount < 2는 최대 1회 재시도입니다. “최대 2회 재시도” 의도라면 retry: 2 또는 failureCount < 3로 바꾸세요.

bongtta pushed a commit that referenced this pull request Sep 5, 2025
* feat: 중복 확인 버튼 추가 (#327)

* feat: 중복 확인 버튼 추가 (#327)

* feat: 닉네임 중복 확인 api 추가 (#327)

* feat: 중복확인 api 연결 (#327)

* feat: 프로필 수정 내 중복확인 api 추가 (#327)

* feat: 프로필 수정 페이지 내 중복확인 api 연결 (#327)

---------

Co-authored-by: heesunee <heesun729@uos.ac.kr>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat new feature 희선

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: 닉네임 중복확인 로직을 추가합니다.

1 participant