[정민주] 스프린트 미션 9#75
Conversation
#1 chore: setup sprint
#4 feat: create article apis
#6 feat: create comment apis
…-structure feat: #10 change db structure to accomodate articles and add seed data
…cles-api feat: #12 create best3 article api
…cles-api feat: #12 add author to bestArticles api and add comments to articleDetail api
…cles-api feat: #12 add author data to getArticles api
…cles-api feat: #12 add author data to comment data in article detail api
…cles-api feat: #12 allow other orderBy bases
…cles-api feat: #12 make article api not recieve userId
refactor: #19 mvc
feat: #19 add error handler
- Replace custom authentication middleware with express-jwt - Remove req.user usage and migrate to req.auth - Apply access token verification middleware to protected routes - Add authorization logic for article, product, and comment ownership - Refactor route protection structure for consistency
feat: #24 create auth
- accesstoken이 올 수도 안 올 수도 있지만 오면 유효성 검사하는 미들웨어인 verifyOptionalAccessToken 함수 생성 - get 관련 API는 인증되지 않은 유저들도 사용할 수 있으니 verifyOptionalAccessToken 사용해주기 - 인증 안 된 유저들은 liked 데이터가 모두 false, 인증 된 유저들은 좋아요 누른 여부에 따라 false/true 리턴
feat: #24 Article과 Product 좋아요 스키마와 API 만들기
…mment feat: #26 create product comment schema and api
feat: create get me api
…ddleware - Make verifyOptionalAccessToken return req.auth as undefined when accessToken is expired instead of throwing error to create "not logged in" state
|
민주님 안녕하세요. 시간이 촉박한 상황에서도 FE와 BE 구현 모두 잘 마무리해 주셨습니다. 실제 개발 상황에서도 시간적으로 제약이 있기 때문에 지금처럼 학습 분량이 많고 프로젝트 준비 등으로 바쁜 상황에서는 시간 내에 가능한 선에서 작업해 주시는 부분 아주 좋습니다. 다만 node_modules 그대로 추가된 부분이 있어 이 부분은 수정해 주시면 좋겠습니다. |
There was a problem hiding this comment.
PR에 node_modules가 통째로 올라와서 변경 파일이 많이 잡히고 있습니다. 이렇게 되면 실제 코드 변경을 확인할 수 없고, 저장소 용량도 급격히 커지기 때문에 .gitignore에 node_modules를 추가해주세요
| const userCheckedByEmail = await authRepository.findByEmail(id); | ||
| const userCheckedByUsername = await authRepository.findByUsername(id); | ||
| const user = userCheckedByEmail || userCheckedByUsername; | ||
| const filteredUser = filterSensitiveUserData(user); |
There was a problem hiding this comment.
filterSensitiveUserData(user)를 if (!user) 체크보다 먼저 호출하고 있어요. 존재하지 않는 계정으로 로그인하면 401이 나가기 전에 undefined를 구조분해하다가 TypeError가 터져서 500으로 떨어지기 때문에 순서를 바꾸시는 것을 추천드립니다.
|
|
||
| async function createProduct(data) { | ||
| const { name, description, price } = data; | ||
| if (!name || !description || !price) |
There was a problem hiding this comment.
!price는 price가 0일 때도 참이라, 0원 상품(나눔)을 등록하면 "필수 값입니다" 400이 나간다는 점을 의식하시면 추후 정책에 따른 엣지케이스를 막을 수 있으니 참고해보세요.
| }, | ||
| }); | ||
|
|
||
| const upload = multer({ storage }); |
There was a problem hiding this comment.
multer에 fileFilter와 limits가 없어서 실행 파일이든 수 GB 파일이든 그대로 서버 디스크에 저장되게 됩니다. 업로드는 공개 서버에서 가장 자주 공격받는 지점이라 이미지의 포맷과 용량에 대해서는 제한을 두시는 편을 추천드립니다.
| return res.status(status).json({ | ||
| path: req.path, | ||
| method: req.method, | ||
| message: error.message ?? "Internal Server Error", |
There was a problem hiding this comment.
error.status가 없는 예상 못 한 에러(Prisma 쿼리 실패 등)도 error.message가 그대로 클라이언트에 나가게 되는 흐름입니다. 내부 구현 정보라 500일 때는 고정 메시지로 감추고 서버 로그로만 남기는 게 안전합니다.
There was a problem hiding this comment.
수정/삭제 권한 확인을 verifyProductAuth처럼 미들웨어로 분리해서 라우터에서 "인증 → 인가 → 컨트롤러" 순서가 한눈에 보이는 구조가 좋습니다. 👍
늦어서 별 코멘트 없이 제출합니다. 죄송합니다.