Skip to content

[FEAT] API 명세 구체화 및 정리 - #7

Merged
suwonthugger merged 5 commits into
mainfrom
feat/6-clear-up-api-spec
Jul 26, 2026
Merged

[FEAT] API 명세 구체화 및 정리#7
suwonthugger merged 5 commits into
mainfrom
feat/6-clear-up-api-spec

Conversation

@suwonthugger

@suwonthugger suwonthugger commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

👥 작업 배경 및 목적

🛠️ 주요 변경 사항

  • 핵심 변경 파일 및 로직을 요약해 주세요.
  • 코드 리뷰어가 집중해서 봐야 할 부분이 있다면 적어주세요.

🧪 테스트 결과 (선택)

👥 작업 배경 및 목적

실제 백엔드(Neo4j 온톨로지) 연동을 앞두고, API 명세를 구체화하기 위해 mock API의 타입/응답 형태를 실 서버 스펙에 맞게 정리했습니다. 뉴스 클릭 시 보여줄 파급 경로 그래프를 별도 엔드포인트로 분리하고, 온톨로지 노드/엣지 타입을 프론트가 실제로 쓰는 최소 필드로 재설계했습니다.

같은 브랜치에 아래 두 작업도 함께 포함되어 있습니다(이슈 범위 밖이지만 선행 작업으로 처리):

  • TanStack Start(SSR) 제거 → 순수 CSR(React + TanStack Router) 전환
  • 예측 검증 탭의 레이아웃이 화면 밖으로 넘쳐 페이지 전체가 스크롤되던 버그 수정

🛠️ 주요 변경 사항

  • 핵심 변경 파일 및 로직을 요약해 주세요.
  • 코드 리뷰어가 집중해서 봐야 할 부분이 있다면 적어주세요.

API 명세 구체화 (모킹 API 수정) — 핵심

  • src/types/index.ts : NodeKind를 COAL → STOCK/CONCEPT로 단순화, 엣지의가상 필드였던 polarity를 실제 온톨로지의 relationType(COMPETITOR 등)으로 대체,
    NewsRelatedStock.chain 제거, ImpactG 입 신규 추가
  • src/lib/data.ts : 위 타입 변경에 맞춰 mock 데이터의 노드 kind·엣지 relationType 매핑을 갱신
  • src/lib/api.ts : getNewsAnalysis 파급 경로 서브그래프를 만드는getNewsImpactGraph 신규 추가
  • src/mocks/handlers.ts : GET /api/n추가
  • src/lib/queries.ts : useNewsImpactGraphQuery 훅 신규 추가
  • src/lib/graphIndex.ts (신규) : 그 산) 로직을 재사용 가능하게 분리(buildGraphIndex, bfsBuild, pathTo, polarityOf)
  • src/lib/layout.ts : 좌표 계산(radi 고 BFS 로직은 graphIndex.ts로 이동
  • src/components/graph/GraphPanel.tsx : 파급 경로 그래프를 useNewsImpactGraphQuery로 조회하도록 변경(기존엔 analysis의 chain으로 프 립했음)
  • src/components/analysis/RelatedList.tsx : hop 수·경로 표시를 새 그래프 BFS 결과로 재계산하도록
    변경
  • docs/KOSLINK-FRONTEND.md : §4 데이터 모델, §5 API 명세를 새 타입/엔드포인트 기준으로 갱신, GET
    /api/news/{id}/graph 섹션 신규 추가
  • CLAUDE.md : API Pattern 섹션에 신규 엔드포인트 반영

TanStack Start 제거 → CSR 전환

  • package.json, pnpm-lock.yaml : @taack/react-router-ssr-query 의존성제거
  • vite.config.ts : tanstackStart() n/vite의 tanstackRouter 직접 등록
  • index.html (신규), src/main.tsx (신규, client.tsx 대체) : 표준 Vite SPA 엔트리로 전환
  • src/router.tsx : SSR 전용 setupRou , QueryClientProvider를 라우터Wrap으로 직접 연결
  • src/routes/__root.tsx : shellCompo 거, 일반 component+Outlet으로 전환
  • src/integrations/tanstack-query/root-provider.tsx : 미사용 placeholder export 제거
  • README.md, CLAUDE.md : 기술 스택

예측 검증 탭 레이아웃 수정

  • src/routes/index.tsx, src/styles.css : 검증 탭 컨테이너를 뉴스맵과 동일하게 화면 높이에 고정하고,
    목록/상세 카드가 남는 공간을 채워 내
  • src/components/verify/VerifyView.tsx, VerifyDetail.tsx : 컨테이너 높이 채움 + 종목별 표 영역만
    내부 스크롤되도록 변경

리뷰어가 특히 봐줬으면 하는 부분: sr경(특히 relationType으로 극성을대체한 부분)과 새 /api/news/{id}/graph 엔드포인트 계약이 실제 백엔드 스펙과 맞는지 확인 부탁드립니다.

🧪 테스트 결과 (선택)

  • 로컬 환경 테스트 결과나 실행 화면 스크린샷이 있다면 첨부해 주세요.

  • pnpm lint, pnpm build 통과 확인

  • 헤드리스 브라우저로 뉴스맵(1홉/2홉 파급, 전체 관계망 토글, 노드 하이라이트, 관심종목 브리핑)과
    예측 검증 탭(내부 스크롤, 페이지 미 콘솔/HTTP 에러 없음을 확인


📎 API 명세 (백엔드 공유용)

임시 문서 · 핵심 필드만 정리

공통 규칙

  • 커서 페이징: cursor는 opaque 값. 이전 응답의 nextCursor를 다음 요청에 그대로 실어 보냄. 마지막 페이지면 nextCursor: null.
  • 좌표(x, y) 미제공: 그래프 배치는 프론트가 originId 기준 BFS로 hop 레벨을 계산해 처리.

엔드포인트 요약

Method Path 설명 페이징
GET /api/news 뉴스 목록 조회 커서
GET /api/news/{id}/analysis 뉴스 영향 분석 패널 -
GET /api/news/{id}/graph 뉴스 파급 경로 서브그래프 (신규) -
GET /api/graph 전체 온톨로지 그래프 -
POST /api/briefing 관심종목 역방향 브리핑 -
GET /api/verify 예측 검증 데이터 news만 커서

GET /api/news — 뉴스 목록 조회

커서 페이징으로 뉴스 목록을 조회한다.

Request

GET /api/news?sector=반도체&limit=20&cursor=n3

Response 200

{
  "items": [
    {
      "id": "n1",
      "title": "SK하이닉스, HBM4 양산 위해 청주 M15X 증설 확정… 2027년 가동",
      "press": "연합뉴스",
      "publishedAt": "2026-07-20T09:12:00+09:00",
      "sector": "반도체"
    }
  ],
  "nextCursor": "n1"
}

GET /api/news/{id}/analysis — 뉴스 영향 분석 패널

요약 + 원문 + 기점 + 관련종목 + 근거를 한 번에 조회한다.

Request

GET /api/news/n1/analysis

Response 200

{
  "newsId": "n1",
  "title": "SK하이닉스, HBM4 양산 위해 청주 M15X 증설 확정… 2027년 가동",
  "sector": "반도체",
  "article": {
    "summary": [
      "SK하이닉스가 청주 M15X 공장 증설 투자를 확정했다고 공시했다.",
      "HBM4 양산 대응이 목적이며 2027년 상반기 가동이 목표다.",
      "장비 발주는 올해 4분기부터 순차 집행될 예정이다."
    ],
    "originUrl": "https://www.yna.co.kr/",
    "press": "연합뉴스",
    "publishedAt": "2026-07-20T09:12:00+09:00"
  },
  "main": {
    "nodeId": "sk",
    "name": "SK하이닉스",
    "ticker": "000660",
    "direction": "UP",
    "reason": "HBM4 증설 발표로 생산능력이 직접 확대되는 당사자"
  },
  "related": [
    { "nodeId": "hanmi", "name": "한미반도체", "ticker": "042700", "direction": "UP", "relation": "장비 공급" },
    { "nodeId": "ss", "name": "삼성전자", "ticker": "005930", "direction": "DOWN", "relation": "경쟁 관계" }
  ],
  "rationale": {
    "event": "SK하이닉스가 HBM4 대응 목적의 청주 M15X 증설을 확정",
    "propagation": "장비를 대는 한미반도체·HPSP·원익IPS에는 수주 확대 요인, 경쟁하는 삼성전자에는 점유율 압박 요인",
    "precedent": "동일 유형 증설 공시 5건 중 4건에서 장비주가 익일 평균 +3.1%"
  }
}

Response 404 — 존재하지 않는 뉴스 ID: 빈 바디.

⚠️ 그래프 경로(hop 수 등)는 이 응답에 없음 — /graph 엔드포인트에서 별도 조회.


GET /api/news/{id}/graph — 뉴스 파급 경로 서브그래프 (신규)

Request

GET /api/news/n1/graph

Response 200

{
  "newsId": "n1",
  "originId": "sk",
  "nodes": [
    { "id": "sk", "name": "SK하이닉스", "kind": "STOCK", "ticker": "000660", "sector": "반도체", "marketCap": 1200000, "direction": "UP" },
    { "id": "hanmi", "name": "한미반도체", "kind": "STOCK", "ticker": "042700", "sector": "반도체", "marketCap": 120000, "direction": "UP" },
    { "id": "hpsp", "name": "HPSP", "kind": "STOCK", "ticker": "403870", "sector": "반도체", "marketCap": 26000, "direction": "UP" },
    { "id": "wonik", "name": "원익IPS", "kind": "STOCK", "ticker": "240810", "sector": "반도체", "marketCap": 22000, "direction": "UP" },
    { "id": "ss", "name": "삼성전자", "kind": "STOCK", "ticker": "005930", "sector": "반도체", "marketCap": 4600000, "direction": "DOWN" }
  ],
  "edges": [
    { "id": "e2", "source": "sk", "target": "hanmi", "relation": "장비 공급" },
    { "id": "e6", "source": "sk", "target": "hpsp", "relation": "고압 어닐링" },
    { "id": "e5", "source": "sk", "target": "wonik", "relation": "증착 장비" },
    { "id": "e3", "source": "sk", "target": "ss", "relation": "경쟁", "relationType": "COMPETITOR" }
  ]
}

필드 규칙

  • ⚠️ 좌표(x, y)는 내려주지 않음 — 프론트가 originId 기준 BFS로 hop 레벨을 계산해 배치.
  • direction: 파급 경로에 포함된 STOCK 노드에만 존재 (없으면 필드 생략).
  • relationType 없는 엣지는 전부 "동조" 관계로 취급 — 경쟁·대체 관계일 때만 "COMPETITOR" 등을 채움.
  • kind: "CONCEPT"는 실제 온톨로지의 Role/Theme를 통칭. 프론트는 거래 가능 여부만 구분하면 됨.

GET /api/graph — 전체 온톨로지 그래프

전체 관계망 뷰용. (전체 36개 노드 · 52개 엣지 중 일부만 예시)

Request

GET /api/graph

Response 200

{
  "nodes": [
    { "id": "sk", "name": "SK하이닉스", "kind": "STOCK", "ticker": "000660", "sector": "반도체", "marketCap": 1200000 },
    { "id": "hbm", "name": "HBM", "kind": "CONCEPT", "sector": "반도체" }
  ],
  "edges": [
    { "id": "e0", "source": "sk", "target": "hbm", "relation": "주력 생산" },
    { "id": "e3", "source": "sk", "target": "ss", "relation": "경쟁", "relationType": "COMPETITOR" }
  ]
}

노드/엣지 스키마는 /news/{id}/graph와 동일 (단, direction 필드는 없음).


POST /api/briefing — 관심종목 역방향 브리핑

Request

POST /api/briefing
{
  "tickers": ["005930", "042700"]
}

tickers는 서버에 저장하지 않음 — 매 요청마다 클라이언트가 그대로 보냄.

Response 200

{
  "totalNews": 25,
  "matched": [
    {
      "ticker": "042700",
      "name": "한미반도체",
      "direction": "UP",
      "relation": "장비 공급",
      "chain": ["sk", "hanmi"],
      "newsId": "n1",
      "newsTitle": "SK하이닉스, HBM4 양산 위해 청주 M15X 증설 확정… 2027년 가동"
    }
  ],
  "unmatched": [
    { "ticker": "005930", "name": "삼성전자" }
  ]
}

GET /api/verify — 예측 검증 데이터

news는 커서 페이징, daily는 페이징 없음.

Request

GET /api/verify?sector=반도체&cursor=v10&limit=10

Response 200

{
  "daily": [
    { "date": "2026-06-26", "hitRate": 0.62 },
    { "date": "2026-07-25", "hitRate": 0.69 }
  ],
  "news": [
    {
      "newsId": "v1",
      "date": "07-17",
      "sector": "반도체",
      "title": "SK하이닉스, 엔비디아향 HBM 공급 계약 확대",
      "items": [
        { "name": "한미반도체", "predicted": "UP", "actualReturn": 3.42, "hit": true, "pathLabel": "장비 공급 · 1단계" }
      ]
    }
  ],
  "nextCursor": "v10"
}

daily(적중률 추이, 30일 고정)는 섹터·페이지와 무관하게 항상 전체를 내려줌. newsnextCursor로 페이징.

Summary by CodeRabbit

  • 새 기능
    • 뉴스별 영향 그래프를 별도 조회해 시각화할 수 있습니다.
    • 그래프 기반으로 영향 경로와 관계를 함께 확인할 수 있습니다.
  • 개선 사항
    • 영향 경로 목록 정렬 및 경로 표시 방식이 그래프 기준으로 업데이트되었습니다.
    • 예측 검증 화면의 스크롤 동작과 반응형 레이아웃이 개선되었습니다.
  • 문서
    • 기술 스택 표기와 데이터/ API 응답 범위를 최신 구조에 맞게 갱신했습니다.

suwonthugger and others added 3 commits July 23, 2026 23:38
SSR이 필요 없는 프로젝트라 TanStack Start의 서버 렌더링/하이드레이션 계층을
걷어내고, TanStack Router는 그대로 유지한 채 index.html + main.tsx 기반의
일반 Vite React SPA 구조로 변경한다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
실제 Neo4j 온톨로지(Stock/Role/Theme, SUPPLY_TO/RELATED_TO)를 가정해 mock API
형태를 정리한다. 프론트가 실제로 렌더링에 쓰는 최소 필드만 받도록 노드 종류를
STOCK/CONCEPT로, 엣지 극성은 relationType(COMPETITOR)에서 유도하도록 바꾸고,
뉴스 클릭 시 파급 경로 그래프를 GET /api/news/{id}/graph로 분리했다. 좌표는
서버가 주지 않으므로 hop 레벨 기반 배치를 프론트에서 계산하도록 그래프
BFS/인덱싱 로직을 lib/graphIndex.ts로 재사용 가능하게 뽑아냈다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
뉴스맵 탭과 달리 검증 탭 컨테이너에 높이 고정이 없어 콘텐츠가 늘어나는 만큼
페이지 전체가 스크롤됐다. .map과 동일하게 화면 높이에 맞추고, 목록·상세
카드 내부에서만 스크롤되도록 flex 레이아웃을 조정했다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@suwonthugger suwonthugger self-assigned this Jul 26, 2026
@suwonthugger suwonthugger added the feature add new feature label Jul 26, 2026
@suwonthugger suwonthugger linked an issue Jul 26, 2026 that may be closed by this pull request
2 tasks
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

React 19 + Vite CSR 구조로 전환하고 뉴스 분석의 chain 데이터를 별도 영향 그래프 API로 분리했습니다. 프런트엔드는 BFS 기반 hop·경로 계산으로 그래프와 관련 목록을 구성하며, 예측 검증 화면의 높이와 내부 스크롤 레이아웃도 조정했습니다.

Changes

CSR 앱 부트스트랩 및 라우터 구성

Layer / File(s) Summary
CSR 엔트리와 라우터 구성
index.html, src/main.tsx, src/router.tsx, src/routes/__root.tsx, src/integrations/tanstack-query/*
TanStack Start 관련 의존성·타입을 제거하고 CSR HTML 셸, MSW 초기화, React Query 컨텍스트, QueryClientProvider 기반 라우터 래퍼를 구성했습니다.
Vite 플러그인 및 스택 문서 갱신
vite.config.ts, package.json, README.md, CLAUDE.md
React Start 플러그인과 SSR 의존성을 제거하고 TanStack Router 플러그인과 React 19 + Vite CSR 구성을 반영했습니다.

영향 그래프 계약과 데이터 서비스

Layer / File(s) Summary
그래프 타입과 데모 데이터
src/types/index.ts, src/lib/data.ts, docs/KOSLINK-FRONTEND.md
노드 종류를 STOCK/CONCEPT로 단순화하고 엣지 계약을 relationType 중심으로 변경했으며 NewsImpactGraph 응답 타입과 문서를 추가했습니다.
그래프 인덱스와 레이아웃 기반
src/lib/graphIndex.ts, src/lib/layout.ts
인접 리스트, 관계 조회, BFS level·parent·pair 계산, 경로 복원 유틸을 추가하고 그래프 생성 책임을 graphIndex로 이동했습니다.
영향 그래프 API와 쿼리
src/lib/api.ts, src/lib/queries.ts, src/mocks/handlers.ts
분석 응답에서 chain을 제거하고 뉴스별 /graph 응답을 구성·조회·모킹하는 API와 Query 훅을 추가했습니다.

영향 그래프 화면 연결

Layer / File(s) Summary
그래프 장면 구성
src/components/graph/GraphPanel.tsx
영향 그래프를 조회한 뒤 BFS와 radial layout으로 장면을 구성하고 origin 정보와 STOCK 기준 노드 표시를 적용했습니다.
관련 목록 경로 계산
src/components/analysis/RelatedList.tsx
관련 항목 정렬과 impact tier를 BFS hop 기준으로 변경하고 pathTo로 표시 경로를 계산합니다.

예측 검증 화면 레이아웃

Layer / File(s) Summary
검증 화면 높이와 스크롤
src/routes/index.tsx, src/components/verify/*, src/styles.css
verify 화면에 전용 클래스를 연결하고 고정 높이, flex 영역, 내부 세로 스크롤 및 1080px 이하 반응형 오버플로우 규칙을 추가했습니다. 문서의 후속 섹션 번호도 갱신했습니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GraphPanel
  participant QueryHook
  participant ImpactGraphAPI
  participant BFSUtilities
  GraphPanel->>QueryHook: selectedNewsId로 영향 그래프 요청
  QueryHook->>ImpactGraphAPI: GET news/{newsId}/graph
  ImpactGraphAPI-->>QueryHook: nodes와 edges 응답
  QueryHook-->>GraphPanel: NewsImpactGraph 전달
  GraphPanel->>BFSUtilities: buildGraphIndex와 bfsBuild 호출
  BFSUtilities-->>GraphPanel: hop level과 경로 데이터 반환
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 34.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 API 명세 구체화와 정리라는 핵심 변경을 간결하게 요약하고 있습니다.
Description check ✅ Passed 배경, 주요 변경 사항, 이슈 번호, 테스트 결과가 모두 포함되어 템플릿 요구사항을 대부분 충족합니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/6-clear-up-api-spec

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

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 26, 2026

Copy link
Copy Markdown

Deploying koslink-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9c90385
Status: ✅  Deploy successful!
Preview URL: https://bdc5ccd4.koslink-fe.pages.dev
Branch Preview URL: https://feat-6-clear-up-api-spec.koslink-fe.pages.dev

View logs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
src/lib/api.ts (1)

169-173: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

requireNode(id)가 던지는 예외의 처리 경로를 확인해 주세요.

chain에 온톨로지에 없는 id가 섞이면 MSW 핸들러(src/mocks/handlers.ts L42-49)에서 예외가 그대로 올라가 404가 아닌 미처리 오류가 됩니다. 실제 Neo4j 백엔드 연동 시 데이터 정합성이 깨질 여지가 있으니 응답 경계에서의 처리 방침을 정해두는 게 좋습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/api.ts` around lines 169 - 173, requireNode(id)가 존재하지 않는 온톨로지 ID에서
던지는 예외가 API 응답 밖으로 전파되지 않도록, ImpactGraphNode를 생성하는 chain 처리 경계에서 예외를 포착하세요. 누락된
노드는 미처리 오류가 아닌 404 응답으로 변환하고, 정상적인 nodeIds 처리와 directionById 적용은 유지하세요.
src/main.tsx (1)

15-24: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

enableMocking() 실패 시 앱이 렌더되지 않습니다.

MSW worker.start()가 거부되면 .then 콜백이 실행되지 않아 빈 화면 + unhandled rejection만 남습니다. 개발 환경 한정이지만 원인 파악이 어렵습니다.

♻️ 렌더링을 mocking 실패와 분리
-enableMocking().then(() => {
+function render() {
   const rootEl = document.getElementById('root')!
   startTransition(() => {
     createRoot(rootEl).render(
       <StrictMode>
         <RouterProvider router={router} />
       </StrictMode>,
     )
   })
-})
+}
+
+enableMocking()
+  .catch((error) => {
+    console.error('MSW worker 시작 실패', error)
+  })
+  .finally(render)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main.tsx` around lines 15 - 24, Update the enableMocking startup flow so
the application render callback runs even when enableMocking() rejects. Handle
the mocking failure without leaving an unhandled rejection, while preserving the
existing createRoot, StrictMode, and RouterProvider rendering behavior.
src/lib/queries.ts (1)

102-111: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

useNewsImpactGraphQuerystaleTime 설정 고려

useGraphQuery는 정적 데이터라 staleTime: Infinity를 쓰는데, 뉴스별 파급 그래프도 발행 후 값이 바뀌지 않는 과거 데이터에 가까워 동일한 최적화가 적용 가능해 보입니다. 현재는 기본 staleTime이라 뉴스 간 전환·재포커스 시 불필요한 재요청이 발생할 수 있습니다.

♻️ 제안 diff
 export function useNewsImpactGraphQuery(newsId: string | null) {
   return useQuery({
     queryKey: queryKeys.newsImpactGraph(newsId ?? ''),
     queryFn: () => fetchNewsImpactGraph(newsId as string),
     enabled: !!newsId,
     placeholderData: () =>
       newsId ? (getNewsImpactGraph(newsId) ?? undefined) : undefined,
+    staleTime: Infinity,
   })
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/queries.ts` around lines 102 - 111, Update useNewsImpactGraphQuery to
set staleTime: Infinity, matching the existing useGraphQuery behavior for
effectively immutable graph data and avoiding unnecessary refetches during news
switching or window refocus.
src/components/analysis/RelatedList.tsx (1)

2-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

buildGraphIndex+bfsBuild 중복 계산 — 공유 훅으로 추출 권장

동일한 impactGraph에 대해 GraphPanel.tsxbuildFocusScene과 이 컴포넌트가 각각 독립적으로 buildGraphIndex/bfsBuild를 호출합니다(쿼리 자체는 캐시되지만 인덱스/BFS 재계산은 두 곳에서 중복). lib/queries.tsuseImpactGraphIndex(newsId) 같은 훅을 추가해 impactGraph, index, builtuseMemo로 한 번만 계산해 재사용하면 중복을 없애고 두 화면 간 계산 결과 불일치 위험도 줄일 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/analysis/RelatedList.tsx` around lines 2 - 24, Extract the
shared impact-graph derivation into a hook such as useImpactGraphIndex in
lib/queries.ts, memoizing the queried impactGraph, buildGraphIndex result, and
bfsBuild result. Update RelatedList and GraphPanel’s buildFocusScene flow to
consume this hook instead of independently calling buildGraphIndex and bfsBuild,
while preserving their existing rendering behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/KOSLINK-FRONTEND.md`:
- Around line 232-236: Update the Markdown code fences for the GET
/api/news/{id}/graph and GET /api/graph examples to include the http language
tag, preserving their existing contents and formatting.

In `@src/lib/api.ts`:
- Around line 155-173: Ensure each related record’s r.nodeId is added to nodeIds
alongside its chain values, keeping nodeIds aligned with directionById so every
related node with direction data is included in the generated nodes array.

---

Nitpick comments:
In `@src/components/analysis/RelatedList.tsx`:
- Around line 2-24: Extract the shared impact-graph derivation into a hook such
as useImpactGraphIndex in lib/queries.ts, memoizing the queried impactGraph,
buildGraphIndex result, and bfsBuild result. Update RelatedList and GraphPanel’s
buildFocusScene flow to consume this hook instead of independently calling
buildGraphIndex and bfsBuild, while preserving their existing rendering
behavior.

In `@src/lib/api.ts`:
- Around line 169-173: requireNode(id)가 존재하지 않는 온톨로지 ID에서 던지는 예외가 API 응답 밖으로
전파되지 않도록, ImpactGraphNode를 생성하는 chain 처리 경계에서 예외를 포착하세요. 누락된 노드는 미처리 오류가 아닌 404
응답으로 변환하고, 정상적인 nodeIds 처리와 directionById 적용은 유지하세요.

In `@src/lib/queries.ts`:
- Around line 102-111: Update useNewsImpactGraphQuery to set staleTime:
Infinity, matching the existing useGraphQuery behavior for effectively immutable
graph data and avoiding unnecessary refetches during news switching or window
refocus.

In `@src/main.tsx`:
- Around line 15-24: Update the enableMocking startup flow so the application
render callback runs even when enableMocking() rejects. Handle the mocking
failure without leaving an unhandled rejection, while preserving the existing
createRoot, StrictMode, and RouterProvider rendering behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ef051841-4a4a-4164-9e11-233b8ccd028b

📥 Commits

Reviewing files that changed from the base of the PR and between 2921517 and c4c3050.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (25)
  • CLAUDE.md
  • README.md
  • docs/KOSLINK-FRONTEND.md
  • index.html
  • package.json
  • src/client.tsx
  • src/components/analysis/RelatedList.tsx
  • src/components/graph/GraphPanel.tsx
  • src/components/verify/VerifyDetail.tsx
  • src/components/verify/VerifyView.tsx
  • src/integrations/tanstack-query/root-provider.tsx
  • src/lib/api.ts
  • src/lib/data.ts
  • src/lib/graphIndex.ts
  • src/lib/layout.ts
  • src/lib/queries.ts
  • src/main.tsx
  • src/mocks/handlers.ts
  • src/routeTree.gen.ts
  • src/router.tsx
  • src/routes/__root.tsx
  • src/routes/index.tsx
  • src/styles.css
  • src/types/index.ts
  • vite.config.ts
💤 Files with no reviewable changes (4)
  • src/client.tsx
  • src/integrations/tanstack-query/root-provider.tsx
  • package.json
  • src/routeTree.gen.ts

Comment thread docs/KOSLINK-FRONTEND.md
Comment thread src/lib/api.ts
suwonthugger and others added 2 commits July 26, 2026 18:47
getNewsImpactGraph가 related[].chain 원소만으로 nodeIds를 모으고 있어,
chain의 마지막 원소가 r.nodeId와 다른 레코드가 생기면 directionById에는
값이 있지만 해당 노드가 응답 nodes 배열에는 없는 상태가 될 수 있었다.
r.nodeId를 항상 명시적으로 nodeIds에 추가해 계약을 고정한다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
enableMocking이 import.meta.env.DEV로만 게이팅돼 있어 pnpm build && pnpm
preview에서는 MSW가 뜨지 않았다. placeholderData로 잠깐 정상 렌더된 뒤,
404난 실 fetch가 재시도까지 실패하면 쿼리가 error 상태가 되며 data가
undefined로 떨어져 그래프·목록이 통째로 사라졌다. docs/KOSLINK-FRONTEND.md
§11이 "빌드된 정적 파일로 발표한다"고 명시하고 있어 이 경로가 반드시
동작해야 한다. http.ts와 동일하게 VITE_API_BASE_URL 유무로 모킹 여부를
판단하도록 통일했다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main.tsx`:
- Around line 14-18: Update the startup flow around enableMocking so a rejected
promise is caught and logged, then createRoot(...).render() still executes.
Preserve the existing behavior for successful mock-worker initialization and
bypass configuration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 58adf4ac-867c-4d8d-9813-264887ef3977

📥 Commits

Reviewing files that changed from the base of the PR and between fee3757 and 9c90385.

📒 Files selected for processing (1)
  • src/main.tsx

Comment thread src/main.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature add new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] API 명세 구체화 및 정리

1 participant