Conversation
* ✨ feat : db 연동 * ✨ feat : 회원가입 기능 구현 * ✨ feat : 로그인 기능 구현 * ✨ feat : 소셜 로그인 * 🐛 fix : Prisma Client Vercel 캐싱 오류 해결
* ✨ feat : kakao map 생성 * ✨ feat : 카카오맵 키워드 별 마커 생성 * ✨ feat : 키워드 검색 기능 구현 * ✨ 카카오맵 키워드 별 리스트 구현
* ♻️ refactor : 유저 생성 Dao 작성 * ✨ feat : 게시판 관련 model 추가 및 게시글 리스트 조회, 생성 구현 * ✨ feat : 글 생성 모달 디자인 * ✨ feat : 게시글 추가, 리스트 조회 구현 * ✨ feat : 게시판 페이지네이션 기능
* ✨ feat : 토스트 컴포넌트 구현 * ♻️ refactor : 게시글 연속 중복 생성 방지 및 로딩 UI 추가 * ✨ feat : pagination skeleton UI
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Lanace
left a comment
There was a problem hiding this comment.
생각보다 많아져서 한번 끊어서 리뷰할게여...ㅠㅠㅠ
근데 깔끔하게 잘 짜고계신데요ㅋㅋㅋ?
| - Next.js(v15), React(v19), App Router | ||
| - Next-Auth V5 | ||
| - Prisma (NeonDB로 이용합니다.) | ||
| - Tanstack Query | ||
| - TypeScript | ||
| - Style : Tailwind CSS | ||
| - UI Lib : Shadcn |
There was a problem hiding this comment.
일반적으로 많이 사용하는거 잘 고르셨네여ㅎㅎ
특히 Shadcn 은 저도 안써보긴 했는데 요즘 엄청 뜨고있더라구요
| images: { | ||
| remotePatterns: [ | ||
| { | ||
| protocol: 'http', |
There was a problem hiding this comment.
imageUrl 응답 확인해보니 프로토콜이 http이더라고욤..
| name String? | ||
| email String? @unique | ||
| emailVerified DateTime? @map("email_verified") | ||
| image String? | ||
| password String? |
There was a problem hiding this comment.
name이나 email이나 password 가 optional 인건 이유가 있을까요??
There was a problem hiding this comment.
아 일단 email에 unique인데 optional인건 잘 이해가 안가서요ㅠ
There was a problem hiding this comment.
name, email의 경우 optional하지 않아도 될 것 같네요..
next auth를 처음 써봤는데 스키마 작성 예시를 그대로 가져와서 사용했어서 이렇게 된 것 같슴다.. 수정하겠슴다!
password의 경우 oauth일 때 비밀번호 안받아서 optional로 해놨슴다!
| refresh_token String? @db.Text | ||
| access_token String? @db.Text |
There was a problem hiding this comment.
refresh_token, access_token, id_token 같은 토큰값을 보통 DB에 저장하지 않고 사용하는데, 따로 저장하신 이유가 있을까요?
아 그리구 타입도 보통은 토큰 길이는 정해져있어서 Text보단 String(255) 같이 사용하는게 좋긴 해요ㅎㅎ
There was a problem hiding this comment.
무의식적으로 활용 안하면서 DB에 넣은 것 같습니다...
말씀 주신 의견 참고해서 수정하겠습니다!
String알려주신 것도 참고하겠습니다!
| parentId String? | ||
| parent Comment? @relation("CommentToComment", fields: [parentId], references: [id], onDelete: SetNull) |
There was a problem hiding this comment.
DB 컨벤션도 맞추면 좋을것같아요!
위쪽에서는 expires_at나 session_state 처럼 _ 를 사용하다가 카멜케이스로 쓰길래여...
보통 DB에서는 스네이크 케이스를 쓰고 js에선 카멜케이스를 쓰니 @@Map을 활용하시면 좋을것같네요ㅎㅎ
|
|
||
| return ( | ||
| <div> | ||
| {JSON.stringify(session)} |
There was a problem hiding this comment.
테스트 코드일텐데, 가급적이면 삭제하고, 나중을 위해서 // TODO: 같은 주석을 추가해두시면 좋을것같아요!
간혹 이런 코드가 production에 나가서 곤란한 경우가 있거든요ㅠㅠㅠ
경험담이라...하ㅠㅠㅠ
There was a problem hiding this comment.
앗 TODO 주석을 깜빡했네요...
말씀 감사합니다!
| const page = parseInt(searchParams.get('page') || '1'); | ||
| const limit = parseInt(searchParams.get('limit') || '10'); |
There was a problem hiding this comment.
음... 저는 NaN || '1' 의 결과값도 '1'로 나오니 괜찮다고 생각했었는데, 말씀 주신 의견 방식이 더 좋은 것 같습니다!
적용해보겠습니다.
| }, | ||
| }); | ||
|
|
||
| return NextResponse.json(post, { status: 201 }); |
| const user = await UserDao.getUserByEmail(email); | ||
| if (!user || !user.password) return null; | ||
|
|
||
| const passwordsMatch = await bcrypt.compare(password, user.password); |
| const urlError = | ||
| searchParams.get('error') === 'OAuthAccountNotLinked' | ||
| ? '다른 소셜 계정에서 사용된 이메일입니다.' | ||
| : ''; |
There was a problem hiding this comment.
이런 에러코드는 dictionary 를 만들어서 처리하면 좋아요ㅎㅎ
나중에 error code가 많이 추가될 수 있으니까요...!
const errorParamsMap: Record<string, string> = {
OAuthAccountNotLinked: "다른 소셜 계정에서 사용된 이메일입니다",
...: ...
}There was a problem hiding this comment.
감사합니다! error Code에 관한 확장성을 고려하지 않았네요... 말씀 주신 의견 반영하겠습니다!

✍️ PR 내용 설명
Code Review에 관한 PR입니다.
✅ 체크리스트
PR
Test
Additional Notes