Phase 1.2: 참고 소스 관리 — 소스 CRUD + UI
백엔드 (crawler_platform/app/api/routes.py):
- POST /projects/{name}/sources: 프로젝트에 소스 추가/업데이트
- InlineSourceConfig 재사용, KnowledgeRepository.upsert_source 호출
- DELETE /projects/{name}/sources/{source_name}: 소스 삭제
- 404 처리 + 외래 키 정리
- GET /projects/{name} 응답에 base_url 필드 추가
프론트엔드 API 레이어 (src/lib/api/):
- sources.ts: sourcesApi.create/delete + Zod 스키마 (Source, deleteSourceResponseSchema)
TanStack Query 훅 (src/hooks/):
- useSources.ts: useCreateSource, useDeleteSource (mutation + 캐시 무효화)
- queryKeys에 sources.byProject 키 팩토리
ConfigureSourcesPage 완전 교체 (src/pages/):
- 2열 레이아웃: 등록된 소스 목록 + 소스 추가 폼
- react-hook-form + zod 검증 (name 정규식, type enum, trust 0~1, rate_limit 1~600)
- 소스 카드 표시: type 배지, 신뢰도, base_url 링크, 삭제 버튼
- 빈 상태/로딩 스켈레톤/에러+재시도 모두 처리
- "크롤 진행" 버튼은 소스 1개 이상일 때만 활성
- sonner 토스트 알림
i18n locale 키 sources.* 추가 (한/영)
다음 단계: Phase 1.3 — URL 시드 크롤 (CrawlPage 실제 구현)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -14,4 +14,9 @@ export const queryKeys = {
|
||||
byDomain: (domain: string) =>
|
||||
[...queryKeys.ontology.all, "byDomain", domain] as const,
|
||||
},
|
||||
sources: {
|
||||
all: ["sources"] as const,
|
||||
byProject: (projectName: string) =>
|
||||
[...queryKeys.sources.all, "byProject", projectName] as const,
|
||||
},
|
||||
};
|
||||
|
||||
29
crawler_platform/app/web/frontend/src/hooks/useSources.ts
Normal file
29
crawler_platform/app/web/frontend/src/hooks/useSources.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { CreateSourceRequest, sourcesApi } from "@/lib/api/sources";
|
||||
import { queryKeys } from "./queryKeys";
|
||||
|
||||
export function useCreateSource(projectName: string) {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (body: CreateSourceRequest) =>
|
||||
sourcesApi.create(projectName, body),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: queryKeys.projects.detail(projectName),
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useDeleteSource(projectName: string) {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (sourceName: string) =>
|
||||
sourcesApi.delete(projectName, sourceName),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: queryKeys.projects.detail(projectName),
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user