Skip to content

♻️ Refactor setup route into FSD structure#55

Merged
nbsp1221 merged 2 commits intomainfrom
refactor/setup-fsd
Oct 2, 2025
Merged

♻️ Refactor setup route into FSD structure#55
nbsp1221 merged 2 commits intomainfrom
refactor/setup-fsd

Conversation

@nbsp1221
Copy link
Owner

@nbsp1221 nbsp1221 commented Oct 1, 2025

Summary

Refactored the Setup page from a monolithic 195-line component to Feature-Sliced Design (FSD) architecture, completing FSD migration for all user-facing pages (7/7).

Changes

  • Business Logic: Extracted to useSetupView hook (123 lines)

    • State management (8 states)
    • Input validation logic
    • API communication and error handling
    • Authentication and redirect flow
  • Presentation: Created SetupView component (159 lines)

    • Pure UI component with props-based interface
    • Accessibility improvements (aria-label, title attributes)
    • Password visibility toggle functionality
  • Composition: Added SetupPage layer (12 lines)

    • Connects hook and widget
  • Route: Refactored routes/setup.tsx (195→11 lines, -94%)

    • Thin controller pattern
    • Delegates to SetupPage component

Code Metrics

Metric Before After Improvement
Total Files 1 4 +3 (layer separation)
Route File Size 195 lines 11 lines -94%
Average File Size 195 lines 76 lines -61%
Reusability None Hook reusable
Testability Difficult Easy

Quality Verification

  • lint:fix: Passed (0 new errors)
  • typecheck: Passed (0 type errors)
  • test: Passed (431 tests)
  • build: Passed (production build successful)

E2E Testing (Playwright)

  • ✅ Setup page rendering
  • ✅ Form interactions (input, button clicks)
  • ✅ Password visibility toggle
  • ✅ API communication
  • ✅ Error handling
  • ✅ Authentication flow
  • ✅ Navigation and redirect

FSD Migration Status

7/7 pages completed (100%)

Breaking Changes

None. Maintains 100% feature parity with original implementation.

Summary by CodeRabbit

  • New Features
    • Added a dedicated Setup page for creating the initial admin account.
    • Form with email, password, and confirm-password fields plus client-side validation.
    • Password visibility toggles and helpful labels/helper text.
    • Shows clear error messages and disables inputs while submitting.
    • Redirects to the home page on successful setup; polished, accessible UI components.

- Extract business logic to useSetupView hook (123 lines)
- Create SetupView presentation component (159 lines)
- Add SetupPage composition layer (12 lines)
- Refactor routes/setup.tsx to thin route (195→11 lines)
- Add accessibility attributes (aria-label, title)
- Maintain 100% feature parity with original implementation

This completes FSD migration for all user-facing pages (7/7).
@coderabbitai
Copy link

coderabbitai bot commented Oct 1, 2025

Walkthrough

Adds a new Setup page composed of a presentation component (SetupView) and a logic hook (useSetupView), wired through a SetupPage container. The route export is adjusted to a typed meta constant and a default SetupRoute that renders SetupPage. The hook handles validation, POST /api/auth/setup, user state update, and navigation.

Changes

Cohort / File(s) Summary
Route integration
app/routes/setup.tsx
Replaces inline route component with SetupRoute that returns <SetupPage />; replaces meta() function with typed export const meta: MetaFunction = () => [...].
Page container
app/pages/setup/ui/SetupPage.tsx
Adds SetupPage component that calls useSetupView() and passes its returned props into SetupView via spread.
Setup view model (hook)
app/widgets/setup-view/model/useSetupView.ts
Adds useSetupView and UseSetupViewReturn. Manages email/password/confirm state, visibility toggles, loading/error, validation (required, email format, min password length, match), POSTs to /api/auth/setup, updates global user state on success, and navigates to home.
Setup view UI (presentation)
app/widgets/setup-view/ui/SetupView.tsx
Adds SetupView and SetupViewProps. Pure presentation form with email, password, confirm password, visibility toggles, disabled state when loading, error alert display, and submit button.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor U as User
    participant R as SetupRoute
    participant P as SetupPage
    participant H as useSetupView
    participant V as SetupView
    participant API as /api/auth/setup
    participant GS as GlobalUserState
    participant Nav as Navigation

    U->>R: Navigate /setup
    R->>P: Render SetupPage
    P->>H: Initialize hook (state & handlers)
    P->>V: Render SetupView with hook props

    U->>V: Enter data & submit
    V->>H: onSubmit()
    H->>H: Validate inputs
    alt valid
        H->>API: POST {email,password}
        API-->>H: 200 OK / error
        alt success
            H->>GS: Update user state
            H->>Nav: Redirect to home
        else failure
            H->>H: Set error message, stop loading
        end
    else invalid
        H->>H: Set validation error
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

I hop to the setup, whiskers twitch with glee,
A form of tiny carrots—email, pass, and key.
Toggles blink like fireflies, secrets softly hide,
I post to the burrow, then slip to the other side.
Homebound with a thump — new warren, open wide. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly states the main change—refactoring the setup route into a Feature-Sliced Design structure—which matches the refactoring and decomposition described in the PR. It is concise, specific, and gives a teammate scanning the history a clear understanding of the primary change.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/setup-fsd

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1db1d88 and e448d8b.

📒 Files selected for processing (1)
  • app/widgets/setup-view/model/useSetupView.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: TypeScript에서 any를 사용하지 않고 모든 함수에 포괄적인 타입 힌트를 제공한다 (strict TS)
로그에 비밀값을 남기지 않도록 모든 콘솔 출력은 민감정보를 마스킹/제거한다

**/*.{ts,tsx}: Use the ~/* path alias (from tsconfig.json) for internal imports
Prefer explicit interfaces when defining object shapes in TypeScript (strict mode)
Avoid using any in TypeScript (project runs in strict mode)
Use two-space indentation throughout TypeScript/TSX files
Name components, hooks, and providers with PascalCase
Name helpers and state setters with camelCase
File names should mirror their primary export

Files:

  • app/widgets/setup-view/model/useSetupView.ts
**/*.{ts,tsx,md,mdx}

📄 CodeRabbit inference engine (CLAUDE.md)

코드 주석과 문서는 영어로 작성한다

Files:

  • app/widgets/setup-view/model/useSetupView.ts
app/**

📄 CodeRabbit inference engine (AGENTS.md)

Place all React Router app source under app/ following the repository’s feature-sliced layout

Files:

  • app/widgets/setup-view/model/useSetupView.ts
app/widgets/**

📄 CodeRabbit inference engine (AGENTS.md)

Put UI compositions in app/widgets/

Files:

  • app/widgets/setup-view/model/useSetupView.ts
🧬 Code graph analysis (1)
app/widgets/setup-view/model/useSetupView.ts (1)
app/stores/auth-store.ts (1)
  • useAuthStore (18-98)
🔇 Additional comments (1)
app/widgets/setup-view/model/useSetupView.ts (1)

19-19: Async contract alignment looks good.

Thanks for updating onSubmit to return Promise<void>—this matches the async handler and clears the mismatch flagged earlier.


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

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc6d969 and 1db1d88.

📒 Files selected for processing (4)
  • app/pages/setup/ui/SetupPage.tsx (1 hunks)
  • app/routes/setup.tsx (1 hunks)
  • app/widgets/setup-view/model/useSetupView.ts (1 hunks)
  • app/widgets/setup-view/ui/SetupView.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: TypeScript에서 any를 사용하지 않고 모든 함수에 포괄적인 타입 힌트를 제공한다 (strict TS)
로그에 비밀값을 남기지 않도록 모든 콘솔 출력은 민감정보를 마스킹/제거한다

**/*.{ts,tsx}: Use the ~/* path alias (from tsconfig.json) for internal imports
Prefer explicit interfaces when defining object shapes in TypeScript (strict mode)
Avoid using any in TypeScript (project runs in strict mode)
Use two-space indentation throughout TypeScript/TSX files
Name components, hooks, and providers with PascalCase
Name helpers and state setters with camelCase
File names should mirror their primary export

Files:

  • app/widgets/setup-view/model/useSetupView.ts
  • app/widgets/setup-view/ui/SetupView.tsx
  • app/pages/setup/ui/SetupPage.tsx
  • app/routes/setup.tsx
**/*.{ts,tsx,md,mdx}

📄 CodeRabbit inference engine (CLAUDE.md)

코드 주석과 문서는 영어로 작성한다

Files:

  • app/widgets/setup-view/model/useSetupView.ts
  • app/widgets/setup-view/ui/SetupView.tsx
  • app/pages/setup/ui/SetupPage.tsx
  • app/routes/setup.tsx
app/**

📄 CodeRabbit inference engine (AGENTS.md)

Place all React Router app source under app/ following the repository’s feature-sliced layout

Files:

  • app/widgets/setup-view/model/useSetupView.ts
  • app/widgets/setup-view/ui/SetupView.tsx
  • app/pages/setup/ui/SetupPage.tsx
  • app/routes/setup.tsx
app/widgets/**

📄 CodeRabbit inference engine (AGENTS.md)

Put UI compositions in app/widgets/

Files:

  • app/widgets/setup-view/model/useSetupView.ts
  • app/widgets/setup-view/ui/SetupView.tsx
**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Split multiline JSX props across lines per Stylistic ESLint rules

Files:

  • app/widgets/setup-view/ui/SetupView.tsx
  • app/pages/setup/ui/SetupPage.tsx
  • app/routes/setup.tsx
app/pages/**

📄 CodeRabbit inference engine (AGENTS.md)

app/pages/**: Keep route shells in app/pages/ (pages expose route shells only)
Keep routes thin in app/pages/ (delegate business logic to modules/hooks)

Files:

  • app/pages/setup/ui/SetupPage.tsx
🧬 Code graph analysis (3)
app/widgets/setup-view/model/useSetupView.ts (1)
app/stores/auth-store.ts (1)
  • useAuthStore (18-98)
app/pages/setup/ui/SetupPage.tsx (2)
app/widgets/setup-view/model/useSetupView.ts (1)
  • useSetupView (26-123)
app/widgets/setup-view/ui/SetupView.tsx (1)
  • SetupView (29-159)
app/routes/setup.tsx (4)
app/routes/login.tsx (1)
  • meta (4-7)
app/routes/add-videos.tsx (1)
  • meta (10-13)
app/routes/player.$id.tsx (1)
  • meta (63-75)
app/pages/setup/ui/SetupPage.tsx (1)
  • SetupPage (8-12)
🔇 Additional comments (7)
app/widgets/setup-view/ui/SetupView.tsx (7)

1-7: LGTM!

Imports are clean, follow the ~/* path alias convention, and include all necessary dependencies.


9-23: LGTM!

The interface is comprehensive and follows strict TypeScript guidelines with explicit types for all props. The controlled component pattern is well-supported.


25-43: LGTM!

Component declaration is clean with clear JSDoc documentation in English. Props destructuring matches the interface exactly.


68-80: LGTM!

Email field has proper label association, controlled input pattern, and good accessibility attributes (type="email", autoComplete, required).


82-112: LGTM!

Password field with visibility toggle is well-implemented with excellent accessibility: aria-label, title attributes, proper button type, and correct autoComplete="new-password" for new account creation.


114-144: LGTM!

Confirm password field mirrors the password field structure with separate state and handlers. Accessibility attributes correctly differentiate the context ("Hide confirm password" vs "Hide password").


44-66: LGTM!

Form structure is well-organized with proper error display, loading states, and informative footer text. Submit button correctly uses type="submit" and provides loading feedback. The separation of concerns is maintained—validation logic belongs in the hook.

Also applies to: 146-158

- Update UseSetupViewReturn.onSubmit type from void to Promise<void>
- Align interface with async handleSubmit implementation
- Resolve CodeRabbit type safety feedback

Refs: PR #55 CodeRabbit review
@nbsp1221 nbsp1221 merged commit 57b5e68 into main Oct 2, 2025
5 checks passed
@nbsp1221 nbsp1221 deleted the refactor/setup-fsd branch October 2, 2025 08:34
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.

1 participant

Comments