Skip to content

Feat(client): Card meta data 반영 & 카테고리 params 동기화#132

Merged
constantly-dev merged 10 commits intodevelopfrom
feat/#131/card-meta-data
Sep 21, 2025
Merged

Feat(client): Card meta data 반영 & 카테고리 params 동기화#132
constantly-dev merged 10 commits intodevelopfrom
feat/#131/card-meta-data

Conversation

@constantly-dev
Copy link
Member

@constantly-dev constantly-dev commented Sep 19, 2025

📌 Related Issues

관련된 Issue를 태그해주세요. (e.g. - close #25)

📄 Tasks

Card meta data 반영 & 카테고리 params 동기화

  • fetch meta useQuery 사용하도록 변경
  • mybookmark card meta data fetch용 container 컴포넌트 구현
  • edit/delete popup padding left 추가
  • fetch card 타입 정리 & fetch card 임시 skeleton 적용 (임시)

⭐ PR Point (To Reviewer)

📷 Screenshot

Summary by CodeRabbit

  • New Features
    • 북마크·리마인드 목록에 링크 미리보기(제목/이미지) 자동 표시
    • 목록 로딩 시 스켈레톤/로딩 상태 제공으로 대기 경험 개선
    • 편집 시 기존 내용이 자동으로 채워져 더 빠른 수정 가능
  • Refactor
    • 카드 UI를 일원화해 목록 전반의 표시와 동작 일관성 개선
    • 링크 메타데이터 조회 흐름을 정비해 표시 안정성 향상
  • Style
    • 옵션 메뉴 버튼 정렬 및 패딩 조정으로 가독성 향상

@vercel
Copy link

vercel bot commented Sep 19, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
pinback-client-client Ready Ready Preview Comment Sep 20, 2025 4:53am

@coderabbitai
Copy link

coderabbitai bot commented Sep 19, 2025

Walkthrough

북마크/리마인드 카드 렌더링을 기존 Card 직접 사용에서 FetchCard 컴포넌트로 교체하고, URL 메타데이터를 조회하는 useGetPageMeta 훅을 추가했습니다. 관련 타입을 export로 전환했으며, 리마인드 편집 흐름에서 상세 조회 훅을 연동했습니다. 옵션 메뉴 버튼 스타일을 조정했고, OG 프록시 구성을 단순화했습니다.

Changes

Cohort / File(s) Summary
MyBookmark FetchCard 적용
apps/client/src/pages/myBookmark/MyBookmark.tsx
리스트 아이템 렌더링을 CardFetchCard로 교체; article 단일 prop 전달, 클릭시 동작과 캐시 무효화 동일 유지.
MyBookmark FetchCard 컴포넌트 추가
apps/client/src/pages/myBookmark/components/fetchCard/FetchCard.tsx
URL 메타 조회(useGetPageMeta) 후 스켈레톤/폴백 처리하여 Card type="bookmark" 렌더링. 기본 타이틀/이미지 파생 로직 포함.
MyBookmark 타입 export
apps/client/src/pages/myBookmark/types/api.ts
BookmarkArticle를 export로 전환.
Remind FetchCard 적용 및 편집 흐름 연동
apps/client/src/pages/remind/Remind.tsx
리스트를 FetchCard로 교체; useGetRemindArticlesisPending 처리 추가; useGetArticleDetail로 편집 전 상세 데이터 로드하여 CardEditModalprevData로 전달; 날짜 포맷 메모 의존성 조정.
Remind FetchCard 컴포넌트 추가
apps/client/src/pages/remind/components/fetchCard/FetchCard.tsx
URL 메타 조회 후 스켈레톤/폴백 처리하여 Card type="remind" 렌더링.
Remind 타입 export
apps/client/src/pages/remind/types/api.ts
ArticleWithCategory를 export로 전환.
OG 메타 조회 훅 추가
apps/client/src/shared/apis/queries.ts
useGetPageMeta(url) 추가: fetchOGData 사용, ogMeta 키, enabled 가드, staleTime: Infinity, retry: false.
옵션 메뉴 버튼 스타일 조정
apps/client/src/shared/components/optionsMenuButton/OptionsMenuButton.tsx
ITEM_STYLEflex items-center justify-centerflex items-center px-[0.8rem]로 변경.
주석 정리(무기능 변경)
apps/client/src/shared/hooks/usePageMeta.ts
주석 제거만, 동작 동일.
OG 프록시 단순화
apps/client/src/shared/utils/fetchOgData.ts
AllOrigins 프록시 주석 처리로 CORSProxy.io만 사용; API/파싱 로직 변경 없음.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant Page as MyBookmark/Remind Page
  participant FC as FetchCard (bookmark/remind)
  participant Q as useGetPageMeta (React Query)
  participant OG as fetchOGData

  U->>Page: 페이지 진입
  Page->>FC: 각 article로 FetchCard 렌더
  FC->>Q: useGetPageMeta(url) 쿼리 시작
  Q->>OG: fetchOGData(url)
  OG-->>Q: meta { title, image } 또는 오류
  alt 로딩 중
    FC-->>U: 스켈레톤 표시
  else 성공/오류
    FC-->>U: Card 렌더(메타 기반 타이틀/이미지, 폴백 처리)
  end

  U->>FC: 카드 클릭
  FC-->>Page: onClick(article)
  Page->>Page: updateToReadStatus, 관련 쿼리 무효화
Loading
sequenceDiagram
  autonumber
  participant U as User
  participant Remind as Remind Page
  participant API as useGetArticleDetail
  participant Modal as CardEditModal

  U->>Remind: 옵션 → 편집 선택
  Remind->>API: 상세 데이터 조회
  API-->>Remind: articleDetail
  Remind->>Modal: open(prevData=articleDetail)
  Modal-->>U: 편집 UI 표시
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

frontend

Suggested reviewers

  • jllee000
  • jjangminii

Poem

토끼는 링크를 톡톡 두드려요
메타를 살짝 훔쳐와 제목을 얹고,
스켈레톤 구름을 걷으면 카드가 보여요.
리마인드는 조심스레 편집을 열고,
북마크는 새 창으로 폴짝!
오늘도 캐시를 정리정돈, 힙합! 🐰✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning 제공된 변경사항은 카드 메타 데이터 반영 관련 요구사항([#131])을 대체로 충족합니다; useGetPageMeta 훅 추가와 FetchCard 컴포넌트 도입 및 myBookmark/Remind 쪽 렌더링 전환이 이를 뒷받침합니다. 그러나 "카테고리 params 동기화"가 라우터/URL 수준에서 완전히 처리되었는지는 요약만으로 확증하기 어렵고 일부 변경(예: 메뉴 앵커에 article.category.categoryId 사용)은 관련되나 전체 동기화 구현 여부는 불명확합니다. 또한 링크된 이슈 #25(Progress 컴포넌트 구현)는 이 PR에서 다뤄지지 않았습니다. 해결 방안으로는 이 PR이 실제로 닫을 이슈(예: #131)만 linked_issues에 남기거나 #25는 별도 PR로 분리해 주세요. 또한 카테고리 파라미터 동기화가 라우터/URL 수준에서 어떻게 구현되었는지(관련 파일·코드 위치 또는 설명)를 명시해 주시면 검증이 가능해집니다.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed PR 제목 "Feat(client): Card meta data 반영 & 카테고리 params 동기화"는 변경의 핵심인 카드 메타 데이터 반영과 카테고리 파라미터 동기화를 간결하게 요약하고 있어 히스토리 상에서 주된 변경점을 빠르게 파악할 수 있습니다. 한 문장으로 구성되어 불필요한 파일 목록이나 이모지가 없어 형식 면에서도 적절합니다.
Out of Scope Changes Check ✅ Passed 변경 내역은 카드 메타 데이터 반영 및 관련 훅/컴포넌트 추가를 중심으로 이루어져 있으며 FetchCard 도입, useGetPageMeta 훅 추가, 타입 export 및 옵션 메뉴 패딩 조정 등은 PR 목표와 연관성이 높아 보입니다. 주석 삭제나 스켈레톤 추가 같은 사소한 수정도 기능 범위 내로 판단됩니다. 다만 fetchOgData에서 AllOrigins 프록시를 제거한 변경은 런타임 동작에 영향을 줄 수 있으므로 배포 전 검증이 필요합니다.
Description Check ✅ Passed PR 설명은 저장소 템플릿 구조(관련 이슈, 작업 목록)를 따르고 있으며 'close #131'로 관련 이슈를 명시했고 주요 작업 항목을 구체적으로 적어두어 전반적으로 설명이 대부분 완전합니다. PR Point와 스크린샷 섹션은 비어있지만 템플릿상 선택적이므로 필수 요건은 충족하고 있습니다.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#131/card-meta-data

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the feat 기능 개발하라 개발 달려라 달려 label Sep 19, 2025
@github-actions
Copy link

github-actions bot commented Sep 19, 2025

✅ Storybook chromatic 배포 확인:
🐿️ storybook

@constantly-dev constantly-dev requested review from jjangminii and jllee000 and removed request for jjangminii and jllee000 September 19, 2025 17:24
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/client/src/pages/remind/Remind.tsx (1)

146-150: 편집 시 articleDetail 데이터 가져오기 타이밍 문제

getArticleDetail을 호출한 직후 setIsEditOpen(true)를 실행하는데, 비동기 호출이므로 articleDetail이 아직 준비되지 않았을 수 있습니다.

mutation의 onSuccess 콜백을 활용하여 데이터가 준비된 후 모달을 여는 것이 안전합니다:

  onEdit={(id) => {
-    getArticleDetail(id);
-    setIsEditOpen(true);
-    closeMenu();
+    getArticleDetail(id, {
+      onSuccess: () => {
+        setIsEditOpen(true);
+        closeMenu();
+      },
+      onError: (error) => {
+        console.error('아티클 상세 정보 조회 실패:', error);
+        closeMenu();
+      }
+    });
  }}
🧹 Nitpick comments (6)
apps/client/src/pages/remind/components/fetchCard/FetchCard.tsx (3)

13-13: useQuery 훅의 반환 값 구조분해 할당 수정 필요

useGetPageMeta 훅이 React Query의 useQuery를 사용하므로, 반환되는 객체에서 isError를 사용해야 합니다. 현재 isError: error로 별칭을 지정하고 있는데, 이는 혼동을 일으킬 수 있습니다.

다음과 같이 수정하세요:

-  const { data: meta, isPending, isError: error } = useGetPageMeta(article.url);
+  const { data: meta, isPending, isError } = useGetPageMeta(article.url);

그리고 21-22번 라인도 함께 수정:

-  const displayTitle = !error && meta.title ? meta.title : '제목 없음';
-  const displayImageUrl = !error ? meta.image : undefined;
+  const displayTitle = !isError && meta?.title ? meta.title : '제목 없음';
+  const displayImageUrl = !isError ? meta?.image : undefined;

21-22: Optional chaining을 사용한 안전한 속성 접근

meta 객체가 undefined일 수 있으므로 optional chaining을 사용하여 더 안전하게 접근해야 합니다.

-  const displayTitle = !error && meta.title ? meta.title : '제목 없음';
-  const displayImageUrl = !error ? meta.image : undefined;
+  const displayTitle = !isError && meta?.title ? meta.title : '제목 없음';
+  const displayImageUrl = !isError && meta?.image ? meta.image : undefined;

15-19: 스켈레톤 UI 크기 일치 확인 — 재사용 컴포넌트 분리 권장

  • 검증: FetchCard의 스켈레톤(w-[24.8rem], h-[35.6rem])이 design-system의 RemindCard(className="h-[35.6rem]")와 BaseCard(className에 "w-[24.8rem]")와 일치합니다. (파일: apps/client/src/pages/remind/components/fetchCard/FetchCard.tsx, packages/design-system/src/components/card/RemindCard.tsx, packages/design-system/src/components/card/BaseCard.tsx)
  • 권장(선택적): 중복 제거 및 유지보수성 향상을 위해 CardSkeleton(또는 BaseCard 크기 상수/prop)으로 분리하여 FetchCard가 재사용하도록 리팩토링하세요.
apps/client/src/pages/remind/Remind.tsx (3)

27-29: formattedDate의 의존성 배열이 비어있어 날짜가 업데이트되지 않음

formattedDate가 컴포넌트 마운트 시에만 계산되고 이후 업데이트되지 않습니다. 이는 사용자가 페이지를 오래 열어둔 경우 날짜가 변경되어도 반영되지 않을 수 있습니다.

실시간 날짜 반영이 필요한 경우 다음과 같이 수정하세요:

  const formattedDate = useMemo(() => {
    return formatLocalDateTime();
-  }, []);
+  }, []); // 현재 날짜가 변경되어도 업데이트가 필요하지 않다면 이대로 유지, 필요하다면 interval 설정 고려

또는 날짜가 변경될 때마다 자동으로 업데이트하려면:

const [formattedDate, setFormattedDate] = useState(formatLocalDateTime());

useEffect(() => {
  const interval = setInterval(() => {
    setFormattedDate(formatLocalDateTime());
  }, 60000); // 1분마다 업데이트
  
  return () => clearInterval(interval);
}, []);

84-86: 임시 로딩 UI 개선 필요

TODO 주석에 명시된 대로 로딩 상태에 대한 적절한 디자인이 필요합니다. 현재는 단순한 텍스트만 표시되고 있습니다.

로딩 스켈레톤 UI를 구현하시겠습니까? 다음과 같은 개선안을 제안합니다:

-  if (isPending) {
-    return <div>Loading...</div>;
-  }
+  if (isPending) {
+    return (
+      <div className="flex flex-col py-[5.2rem] pl-[8rem] pr-[5rem]">
+        <div className="h-8 w-32 bg-gray-200 animate-pulse rounded" />
+        <div className="mt-[3rem] flex gap-[2.4rem]">
+          <div className="h-10 w-24 bg-gray-200 animate-pulse rounded-full" />
+          <div className="h-10 w-24 bg-gray-200 animate-pulse rounded-full" />
+        </div>
+        <div className="mt-[2.6rem] flex flex-wrap gap-[1.6rem]">
+          {[1, 2, 3].map((i) => (
+            <div key={i} className="bg-gray-200 h-[35.6rem] w-[24.8rem] animate-pulse rounded-[1.2rem]" />
+          ))}
+        </div>
+      </div>
+    );
+  }

이 작업을 위한 새로운 이슈를 생성할까요?


187-187: 조건부 렌더링 로직 개선

articleDetail이 없으면 모달이 렌더링되지 않지만, 사용자는 편집 버튼을 클릭했는데 아무 반응이 없는 것처럼 보일 수 있습니다.

로딩 상태를 추가하여 사용자 경험을 개선하세요:

-  {isEditOpen && articleDetail && (
+  {isEditOpen && (
     <div className="fixed inset-0 z-[1000]" aria-modal="true" role="dialog">
       <div
         className="absolute inset-0 bg-black/60 backdrop-blur-[2px]"
         onClick={() => setIsEditOpen(false)}
       />
       <div className="absolute inset-0 flex items-center justify-center p-4">
-        <CardEditModal
-          onClose={() => setIsEditOpen(false)}
-          prevData={articleDetail}
-        />
+        {articleDetail ? (
+          <CardEditModal
+            onClose={() => setIsEditOpen(false)}
+            prevData={articleDetail}
+          />
+        ) : (
+          <div className="bg-white rounded-lg p-8">
+            <div className="animate-spin h-8 w-8 border-4 border-primary border-t-transparent rounded-full" />
+          </div>
+        )}
       </div>
     </div>
   )}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01b4e51 and 8b8385b.

📒 Files selected for processing (10)
  • apps/client/src/pages/myBookmark/MyBookmark.tsx (3 hunks)
  • apps/client/src/pages/myBookmark/components/fetchCard/FetchCard.tsx (1 hunks)
  • apps/client/src/pages/myBookmark/types/api.ts (1 hunks)
  • apps/client/src/pages/remind/Remind.tsx (5 hunks)
  • apps/client/src/pages/remind/components/fetchCard/FetchCard.tsx (1 hunks)
  • apps/client/src/pages/remind/types/api.ts (1 hunks)
  • apps/client/src/shared/apis/queries.ts (2 hunks)
  • apps/client/src/shared/components/optionsMenuButton/OptionsMenuButton.tsx (1 hunks)
  • apps/client/src/shared/hooks/usePageMeta.ts (1 hunks)
  • apps/client/src/shared/utils/fetchOgData.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: constantly-dev
PR: Pinback-Team/pinback-client#2
File: pnpm-workspace.yaml:3-3
Timestamp: 2025-08-18T13:48:59.065Z
Learning: constantly-dev는 docs 디렉터리를 컨벤션 문서 추가용으로 사용할 예정이라고 명시했습니다.
🧬 Code graph analysis (4)
apps/client/src/shared/apis/queries.ts (1)
apps/client/src/shared/utils/fetchOgData.ts (1)
  • fetchOGData (92-125)
apps/client/src/pages/myBookmark/components/fetchCard/FetchCard.tsx (2)
apps/client/src/pages/myBookmark/types/api.ts (1)
  • BookmarkArticle (7-14)
apps/client/src/shared/apis/queries.ts (1)
  • useGetPageMeta (130-138)
apps/client/src/pages/remind/components/fetchCard/FetchCard.tsx (2)
apps/client/src/pages/remind/types/api.ts (1)
  • ArticleWithCategory (8-16)
apps/client/src/shared/apis/queries.ts (1)
  • useGetPageMeta (130-138)
apps/client/src/pages/remind/Remind.tsx (3)
apps/client/src/shared/apis/axios.ts (1)
  • getArticleDetail (50-53)
apps/client/src/shared/apis/queries.ts (3)
  • useGetArticleDetail (108-116)
  • usePutArticleReadStatus (92-100)
  • useDeleteRemindArticle (102-106)
apps/client/src/pages/remind/apis/queries.ts (1)
  • useGetRemindArticles (6-16)
🔇 Additional comments (12)
apps/client/src/pages/remind/types/api.ts (1)

8-8: 인터페이스 export 변경이 적절합니다.

ArticleWithCategory 인터페이스를 export하여 다른 모듈에서 사용할 수 있도록 한 변경사항이 적절합니다. 새로운 FetchCard 컴포넌트에서 이 타입을 사용하게 되므로 필요한 변경입니다.

apps/client/src/pages/myBookmark/types/api.ts (1)

7-7: 타입 export 변경이 올바릅니다.

BookmarkArticle 인터페이스를 export하여 새로운 FetchCard 컴포넌트에서 사용할 수 있도록 한 변경사항입니다. 컴포넌트 간 타입 안전성을 보장하기 위한 적절한 수정입니다.

apps/client/src/shared/components/optionsMenuButton/OptionsMenuButton.tsx (1)

12-12: 스타일 변경이 적절합니다.

옵션 메뉴 버튼의 스타일을 justify-center에서 px-[0.8rem]으로 변경하여 좌측 정렬과 적절한 패딩을 적용한 개선사항입니다. 사용자 경험이 향상될 것으로 예상됩니다.

apps/client/src/shared/apis/queries.ts (2)

28-28: fetchOGData import가 올바릅니다.

새로운 useGetPageMeta 훅을 위해 필요한 import입니다.


130-138: React Query 훅 구현이 적절합니다.

새로운 useGetPageMeta 훅의 구현이 올바릅니다:

  • enabled: !!url로 URL이 있을 때만 실행
  • staleTime: Infinity로 무한 캐싱 설정
  • retry: false로 재시도 비활성화

이러한 설정은 페이지 메타데이터의 특성상 적절한 선택입니다.

apps/client/src/shared/hooks/usePageMeta.ts (1)

47-47: 코드 정리가 완료되었습니다.

인라인 주석을 제거한 변경사항입니다. 기능적 동작은 변경되지 않았으며, 코드가 더 깔끔해졌습니다.

apps/client/src/pages/myBookmark/components/fetchCard/FetchCard.tsx (4)

1-4: import 구문이 올바릅니다.

필요한 타입과 컴포넌트들을 적절히 import하고 있습니다.


6-10: props 인터페이스 정의가 적절합니다.

FetchCard 컴포넌트의 props를 명확하게 정의했습니다. onOptionsClick을 선택적 prop으로 처리한 것이 적절합니다.


12-23: 메타데이터 로딩 상태 처리가 적절합니다.

useGetPageMeta 훅을 사용하여 메타데이터를 가져오고, 로딩 중에는 스켈레톤 UI를 표시하는 구현이 좋습니다. 에러 상태에 대한 폴백 처리도 잘 되어 있습니다.


24-36: Card 컴포넌트 렌더링이 적절합니다.

메타데이터를 활용하여 Card 컴포넌트에 필요한 props를 올바르게 전달하고 있습니다. 날짜 형식을 한국어로 변환하는 부분도 적절합니다.

apps/client/src/pages/myBookmark/MyBookmark.tsx (2)

1-1: FetchCard import로 변경이 완료되었습니다.

기존 Card 컴포넌트에서 새로운 FetchCard 컴포넌트로 변경하고 관련 import를 적절히 수정했습니다.

Also applies to: 23-23


148-178: FetchCard 컴포넌트로의 전환이 적절합니다.

기존의 개별 props 전달 방식에서 article 객체를 통째로 전달하는 방식으로 변경했습니다. 메타데이터를 자동으로 가져오는 FetchCard의 특성을 잘 활용한 구현입니다. onClickonOptionsClick 핸들러도 그대로 유지되어 기존 기능이 보존됩니다.

Comment on lines +33 to +34
const { mutate: getArticleDetail, data: articleDetail } =
useGetArticleDetail();
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

🧩 Analysis chain

useGetArticleDetail이 mutation으로 사용되고 있음

useGetArticleDetail이 데이터를 가져오는 용도임에도 불구하고 useMutation으로 구현되어 있습니다. 이는 일반적인 패턴이 아니며, useQuery를 사용하는 것이 더 적절합니다.

현재 구현을 확인하기 위해 다음 스크립트를 실행합니다:

useQuery를 사용하도록 리팩토링하는 것을 권장합니다:

export const useGetArticleDetail = (articleId: number, enabled = false) => {
  return useQuery({
    queryKey: ['articleDetail', articleId],
    queryFn: () => getArticleDetail(articleId),
    enabled: enabled && !!articleId,
  });
};

🏁 Script executed:

#!/bin/bash
# useGetArticleDetail 훅의 구현 확인
rg -A 10 "useGetArticleDetail" apps/client/src/shared/apis/queries.ts

# 일반적으로 GET 요청은 useQuery를 사용하는 패턴 확인
rg "useGet" apps/client/src/shared/apis/queries.ts -A 3

Length of output: 776


useGetArticleDetail: useMutation → useQuery로 리팩토링 필요

apps/client/src/shared/apis/queries.ts의 useGetArticleDetail이 조회 훅임에도 useMutation으로 구현되어 있습니다 — 조회(GET)는 useQuery가 적절하므로 훅을 useQuery로 교체하고 호출부(apps/client/src/pages/remind/Remind.tsx:33-34)도 함께 수정하세요.

제안 구현 예시:

export const useGetArticleDetail = (articleId?: number, enabled = false) =>
  useQuery({
    queryKey: ['articleDetail', articleId],
    queryFn: () => getArticleDetail(articleId!),
    enabled: enabled && !!articleId,
  });

영향 호출 예시 변경:

  • 현재: const { mutate: getArticleDetail, data: articleDetail } = useGetArticleDetail();
  • 변경: const { data: articleDetail } = useGetArticleDetail(articleId, !!articleId);
🤖 Prompt for AI Agents
In apps/client/src/pages/remind/Remind.tsx around lines 33-34, the component
currently destructures a useGetArticleDetail hook implemented as a mutation
(mutate) but it should use a query; update the call to the refactored
useGetArticleDetail(query) signature by passing the articleId and an enabled
flag and remove mutate usage — e.g., replace the current destructure that gets
mutate and data with simply { data: articleDetail } =
useGetArticleDetail(articleId, !!articleId); also ensure the hook implementation
in apps/client/src/shared/apis/queries.ts is converted from useMutation to
useQuery with queryKey ['articleDetail', articleId], queryFn calling
getArticleDetail(articleId!) and enabled set to enabled && !!articleId, and
adjust any imports accordingly.

Comment on lines +79 to +85
// TODO: 2개까지 보낼 필요 없어서 일단 주석처리
// {
// name: 'AllOrigins',
// buildUrl: (targetUrl: string) =>
// `https://api.allorigins.win/get?url=${encodeURIComponent(targetUrl)}`,
// extractHtml: (response: AxiosResponse) => response.data?.contents,
// },
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

🧩 Analysis chain

프록시 서비스 간소화를 검증해 주세요.

AllOrigins 프록시를 제거하고 CORSProxy.io만 남겨둔 변경사항입니다. 단일 프록시 의존성으로 인한 장애 가능성을 고려해야 합니다.

다음 스크립트를 실행하여 CORSProxy.io 서비스의 안정성과 가용성을 확인해주세요:


🏁 Script executed:

#!/bin/bash
# CORSProxy.io 서비스 가용성과 응답 시간 테스트

echo "Testing CORSProxy.io availability and response time..."

# 테스트용 URL들
TEST_URLS=("https://example.com" "https://github.com" "https://stackoverflow.com")

for url in "${TEST_URLS[@]}"; do
  echo "Testing: $url"
  
  # CORSProxy.io를 통한 요청 테스트
  proxy_url="https://corsproxy.io/?$(echo "$url" | sed 's/:/%3A/g; s/\//%2F/g')"
  
  # 응답 시간과 상태 코드 확인
  response=$(curl -s -w "%{http_code}|%{time_total}" -o /dev/null "$proxy_url" --max-time 15)
  
  if [ $? -eq 0 ]; then
    status_code=$(echo "$response" | cut -d'|' -f1)
    time_total=$(echo "$response" | cut -d'|' -f2)
    echo "  Status: $status_code, Time: ${time_total}s"
  else
    echo "  Request failed or timed out"
  fi
  
  echo ""
done

Length of output: 242


CORSProxy.io가 테스트에서 403 응답 — AllOrigins 제거는 위험합니다.

스크립트 결과: example.com / github.com / stackoverflow.com 모두 CORSProxy.io를 통해 403을 반환했습니다. 현 구성으로는 OG 데이터 수집 실패 가능성이 높습니다.

  • 조치: apps/client/src/shared/utils/fetchOgData.ts에 AllOrigins를 fallback으로 복원하거나 백엔드 서버사이드 프록시로 대체하세요.
  • 추가: 4xx/5xx 에러 시 재시도·fallback·로깅 로직을 추가하고, CORSProxy.io의 사용 제한(정책/차단/레이트리밋)을 확인하세요.
🤖 Prompt for AI Agents
In apps/client/src/shared/utils/fetchOgData.ts around lines 79 to 85, removing
the AllOrigins fallback makes OG fetching brittle because CORSProxy.io returns
403 in tests; restore AllOrigins as a fallback option (or replace with a backend
server-side proxy) and update the fetch logic to: detect 4xx/5xx responses,
implement a retry strategy with backoff, attempt the fallback proxy when
CORSProxy.io fails, and log failures with response details and the proxy used;
also add a note/config to document CORSProxy.io usage limits and alternative
endpoints so the fallback/proxy choice is configurable.

@constantly-dev constantly-dev merged commit e634da5 into develop Sep 21, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 기능 개발하라 개발 달려라 달려

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] Card meta data 반영 & 카테고리 params 동기화

1 participant