Skip to content

[REFACTOR] 온보딩 페이지 리팩토링#35

Merged
KOJ50 merged 10 commits into
mainfrom
feature/#33-onboarding-refactor
Jun 19, 2026
Merged

[REFACTOR] 온보딩 페이지 리팩토링#35
KOJ50 merged 10 commits into
mainfrom
feature/#33-onboarding-refactor

Conversation

@KOJ50

@KOJ50 KOJ50 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

📢 PR 유형

어떤 변경 사항이 있었나요?

  • 새로운 기능 추가
  • 버그 수정
  • 코드에 영향을 주지 않는 변경사항(오타 수정, 탭 사이즈 변경, 변수명 변경)
  • 코드 리팩토링
  • 주석 추가 및 수정
  • 문서 수정
  • 빌드 부분 혹은 패키지 매니저 수정
  • 파일 혹은 폴더명 수정
  • 파일 혹은 폴더 삭제

📌 관련 이슈번호


✅ Key Changes

회원가입 파일 구조 수정

기존 app/signup/page.tsx
-> features/signup/ui/UserTypeStep.tsx 로 이동

기존 app/signup/instructor/step1/page.tsx
기존 app/signup/designer/step1/page.tsx
-> features/signup/ui/TermsProfileStep.tsx 로 통합

기존 step2 page들
-> features/signup/ui/AccountStep.tsx 로 통합

기존 app/signup/designer/step3/page.tsx
-> features/signup/ui/DesignerAdditionalStep.tsx 로 이동

전체 step 조립
-> widgets/signup/ui/SignupFunnel.tsx

라우트 진입
-> app/signup/page.tsx
  • 단일 URL를 사용하는 퍼널 구조로 정리

유저 유형에 따른 URL 접근 제한 및 헤더 적용

  • src/proxy.ts 추가 및 유저 유형 기반 페이지 접근 제한 구조 구성
  • 비로그인 사용자 - /designer, /instructor 하위 페이지에 직접 접근 시, /login으로 redirect
  • designer 사용자의 /instructor 접근과 instructor 사용자의 /designer 접근 제한
  • accessToken과 유효한 userRole이 모두 있을 때만 “내 계정” 표시
  • 로그인 전 상태에서는 헤더에 "로그인 / 회원가입"으로 각 링크 연결
  • 헤더의 “내 계정” 링크를 유저 유형별 경로 연결
  • 강사 - /instructor/my, 디자이너 - 임시로 /designer 연결

단계별 인디케이터 이미지 제거 및 컴포넌트화

  • 회원가입 단계 표시를 정적 SVG에서 SignupProgressIcon 컴포넌트로 전환
  • FSD 구조에 맞춰 features/signup/ui에 배치
  • currentStep/totalSteps 기반으로 디자이너 3단계, 강사 2단계 플로우를 재사용 가능하게 구성했습니다.
  • 연결선 스타일을 피그마 스펙을 통해 구현
  • 미사용 단계 SVG 파일 및 export 삭제

📸 스크린샷 or 실행영상

2026-06-19.02.12.06.mov

🎸 기타 사항 or 추가 코멘트

  • 유저 유형에 따른 페이지 접근 제한 구조는 API 연동을 진행하며 수정될 예정입니다.

Summary by CodeRabbit

Release Notes

  • New Features

    • 회원가입 흐름을 체계적인 퍼널 구조로 개편하여 더욱 직관적인 가입 프로세스 제공
    • 역할별(디자이너/강사) 맞춤형 회원가입 단계 설정
    • 회원가입 진행 상황을 시각적으로 표시하는 진행률 UI 추가
    • 역할 기반 자동 라우팅으로 인증 보안 강화
  • Refactor

    • 헤더의 쿠키 기반 인증 상태 동기화 기능 개선

@KOJ50 KOJ50 self-assigned this Jun 18, 2026
@KOJ50 KOJ50 added ♻️ Refactor 코드 리팩토링 🍀 오진 labels Jun 18, 2026
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

라우트 기반 단계별 signup 페이지를 제거하고, SignupFunnel 위젯 중심의 컴포넌트 퍼널 구조로 전환합니다. Step 컴포넌트들은 내부 useRouter를 제거하고 props 기반 네비게이션으로 교체되며, SignupProgressIconUserTypeStep이 신규 추가됩니다. proxy.ts에 역할 기반 접근 제어 미들웨어가 추가되고, Header는 쿠키 기반 인증 상태 동기화를 갖추도록 변경됩니다.

Changes

회원가입 퍼널 리팩토링

Layer / File(s) Summary
퍼널 타입 정의, 단계 설정 상수, 아이콘 교체
src/features/signup/model/signup.ts, src/features/signup/config/signupFunnel.ts, src/shared/assets/icons/index.ts, src/features/signup/index.ts
SignupRole, SignupFunnelStep, SignupRoleStep 타입과 SIGNUP_INITIAL_STEP/SIGNUP_STEPS_BY_ROLE 상수를 추가합니다. Step* 아이콘 5종을 제거하고 UserType* 아이콘 2종을 추가하며, features/signup 배럴 파일을 확장합니다.
Step UI 컴포넌트 props 기반 전환
src/features/signup/ui/SignupProgressIcon.tsx, src/features/signup/ui/UserTypeStep.tsx, src/features/signup/ui/TermsProfileStep.tsx, src/features/signup/ui/AccountStep.tsx, src/features/signup/ui/DesignerAdditionalStep.tsx
SignupProgressIconUserTypeStep을 신규 추가합니다. AccountStep/TermsProfileStep/DesignerAdditionalStep의 내부 useRouter 라우팅과 하드코딩된 아이콘을 제거하고, progressIcon/onPrev/onNext/onSubmit props 기반으로 전환합니다.
SignupFunnel 위젯 조합 및 단계 상태 관리
src/widgets/signup/ui/SignupFunnel.tsx, src/widgets/signup/index.ts, src/app/signup/page.tsx
SignupFunnelselectedRole/currentStep 상태를 관리하며 SIGNUP_STEPS_BY_ROLE 인덱스 기반으로 이전/다음 이동을 처리합니다. 역할과 단계 조합에 따라 Step 컴포넌트를 조건부 렌더링하고 마지막 단계 완료 시 /login으로 라우팅합니다. /signup 페이지를 SignupFunnel 단일 렌더링으로 교체합니다.
기존 라우트 기반 페이지 삭제
src/app/signup/designer/step2/page.tsx, src/app/signup/instructor/step1/page.tsx
useRouter 기반 단계 네비게이션 로직을 포함한 기존 라우트 페이지 구현 전체를 삭제합니다.

역할 기반 접근 제어 미들웨어 및 Header 인증 상태

Layer / File(s) Summary
proxy.ts 역할 검증 미들웨어
src/proxy.ts
UserRole 타입, ROLE_HOME_PATH 매핑, normalizeRole/parseJwtPayload/getUserRole/getRequiredRole 헬퍼를 정의합니다. proxy 미들웨어에서 accessToken 쿠키 유무와 역할 일치 여부에 따라 /login 또는 역할별 홈으로 리다이렉트하며, /designer/:path*, /instructor/:path*에 적용됩니다.
Header 쿠키 기반 인증 상태 동기화
src/shared/ui/Header.tsx
accessToken/userRole 쿠키를 읽어 authState를 설정하는 useEffectfocus 이벤트 재동기화, 역할별 accountHref를 계산하는 useMemo를 추가합니다. 로그인 시 내 계정 영역을 Link 컴포넌트로 렌더링하도록 변경합니다.

Sequence Diagram(s)

sequenceDiagram
  participant 사용자
  participant SignupFunnel
  participant StepComponents
  participant proxy

  사용자->>SignupFunnel: /signup 진입
  SignupFunnel->>StepComponents: UserTypeStep 렌더링
  사용자->>StepComponents: 역할 선택 후 다음 클릭
  StepComponents->>SignupFunnel: onNext(selectedRole)
  SignupFunnel->>StepComponents: TermsProfileStep 렌더링 (progressIcon, terms, onPrev/onNext)
  사용자->>StepComponents: 약관 동의 후 다음 클릭
  StepComponents->>SignupFunnel: onNext()
  SignupFunnel->>StepComponents: AccountStep 렌더링
  사용자->>StepComponents: 계정 입력 후 다음 클릭
  StepComponents->>SignupFunnel: onNext()
  Note over SignupFunnel: designer인 경우 DesignerAdditionalStep 렌더링
  SignupFunnel->>사용자: /login 라우팅 (완료)

  사용자->>proxy: /designer/* 또는 /instructor/* 접근
  proxy->>proxy: accessToken 쿠키 확인
  proxy->>proxy: parseJwtPayload → getUserRole
  proxy->>사용자: 역할 불일치 시 /login 또는 ROLE_HOME_PATH 리다이렉트
  proxy->>사용자: 역할 일치 시 NextResponse.next()
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • Ditda-Official/Ditda-Frontend#22: 본 PR이 대체하는 src/app/signup/** 단계별 라우트 페이지와 useSignupStep2Form 기반 구현이 원래 추가된 PR입니다.
  • Ditda-Official/Ditda-Frontend#26: src/shared/assets/icons/index.tssrc/features/signup/index.ts 배럴 파일을 공통으로 수정하는 signup 관련 변경이 포함된 PR입니다.

Suggested labels

❄️ 유민

Suggested reviewers

  • waldls
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 온보딩 페이지 리팩토링이라는 주요 변경 사항을 명확하게 요약하고 있으며, 변경 사항의 핵심 의도를 잘 나타냅니다.
Linked Issues check ✅ Passed PR은 이슈 #33의 모든 네 가지 주요 목표를 충족합니다: 파일 구조 재정렬, URL 접근 제한(proxy.ts), 헤더 연결, 단계 인디케이터 컴포넌트화가 모두 구현되었습니다.
Out of Scope Changes check ✅ Passed 모든 변경 사항이 온보딩 리팩토링 범위 내이며, 이슈 #33에 정의된 목표와 직접 관련이 있습니다. 범위 외의 변경은 발견되지 않았습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/#33-onboarding-refactor

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 (3)
src/proxy.ts (1)

4-4: ⚡ Quick win

UserRole 타입과 normalizeRole 함수가 Header.tsx와 중복됩니다.

동일한 코드가 src/shared/ui/Header.tsx에도 존재합니다. 공유 위치(예: src/shared/model/auth.ts)로 추출하여 일관성을 유지하고 향후 변경 시 동기화 문제를 방지하세요.

Also applies to: 14-22

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/proxy.ts` at line 4, The UserRole type definition and normalizeRole
function are duplicated between src/proxy.ts (lines 4-22) and
src/shared/ui/Header.tsx. Extract both the UserRole type and normalizeRole
function to a new shared module at src/shared/model/auth.ts, then update the
import statements in both src/proxy.ts and Header.tsx to import these shared
definitions instead of maintaining duplicate definitions. This ensures
consistency across the codebase and prevents synchronization issues when these
definitions need to be updated in the future.
src/shared/ui/Header.tsx (1)

9-14: ⚡ Quick win

UserRole 타입과 normalizeRole 함수가 proxy.ts와 중복됩니다.

src/proxy.ts에 동일한 코드가 있습니다. 공유 모듈로 추출하여 중복을 제거하세요.

// src/shared/model/auth.ts
export type UserRole = "designer" | "instructor";

export const normalizeRole = (role?: string): UserRole | null => {
  const normalizedRole = role?.toLowerCase();
  if (normalizedRole === "designer" || normalizedRole === "instructor") {
    return normalizedRole;
  }
  return null;
};

Also applies to: 34-42

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/ui/Header.tsx` around lines 9 - 14, The UserRole type and
normalizeRole function are duplicated across Header.tsx and proxy.ts, which
violates the DRY principle. Create a new shared module file to centralize these
definitions, then move the UserRole type definition and the normalizeRole
function implementation to this shared module and export both from there.
Finally, update the import statements in both Header.tsx and proxy.ts to import
UserRole and normalizeRole from the new shared module instead of defining them
locally.
src/app/signup/page.tsx (1)

3-7: ⚡ Quick win

서버 페이지 컴포넌트 명을 소문자 page로 맞춰주세요.

현재 선언은 동작에는 문제없지만, 이 저장소의 페이지 네이밍 규칙과 다릅니다.

🔧 제안 수정
-const Page = () => {
+const page = () => {
   return <SignupFunnel />;
 };
 
-export default Page;
+export default page;

As per coding guidelines, "use client" 지시어가 없는 페이지: 소문자 page로 선언해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/signup/page.tsx` around lines 3 - 7, The component declaration uses
uppercase `Page` but according to the repository's naming conventions, server
page components without a "use client" directive should be declared with
lowercase `page`. Rename the const declaration from `Page` to `page` in the Page
component definition and update the export statement from `export default Page`
to `export default page` to align with the repository's coding guidelines.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/proxy.ts`:
- Around line 24-38: The parseJwtPayload function decodes the JWT payload
without verifying the JWT signature, creating a security vulnerability where
malicious users can forge JWTs with arbitrary role values to bypass access
control. Implement JWT signature verification in the parseJwtPayload function
using a library like jose to verify the token signature against your server's
secret or public key before parsing and returning the payload. This ensures that
only valid, server-signed tokens are trusted for role-based access control
decisions.
- Around line 63-92: Rename the file from proxy.ts to middleware.ts and change
the exported function name from proxy to middleware to comply with Next.js
middleware standards. Next.js only recognizes middleware files named
middleware.ts with a function named middleware, so the current naming convention
causes the middleware to be ignored by the routing system. Keep the config
object with the matcher array as-is when moving the code to the new
middleware.ts file.

---

Nitpick comments:
In `@src/app/signup/page.tsx`:
- Around line 3-7: The component declaration uses uppercase `Page` but according
to the repository's naming conventions, server page components without a "use
client" directive should be declared with lowercase `page`. Rename the const
declaration from `Page` to `page` in the Page component definition and update
the export statement from `export default Page` to `export default page` to
align with the repository's coding guidelines.

In `@src/proxy.ts`:
- Line 4: The UserRole type definition and normalizeRole function are duplicated
between src/proxy.ts (lines 4-22) and src/shared/ui/Header.tsx. Extract both the
UserRole type and normalizeRole function to a new shared module at
src/shared/model/auth.ts, then update the import statements in both src/proxy.ts
and Header.tsx to import these shared definitions instead of maintaining
duplicate definitions. This ensures consistency across the codebase and prevents
synchronization issues when these definitions need to be updated in the future.

In `@src/shared/ui/Header.tsx`:
- Around line 9-14: The UserRole type and normalizeRole function are duplicated
across Header.tsx and proxy.ts, which violates the DRY principle. Create a new
shared module file to centralize these definitions, then move the UserRole type
definition and the normalizeRole function implementation to this shared module
and export both from there. Finally, update the import statements in both
Header.tsx and proxy.ts to import UserRole and normalizeRole from the new shared
module instead of defining them locally.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c7629e85-c839-4211-88ba-dea24d234c3a

📥 Commits

Reviewing files that changed from the base of the PR and between c903851 and 8d351c6.

⛔ Files ignored due to path filters (5)
  • src/shared/assets/icons/icon_step_one_designer.svg is excluded by !**/*.svg
  • src/shared/assets/icons/icon_step_one_instructor.svg is excluded by !**/*.svg
  • src/shared/assets/icons/icon_step_three_designer.svg is excluded by !**/*.svg
  • src/shared/assets/icons/icon_step_two_designer.svg is excluded by !**/*.svg
  • src/shared/assets/icons/icon_step_two_instructor.svg is excluded by !**/*.svg
📒 Files selected for processing (16)
  • src/app/signup/designer/step2/page.tsx
  • src/app/signup/instructor/step1/page.tsx
  • src/app/signup/page.tsx
  • src/features/signup/config/signupFunnel.ts
  • src/features/signup/index.ts
  • src/features/signup/model/signup.ts
  • src/features/signup/ui/AccountStep.tsx
  • src/features/signup/ui/DesignerAdditionalStep.tsx
  • src/features/signup/ui/SignupProgressIcon.tsx
  • src/features/signup/ui/TermsProfileStep.tsx
  • src/features/signup/ui/UserTypeStep.tsx
  • src/proxy.ts
  • src/shared/assets/icons/index.ts
  • src/shared/ui/Header.tsx
  • src/widgets/signup/index.ts
  • src/widgets/signup/ui/SignupFunnel.tsx
💤 Files with no reviewable changes (3)
  • src/shared/assets/icons/index.ts
  • src/app/signup/designer/step2/page.tsx
  • src/app/signup/instructor/step1/page.tsx

Comment thread src/proxy.ts
Comment on lines +24 to +38
const parseJwtPayload = (token: string): Record<string, unknown> | null => {
const [, payload] = token.split(".");

if (payload == null) return null;

try {
const base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
const paddedBase64 = base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), "=");
const decodedPayload = atob(paddedBase64);

return JSON.parse(decodedPayload) as Record<string, unknown>;
} catch {
return null;
}
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

JWT 서명 검증 없이 페이로드를 파싱하고 있습니다.

parseJwtPayload는 JWT 서명을 검증하지 않고 페이로드만 디코딩합니다. 악의적인 사용자가 원하는 role 값을 가진 JWT를 위조하여 쿠키에 설정하면 접근 제어를 우회할 수 있습니다.

미들웨어에서 역할 기반 라우트 보호를 수행하려면 서버 측에서 JWT 서명 검증이 필요합니다. API 통합 시 백엔드에서 토큰 검증을 수행하거나, 미들웨어에서 jose 같은 라이브러리로 서명을 검증하는 것을 권장합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/proxy.ts` around lines 24 - 38, The parseJwtPayload function decodes the
JWT payload without verifying the JWT signature, creating a security
vulnerability where malicious users can forge JWTs with arbitrary role values to
bypass access control. Implement JWT signature verification in the
parseJwtPayload function using a library like jose to verify the token signature
against your server's secret or public key before parsing and returning the
payload. This ensures that only valid, server-signed tokens are trusted for
role-based access control decisions.

Comment thread src/proxy.ts
Comment on lines +63 to +92
export function proxy(request: NextRequest) {
const { pathname } = request.nextUrl;
const requiredRole = getRequiredRole(pathname);

if (requiredRole == null) {
return NextResponse.next();
}

const accessToken = request.cookies.get(ACCESS_TOKEN_COOKIE_NAME)?.value;

if (accessToken == null) {
return redirect("/login", request);
}

const userRole = getUserRole(request, accessToken);

if (userRole == null) {
return redirect("/login", request);
}

if (userRole !== requiredRole) {
return redirect(ROLE_HOME_PATH[userRole], request);
}

return NextResponse.next();
}

export const config = {
matcher: ["/designer/:path*", "/instructor/:path*"],
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if there's a middleware.ts file that imports proxy
fd -e ts -e js "middleware" --max-depth 3

# If middleware.ts exists, check its content
if [ -f "src/middleware.ts" ]; then
  cat src/middleware.ts
elif [ -f "middleware.ts" ]; then
  cat middleware.ts
fi

Repository: Ditda-Official/Ditda-Frontend

Length of output: 55


🏁 Script executed:

# Search for imports of proxy function
rg "import.*proxy|from.*proxy" --type ts --type js

# Check for any next.config files
fd -e js -e ts "next.config"

# Look for any middleware setup
rg "middleware" --type ts --type js -i

# Check the project structure
git ls-files | head -20

Repository: Ditda-Official/Ditda-Frontend

Length of output: 487


🏁 Script executed:

# More specific search for proxy imports
rg "from.*proxy|import.*proxy" --type ts --type js -i

# Search for any middleware references
rg "middleware" --type ts --type js

# Check the src directory structure
find src -type f -name "*.ts" -o -name "*.js" | head -20

# Check next.config.ts
cat next.config.ts

Repository: Ditda-Official/Ditda-Frontend

Length of output: 1190


🏁 Script executed:

# Look for all TypeScript files in src root
ls -la src/*.ts

# Check if proxy is exported as middleware or default export
cat src/proxy.ts

# Look for any references to src/proxy in entire codebase
rg "proxy" --type ts --type js

Repository: Ditda-Official/Ditda-Frontend

Length of output: 2717


src/proxy.ts 파일명과 함수명을 Next.js 미들웨어 표준에 맞춰 변경해야 합니다.

Next.js는 미들웨어 파일을 반드시 middleware.ts로 명명하고, 내보내는 함수를 middleware로 명명해야만 인식합니다. 현재 src/proxy.ts에서 proxy 함수를 내보내고 있어 Next.js 라우팅 시스템에서 완전히 무시되며 미들웨어가 실행되지 않습니다.

  • 파일명: src/proxy.tssrc/middleware.ts로 변경
  • 함수명: export function proxyexport function middleware로 변경
  • config 객체와 matchermiddleware.ts 파일에 유지
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/proxy.ts` around lines 63 - 92, Rename the file from proxy.ts to
middleware.ts and change the exported function name from proxy to middleware to
comply with Next.js middleware standards. Next.js only recognizes middleware
files named middleware.ts with a function named middleware, so the current
naming convention causes the middleware to be ignored by the routing system.
Keep the config object with the matcher array as-is when moving the code to the
new middleware.ts file.

@waldls waldls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

수고하셨습니당!!

@KOJ50 KOJ50 merged commit 9c4101c into main Jun 19, 2026
2 checks passed
@KOJ50 KOJ50 deleted the feature/#33-onboarding-refactor branch June 19, 2026 16:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REFACTOR] 온보딩 리팩토링

2 participants