Skip to content

[송현규] 스프린트 미션 9#189

Open
singsangsong28 wants to merge 15 commits into
codeit-sprint-fullstack:next-송현규from
singsangsong28:next-송현규

Hidden character warning

The head ref may contain hidden characters: "next-\uc1a1\ud604\uaddc"
Open

[송현규] 스프린트 미션 9#189
singsangsong28 wants to merge 15 commits into
codeit-sprint-fullstack:next-송현규from
singsangsong28:next-송현규

Conversation

@singsangsong28

@singsangsong28 singsangsong28 commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator

요구사항

기본 요구사항

공통

  • Github에 위클리 미션 PR을 만들어 주세요.
  • React.js 혹은 Next.js를 사용해 진행합니다.
  • RESTful를 설계하고 백엔드 코드를 변경하세요.
  • (풀스택) 설계한 백엔드 코드에 맞게 프론트엔드 코드를 변경해 주세요.
  • (백엔드) 프론트엔드 코드에 맞게 백엔드 코드를 변경해 주세요.
  • 백엔드 코드에 swagger를 추가해 API 명세 문서를 생성해 주세요.

중고마켓 페이지

  • 디폴트 이미지로 처리한 이미지를 실제 Product Get API에서 가져온 이미지로 변경해 주세요.
  • 좋아요 순 정렬 기능을 붙여주세요.
  • 베스트 상품 기능을 추가해 주세요. 베스트 상품은 가장 많이 좋아요를 받은 순으로 PC 기준 최대 4개까지 조회 가능합니다.

상품 등록하기 페이지

  • 상품 이미지 등록 기능을 구현합니다. 파일을 선택해 이미지를 업로드하고, preview를 볼 수 있도록 구현합니다. 이미지는 최대 3개까지만 등록 가능하도록 구현해 주세요.
  • 동일하게 상품 이미지 수정 기능도 추가합니다.
  • 상품 등록 성공 시 중고마켓 페이지로 이동해 주세요.

@singsangsong28
singsangsong28 requested a review from Irelander July 12, 2026 14:56
@singsangsong28 singsangsong28 self-assigned this Jul 12, 2026
@singsangsong28 singsangsong28 added 최종제출 스프린트 미션 최종 제출 PR입니다. 코드리뷰 및 평가해주세요! 순한맛🐑 마음이 많이 여립니다.. labels Jul 12, 2026

@Irelander Irelander left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

지난번에 빠져 있던 내용들까지 포함해서 작업하느라 너무 고생 많으셨어요!

CommentBoard로 댓글/문의를 한쪽으로 모은 것도 화면이 늘었을 때 유지보수성이 높아져서 더 좋은거 같아요.

다른것들은 문제 없는데, 머지 충돌 코드가 그대로 있어서 해당 부분 고치고 머지해야할것 같습니다 !
이번 미션도 고생 많으셨습니다 :)

Comment on lines +43 to +46
<<<<<<<< HEAD:src/components/comments/CommentItem.jsx
========
{/* 수정 중이 아닐 때만 케밥 메뉴 노출 */}
>>>>>>>> upstream/next-송현규:src/app/(main)/community/[id]/_components/CommentItem.jsx

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

충돌 마커가 JSX 안에 그대로 있어요 ! 머지가 제대로 안된거 같은데 확인이 필요할것 같아요 !

Comment on lines 42 to +43
const res = await fetch(
"https://panda-market-api.vercel.app/auth/signIn",
"https://backend-deploy-d1um.onrender.com/login",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

엇 다른곳에선 NEXT_PUBLIC_API_KEY 잘 쓰고 계신데 여기만 하드코딩이네요 !

Comment thread src/lib/fetchClient.js
Comment on lines +57 to +66
export const tokenUploadFetch = async (url, formData) => {
const token = typeof window !== 'undefined' ? localStorage.getItem('accessToken') : null;
const res = await fetch(`${BASE_URL}${url}`, {
method: 'POST',
headers: { ...(token && { Authorization: `Bearer ${token}` }) },
body: formData,
});
if (!res.ok) throw new Error(`API error: ${res.status}`);
return parseResponse(res);
};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tokenFetch는 401이면 refresh 후 재시도하는데, 이미지 업로드는 그 흐름이 빠져 있어요.

토큰이 만료된 채로 상품 등록/수정을 하면 업로드만 실패하고 나머지는 정상처럼 보일 수 있어요. 업로드도 같은 refresh·재시도 로직을 타게 하거나, tokenFetch 한쪽으로 합치는 방향을 추천합니다.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

미션에선 상관없지만 실무적인 팁을 하나 드리려고해요. 지금 구조에선 서버에서 상세를 prefetch할 때 토큰 없이 가져오고, 클라 마운트 후에 localStorage를 보고 /login으로 보내는 구조예요.

비로그인 사용자도 잠깐 데이터가 그려질 수 있고, 보호도 토큰 존재 여부에만 의존해요. Next라면 middleware나 쿠키 기반 서버 검증으로 진입 자체를 막는 쪽이 “UI를 가리는 것”보다 안전해요.

Comment on lines +31 to +39
function getCachedUser() {
if (typeof window === "undefined") return null;
try {
const cached = localStorage.getItem("cachedUser");
return cached ? JSON.parse(cached) : null;
} catch {
return null;
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

여기도 실무적인 팁 하나 !

로그인 유저 객체를 JSON으로 캐시해 GNB·댓글 소유자 판별에 쓰면, 서버에서 닉네임/권한이 바뀌어도 클라가 예전 값을 오래 들고 있을 수 있어요. XSS 시에도 노출면이 넓어지고요. 토큰만 들고 프로필은 ["me"] 쿼리로 가져오거나, 캐시 TTL을 짧게 잡는 편이 덜 위험해요.

Comment on lines +17 to +30
return (
<>
<section className="grid grid-cols-5 gap-6 mt-6 mb-10.5">
{products.map((p) => (
<Products key={p.id} post={p} />
))}
</section>
<Pagination
totalCount={totalCount}
pageSize={pageSize}
currentPage={page}
/>
</>
);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

댓글 CommentBoardisLoading/isError를 보여주는데, 해당 부분도 동일하게 처리하면 더 좋을꺼 같아요 !

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

Labels

순한맛🐑 마음이 많이 여립니다.. 최종제출 스프린트 미션 최종 제출 PR입니다. 코드리뷰 및 평가해주세요!

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants