[김수빈]Sprint10#38
Conversation
| export const ExceptionMessage = { | ||
| ARTICLE_NOT_FOUND: 'Article not found', | ||
| PRODUCT_NOT_FOUND: 'Product not found', | ||
| COMMENT_NOT_FOUND: 'Comment not found', | ||
| }; |
| export const createArticle = async (req, res) => { | ||
| const { title, content } = req.body; | ||
| const userId = req.userId; // 로그인된 유저 ID | ||
| console.log('컨트롤러에서 유저아이디:', req.user); |
There was a problem hiding this comment.
[P0]
디버깅용 console들은 remote에 푸쉬하기전에 꼭 삭제하는 습관을 들이시면 좋습니다!
| if (!refreshToken) { | ||
| throw new HttpError(400, '리프레시 토큰이 필요합니다'); | ||
| } |
There was a problem hiding this comment.
[P2]
추후 이런 부분은 validationLayer와 같은 미들웨어에서 처리하면 깔끔해질 것 같습니다!
|
|
||
| function validateProductData(data) { | ||
| if (!data.name || typeof data.name !== 'string' || data.name.trim() === '') { | ||
| throw new HttpError(400, '상품 이름은 필수입니다'); |
There was a problem hiding this comment.
[P2]
ExecptionMessage 하신 것처럼 코드 상수로 관리하면 추후 국제화라던지 유지보수면에서 좋을 것 같습니다.
|
|
||
| validateProductData(req.body); | ||
|
|
||
| const updatedProduct = await productService.updateProduct(productId, userId, req.body); |
There was a problem hiding this comment.
[P1]
Body를 직접 넘겨주는 것보다 필요한 값들만 뽑아서 넣어주는 것이 좋습니다. 혹은 바디가 모두 필요하다면
const productInfo = req.body와 같이 전달해주는 편이 좋을 것 같아요!
그럼 아래 코드들도 간결해질 것 같습니다.
validateProductDate(productInfo)
...
| function assertUserId(req) { | ||
| if (!req.userId) { | ||
| throw new HttpError(401, '로그인이 필요합니다'); | ||
| } | ||
| return req.userId; | ||
| } |
| export const Update = async (id, data) => { | ||
| return prismaClient.$transaction(async (tx) => { | ||
| const exists = await tx.article.findUnique({ where: { id } }); | ||
| if (!exists) throw new Error('Article not found'); | ||
| return tx.article.update({ | ||
| where: { id }, | ||
| data, | ||
| include: { | ||
| author: { | ||
| select: { | ||
| id: true, | ||
| nickname: true, | ||
| }, | ||
| }, | ||
| }, | ||
| }); | ||
| }); | ||
| }; |
There was a problem hiding this comment.
[P1]
네이밍이 findOneAndUpdate가 맞을 것 같습니다. 추후 찾지않고 바로 업데이트하는 함수가 필요해질 경우 겹칠 것 같아요!
|
|
||
| // 회원 가입용 (비밀번호 bcrypt로 해싱 후 저장) | ||
| export async function save(user) { | ||
| const hashedPassword = await bcrypt.hash(user.password, 10); |
There was a problem hiding this comment.
[P1]
비밀번호 해싱관련해서는 서비스 로직에서 담당하는게 맞을 것 같습니다.
비즈니스 로직이다보니 서비스에서 하면 좋을 것 같아요!
7b282af
into
codeit-sprint-fullstack:express-김수빈
백엔드 구현 요구사항
상품 등록
[ o ] "상품 등록하기" 버튼 클릭 시, 상품 정보 등록 API 엔드포인트에 요청을 보내 상품을 등록합니다.
[ o ] 상품 등록 시 필요한 필드(이름, 설명, 가격 등)의 유효성을 검증하는 미들웨어를 구현합니다.
[ o ] multer 미들웨어를 사용하여 이미지 업로드 API를 구현해 주세요.
[ o ] 업로드된 이미지는 서버에 저장하고, 해당 이미지의 경로를 response 객체에 포함해 반환합니다.
상품 상세
[ 애매 ] 상품을 조회할 때, 해당 상품에 대한 댓글 리스트, 사용자가 '좋아요'를 눌렀는지 여부를 확인할 수 있도록 응답 객체에 포함시켜 반환해 주세요.
좋아요 기능
[ o ] '좋아요' API를 만들어 주세요.
[ o ] 사용자는 상품 또는 게시글에 '좋아요'를 할 수 있습니다.
[ o ] $transaction을 사용해 주세요.
[ o ] '좋아요' 취소 API를 만들어 주세요.
[ o ] 사용자는 상품 또는 게시글에 '좋아요'를 취소할 수 있습니다.
[ o ] $transaction을 사용해 주세요.
[에매 ] 상품 또는 게시글을 조회할 때, 사용자가 '좋아요'를 누른 항목인지 확인할 수 있도록 isLiked 필드를 응답 객체에 포함시켜 반환해 주세요.
에러 처리
[ o ] 모든 예외 상황을 처리할 수 있는 에러 핸들러 미들웨어를 구현합니다.
[ o ] 서버 오류(500), 사용자 입력 오류(400 시리즈), 리소스 찾을 수 없음(404) 등 상황에 맞는 상태값을 반환합니다.
라우트 중복 제거
[ o ] 중복되는 라우트 경로(예: /users에 대한 get 및 post 요청)를 app.route()로 통합해 중복을 제거합니다.
[ o ] express.Router()를 활용하여 중고마켓/자유게시판 관련 라우트를 별도의 모듈로 구분합니다.
인증
[ o ] User 스키마를 작성해 주세요.
[ o ] id, email, nickname, image, encryptedPassword, createdAt, updatedAt 필드를 가집니다.
[ o ] 회원가입 API를 만들어 주세요.
[ o ] email, nickname, password 를 입력하여 회원가입을 진행합니다.
[ o ] password는 해싱해 저장합니다.
[ o ] 로그인 API를 만들어 주세요.
[ o ] 사용자의 신원을 확인하고, 성공적인 인증 후에는 액세스 토큰을 발급해 response 객체에 포함해 반환합니다.
상품 기능 인가
[ ] 로그인한 사용자만 상품을 등록할 수 있습니다.
[ o ] 상품을 등록한 사용자만 해당 상품의 정보를 수정 및 삭제를 할 수 있습니다.
[ o ] 로그인한 사용자만 상품에 '좋아요'를 추가하거나 삭제할 수 있습니다.
게시글 기능 인가
[ o ] 로그인한 사용자만 게시글을 등록할 수 있습니다.
[ o ] 게시글을 등록한 사용자만 해당 게시글 정보를 수정 및 삭제할 수 있습니다.
[ o ] 로그인한 사용자만 게시글에 '좋아요'를 추가하거나 삭제할 수 있습니다.
댓글 기능 인가
[ o ] 로그인한 사용자만 상품에 댓글을 등록할 수 있습니다.
[ o ] 로그인한 사용자만 게시글에 댓글을 등록할 수 있습니다.
[ o ] 댓글을 등록한 사용자만 댓글을 수정하거나 삭제할 수 있습니다.
심화 요구사항
상태코드 (웹 API 관련)
[ o ] 프론트엔드에서는 서버 응답의 상태코드에 따라 적절한 사용자 피드백을 제공합니다.
멘토님께 전하는 말
MVC패턴으로 나름 API를 작성하였는데 수요일부터 팀프로젝트 작업으로 인해 통일성이 좀 부족합니다.
전역 에러핸들링 미들웨어를 잘 작성한것인지 모르겠습니다.
좋아요 기능 구현은 햇는데 그 Optimistic Update 하다가 말아서 isLiked 값 보내주는거랑 Optimistic 구현이 제대로 안된거 같습니다.
나머지 MVC패턴은 나름 구현을 햇는데 처음이라 잘 한것인지 헷갈립니다.