Skip to content

[이제창] 스프린트미션5#143

Open
Jerang2 wants to merge 65 commits intocodeit-bootcamp-nodejs:mainfrom
Jerang2:sprintmission5
Open

[이제창] 스프린트미션5#143
Jerang2 wants to merge 65 commits intocodeit-bootcamp-nodejs:mainfrom
Jerang2:sprintmission5

Conversation

@Jerang2
Copy link
Collaborator

@Jerang2 Jerang2 commented Sep 21, 2025

기본

  • tsconfig.json 파일을 생성하고, 필요한 옵션을 설정해 주세요. (예: outDir).
  • 필요한 npm script를 설정해 주세요. (예: 빌드 및 개발 서버 실행 명령어)
  • 기존 Express.js 프로젝트를 타입스크립트 프로젝트로 마이그레이션 해주세요.
  • 필요한 타입 패키지를 설치해 주세요.
  • any 타입의 사용은 최소화해주세요.
  • 복잡한 객체 구조나 배열 구조를 가진 변수에 인터페이스 또는 타입 별칭을 사용하세요.
  • 필요한 경우, 타입 별칭 또는 유틸리티 타입을 사용해 타입 복잡성을 줄여주세요
  • 필요한 경우, declare를 사용하여 타입을 오버라이드하거나 확장합니다. (예: req.user)

개발 환경 설정

  • ts-node 를 사용해 .ts 코드를 바로 실행할 수 있는 npm script를 만들어 주세요. (예: npm run dev)
  • nodemon을 사용해 .ts 코드가 변경될 때마다 서버가 다시 실행되는 npm script를 만들어 주세요. (예: npm run dev)

심화

  • Controller, Service, Repository로 나누어 코드를 리팩토링해 주세요.
  • 필요하다면, 계층 사이에서 데이터를 주고 받을 때 DTO를 활용해 주세요.

-> 구현에 또 에러가 생겨서 해결중입니다.. ㅠㅠ

@Jerang2 Jerang2 changed the title Sprintmission5 [이제창] 스프린트미션5 Sep 21, 2025
@Jerang2 Jerang2 requested a review from rdd9223 September 22, 2025 00:02
@Jerang2 Jerang2 added the 순한맛🐑 마음이 많이 여립니다.. label Sep 22, 2025
Copy link
Collaborator

@rdd9223 rdd9223 left a comment

Choose a reason for hiding this comment

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

전반적으로 잘 작성해주셨지만, 중간중간 아쉬운 점이 보입니다. 특히 service는 service디렉토리 하위에서 컨트롤 할 수 있도록 수정해주세요.

console.log(`서버가 ${PORT}번에서 실행중입니다.`);
});

export default prisma;
Copy link
Collaborator

Choose a reason for hiding this comment

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

레포지토리/미들웨어가 사용하는 prisma를 여기서 export 하면 안됩니다. 항상 의존(import)하는 건 단방향이어야 해요. repository > service > controller > route(middleware) > index가 되도록 해주세요. 현재는 index > repository > service > controller > route(middleware) > index 여서 순환참조가 일어나고 있어요. 전용 모듈로 별도로 분리하는 것이 좋습니다.

Comment on lines +16 to +22
constructor(productService: ProductService) {
this.productService = productService;
const commentRepository = new CommentRepository();
this.commentService = new CommentService(commentRepository);
const likeRepository = new LikeRepository();
this.likeService = new LikeService(likeRepository);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

해당 ProductsController를 여러 route에서 사용하게 된다면 여러 생성자들이 추가로 생성하게 될 수 있어요. 의존성 주입 일관성을 위해서 라우터 조립부에서 생성해서 컨트롤러 생성자에 주입하는 것이 좋습니다.

Suggested change
constructor(productService: ProductService) {
this.productService = productService;
const commentRepository = new CommentRepository();
this.commentService = new CommentService(commentRepository);
const likeRepository = new LikeRepository();
this.likeService = new LikeService(likeRepository);
}
constructor(productService: ProductService, commendService: CommentService, likeService: LikeService) {
this.productService = productService;
this.commentRepository = commentService
this.likeRepository = likeRepository
}

router.delete('/products/comments/:commentId', authMiddleware, productsController.deleteComment);

// 상품 좋아요 API
router.post('/:productId/like', authMiddleware, productsController.toggleLike);
Copy link
Collaborator

Choose a reason for hiding this comment

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

/:productId/like/:articleId/like와 경로가 겹칩니다. /1234/like로 요청한다면 어떤 경로로 들어갈지 생각해보세요. /product/:productid/like 같이 표현하는 것이 좋아요.

router
.route('/products/:productId')
.get(optionalAuthMiddleware, productsController.getProductById)
.patch(validateProduct, authMiddleware, productsController.updateProduct)
Copy link
Collaborator

Choose a reason for hiding this comment

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

이 경로로 보면 인증검증 로직보다 입력값 검증 로직이 더 빨라요. 일반적으로는 인증로직이 우선이에요.

router
.route('/articles/:articleId')
.get(optionalAuthMiddleware, articlesController.getArticleById)
.patch(authMiddleware, validateArticle, articlesController.updateArticle)
Copy link
Collaborator

Choose a reason for hiding this comment

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

이 리뷰와 동일한 내용입니다.

@@ -0,0 +1,50 @@
import { Product as PrismaProduct, Prisma } from '@prisma/client';
Copy link
Collaborator

Choose a reason for hiding this comment

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

바로 사용하지 말고 repository를 사용하도록 해주세요.

"main": "index.js",
"scripts": {
"build": "tsc",
"dev": "ts-node-dev --respawn --transpile-only src/index.ts",
Copy link
Collaborator

Choose a reason for hiding this comment

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

--transpile-only은 타입에러를 런타임까지 가져갈 수 있어요. 타입스크립트의 장점을 살리기 위해 제거해주세요!

return res.status(403).json({ message: '상품 수정 권한이 없습니다.' });
}

const updatedProduct = await this.productService.updateProduct(parseInt(productId), {
Copy link
Collaborator

Choose a reason for hiding this comment

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

이런 비즈니스 로직은 Service에서 구현해주세요! Controller는 얇게 유지하는 것이 좋습니다.

@@ -0,0 +1,20 @@
{
Copy link
Collaborator

Choose a reason for hiding this comment

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

프로젝트 전반적으로 상대경로가 많습니다. baseUrl, paths옵션을 이용해서 절대 경로로 사용할 수 있도록 구성해보세요.

Copy link
Collaborator

Choose a reason for hiding this comment

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

dist 하위의 빌드 파일은 커밋할 필요 없습니다. .gitignore에 해당 디렉토리를 추가해주세요.

@rdd9223
Copy link
Collaborator

rdd9223 commented Sep 23, 2025

@Jerang2 target branch 가 잘못된 것 같네요. 개인 브랜치로 변경해주세요.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

순한맛🐑 마음이 많이 여립니다..

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants