-
Notifications
You must be signed in to change notification settings - Fork 0
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
Conversation
Walkthrough이번 변경사항은 Next.js 설정 파일에서 API 리다이렉션 로직을 제거하고 webpack 설정을 추가하여 SVG 파일 처리 방식을 개선합니다. 또한, HobbyMate 애플리케이션의 매니페스트 파일이 추가되었으며, 여러 디렉토리에 빈 상태를 유지하기 위한 .gitkeep 파일들이 추가되었습니다. 추가적으로, 레이아웃 파일의 메타데이터가 업데이트되고, React Query를 위한 Providers 컴포넌트가 도입되었습니다. Firebase 설정에는 Realtime Database 지원이 포함되었고, 인증 미들웨어와 새로운 TypeScript 인터페이스들이 추가되었습니다. Changes
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
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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
📒 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 theawait
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"
inpackage.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
Module Dependency Resolution:
- Modern implementations (spec variation B) don't block sibling modules[8]
- Only delays execution of dependent modules[8]
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`);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:
- 1: https://www.stefanjudis.com/today-i-learned/top-level-await-is-available-in-node-js-modules/
- 2: https://caniuse.com/?search=top+level+await
- 3: https://dev.to/stefanjudis/til-top-level-await-is-available-in-node-js-modules-22i3
- 4: https://javascript.plainenglish.io/exploring-the-new-javascript-feature-top-level-await-307c174f53a1?gi=7870895260ae
- 5: https://blog.stackademic.com/top-level-await-in-node-js-es-modules-vs-commonjs-c72313ca6685?gi=958dc8c6d227
- 6: https://www.infoworld.com/article/2334675/ecmascript-2022-blesses-class-elements-top-level-await.html
- 7: https://gist.github.com/Rich-Harris/0b6f317657f5167663b493c722647221
- 8: https://dev.to/dayvster/comment/22aid
- 9: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await?hl=RU
- 10: [Bug]: top-level
await
does not work with libraries when enabled (and is not supported out of the box) solidjs/solid-start#1614
실험적 기능 사용 관련 검토 결과
top-level await는 Node.js (ES 모듈 환경, 최소 v14.8 이상)와 최신 브라우저에서 지원되므로, 해당 기능을 활성화하는 것은 현재 기술 환경에서 문제가 되지 않습니다. 다만, 아래 사항들을 반드시 확인해 주세요:
- 프로젝트에서 ES 모듈(.mjs 또는 "type": "module")을 사용 중인지 확인
- 타 시스템(예: 번들러, 배포 환경)과의 호환성 점검
- 번들 크기 및 성능에 미치는 영향에 대한 추가 검토
{/* <head> | ||
<meta name="theme-color" content="#000000" /> | ||
<link rel="apple-touch-icon" href="/icon-192x192.png" /> | ||
</head> */} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
주석 처리된 코드 정리 필요
주석 처리된 head 태그 내용은 제거하거나 활성화해야 합니다. PWA 관련 메타 태그라면 적절히 활성화하는 것이 좋습니다.
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(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
보안 및 에러 처리 강화 필요
현재 구현에서 몇 가지 보안 관련 개선사항이 필요합니다:
- 세션 쿠키의 유효성 검증이 부족합니다
- 리다이렉션 URL의 유효성 검증이 없습니다
- 에러 처리가 누락되어 있습니다
다음과 같이 개선하는 것을 추천드립니다:
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;
}
}
#️⃣ 이슈
📝 작업 내용
이번 PR에서 작업한 내용을 간략히 설명해주세요.
폴더구조 및 라우트 설정
📸 스크린샷
✅ 체크 리스트
👩💻 공유 포인트 및 논의 사항
Summary by CodeRabbit
새로운 기능
개선 사항