Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat #95] :: 회원가입 퍼블리싱 #96

Merged
merged 16 commits into from
Jan 3, 2025

Conversation

parkuiery
Copy link
Member

@parkuiery parkuiery commented Jan 3, 2025

개요

회원가입 퍼블리싱을 하였습니다.

Android iOS Desktop

작업사항

추가 로 할 말

Summary by CodeRabbit

릴리즈 노트:

  • 새로운 기능

    • 회원가입 프로세스에 학생 번호 입력 화면 추가
    • 이메일 인증 코드 화면에 타이머 기능 도입
    • 체크박스 및 타이머 디자인 시스템 컴포넌트 개선
    • 학생 번호 입력을 위한 새로운 UI 컴포넌트 추가
    • 사용자 인터페이스 개선을 위한 여러 화면 업데이트
  • 버그 수정

    • 회원가입 흐름의 탐색 로직 최적화
    • 상태 관리 및 UI 컴포넌트 일관성 개선
  • 디자인 개선

    • 회원가입 화면의 레이아웃 및 사용자 경험 강화
    • 새로운 정보 배너와 입력 필드 추가

@parkuiery parkuiery added feat 새로운 기능을 추가 할 경우 refactor 코드 리팩토링 할 경우 labels Jan 3, 2025
@parkuiery parkuiery self-assigned this Jan 3, 2025
@parkuiery parkuiery linked an issue Jan 3, 2025 that may be closed by this pull request
Copy link
Contributor

coderabbitai bot commented Jan 3, 2025

워크스루

이 풀 리퀘스트는 회원가입 프로세스의 새로운 학생 번호 입력 화면을 도입합니다. 주요 변경 사항은 학생 번호를 입력하는 새로운 네비게이션 흐름, 관련 뷰모델, UI 컴포넌트 추가를 포함합니다. 이 변경은 기존 회원가입 흐름을 확장하여 학생들이 학년, 반, 번호를 입력할 수 있도록 합니다.

변경 사항

파일 변경 요약
DmsNavigator.kt 학생 번호 입력 화면으로 이동하는 새로운 메서드 추가
AuthNavigation.kt signUp 함수에 학생 번호 입력 네비게이션 추가
EnterStudentNumberNavigation.kt 학생 번호 입력을 위한 네비게이션 함수 추가
SignUpNavigation.kt 학생 번호 입력 네비게이션 흐름 업데이트
EnterStudentNumberScreen.kt 새로운 학생 번호 입력 화면 컴포넌트 생성
EnterStudentNumberViewModel.kt 학생 번호 입력 상태 및 로직 관리를 위한 뷰모델 추가
EnterEmailVerificationCodeNavigation.kt 네비게이션 매개변수 이름 변경
EnterEmailVerificationCodeViewModel.kt 네비게이션 흐름 변경 및 상태 업데이트
EnterSchoolVerificationCodeViewModel.kt 학교 인증 코드 길이 상수 추가
SetIdViewModel.kt ID 입력 로직 변경 및 상태 관리 수정
SetPasswordScreen.kt 비밀번호 입력 UI 및 로직 개선
TermsScreen.kt 약관 동의 UI 개선 및 함수 시그니처 변경

시퀀스 다이어그램

sequenceDiagram
    participant User
    participant EnterEmailScreen
    participant EmailVerificationScreen
    participant EnterStudentNumberScreen
    participant SetIdScreen

    User->>EnterEmailScreen: 이메일 입력
    EnterEmailScreen->>EmailVerificationScreen: 인증 코드 전송
    EmailVerificationScreen->>EnterStudentNumberScreen: 인증 완료
    User->>EnterStudentNumberScreen: 학생 번호 입력
    EnterStudentNumberScreen->>SetIdScreen: 다음 단계로 이동
Loading

관련 가능성 있는 PR

🐰 학생 번호를 입력하는 토끼의 노래
학년과 반, 번호를 적어
회원가입 길을 열어가네
한 칸 한 칸 채워지는 꿈
새로운 시작을 향해 달려가네! 🚀


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai 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

Documentation and Community

  • 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.

Copy link
Contributor

@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: 1

🧹 Nitpick comments (19)
core/design-system/src/commonMain/kotlin/team/aliens/dms/kmp/core/designsystem/timer/DmsTimer.kt (2)

39-39: 타이머 종료 시 콜백 호출 처리 확인 필요
onTimerFinished(timerFinished) 호출로 종료 상태를 알리는 로직은 적절하지만, 이 때 timerFinished 플래그를 별도로 반환하는 이유가 있는지 다시 한 번 검토해주세요. 단순히 true를 넘겨도 동일한 의미를 갖는다면 코드가 더 간결해질 수 있습니다.


56-60: 시간 포매팅 로직이 단순해지고 가독성이 높아졌습니다
분/초 형태를 상황에 맞게 다르게 보여주어 사용자 입장에서 남은 시간을 직관적으로 파악할 수 있습니다. 다만, i18n(다국어) 지원이 필요한 경우, "분", "초" 등의 단어 사용을 문자열 리소스 형태로 분리하는 방안을 고려해보세요.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/SetIdViewModel.kt (2)

8-10: 입력 후 즉시 버튼 활성화 가능성 고려하기
setState로 id를 업데이트한 뒤, 바로 setButtonEnabled를 호출하는 방식은 사용자 입력에 따라 즉각적으로 버튼 활성화 여부가 결정되어 유연합니다. 다만, setState가 여러 곳에서 연속적으로 호출될 수 있는 경우 성능 부담이 늘어날 수 있으니, 가능한 한 단일 setState 블록 안에서 함께 처리할 수 있는지 고려해 보시면 좋겠습니다.


13-15: 버튼 활성화 로직의 조건 검토
id.isNotEmpty()만으로 버튼 활성화를 판단하는 것은 직관적이며 간단합니다. 그러나 가입 시 ID 형식(예: 최소 길이, 특정 문자를 포함해야 함 등)에 대한 조건이 추가될 가능성이 있다면, 향후 확장성을 고려해 별도의 유효성 검사 메서드를 만드는 방안을 고민해 보세요.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterSchoolVerificationQuestionScreen.kt (1)

70-82: 앱 바(DmsTopAppBar)와 배너(SignUpInfoBanner) 구성

  • 앱 바에 "회원가입" 타이틀을 설정하고 뒤로 가기 버튼을 사용하는 방식이 사용자 경험 측면에서 직관적입니다.
  • SignUpInfoBanner의 제목과 설명을 통해 학교 인증 질문임을 사용자가 쉽게 이해하도록 구성한 점은 유용합니다.

추가로, SignUpInfoBannertitle이나 description이 동적으로 팀 내 일부 국제화(i18n) 요구사항이 있는 경우를 대비해 문자열 리소스 활용 방안도 고려해 보시면 좋겠습니다.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterSchoolVerificationCodeScreen.kt (2)

71-82: 상단 앱바와 배너 구성 적절
'회원가입' 타이틀과 안내 배너가 적절하게 구현되어 사용자에게 의도를 명확히 전달합니다. 추가로 설명 문구를 좀 더 구체화하여 사용자 불편을 줄일 수 있을지 검토해보는 것도 좋겠습니다.


83-91: 인증코드 입력 필드 사용성
DmsNumberField를 사용해 8자리 확인코드를 제한하는 접근이 합리적입니다. 다만, 사용자가 8자리를 모두 입력하기 전에는 어떻게 안내될지 UX 관점에서 리뷰를 권장합니다.

core/design-system/src/commonMain/kotlin/team/aliens/dms/kmp/core/designsystem/checkbox/DmsCheckbox.kt (1)

20-20: 콜론(:) 앞의 공백을 제거해주세요
코틀린 스타일 가이드에서 권장하는 포맷팅을 준수하기 위해서, 콜론 앞의 공백을 제거하는 것이 좋습니다.

-    interactionSource : MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
🧰 Tools
🪛 GitHub Actions: Kotlin Multiplatform CI

[error] 20-20: Unexpected spacing before ':' (standard:colon-spacing)

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/TermsScreen.kt (3)

98-102: 체크박스 상태와 콜백 처리
AgreeCheckBox 호출 시 isCheck 값이 state.buttonEnabled와 직접 연결되어 있습니다. 체크박스의 상태 변경이 즉시 버튼 활성화 상태를 반영하도록 구현한 것으로 보이는데, 동의 여부뿐만 아니라 비즈니스 로직상 다른 조건(예: 부분 동의 항목 등)은 없는지 재확인해 주세요.


103-114: '다음' 버튼 활성화 여부 검증
enabled = state.buttonEnabled로 설정된 부분이 직관적이며, 동의 여부와 버튼 활성화 사이의 로직이 단순화되어 깔끔합니다. 다만 실제 회원가입 진행 시 추가 검증이 필요한 경우, 이 시점에서 예외 처리를 고려해야 할 수 있습니다.


116-140: AgreeCheckBox 컴포저블의 명확한 확장성
해당 컴포넌트는 단일 항목 동의 여부만을 제어하고 있습니다. 추후 이 컴포넌트를 확장해 세부 약관별 동의 여부를 처리하거나, 멀티라인 텍스트를 동적으로 받아야 할 필요가 생길 수 있습니다. 재사용성을 높이려면 추후 확장 가능성을 고려해 Props 구조 등을 도입하는 것도 좋겠습니다.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/navigation/EnterStudentNumberNavigation.kt (1)

13-13: [네비게이션 상수 명명 규칙 확인]

NAVIGATION_ENTER_STUDENT_NUMBER 상수는 네비게이션 경로를 잘 표현하고 있습니다. 다만, 기존 코드 전반에서 사용 중인 동일한 네이밍 패턴 혹은 접두사·접미사가 있는지 확인하여 프로젝트 전반적으로 컨벤션이 일치하도록 유지해 주세요.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterEmailVerificationCodeViewModel.kt (2)

20-26: [타이머 완료 상태 설정 메서드]

setTimerFinished(timerFinished: Boolean) 함수를 통해 뷰 모델 상태를 명확히 업데이트하고 있습니다. 타이머가 완료된 후에만 특정 UI나 로직이 동작해야 한다면, 여기에 추가적인 로직(예: 사이드 이펙트 처리 등)을 검토해볼 수 있습니다.

🧰 Tools
🪛 GitHub Actions: Kotlin Multiplatform CI

[error] 23-23: Missing trailing comma before ')' (standard:trailing-comma-on-call-site)


23-23: [파이프라인 실패: trailing comma 누락]

CI 파이프라인 로그에 따르면, 23번째 줄 부근에서 trailing comma가 누락되어 있습니다. Kotlin Multiplatform 스타일 규칙(특히 trailing-comma-on-call-site)을 준수하기 위해 아래와 같이 쉼표가 필요할 수 있습니다:

-    timerFinished = timerFinished
+    timerFinished = timerFinished,
🧰 Tools
🪛 GitHub Actions: Kotlin Multiplatform CI

[error] 23-23: Missing trailing comma before ')' (standard:trailing-comma-on-call-site)

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/component/SignUpInfoBanner.kt (2)

13-18: KDoc 문서화를 추가하면 좋을 것 같습니다.

컴포넌트의 용도와 각 매개변수의 역할을 설명하는 KDoc을 추가하면 다른 개발자들이 더 쉽게 이해하고 사용할 수 있을 것 같습니다.

다음과 같이 문서화를 추가해보세요:

+/**
+ * 회원가입 과정에서 사용되는 정보 배너 컴포넌트입니다.
+ *
+ * @param modifier 컴포넌트의 크기, 패딩 등을 수정하기 위한 Modifier
+ * @param title 배너의 제목
+ * @param description 배너의 설명 텍스트
+ */
@Composable
internal fun SignUpInfoBanner(
    modifier: Modifier = Modifier,
    title: String,
    description: String,
)

19-33: 디자인 시스템의 일관성을 위해 간격 값을 상수로 분리하면 좋을 것 같습니다.

현재 하드코딩된 8.dp 값을 디자인 시스템의 상수로 분리하면 디자인 일관성을 더 잘 유지할 수 있을 것 같습니다.

DmsSpacing 또는 유사한 객체에 다음과 같이 상수를 추가하고 사용하는 것을 추천드립니다:

-        verticalArrangement = Arrangement.spacedBy(8.dp),
+        verticalArrangement = Arrangement.spacedBy(DmsSpacing.medium),
feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterEmailVerificationCodeScreen.kt (2)

36-37: 상수 정의에 대한 의견
EMAIL_VERIFICATION_CODE_LENGTH 상수를 명시적으로 선언함으로써 코드 가독성 및 유지보수성이 향상되었습니다. 다만, 향후 재사용 가능성을 고려해 별도의 상수나 Config 파일로 분리하는 방안도 검토하시면 좋을 것 같습니다.


99-107: 인증코드 재발송 버튼
재발송 버튼 구현 자체는 문제 없어 보이나, 클릭 시 실질적으로 재발송을 처리하는 로직이 미구현으로 보입니다. 실제 재전송 API 연동 또는 서버 호출을 고려해 추가 구현을 권장합니다.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterStudentNumberScreen.kt (1)

125-174: [라인 125-174] StudentNumberInputs 함수 내 포커스 이동 로직
학년, 반, 번호 필드간 자동 포커스 이동을 구현하여 사용자 경험을 개선하고 있습니다.
다만, if문 뒤에 공백이 누락되어 GitHub Actions CI에서 경고가 발생하고 있습니다. 다음과 같이 수정해 주세요.

-            if(grade.isNotEmpty()) classroomFocusRequest.requestFocus()
+            if (grade.isNotEmpty()) classroomFocusRequest.requestFocus()
🧰 Tools
🪛 GitHub Actions: Kotlin Multiplatform CI

[error] 147-147: Missing spacing after 'if' (standard:keyword-spacing)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a7ce323 and 766614b.

📒 Files selected for processing (21)
  • composeApp/src/commonMain/kotlin/team/aliens/dms/kmp/DmsNavigator.kt (2 hunks)
  • composeApp/src/commonMain/kotlin/team/aliens/dms/kmp/navigation/authorized/AuthNavigation.kt (1 hunks)
  • core/design-system/src/commonMain/kotlin/team/aliens/dms/kmp/core/designsystem/checkbox/DmsCheckbox.kt (1 hunks)
  • core/design-system/src/commonMain/kotlin/team/aliens/dms/kmp/core/designsystem/timer/DmsTimer.kt (3 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/component/SignUpInfoBanner.kt (1 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/di/SignIUpModel.kt (2 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/navigation/EnterEmailVerificationCodeNavigation.kt (1 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/navigation/EnterStudentNumberNavigation.kt (1 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/navigation/SignUpNavigation.kt (2 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterEmailScreen.kt (2 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterEmailVerificationCodeScreen.kt (4 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterSchoolVerificationCodeScreen.kt (2 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterSchoolVerificationQuestionScreen.kt (2 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterStudentNumberScreen.kt (1 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/SetIdScreen.kt (3 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/SetPasswordScreen.kt (3 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/TermsScreen.kt (3 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterEmailVerificationCodeViewModel.kt (2 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterSchoolVerificationCodeViewModel.kt (2 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterStudentNumberViewModel.kt (1 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/SetIdViewModel.kt (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Kotlin Multiplatform CI
feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/SetPasswordScreen.kt

[error] 133-133: Missing trailing comma before ')' (standard:trailing-comma-on-call-site)


[error] 141-141: Missing trailing comma before ')' (standard:trailing-comma-on-call-site)

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterEmailVerificationCodeViewModel.kt

[error] 23-23: Missing trailing comma before ')' (standard:trailing-comma-on-call-site)

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterStudentNumberViewModel.kt

[error] 36-36: Missing trailing comma before ')' (standard:trailing-comma-on-call-site)

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterStudentNumberScreen.kt

[error] 147-147: Missing spacing after 'if' (standard:keyword-spacing)

core/design-system/src/commonMain/kotlin/team/aliens/dms/kmp/core/designsystem/checkbox/DmsCheckbox.kt

[error] 20-20: Unexpected spacing before ':' (standard:colon-spacing)

🔇 Additional comments (65)
feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterSchoolVerificationCodeViewModel.kt (2)

4-4: 상수 분리를 통한 가독성 및 유지보수성 개선
SCHOOL_VERIFICATION_CODE_LENGTH를 별도의 상수로 분리하여, 코드 길이를 중앙에서 관리할 수 있게 된 점은 매우 좋습니다. 이후 다른 로직에서 검증 코드 길이가 변경되어야 할 경우, 한 곳만 수정하면 되므로 유지보수성이 향상됩니다.


22-22: 버튼 활성화 로직에 신규 상수 적용
verificationCode.length == SCHOOL_VERIFICATION_CODE_LENGTH로 검증하는 방식으로, 긴 하드코드를 제거하고 상수에 의존하도록 변경한 부분은 훌륭합니다. 이로 인해 오타나 변경 누락으로 인한 오류를 더 쉽게 방지할 수 있습니다.

core/design-system/src/commonMain/kotlin/team/aliens/dms/kmp/core/designsystem/timer/DmsTimer.kt (2)

21-21: onTimerFinished 콜백 인자로 Boolean 을 사용하는 방식이 유연하고 명확합니다.
타이머 동작이 끝났을 때, UI 혹은 로직에서 필요한 처리를 즉시 반영하는 데 적절합니다.


49-49: 컬러 변경이 디자인 시스템과 잘 어우러집니다
inversePrimary를 사용하여 시인성을 높인 점이 좋습니다. 단, 나머지 텍스트나 UI 요소들과의 일관성도 확인해보면 좋겠습니다.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/SetIdViewModel.kt (2)

29-29: State 모델에 대한 재확인
buttonEnabled 프로퍼티를 SetIdState에 포함한 것은, UI와 상태를 직관적으로 연결하기에 적절해 보입니다. 추후 다른 조건(예: ID 형식)에 따라 버튼 활성화 여부가 달라질 수 있으니, 추가 요구사항이 생길 경우 유연하게 확장할 수 있도록 주의가 필요합니다.


34-34: 초기 값 설정 검토
기본 상태에서 buttonEnabled = false로 설정한 것은 아직 ID를 입력하지 않은 상황임을 잘 드러냅니다. 기획 의도와 합치하는지 다시 한번 확인해 보시고, 만약 다른 초기 상태가 필요하다면 관련 요구사항에 맞춰 조정하시면 됩니다.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterSchoolVerificationQuestionScreen.kt (5)

5-8: 레이아웃 확장을 위한 Import 추가 확인
스페이서(Spacer), fillMaxWidth, padding 등을 불러와 UI 레이아웃 조정에 활용하는 것은 적절해 보입니다. 프로젝트 내 다른 Compose 컴포넌트와 호환성도 좋아 보이며, 가독성 및 재사용성을 높일 수 있어 좋습니다.


14-14: dp 단위 활용
dp 단위를 단순 Import해서 바로 쓰는 것은 Compose 환경에서 확장성과 가독성을 높이는 방법입니다. 현재로서는 문제가 없어 보입니다.


16-25: UI 헬퍼 함수와 디자인 시스템 Import 구조
horizontalPadding, startPadding, topPadding 등의 커스텀 확장함수와 DmsTopAppBar, DmsButton, DmsTextField 등 디자인 시스템 컴포넌트의 Import 구성은 명확하고 일관성이 있습니다. 팀 내 디자인 시스템을 적극적으로 활용하는 점이 유지보수에 이점이 큽니다.


83-91: 인증 답변 입력 필드 구성

  • DmsTextField 컴포저블을 사용해 힌트("답변")를 제공하고, Clear 아이콘도 표시되어 있어 사용자 편의성에 유리합니다.
  • onValueChangeviewModel::setSchoolVerificationAnswer를 바로 연결해 반응형으로 상태를 업데이트하는 것은 합리적인 접근입니다.

별다른 문제점은 없어 보이며, 명확하고 일관성 있는 Compose 코드 작성이 좋습니다.


92-102: 다음 단계로 이동하는 버튼(DmsButton) 설정

  • modifier를 통해 폭을 가득 채우고 padding(24.dp)을 적용한 점이 사용자 인터페이스에서 보기 좋습니다.
  • buttonTypebuttonColor를 명시적으로 지정해, 디자인 시스템과의 일관성도 준수하고 있습니다.
  • enabled 상태를 state.buttonEnabled로 제어하여 폼 유효성 검사와 연동하는 방식도 바람직합니다.

현재 구조에서 별다른 문제점은 없어 보이며, 기획/디자인 사양 변동 시에도 쉽게 대응 가능해 보입니다.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterSchoolVerificationCodeScreen.kt (3)

5-25: 필요한 UI 컴포넌트 임포트 확인
추가된 UI 관련 임포트들이 기존 코드와 충돌 없이 정상적으로 사용되고 있습니다. 전체적인 UI 구성을 위해 적절한 라이브러리를 임포트하신 것으로 보이며, 유지보수에 문제 없어 보입니다.


31-31: 인증 코드 길이 증가 확인 (6 → 8)
학교 인증코드 길이를 8자로 변경한 것은 요구사항 충족을 위한 것으로 보입니다. 외부에서 사용되는 모든 로직(유효성 검사, API 통신 등)이 함께 변경되었는지 점검을 권장합니다.


93-102: 다음 단계 전환 버튼 UI 확인
Enabled 속성이 state.buttonEnabled와 연동되어 있어 비활성/활성 전환이 단순하고 명확합니다. 버튼 색상과 타입도 시각적 우선순위를 고려해 잘 설정한 것으로 보입니다.

core/design-system/src/commonMain/kotlin/team/aliens/dms/kmp/core/designsystem/checkbox/DmsCheckbox.kt (2)

13-30: DmsCheckbox 구현이 깔끔합니다.
기본값 설정과 파라미터 구성 방식이 명확하고 재사용성이 높아 보입니다.

🧰 Tools
🪛 GitHub Actions: Kotlin Multiplatform CI

[error] 20-20: Unexpected spacing before ':' (standard:colon-spacing)


32-50: DmsCheckboxDefaults 사용 방법이 직관적입니다.
Colors 함수를 통해 체크박스 색상을 유연하게 설정할 수 있어, 확장성 측면에서 매우 좋습니다.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/TermsScreen.kt (3)

54-54: onAllAgreeButtonClick → onAgreeButtonClick 변경 확인
이벤트 핸들러의 이름을 좀 더 직관적으로 변경하여, 전체 동의가 아닌 일반 동의를 처리하는 용도로 바뀌었습니다. 기존에 이를 호출하는 다른 로직이 있다면 모두 반영되었는지 확인해주세요.

Also applies to: 65-65


73-84: UI 요소 배치와 정보 배너 구성 확인
이 부분은 회원가입 과정을 간단명료하게 안내해 주는 구성으로 보입니다. 디자인 의도에 맞춰 배너와 타이틀을 적절히 배치하였는지, 요구사항과 UI 스펙이 일치하는지 최종 점검을 권장드립니다.


5-17: 불필요한 Import 여부 점검 권장
주석 처리된 내용은 없으나, 실제 사용되지 않는 임포트가 있는지 확인해 보시길 권장드립니다.

✅ Verification successful

Let me check the usage of imports in the TermsScreen.kt file.


모든 import 문이 코드에서 사용되고 있음을 확인했습니다

파일 내용을 검토한 결과, 모든 import 문이 코드 내에서 실제로 사용되고 있습니다:

  • 레이아웃 관련 import들 (Column, Row, Arrangement 등)은 UI 구성에 사용
  • Composable 관련 import들은 @composable 함수들에서 사용
  • DMS 관련 컴포넌트들 (DmsTopAppBar, DmsButton 등)이 UI에서 활용
  • HorizontalDivider가 구분선으로 사용
  • 테마와 상태 관리 관련 import들도 모두 활용됨
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 임포트 중 사용되지 않는 항목이 있는지 확인합니다.
rg -A 3 "import" --glob "*.kt"

Length of output: 93874


Script:

#!/bin/bash
# Check the content of TermsScreen.kt to verify import usage
cat feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/TermsScreen.kt

Length of output: 4750

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/navigation/EnterEmailVerificationCodeNavigation.kt (1)

17-25: [네비게이션 파라미터 명칭 개선]

navigateToSetId에서 navigateToEnterStudentNumber로 변경된 부분이 기존 네이밍보다 명확하고 의도를 잘 드러냅니다. 덕분에 코드 가독성 및 유지보수성이 좋아질 것으로 보입니다. 관련된 ViewModel, 다른 네비게이션 함수에서도 동일한 이름 통일을 확인해 주세요.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/navigation/EnterStudentNumberNavigation.kt (2)

15-29: [Composable 라우트 설계 검토]

enterStudentNumber 함수를 통해 Composable 라우트를 정의하는 구조가 직관적입니다. 파라미터로 SignUpData를 전달하는 로직이 분리되어 있어 재사용성에 이점이 있습니다. 다만, 예외 상황(예: SignUpData가 null이거나 JSON 역직렬화 실패 등)에 대한 처리가 필요한지 확인해 보시기 바랍니다.


31-33: [NavController 확장 함수 사용]

navigateToEnterStudentNumber 확장 함수를 통해 네비게이션 로직을 간결하게 관리할 수 있습니다. 함수명과 라우트 상수의 일관성이 잘 맞아 코드 추적이 용이합니다.

composeApp/src/commonMain/kotlin/team/aliens/dms/kmp/navigation/authorized/AuthNavigation.kt (1)

35-35: [신규 네비게이션 파라미터 연동 확인]

navigateToEnterStudentNumber 파라미터 추가로, 이메일 인증 완료 후 곧바로 학생 번호 입력 화면으로 이동이 가능해졌습니다. 네이밍과 설계가 추가 확장성에도 유연해 보입니다. 의도한 순서대로 실제 네비게이션 동작이 잘 이어지는지 한번 더 테스트해 보시기 바랍니다.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterEmailVerificationCodeViewModel.kt (4)

4-4: [상수 사용으로 코드 가독성 향상]

EMAIL_VERIFICATION_CODE_LENGTH 상수를 사용해 매직 넘버를 제거한 점이 좋습니다. 이런 방식으로 유지보수 시 상수만 변경해도 코드 전반이 일관성 있게 적용될 수 있습니다.


30-30: [버튼 활성화 로직 개선]

emailVerificationCode.length를 상수와 비교함으로써 로직이 명확해졌습니다. 다만, 인증 코드 형식이 변경될 가능성(예: 문자 포함, 하이픈 등의 추가)이 있다면, 더 유연한 검사 방식이 필요할 수도 있습니다.


34-34: [사이드 이펙트 명칭 변경 검토]

MoveToSetId에서 MoveToEnterStudentNumber로 사이드 이펙트를 변경했습니다. 변경 의도가 뚜렷하며, 네비게이션 로직과의 일관성이 높아졌습니다. 다른 부분에서 동일한 호출이나 참조가 남아있지 않은지 확인해 주세요.


53-53: [SideEffect 데이터 구조 업데이트]

sealed interface를 통해 MoveToEnterStudentNumber를 선언한 점이 명확합니다. 필요한 경우, 추후 파라미터(authCode)를 확장하여 추가 정보를 전달할 수 있습니다.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/navigation/SignUpNavigation.kt (3)

18-18: 새로운 학번 입력 네비게이션 파라미터 추가 감사합니다
사용자가 학번을 입력할 수 있는 흐름을 명확히 분리하여 가독성과 유지보수성이 향상되었습니다.


42-44: 학번 입력 화면으로의 네비게이션 호출 처리 확인
navigateToEnterStudentNumber 전달로 인해 학번 입력 화면으로 올바르게 이동하는지 여부를 확인해 보세요. 실제 화면 전환 시 필요한 데이터가 누락되지 않았는지도 점검을 권장합니다.


45-45: 신규 enterStudentNumber 호출 추가
새로운 화면 진입 경로가 추가되어 전체 회원가입 플로우가 확장되었습니다. 기존 화면들과의 연동이 문제 없이 동작하는지 테스트를 진행하면 좋겠습니다.

composeApp/src/commonMain/kotlin/team/aliens/dms/kmp/DmsNavigator.kt (2)

13-13: 학번 입력 네비게이션 import 추가
navigateToEnterStudentNumber 함수를 사용하기 위해 필요한 import가 잘 추가되었습니다.


52-54: 학번 입력 화면 이동 함수 도입
navigateToEnterStudentNumber 함수를 통해 SignUpData를 전달하여 화면을 전환하는 흐름이 유연해졌습니다. 전체 플로우에서 누락된 데이터가 없는지 확인해 주세요.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterEmailScreen.kt (2)

5-25: 레이아웃과 디자인 리소스 Import 추가
UI 구성 요소를 위한 다양한 Modifier와 디자인 시스템 컴포넌트 import가 잘 이루어졌습니다. 향후 UI 변경 시 불필요한 import가 남지 않도록 주의해 주세요.


70-102: 이메일 입력 화면의 UI 구성 확인

  • TopAppBar 사용으로 상단 네비게이션 바가 직관적입니다.
  • SignUpInfoBanner로 단계별 안내가 명확해졌습니다.
  • TextField와 Button이 적절히 배치되어, 사용자 경험이 향상되었습니다.
feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/SetIdScreen.kt (2)

58-58: ID 변경 콜백 추가
기존 grade, classRoom, number 대신 onIdChange를 통해 ID만 관리하도록 변경된 점이 단순화에 도움이 됩니다.


67-106: 아이디 설정 화면 UI 구성 개선

  • TopAppBar로 화면 전환 시 사용자 인지를 돕습니다.
  • SignUpInfoBannerDmsTextField로 아이디 입력 과정을 직관적으로 안내하고 있어 좋습니다.
  • Button 활성 상태가 state.buttonEnabled에 연동되어 있어 유효성 검증 흐름이 깔끔합니다.
feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/component/SignUpInfoBanner.kt (2)

1-12: 패키지 구조와 임포트가 깔끔합니다!

팀 컨벤션을 잘 따르고 있으며, 내부 디자인 시스템을 일관되게 사용하고 있습니다.


1-33: 전반적으로 잘 구현된 컴포넌트입니다! 👍

  • 컴포즈 패턴을 잘 따르고 있습니다
  • 디자인 시스템을 일관되게 활용하고 있습니다
  • 여러 화면에서 재사용 가능하도록 잘 설계되었습니다
feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterEmailVerificationCodeScreen.kt (11)

4-30: Import 구문 추가에 대한 확인
해당 임포트들은 Compose UI 구성요소와 DMS 디자인 시스템 연동을 위해 필요한 의존성으로 보입니다. 중복되거나 불필요한 임포트는 없어 보이며, 사용 목적이 명확하므로 현재 상태로도 적절해 보입니다.


41-41: 함수 시그니처 변경: navigateToEnterStudentNumber
navigateToSetId에서 navigateToEnterStudentNumber로 변경됨에 따라, 다른 부분에서 해당 함수를 호출할 때도 변경 사항이 정확히 반영되었는지 확인이 필요합니다.


50-51: SideEffect 변경: MoveToEnterStudentNumber
SideEffect가 예상대로 동작하면 authCode가 주입되어 navigateToEnterStudentNumber가 호출됩니다. 이 로직이 정상동작하는지 테스트 코드 또는 QA를 통해 재확인하시면 좋겠습니다.


62-62: 타이머 완료 콜백 주입
onTimerFinished = viewModel::setTimerFinished를 통해 ViewModel 상태를 업데이트하는 로직은 적절해 보입니다. 타이머가 끝난 뒤 실제 화면 전환 혹은 에러 처리 등 추가 액션이 필요한 경우를 고려해 보시면 좋겠습니다.


72-72: EnterEmailVerificationCodeScreen에 타이머 콜백 추가
파라미터에 onTimerFinished를 추가함으로써 재전송 타이밍이나 UX 개선 등에 활용할 수 있게 되었습니다. 추후 호출부 로직에서 명확한 처리 흐름을 구현해 보시면 좋겠습니다.


79-82: DmsTopAppBar 사용
“회원가입” 타이틀과 함께 Top AppBar가 적절히 구성되어 있습니다. 뒤로 가기 동작을 위한 onBackPressed 콜백도 정상적으로 설정되어 있어 가독성과 유지보수성에 문제 없어 보입니다.


83-89: EmailVerificationCodeInfoBanner 호출
인증 안내 배너를 따로 추출하여 재사용성과 가독성을 확보한 점이 좋습니다. onTimerFinished 콜백을 외부로 전달하는 구조도 깔끔합니다.


90-98: 인증 코드 입력을 위한 DmsNumberField
6자리 인증 코드 입력을 위한 EMAIL_VERIFICATION_CODE_LENGTH를 명시적으로 사용하고 있으며, 사용자 입력을 onValueChange로 즉시 전달해 ViewModel에 반영하는 형태가 적절합니다.


108-119: ‘다음’ 버튼
다음 단계로 넘어가는 핵심 동작을 담당하는 버튼입니다. enabled = state.buttonEnabled 속성을 통해 상태에 따라 활성화가 제어되어 있어 좋은 접근입니다.


120-120: 마무리 괄호
구조상 별다른 문제 없이 Composable을 닫는 부분입니다.


122-147: EmailVerificationCodeInfoBanner 컴포저블 신규 추가
사용자 안내 문구와 함께 타이머에 대한 콜백까지 처리되는 구조가 명확합니다. 텍스트 스타일 지정과 배치를 위해 DmsThemeDmsTypography를 적극 활용하셨으며, 재사용 가능해 보입니다. UX 개선을 위해 중간에 남은 시간을 강조하거나, 가독성을 높이는 추가 디자인도 검토해 보시면 좋겠습니다.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/di/SignIUpModel.kt (2)

9-9: [라인 9] EnterStudentNumberViewModel 임포트에 대한 확인
이 뷰모델은 회원가입 기능 확장을 위한 로직과 잘 맞춰지고 있습니다. 현재까지 별다른 문제점은 보이지 않습니다.


19-19: [라인 19] signUpModule에 EnterStudentNumberViewModel 추가
DI 모듈에 뷰모델을 추가하여 화면에서 상태를 직접 관리할 수 있도록 하는 설계가 타당해 보입니다. 다른 뷰모델들과 일관된 패턴으로 사용됩니다.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterStudentNumberViewModel.kt (8)

1-6: [라인 1-6] EnterStudentNumberViewModel 클래스 정의
ViewModel 클래스를 내부적으로 선언함으로써, 외부 모듈에서 불필요하게 사용할 수 없도록 제한하여 의도를 명확히 드러냅니다. BaseViewModel을 상속하여 상태와 사이드이펙트를 다루는 구조도 일관성 있어 보입니다.


8-11: [라인 8-11] setGrade 함수
상태 변경 후 buttonEnabled 함수를 호출하여 버튼 활성화 로직을 한 번 더 처리하는 방식이 유지보수에 용이합니다.


13-16: [라인 13-16] setClassRoom 함수
setGrade 함수와 동일한 로직을 공유하며 일관성을 유지하고 있습니다.


18-21: [라인 18-21] setNumber 함수
학년, 반, 번호 입력 시 동일한 패턴으로 처리되어 가독성이 좋습니다.


23-28: [라인 23-28] buttonEnabled 함수
with(state.value)를 사용하여 가독성을 높이고, 학년·반·번호 중 하나라도 비어 있으면 버튼을 비활성화하는 로직이 명확합니다.


41-55: [라인 41-55] EnterStudentNumberState 데이터 클래스
buttonEnabled 필드를 함께 관리함으로써, 모든 상태를 일괄적으로 파악하기 쉽습니다. Companion object로 기본 상태를 제공하는 구조도 적절해 보입니다.


57-63: [라인 57-63] EnterStudentNumberSideEffect 정의
다음 화면으로 이동하기 위한 사이드이펙트 모델이 명확하게 정의되어 있습니다. 뷰모델-UI 간에 필요한 정보만 포함하고 있어 좋습니다.


30-38: ⚠️ Potential issue

[라인 30-38] onNextClick 함수
다음 화면으로 이동하기 위한 사이드이펙트를 명시적으로 처리하고 있습니다.
단, [오류 로그]에서 언급된 대로 36번째 줄에서 닫는 괄호 전의 쉼표가 누락된 것으로 보입니다. Kotlin 스타일 가이드에 맞춰 다음과 같이 수정해 주세요.

     EnterStudentNumberSideEffect.MoveToSetId(
         grade = "",
         classroom = "",
         number = "",
-    )
+    , // 닫는 괄호 전에 쉼표 추가 필요
 )

Likely invalid or redundant comment.

🧰 Tools
🪛 GitHub Actions: Kotlin Multiplatform CI

[error] 36-36: Missing trailing comma before ')' (standard:trailing-comma-on-call-site)

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterStudentNumberScreen.kt (3)

1-37: [라인 1-37] EnterStudentNumber 컴포저블 및 기본 세팅
DI에서 주입된 EnterStudentNumberViewModel 상태를 구독하고 사이드이펙트를 수신하는 구조가 다른 화면과 일관성이 있어 좋습니다. 또한 navigateToSetId 콜백을 통해 SignUpData를 넘기는 방식이 명확합니다.


47-60: [라인 47-60] LaunchedEffect 내 사이드이펙트 처리
뷰모델 내 MoveToSetId 사이드이펙트를 즉시 감지 및 처리하여, 네비게이션 로직이 깔끔하게 분리되어 있습니다.


73-123: [라인 73-123] EnterStudentNumberScreen UI 구현
학년/반/번호 입력 필드를 하나의 Column에 나열하고, 버튼을 맨 아래에 배치해 시인성이 좋습니다. “다음” 버튼의 활성화 여부를 상태로 제어하는 방식도 적절합니다.

feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/SetPasswordScreen.kt (3)

58-58: [함수 시그니처 변경 확인]
onPasswordCheckChange로 이름을 변경하여 의도가 더욱 명확해졌습니다. 관련 호출부와 동기화도 잘 이뤄졌는지 확인하면 좋겠습니다.


68-68: [파라미터 일관성 점검]
SetPasswordScreen 내부에서도 onPasswordCheckChange로 동일한 네이밍을 사용해 잘 반영하였습니다.


113-142: [컴포저블 분리 칭찬]
PasswordInputs 함수로 비밀번호 입력 로직을 따로 분리하여 가독성과 재사용성이 좋아졌습니다. 앞으로도 이런 방식으로 UI 요소를 모듈화하면 관리가 수월해질 것입니다.

🧰 Tools
🪛 GitHub Actions: Kotlin Multiplatform CI

[error] 133-133: Missing trailing comma before ')' (standard:trailing-comma-on-call-site)


[error] 141-141: Missing trailing comma before ')' (standard:trailing-comma-on-call-site)

hint = "비밀번호",
showVisibleIcon = true,
isError = isPasswordFormatError,
errorMessage = "형식이 일치하지 않습니다."
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

[파이프라인 빌드 차단: 트레일링 콤마 및 오타 수정 필요]
해당 라인들에서 콤마가 누락되어 있고, "비빌번호" 오타가 확인됩니다. 파이프라인에서 실패를 야기하므로 반드시 수정해 주세요.

아래와 같이 수정하면 에러 해결이 가능합니다:

 DmsTextField(
     value = password,
     onValueChange = onPasswordChange,
     hint = "비밀번호",
     showVisibleIcon = true,
     isError = isPasswordFormatError,
-    errorMessage = "형식이 일치하지 않습니다."
+    errorMessage = "형식이 일치하지 않습니다.",
 )

 DmsTextField(
     value = passwordCheck,
     onValueChange = onPasswordCheckChange,
     hint = "비밀번호 확인",
     showVisibleIcon = true,
     isError = isPasswordMatchError,
-    errorMessage = "비빌번호가 일치하지 않습니다."
+    errorMessage = "비밀번호가 일치하지 않습니다.",
 )

Also applies to: 141-141

🧰 Tools
🪛 GitHub Actions: Kotlin Multiplatform CI

[error] 133-133: Missing trailing comma before ')' (standard:trailing-comma-on-call-site)

Copy link
Contributor

@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: 2

🧹 Nitpick comments (1)
feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterStudentNumberScreen.kt (1)

85-97: 접근성 개선을 위한 컨텐츠 설명 추가 필요

사용자 접근성 향상을 위해 다음 사항들을 고려해주세요:

  1. TopAppBar에 contentDescription 추가
  2. SignUpInfoBanner에 스크린리더를 위한 설명 추가
DmsTopAppBar(
    title = "회원가입",
    onBackPressed = onBackPressed,
+   contentDescription = "회원가입 화면, 뒤로가기"
)
SignUpInfoBanner(
    modifier = Modifier
        .fillMaxWidth()
        .startPadding(24.dp)
        .topPadding(48.dp),
    title = "학번을 입력해주세요",
    description = "숫자만 입력해주세요.",
+   contentDescription = "학번 입력 안내: 학년, 반, 번호를 숫자로만 입력해주세요"
)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 766614b and e5b0c30.

📒 Files selected for processing (3)
  • core/design-system/src/commonMain/kotlin/team/aliens/dms/kmp/core/designsystem/checkbox/DmsCheckbox.kt (1 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterStudentNumberScreen.kt (1 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/SetPasswordScreen.kt (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/SetPasswordScreen.kt
  • core/design-system/src/commonMain/kotlin/team/aliens/dms/kmp/core/designsystem/checkbox/DmsCheckbox.kt
🔇 Additional comments (1)
feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/EnterStudentNumberScreen.kt (1)

37-42: 단위 테스트 추가 권장

다음 테스트 케이스들의 추가를 권장드립니다:

  1. 입력값 유효성 검증
  2. 네비게이션 로직
  3. 상태 관리
  4. 사이드 이펙트 처리

예시 테스트 코드를 생성해드릴까요?

Comment on lines +51 to +55
signUpData.copy(
grade = 1,
classRoom = 1,
number = 1,
),
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

하드코딩된 값을 실제 입력값으로 교체해주세요

현재 SignUpData를 복사할 때 grade, classRoom, number가 모두 1로 하드코딩되어 있습니다. 이는 사용자가 입력한 실제 값과 일치하지 않을 수 있습니다.

signUpData.copy(
-   grade = 1,
-   classRoom = 1,
-   number = 1,
+   grade = state.grade.toIntOrNull() ?: 0,
+   classRoom = state.classroom.toIntOrNull() ?: 0,
+   number = state.number.toIntOrNull() ?: 0,
)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
signUpData.copy(
grade = 1,
classRoom = 1,
number = 1,
),
signUpData.copy(
grade = state.grade.toIntOrNull() ?: 0,
classRoom = state.classroom.toIntOrNull() ?: 0,
number = state.number.toIntOrNull() ?: 0,
),

Comment on lines +141 to +171
DmsTextField(
modifier = Modifier.weight(1f),
value = grade,
onValueChange = { grade ->
onGradeChange(grade)
if (grade.isNotEmpty()) classroomFocusRequest.requestFocus()
},
hint = "학년",
keyboardType = KeyboardType.Number,
)
DmsTextField(
modifier = Modifier
.weight(1f)
.focusRequester(classroomFocusRequest),
value = classroom,
onValueChange = { classroom ->
onClassroomChange(classroom)
if (classroom.isNotEmpty()) numberFocusRequest.requestFocus()
},
hint = "반",
keyboardType = KeyboardType.Number,
)
DmsTextField(
modifier = Modifier
.weight(1f)
.focusRequester(numberFocusRequest),
value = number,
onValueChange = onNumberChange,
hint = "번호",
keyboardType = KeyboardType.Number,
)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

입력값 유효성 검사 및 에러 처리 추가 필요

현재 구현에서 다음과 같은 보완이 필요합니다:

  1. 숫자 입력 제한
  2. 최대 길이 제한
  3. 에러 상태 처리
DmsTextField(
    modifier = Modifier.weight(1f),
    value = grade,
    onValueChange = { grade ->
+       if (grade.length <= 1 && grade.all { it.isDigit() }) {
            onGradeChange(grade)
            if (grade.isNotEmpty()) classroomFocusRequest.requestFocus()
+       }
    },
    hint = "학년",
    keyboardType = KeyboardType.Number,
+   isError = grade.isNotEmpty() && (grade.toIntOrNull() ?: 0) !in 1..3,
+   errorMessage = "1~3 사이의 숫자를 입력해주세요",
)

비슷한 방식으로 반과 번호 입력 필드에도 적절한 유효성 검사를 추가해주세요.

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

@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: 3

🧹 Nitpick comments (3)
feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterStudentNumberViewModel.kt (2)

5-6: 클래스 문서화 추가 필요

ViewModel의 목적과 책임을 명확히 하기 위해 KDoc 문서화를 추가하는 것이 좋습니다.

다음과 같이 문서화를 추가해보세요:

+/**
+ * 학생 번호 입력 화면의 상태를 관리하는 ViewModel
+ *
+ * @property state 학생 번호 입력 화면의 상태
+ */
internal class EnterStudentNumberViewModel :
    BaseViewModel<EnterStudentNumberState, EnterStudentNumberSideEffect>(EnterStudentNumberState.getDefaultState()) {

42-56: 상태 클래스 개선 필요

상태 클래스에 입력값 제한사항과 문서화가 필요합니다.

다음과 같이 개선해보세요:

+/**
+ * 학생 번호 입력 화면의 상태를 나타내는 데이터 클래스
+ *
+ * @property grade 학년 (1-3)
+ * @property classroom 반 (1-20)
+ * @property number 번호 (1-50)
+ * @property buttonEnabled 다음 버튼 활성화 여부
+ */
data class EnterStudentNumberState(
    val grade: String,
    val classroom: String,
    val number: String,
    val buttonEnabled: Boolean,
) {
    companion object {
+        private const val EMPTY_STRING = ""
+
        fun getDefaultState() = EnterStudentNumberState(
-            grade = "",
-            classroom = "",
-            number = "",
+            grade = EMPTY_STRING,
+            classroom = EMPTY_STRING,
+            number = EMPTY_STRING,
            buttonEnabled = false,
        )
    }
}
feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterEmailVerificationCodeViewModel.kt (1)

40-40: 상태 초기화 로직 검토 필요

timerFinished 상태가 추가되었습니다. 다음 사항들을 고려해주세요:

  1. 타이머 초기화가 필요한 시점 (예: 화면 재진입)
  2. 상태 저장 필요성 (예: 프로세스 종료 후 재시작)

상태 변경에 대한 로깅을 추가하는 것이 디버깅에 도움이 될 것 같습니다:

    internal fun setTimerFinished(timerFinished: Boolean) {
+       println("Timer finished state changed to: $timerFinished")
        setState {
            state.value.copy(
                timerFinished = timerFinished,
            )
        }
    }

Also applies to: 46-46

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e5b0c30 and 883cfed.

📒 Files selected for processing (3)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/SetPasswordScreen.kt (3 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterEmailVerificationCodeViewModel.kt (2 hunks)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterStudentNumberViewModel.kt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/ui/SetPasswordScreen.kt
🔇 Additional comments (5)
feature/signup/src/commonMain/kotlin/team/aliens/dms/kmp/feature/signup/viewmodel/EnterEmailVerificationCodeViewModel.kt (5)

4-4: 하드코딩된 값을 상수로 대체한 것이 좋습니다!

매직 넘버를 제거하고 EMAIL_VERIFICATION_CODE_LENGTH 상수를 사용한 것이 코드의 유지보수성을 향상시켰습니다.


20-26: 타이머 완료 상태 관리 로직 검토 필요

타이머 완료 상태를 관리하는 새로운 기능이 추가되었습니다만, 몇 가지 고려사항이 있습니다:

  1. 타이머가 완료되었을 때 사용자에게 어떤 피드백을 제공하는지
  2. 타이머 완료 후 재시도 기능이 필요한지
  3. 타이머 완료 상태가 이메일 인증 코드 입력에 어떤 영향을 미치는지

타이머 완료 후의 UX 플로우를 검증해주시기 바랍니다.


30-30: 이메일 인증 코드 길이 검증 로직이 개선되었습니다!

하드코딩된 숫자 대신 EMAIL_VERIFICATION_CODE_LENGTH 상수를 사용하여 버튼 활성화 조건을 검증하는 것이 좋습니다.


53-53: 사이드 이펙트 이름 변경이 적절합니다

MoveToEnterStudentNumber로의 이름 변경이 새로운 회원가입 플로우를 더 명확하게 표현합니다.


34-34: 네비게이션 플로우 변경 사항 확인 필요

MoveToSetId에서 MoveToEnterStudentNumber로 변경된 것은 회원가입 플로우의 변경을 의미합니다. 다음 사항들을 확인해주세요:

  1. 새로운 학생 번호 입력 화면이 구현되어 있는지
  2. 기존 ID 설정 단계가 제거되었는지
  3. 전체 회원가입 플로우가 올바르게 연결되어 있는지
✅ Verification successful

Let me gather more information about the signup flow implementation.


Let me check the student number screen implementation.


회원가입 플로우 변경 검증 완료

검증 결과, 회원가입 플로우가 올바르게 구현되어 있습니다:

  1. 학생 번호 입력 화면(EnterStudentNumberScreen)이 완전히 구현되어 있으며, 학년/반/번호를 입력받는 UI와 관련 로직이 구현되어 있습니다.
  2. 네비게이션 플로우가 다음과 같이 올바르게 연결되어 있습니다:
    • 이메일 인증 코드 → 학생 번호 입력 (MoveToEnterStudentNumber)
    • 학생 번호 입력 → ID 설정 (MoveToSetId)
  3. ID 설정 단계는 제거되지 않았으며, 학생 번호 입력 후 자연스럽게 연결됩니다.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 회원가입 관련 화면들의 연결 상태 확인
rg "MoveToEnterStudentNumber|MoveToSetId" --type kotlin

Length of output: 1174


Script:

#!/bin/bash
# Check if student number screen exists and its implementation
ast-grep --pattern 'class EnterStudentNumberScreen'

# Check the navigation flow in the screens
rg "NavGraph|navigation" --type kotlin -A 3

Length of output: 43021


Script:

#!/bin/bash
# Check the EnterStudentNumber screen implementation
fd "EnterStudentNumberScreen.kt" --type f --exec cat {}

# Check the signup flow sequence
rg "sealed class.*SideEffect" --type kotlin -A 5

Length of output: 6093


Script:

#!/bin/bash
# Check the signup flow sequence in SideEffect classes
rg "sealed class.*SideEffect|data class.*SideEffect" --type kotlin

# Check the navigation flow implementation
rg "NAVIGATION_.*STUDENT|NAVIGATION_.*ID" --type kotlin

Length of output: 1809

Comment on lines +31 to +39
internal fun onNextClick() {
postSideEffect(
EnterStudentNumberSideEffect.MoveToSetId(
grade = "",
classroom = "",
number = "",
),
)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

사용자 입력값 전달 오류

onNextClick에서 빈 문자열을 전달하고 있어 사용자가 입력한 정보가 손실됩니다.

다음과 같이 수정해주세요:

internal fun onNextClick() {
    postSideEffect(
        EnterStudentNumberSideEffect.MoveToSetId(
-            grade = "",
-            classroom = "",
-            number = "",
+            grade = state.value.grade,
+            classroom = state.value.classroom,
+            number = state.value.number,
        ),
    )
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
internal fun onNextClick() {
postSideEffect(
EnterStudentNumberSideEffect.MoveToSetId(
grade = "",
classroom = "",
number = "",
),
)
}
internal fun onNextClick() {
postSideEffect(
EnterStudentNumberSideEffect.MoveToSetId(
grade = state.value.grade,
classroom = state.value.classroom,
number = state.value.number,
),
)
}

Comment on lines +23 to +29
private fun buttonEnabled() = setState {
with(state.value) {
val isStudentNumberNotBlank =
grade.isNotBlank() && classroom.isNotBlank() && number.isNotBlank()
copy(buttonEnabled = isStudentNumberNotBlank)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

버튼 활성화 조건 강화 필요

현재는 단순히 빈 값이 아닌지만 확인하고 있습니다. 실제 입력값의 유효성도 검증해야 합니다.

다음과 같이 검증 로직을 강화해보세요:

private fun buttonEnabled() = setState {
    with(state.value) {
-        val isStudentNumberNotBlank =
-            grade.isNotBlank() && classroom.isNotBlank() && number.isNotBlank()
+        val isValidGrade = grade.isNotBlank() && grade.toIntOrNull() in 1..3
+        val isValidClassroom = classroom.isNotBlank() && classroom.toIntOrNull() in 1..20
+        val isValidNumber = number.isNotBlank() && number.toIntOrNull() in 1..50
+        val isStudentNumberValid = isValidGrade && isValidClassroom && isValidNumber
-        copy(buttonEnabled = isStudentNumberNotBlank)
+        copy(buttonEnabled = isStudentNumberValid)
    }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private fun buttonEnabled() = setState {
with(state.value) {
val isStudentNumberNotBlank =
grade.isNotBlank() && classroom.isNotBlank() && number.isNotBlank()
copy(buttonEnabled = isStudentNumberNotBlank)
}
}
private fun buttonEnabled() = setState {
with(state.value) {
val isValidGrade = grade.isNotBlank() && grade.toIntOrNull() in 1..3
val isValidClassroom = classroom.isNotBlank() && classroom.toIntOrNull() in 1..20
val isValidNumber = number.isNotBlank() && number.toIntOrNull() in 1..50
val isStudentNumberValid = isValidGrade && isValidClassroom && isValidNumber
copy(buttonEnabled = isStudentNumberValid)
}
}

Comment on lines +8 to +21
internal fun setGrade(grade: String) {
setState { state.value.copy(grade = grade) }
buttonEnabled()
}

internal fun setClassRoom(classroom: String) {
setState { state.value.copy(classroom = classroom) }
buttonEnabled()
}

internal fun setNumber(number: String) {
setState { state.value.copy(number = number) }
buttonEnabled()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

입력값 검증 로직 추가 필요

학년, 반, 번호에 대한 유효성 검사가 누락되어 있습니다. 각 필드에 대한 적절한 제한이 필요합니다.

다음과 같은 검증 로직을 추가해보세요:

internal fun setGrade(grade: String) {
+    if (grade.length > 1 || !grade.all { it.isDigit() }) {
+        return
+    }
    setState { state.value.copy(grade = grade) }
    buttonEnabled()
}

internal fun setClassRoom(classroom: String) {
+    if (classroom.length > 2 || !classroom.all { it.isDigit() }) {
+        return
+    }
    setState { state.value.copy(classroom = classroom) }
    buttonEnabled()
}

internal fun setNumber(number: String) {
+    if (number.length > 2 || !number.all { it.isDigit() }) {
+        return
+    }
    setState { state.value.copy(number = number) }
    buttonEnabled()
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
internal fun setGrade(grade: String) {
setState { state.value.copy(grade = grade) }
buttonEnabled()
}
internal fun setClassRoom(classroom: String) {
setState { state.value.copy(classroom = classroom) }
buttonEnabled()
}
internal fun setNumber(number: String) {
setState { state.value.copy(number = number) }
buttonEnabled()
}
internal fun setGrade(grade: String) {
if (grade.length > 1 || !grade.all { it.isDigit() }) {
return
}
setState { state.value.copy(grade = grade) }
buttonEnabled()
}
internal fun setClassRoom(classroom: String) {
if (classroom.length > 2 || !classroom.all { it.isDigit() }) {
return
}
setState { state.value.copy(classroom = classroom) }
buttonEnabled()
}
internal fun setNumber(number: String) {
if (number.length > 2 || !number.all { it.isDigit() }) {
return
}
setState { state.value.copy(number = number) }
buttonEnabled()
}

@parkuiery parkuiery merged commit eeaeb69 into develop Jan 3, 2025
2 of 5 checks passed
@parkuiery parkuiery deleted the feature/95-feat-회원가입-퍼블리싱 branch January 3, 2025 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat 새로운 기능을 추가 할 경우 refactor 코드 리팩토링 할 경우
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

[Feat]: 회원가입 퍼블리싱
1 participant