Skip to content

Conversation

@opuswork
Copy link
Collaborator

요구사항

기본

  • [x]
  • []
  • []

심화

  • [x]
  • []

주요 변경사항

스크린샷

image

멘토에게

  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@opuswork opuswork self-assigned this Nov 17, 2025
@opuswork opuswork requested a review from iamjaeholee November 17, 2025 05:05
Copy link
Collaborator

@iamjaeholee iamjaeholee left a comment

Choose a reason for hiding this comment

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

스프린트 미션6 작업하느라 수고하셨어요 🥇

전반적으로 태영님께서 얼마나 많이 고민하시고 작업을 진행해주셨는지 느껴지는 PR이었습니다.
여러 상황에 대응하기 위해 validation 처리해주시는 부분, 데이터 변환 해주시는 부분 등 너무 훌륭한 부분들이 많았어요 👍

Comment on lines +1 to +2
DATABASE_URL="postgresql://postgres:java7670@localhost:5432/comazon_dev?schema=public"
PORT=3000 No newline at end of file
Copy link
Collaborator

Choose a reason for hiding this comment

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

.env파일에는 민감한 정보 (예를들면 DB_URL 같은 것)가 포함될 수 있어 왠만하면 .gitignore에 추가하는 것을 추천드려요 :-)

Comment on lines +1 to +2
import * as dotenv from 'dotenv';
dotenv.config();
Copy link
Collaborator

Choose a reason for hiding this comment

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

dotenv패키지 활용해 환경변수 제어해주는 부분 좋습니다 !

Comment on lines +14 to +25
const corsOptions = {
origin: ['http://localhost:5173', 'http://localhost:3000', 'http://127.0.0.1:5173'],
credentials: true,
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization']
};
app.use(cors(corsOptions)); // CORS 허용
app.use(express.json({ limit: '50mb' })); // JSON 파싱 (이미지 업로드를 위해 크기 제한 증가)
app.use(express.urlencoded({ extended: true, limit: '50mb' })); // URL 인코딩된 데이터 파싱

// OPTIONS 요청 처리 (preflight)
app.options('*', cors(corsOptions));
Copy link
Collaborator

Choose a reason for hiding this comment

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

corsOptions에서 OPTIONS가 포함되어 있어서 요것은 중복되는 부분이 아닌가 하는 의견입니다 !

Comment on lines +103 to +129
try {
return {
id: product.id,
name: product.name,
description: product.description || '',
category: product.category,
price: product.price,
stock: product.stock,
// 스키마의 image 필드를 사용 (productImage가 아니라 image)
productImage: product.image,
images: product.image || '/src/assets/products/default.png',
// 스키마에 favoriteCount 필드가 있음
favoriteCount: product.favoriteCount || 0,
createdAt: product.createdAt,
updatedAt: product.updatedAt,
// 태그 정보 (선택사항) - 태그가 없을 수 있으므로 안전하게 처리
tags: (product.tags && Array.isArray(product.tags))
? product.tags.map(pt => ({
id: pt.tag?.id,
name: pt.tag?.name
})).filter(tag => tag.id && tag.name) // null 제거
: []
};
} catch (error) {
console.error('[Backend] Error transforming product:', product.id, error);
// 에러가 발생해도 기본 정보는 반환
return {
Copy link
Collaborator

Choose a reason for hiding this comment

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

productreact에서 원하는 형태로 변환하는 과정에서 에러가 발생하게 될 경우 기본값을 반환해주는 로직에 try catch문을 활용해주고 계세요 !
에러가 발생해 catch구문에 들어가게 될 경우 기본값을 반환하는 로직이기 때문에 try catch를 쓰지 않고 ?., ??, ? : 등의 다양한 오퍼레이터를 활용하면 에러가 나지 않고 기본값을 반환하도록 수정할 수도 있을 것 같아요. !

: []
};

res.json(transformedProduct);
Copy link
Collaborator

Choose a reason for hiding this comment

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

이 파일 내에서 어떤 부분에서는 return값을 사용하고 있고, 어떤 부분에서는 사용하지 않고 있어서 통일성을 맞춰주면 좋을 것 같다는 의견이에요 : -)

Comment on lines +54 to +59
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");

-- CreateIndex
CREATE UNIQUE INDEX "Tag_name_key" ON "Tag"("name");

Copy link
Collaborator

Choose a reason for hiding this comment

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

쿼리 최적화를 위해 인덱스 설정해주는 부분 너무 좋아요

Comment on lines +41 to +49
enum Category {
FASHION
BEAUTY
SPORTS
ELECTRONICS
HOME_INTERIOR
HOUSEHOLD_SUPPLIES
KITCHENWARE
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

enum활용해 스키마 작성해주는 부분 너무 좋습니다.

@@ -0,0 +1,112 @@
const ListProducts = "http://localhost:3000/products";
Copy link
Collaborator

Choose a reason for hiding this comment

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

url같은 부분은 환경변수를 통해서 주입받으면 더 유연하게 대처할 수 있을 것 같아요 : -)

Comment on lines +44 to +62
export async function getProducts({ page = 1, pageSize = 10, orderBy = "recent", keyword = "" } = {}) {
try {
const url = new URL(ListProducts);
url.searchParams.set("page", String(page));
url.searchParams.set("pageSize", String(pageSize));
if (keyword) {
url.searchParams.set("keyword", keyword);
}
if (orderBy) {
url.searchParams.set("orderBy", orderBy);
}

console.log('[getProducts] Fetching URL:', url.toString());

let response;
try {
response = await fetch(url.toString(), {
method: 'GET',
headers: {
Copy link
Collaborator

Choose a reason for hiding this comment

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

이 부분은 api를 호출하는 소스를 담고있는 파일인 것 같아요. 사실상 jsx의 확장자를 활용하지 않고 있어서 js확장자로 사용해도 될 것 같습니다.

Comment on lines +24 to +26
} finally {
setLoading(false);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

finally활용해주는 부분 너무 좋습니다.

@iamjaeholee
Copy link
Collaborator

conflict만 해결하고 머지해주시면 됩니다 : -)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants