[송현규] 스프린트 미션 9#189
Hidden character warning
Conversation
Irelander
left a comment
There was a problem hiding this comment.
지난번에 빠져 있던 내용들까지 포함해서 작업하느라 너무 고생 많으셨어요!
CommentBoard로 댓글/문의를 한쪽으로 모은 것도 화면이 늘었을 때 유지보수성이 높아져서 더 좋은거 같아요.
다른것들은 문제 없는데, 머지 충돌 코드가 그대로 있어서 해당 부분 고치고 머지해야할것 같습니다 !
이번 미션도 고생 많으셨습니다 :)
| <<<<<<<< HEAD:src/components/comments/CommentItem.jsx | ||
| ======== | ||
| {/* 수정 중이 아닐 때만 케밥 메뉴 노출 */} | ||
| >>>>>>>> upstream/next-송현규:src/app/(main)/community/[id]/_components/CommentItem.jsx |
There was a problem hiding this comment.
충돌 마커가 JSX 안에 그대로 있어요 ! 머지가 제대로 안된거 같은데 확인이 필요할것 같아요 !
| const res = await fetch( | ||
| "https://panda-market-api.vercel.app/auth/signIn", | ||
| "https://backend-deploy-d1um.onrender.com/login", |
There was a problem hiding this comment.
엇 다른곳에선 NEXT_PUBLIC_API_KEY 잘 쓰고 계신데 여기만 하드코딩이네요 !
| 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); | ||
| }; |
There was a problem hiding this comment.
tokenFetch는 401이면 refresh 후 재시도하는데, 이미지 업로드는 그 흐름이 빠져 있어요.
토큰이 만료된 채로 상품 등록/수정을 하면 업로드만 실패하고 나머지는 정상처럼 보일 수 있어요. 업로드도 같은 refresh·재시도 로직을 타게 하거나, tokenFetch 한쪽으로 합치는 방향을 추천합니다.
There was a problem hiding this comment.
미션에선 상관없지만 실무적인 팁을 하나 드리려고해요. 지금 구조에선 서버에서 상세를 prefetch할 때 토큰 없이 가져오고, 클라 마운트 후에 localStorage를 보고 /login으로 보내는 구조예요.
비로그인 사용자도 잠깐 데이터가 그려질 수 있고, 보호도 토큰 존재 여부에만 의존해요. Next라면 middleware나 쿠키 기반 서버 검증으로 진입 자체를 막는 쪽이 “UI를 가리는 것”보다 안전해요.
| function getCachedUser() { | ||
| if (typeof window === "undefined") return null; | ||
| try { | ||
| const cached = localStorage.getItem("cachedUser"); | ||
| return cached ? JSON.parse(cached) : null; | ||
| } catch { | ||
| return null; | ||
| } | ||
| } |
There was a problem hiding this comment.
여기도 실무적인 팁 하나 !
로그인 유저 객체를 JSON으로 캐시해 GNB·댓글 소유자 판별에 쓰면, 서버에서 닉네임/권한이 바뀌어도 클라가 예전 값을 오래 들고 있을 수 있어요. XSS 시에도 노출면이 넓어지고요. 토큰만 들고 프로필은 ["me"] 쿼리로 가져오거나, 캐시 TTL을 짧게 잡는 편이 덜 위험해요.
| 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} | ||
| /> | ||
| </> | ||
| ); |
There was a problem hiding this comment.
댓글 CommentBoard는 isLoading/isError를 보여주는데, 해당 부분도 동일하게 처리하면 더 좋을꺼 같아요 !
요구사항
기본 요구사항
공통
중고마켓 페이지
상품 등록하기 페이지