Files
AI/crawler_platform/app/web/frontend/src/hooks/useResearch.ts

38 lines
1.1 KiB
TypeScript
Raw Normal View History

Phase 1.4: 자율 연구 — by-project 엔드포인트 + ResearchPage + 세션 이력 백엔드 (crawler_platform/app/api/routes.py): - POST /research/run/by-project 추가 — config_path 의존 제거 - ResearchRunByProjectRequest: project_name 기반, DB project.config 재구성 - GraphResearchLoop 동기 실행 (장시간 가능), asdict(result) 반환 - 기존 /projects/{n}/research/sessions, /research/sessions/{job_id}는 변경 없음 프론트엔드 API (src/lib/api/): - research.ts: researchApi.startByProject/listSessions/getSession + Zod 스키마 - 결과 페이로드는 passthrough() (백엔드 dataclass 그대로 노출) TanStack Query 훅 (src/hooks/): - useResearch.ts: useStartResearch, useResearchSessions, useResearchSession - queryKeys에 research.sessions, research.session 키 ResearchPage 신규 (src/pages/ResearchPage.tsx): - 2열 레이아웃: 좌측 연구 설정 폼 + 우측 결과/이력 - 폼: 소스 선택, goal 텍스트(필수, 3~500자), 시드 URL(선택), max_steps/max_branch/max_depth/min_relevance, same_domain_only react-hook-form + zod 검증 - 결과 카드: 단계/페이지/엔티티/클레임 4종 stats + raw JSON details - 세션 이력 카드: GET /projects/{n}/research/sessions 결과 리스트 - 실행 중 안내 (장시간 가능), sonner 토스트 라우팅 & Sidebar: - App.tsx: /research/:projectId 라우트 추가 - AppShell: 사이드바에 "자율 연구" 메뉴 (Brain 아이콘) i18n: research.*, nav.research 키 (한/영) 다음 단계: Phase 1.5 — 엔티티/클레임 직접 입력 (백엔드 POST /projects/{n}/entities, /claims 신규 필요) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 19:01:52 +09:00
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import {
researchApi,
ResearchRunResult,
ResearchSessionDetail,
ResearchSessionItem,
StartResearchRequest,
} from "@/lib/api/research";
import { queryKeys } from "./queryKeys";
export function useStartResearch(projectName: string) {
const queryClient = useQueryClient();
return useMutation<ResearchRunResult, Error, StartResearchRequest>({
mutationFn: (body) => researchApi.startByProject(body),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: queryKeys.research.sessions(projectName),
});
},
});
}
export function useResearchSessions(projectName: string, limit = 25) {
return useQuery<ResearchSessionItem[]>({
queryKey: queryKeys.research.sessions(projectName),
queryFn: () => researchApi.listSessions(projectName, limit),
enabled: Boolean(projectName),
});
}
export function useResearchSession(jobId: string | null | undefined) {
return useQuery<ResearchSessionDetail>({
queryKey: queryKeys.research.session(jobId ?? ""),
queryFn: () => researchApi.getSession(jobId!),
enabled: Boolean(jobId),
});
}