Skip to content

setting: 폴더구조및 라우트 설정 #6

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

Merged
merged 2 commits into from
Feb 12, 2025
Merged

setting: 폴더구조및 라우트 설정 #6

merged 2 commits into from
Feb 12, 2025

Conversation

Han-wo
Copy link
Owner

@Han-wo Han-wo commented Feb 12, 2025

#️⃣ 이슈

📝 작업 내용

이번 PR에서 작업한 내용을 간략히 설명해주세요.

폴더구조 및 라우트 설정

📸 스크린샷

✅ 체크 리스트

  • 적절한 Title 작성
  • 적절한 Label 지정
  • Assignee 및 Reviewer 지정
  • 로컬 작동 확인
  • Merge 되는 브랜치 확인

👩‍💻 공유 포인트 및 논의 사항

Summary by CodeRabbit

  • 새로운 기능

    • PWA 경험 강화: 새로운 웹 앱 manifest 도입으로 홈 화면 추가 기능 및 오프라인 사용 지원.
    • 인증 보안 개선: 사용자 인증 처리가 강화되어 로그인 및 보호된 영역 접근이 개선되었습니다.
    • 실시간 업데이트: 실시간 데이터 반영을 위한 새로운 데이터베이스 지원이 추가되었습니다.
  • 개선 사항

    • UI 업데이트: "HobbyMate" 브랜드를 반영한 제목, 설명 및 새로운 폰트 적용으로 디자인이 개선되었습니다.
    • 아이콘 품질 향상: 개선된 벡터 이미지 처리 방식으로 아이콘 및 그래픽 표시가 더욱 깔끔해졌습니다.

@Han-wo Han-wo self-assigned this Feb 12, 2025
@Han-wo Han-wo linked an issue Feb 12, 2025 that may be closed by this pull request
Copy link

coderabbitai bot commented Feb 12, 2025

Walkthrough

이번 변경사항은 Next.js 설정 파일에서 API 리다이렉션 로직을 제거하고 webpack 설정을 추가하여 SVG 파일 처리 방식을 개선합니다. 또한, HobbyMate 애플리케이션의 매니페스트 파일이 추가되었으며, 여러 디렉토리에 빈 상태를 유지하기 위한 .gitkeep 파일들이 추가되었습니다. 추가적으로, 레이아웃 파일의 메타데이터가 업데이트되고, React Query를 위한 Providers 컴포넌트가 도입되었습니다. Firebase 설정에는 Realtime Database 지원이 포함되었고, 인증 미들웨어와 새로운 TypeScript 인터페이스들이 추가되었습니다.

Changes

파일 경로 변경 사항 요약
next.config.mjs 비동기 rewrites 함수 제거, webpack 함수 추가 (SVG 파일 처리 규칙 수정, topLevelAwait 활성화)
public/manifest.json HobbyMate 웹앱 매니페스트 추가 (앱 이름, 시작 URL, display, 배경 및 테마 색상 설정)
.../.gitkeep (여러 디렉토리) src/api, src/app/(auth)/login, src/app/(auth)/signup, src/app/(protect)/chat, src/app/(protect)/chat/[id], 등 빈 디렉토리 추적용 파일 추가
src/app/layout.tsx 메타데이터 업데이트 (타이틀, 설명, manifest 경로 추가), <body>className 적용, Providers 컴포넌트로 children 감싸기
src/components/provider/index.tsx React Query용 Providers 컴포넌트 추가 (QueryClient 초기화 및 QueryClientProvider 구현)
src/firebase/config.ts Firebase 설정 업데이트: databaseURL 추가, Firebase Realtime Database 인스턴스 rtdb 생성
src/middleware.ts 인증 미들웨어 추가: /protected 경로 미인증 시 /login으로, /auth 경로 인증 시 /로 리디렉션 처리, 라우트 매칭 설정 추가
src/types/index.ts 새로운 TypeScript 인터페이스 추가: User, Match, Group

Sequence Diagram(s)

sequenceDiagram
    participant Req as NextRequest
    participant MW as 미들웨어
    participant User as 사용자 세션

    Req->>MW: /protected 혹은 /auth 경로 요청
    alt 경로가 /protected && 미인증인 경우
        MW->>Req: /login으로 리디렉션
    else 경로가 /auth && 인증된 경우
        MW->>Req: /로 리디렉션
    else
        MW->>Req: 요청 승인 (NextResponse.next())
    end
Loading

Poem

달빛 아래 토끼 발자국이 춤추며
코드 숲 속 변화의 노래를 부릅니다 🐇
webpack의 리듬, 미들웨어의 선율
정갈한 매니페스트와 타입들이 어우러져
나의 귀여운 발걸음에 행복을 실어줍니다!

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

🪧 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

@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 (9)
src/firebase/config.ts (2)

31-31: 코드 가독성을 위한 주석 추가를 제안드립니다.

다른 Firebase 서비스 초기화와 마찬가지로, Realtime Database 초기화에 대한 설명 주석을 추가하면 좋을 것 같습니다.

-export const rtdb = getDatabase(app);
+export const rtdb = getDatabase(app); // Realtime Database 초기화

23-31: Firebase 서비스 초기화 에러 처리 개선을 제안드립니다.

현재 Firebase 서비스들(Firestore, Storage, Messaging, Analytics, Realtime Database)의 초기화 과정에서 발생할 수 있는 에러에 대한 처리가 없습니다. 서비스 안정성을 위해 각 초기화 단계에 try-catch 블록을 추가하는 것을 고려해보세요.

예시 구현:

export const initializeFirebaseServices = () => {
  try {
    auth = getAuth(app);
    db = getFirestore(app);
    storage = getStorage(app);
    rtdb = getDatabase(app);
    
    if (typeof window !== "undefined") {
      messaging = getMessaging(app);
      analytics = getAnalytics(app);
    }
    
    return { auth, db, storage, rtdb, messaging, analytics };
  } catch (error) {
    console.error("Firebase 서비스 초기화 중 오류 발생:", error);
    throw error;
  }
};
src/components/provider/index.tsx (1)

6-12: QueryClient 구성 옵션 추가 검토

현재 구현은 기본 설정의 QueryClient를 사용하고 있습니다. 프로덕션 환경에서는 재시도 횟수, 캐시 시간 등의 세부 설정이 필요할 수 있습니다.

다음과 같이 QueryClient 설정을 추가하는 것을 고려해보세요:

-  const [queryClient] = useState(() => new QueryClient());
+  const [queryClient] = useState(
+    () =>
+      new QueryClient({
+        defaultOptions: {
+          queries: {
+            retry: 1,
+            staleTime: 5 * 60 * 1000,
+            cacheTime: 10 * 60 * 1000,
+          },
+        },
+      })
+  );
src/app/layout.tsx (1)

9-13: 메타데이터 보완 필요

SEO 최적화를 위해 추가적인 메타데이터 설정이 필요합니다.

다음과 같이 메타데이터를 보완하는 것을 추천드립니다:

 export const metadata = {
   title: "HobbyMate",
   description: "취미 기반 모임 매칭 서비스",
   manifest: "/manifest.json",
+  keywords: "취미, 모임, 매칭, 소셜",
+  openGraph: {
+    title: "HobbyMate",
+    description: "취미 기반 모임 매칭 서비스",
+    type: "website",
+  },
 };
src/types/index.ts (3)

1-13: User 인터페이스 보완 필요

사용자 데이터의 유효성 검증을 위한 제약 조건과 문서화가 필요합니다.

다음과 같이 개선하는 것을 추천드립니다:

+/**
+ * 사용자 정보를 나타내는 인터페이스
+ */
 export interface User {
   id: string;
-  email: string;
+  email: string & { __brand: 'Email' }; // 이메일 유효성 검증을 위한 브랜딩
   name: string;
-  interests: string[];
+  interests: readonly string[]; // 불변성 보장
   location: {
     city: string;
     district: string;
   };
-  matchCount: number;
+  matchCount: NonNegativeInteger; // 음수가 될 수 없음
   lastMatchDate: Date;
   fcmToken?: string;
 }
+
+// 타입 유틸리티
+type NonNegativeInteger = number & { __brand: 'NonNegativeInteger' };

15-21: Match 인터페이스 개선 필요

매칭 상태에 대한 타입 안전성 강화가 필요합니다.

다음과 같이 개선하는 것을 추천드립니다:

+/**
+ * 사용자 간 매칭 정보를 나타내는 인터페이스
+ */
 export interface Match {
   id: string;
-  users: [string, string];
+  users: readonly [UserId, UserId]; // 사용자 ID 타입 안전성 보장
-  status: "pending" | "accepted" | "rejected";
+  status: MatchStatus; // 상태값을 별도 타입으로 분리
   chatRoomId?: string;
   createdAt: Date;
 }
+
+type UserId = string & { __brand: 'UserId' };
+type MatchStatus = "pending" | "accepted" | "rejected";

23-40: Group 인터페이스 보완 필요

그룹 데이터의 무결성을 위한 추가적인 제약 조건이 필요합니다.

다음과 같이 개선하는 것을 추천드립니다:

+/**
+ * 모임 그룹 정보를 나타내는 인터페이스
+ */
 export interface Group {
   id: string;
   hostId: string;
-  title: string;
+  title: NonEmptyString; // 빈 문자열 방지
-  content: string;
+  content: NonEmptyString;
   chatLink: string;
   meetingDate?: Date;
   location: {
     city: string;
     district: string;
   };
-  applicants: {
+  applicants: readonly {
     userId: string;
-    status: "pending" | "accepted" | "rejected";
+    status: ApplicationStatus; // 상태값을 별도 타입으로 분리
     appliedAt: Date;
   }[];
   createdAt: Date;
 }
+
+type NonEmptyString = string & { __brand: 'NonEmptyString' };
+type ApplicationStatus = "pending" | "accepted" | "rejected";
next.config.mjs (2)

3-11: 주석 처리된 코드를 제거하거나 문서화하세요.

사용하지 않는 코드는 제거하는 것이 좋습니다. 만약 이 API 리다이렉션 설정이 나중에 필요하다면, 왜 주석 처리했는지 설명하는 주석을 추가하거나 별도의 문서에 기록하는 것이 좋습니다.

-  // async rewrites() {
-  //   return [
-  //     {
-  //       source: "/api/:path*",
-  //       destination: `${process.env.NEXT_PUBLIC_API_URL}/api/:path*`,
-  //       basePath: false,
-  //     },
-  //   ];
-  // },

23-42: SVG 설정이 잘 구현되었습니다.

SVG 파일 처리를 위한 웹팩 설정이 체계적으로 구현되었습니다:

  • URL 임포트와 React 컴포넌트 임포트를 모두 지원
  • 기존 파일 로더 규칙을 적절히 재활용

다만, 사용 방법에 대한 문서화를 추가하면 좋을 것 같습니다.

다음과 같은 주석을 추가하는 것을 추천드립니다:

 const nextConfig = {
   webpack: (config) => {
+    // SVG 파일 처리를 위한 설정
+    // 사용 예시:
+    // 1. React 컴포넌트로 사용: import Logo from './logo.svg'
+    // 2. URL로 사용: import logoUrl from './logo.svg?url'
     const fileLoaderRule = config.module.rules.find((rule) =>
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a7e48ed and 7ab1741.

📒 Files selected for processing (15)
  • next.config.mjs (1 hunks)
  • public/manifest.json (1 hunks)
  • src/api/.gitkeep (1 hunks)
  • src/app/(auth)/login/.gitkeep (1 hunks)
  • src/app/(auth)/signup/.gitkeep (1 hunks)
  • src/app/(protect)/chat/.gitkeep (1 hunks)
  • src/app/(protect)/chat/[id]/.gitkeep (1 hunks)
  • src/app/(protect)/groups/.gitkeep (1 hunks)
  • src/app/(protect)/groups/[id]/.gitkeep (1 hunks)
  • src/app/(protect)/matches/.gitkeep (1 hunks)
  • src/app/layout.tsx (1 hunks)
  • src/components/provider/index.tsx (1 hunks)
  • src/firebase/config.ts (3 hunks)
  • src/middleware.ts (1 hunks)
  • src/types/index.ts (1 hunks)
✅ Files skipped from review due to trivial changes (9)
  • src/app/(protect)/chat/[id]/.gitkeep
  • src/app/(protect)/matches/.gitkeep
  • src/app/(auth)/signup/.gitkeep
  • src/app/(protect)/groups/.gitkeep
  • src/app/(auth)/login/.gitkeep
  • src/api/.gitkeep
  • src/app/(protect)/chat/.gitkeep
  • src/app/(protect)/groups/[id]/.gitkeep
  • public/manifest.json
🔇 Additional comments (3)
src/firebase/config.ts (2)

8-8: Firebase Realtime Database 임포트가 올바르게 추가되었습니다!

다른 Firebase 서비스 임포트와 함께 일관성 있게 배치되어 있습니다.


18-18: 환경 변수 설정을 확인해주세요.

NEXT_PUBLIC_FIREBASE_DATABASE_URL 환경 변수가 올바르게 설정되어 있는지 확인이 필요합니다.

❌ Verification inconclusive

🏁 Script executed:

#!/bin/bash
# Description: Check if the database URL environment variable is defined in any .env files

echo "Checking for NEXT_PUBLIC_FIREBASE_DATABASE_URL in .env files..."
fd -H "^.env" -x grep -l "NEXT_PUBLIC_FIREBASE_DATABASE_URL"

Length of output: 197


환경 변수 설정 확인 필요

현재 저장소 내의 환경 변수 파일(.env 계열)에서 "NEXT_PUBLIC_FIREBASE_DATABASE_URL" 변수를 찾을 수 없었습니다.

  • 이 변수가 배포 환경이나 별도의 환경 설정(예: CI/CD, 클라우드 서비스)에서 제공된다면 문제가 없지만, 로컬 개발 또는 빌드 시에도 반드시 참조되어야 한다면 해당 변수가 올바르게 정의되어 있는지 재확인해 주세요.
next.config.mjs (1)

18-21: 실험적 기능 사용에 대한 검토가 필요합니다.

topLevelAwait는 실험적 기능이므로, 프로덕션 환경에서 사용하기 전에 다음 사항을 확인해주세요:

  • 프로젝트의 Node.js 버전 호환성
  • 번들 크기에 미치는 영향
  • 브라우저 호환성
✅ Verification successful

🌐 Web query:

What is the current status of top-level await support in Node.js and major browsers?

💡 Result:

Top-level await allows using the await keyword outside async functions in JavaScript modules, simplifying asynchronous code handling. Here's its current support status:

Node.js Support

  • Available since Node.js v14.8 (unflagged) but exclusive to ES Modules:
    • Use .mjs file extension[1][3]
    • Set "type": "module" in package.json[1][5]
    • Use --input-type=module flag for string evaluation[1][3]
  • Not supported in CommonJS modules (require syntax)[5]

Browser Support

  • Standardized in ECMAScript 2022 (ES13)[2][6]
  • Native support in all modern browsers (Chrome, Firefox, Safari, Edge) since 2021[2][9]
  • Requires ES module usage (<script type="module">)[9]

Key Considerations

  1. Module Dependency Resolution:

    • Modern implementations (spec variation B) don't block sibling modules[8]
    • Only delays execution of dependent modules[8]
  2. Practical Use Cases:

    // Module initialization
    const config = await fetch('/config.json');
    export const API_KEY = config.key;
    
    // Dynamic imports
    const library = await import(`./${feature}.js`);
  3. Performance Impact:

    • Can improve cold starts in serverless environments (e.g., AWS Lambda)[5]
    • Might delay module availability if overused[8]

Current Adoption (2025)

  • Node.js: Fully supported in ES modules since v14 (~4 years old)[1][10]
  • Browsers: Universally supported in modern versions[2][9]
  • Tools: Compatible with major bundlers (Webpack/Rollup v5+, Vite)[8]

While initially controversial due to potential blocking issues[7], modern implementations have addressed these concerns through non-blocking resolution algorithms[8]. Developers should prefer ES modules and check transpiler configurations when targeting older environments[5].

Citations:


실험적 기능 사용 관련 검토 결과

top-level await는 Node.js (ES 모듈 환경, 최소 v14.8 이상)와 최신 브라우저에서 지원되므로, 해당 기능을 활성화하는 것은 현재 기술 환경에서 문제가 되지 않습니다. 다만, 아래 사항들을 반드시 확인해 주세요:

  • 프로젝트에서 ES 모듈(.mjs 또는 "type": "module")을 사용 중인지 확인
  • 타 시스템(예: 번들러, 배포 환경)과의 호환성 점검
  • 번들 크기 및 성능에 미치는 영향에 대한 추가 검토

Comment on lines +22 to +25
{/* <head>
<meta name="theme-color" content="#000000" />
<link rel="apple-touch-icon" href="/icon-192x192.png" />
</head> */}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

주석 처리된 코드 정리 필요

주석 처리된 head 태그 내용은 제거하거나 활성화해야 합니다. PWA 관련 메타 태그라면 적절히 활성화하는 것이 좋습니다.

Comment on lines +4 to +22
export function middleware(request: NextRequest) {
const isAuthenticated = request.cookies.get("session");

// 보호된 라우트 체크
if (request.nextUrl.pathname.startsWith("/(protected)")) {
if (!isAuthenticated) {
return NextResponse.redirect(new URL("/login", request.url));
}
}

// 이미 로그인한 사용자가 auth 페이지 접근 시
if (request.nextUrl.pathname.startsWith("/(auth)")) {
if (isAuthenticated) {
return NextResponse.redirect(new URL("/", request.url));
}
}

return NextResponse.next();
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

보안 및 에러 처리 강화 필요

현재 구현에서 몇 가지 보안 관련 개선사항이 필요합니다:

  1. 세션 쿠키의 유효성 검증이 부족합니다
  2. 리다이렉션 URL의 유효성 검증이 없습니다
  3. 에러 처리가 누락되어 있습니다

다음과 같이 개선하는 것을 추천드립니다:

 export function middleware(request: NextRequest) {
-  const isAuthenticated = request.cookies.get("session");
+  try {
+    const session = request.cookies.get("session");
+    const isAuthenticated = session && validateSession(session.value);
+    const redirectUrl = new URL(request.url);
+    
+    if (request.nextUrl.pathname.startsWith("/(protected)")) {
+      if (!isAuthenticated) {
+        redirectUrl.pathname = "/login";
+        return NextResponse.redirect(redirectUrl);
+      }
+    }
 
-  // 보호된 라우트 체크
-  if (request.nextUrl.pathname.startsWith("/(protected)")) {
-    if (!isAuthenticated) {
-      return NextResponse.redirect(new URL("/login", request.url));
-    }
-  }
+    if (request.nextUrl.pathname.startsWith("/(auth)")) {
+      if (isAuthenticated) {
+        redirectUrl.pathname = "/";
+        return NextResponse.redirect(redirectUrl);
+      }
+    }
 
-  // 이미 로그인한 사용자가 auth 페이지 접근 시
-  if (request.nextUrl.pathname.startsWith("/(auth)")) {
-    if (isAuthenticated) {
-      return NextResponse.redirect(new URL("/", request.url));
+    return NextResponse.next();
+  } catch (error) {
+    console.error("Middleware error:", error);
+    const errorUrl = new URL("/error", request.url);
+    return NextResponse.redirect(errorUrl);
   }
- }
-
-  return NextResponse.next();
 }

추가로 세션 검증을 위한 유틸리티 함수를 구현해야 합니다:

function validateSession(session: string): boolean {
  try {
    // JWT 토큰 검증 또는 세션 유효성 검사 로직 구현
    return true;
  } catch {
    return false;
  }
}

@Han-wo Han-wo merged commit c9df47b into develop Feb 12, 2025
2 of 3 checks passed
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.

setting: 폴더구조 및 라우트 파이어베이스 토큰설정
1 participant