feat: 사이트 검사 최대 페이지 수 무제한 옵션 추가

- max_pages=0으로 무제한 모드 지원 (안전 상한 500페이지)
- 프론트엔드에 "무제한" 버튼 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jungwoo choi
2026-02-13 17:14:32 +09:00
parent 81b9104aea
commit 3e224d221a
3 changed files with 9 additions and 5 deletions

View File

@ -28,7 +28,7 @@ class PageStatus(str, Enum):
class StartSiteInspectionRequest(BaseModel): class StartSiteInspectionRequest(BaseModel):
url: HttpUrl url: HttpUrl
max_pages: int = Field(default=20, ge=1, le=50, description="최대 크롤링 페이지 수") max_pages: int = Field(default=20, ge=0, le=500, description="최대 크롤링 페이지 수 (0=무제한)")
max_depth: int = Field(default=2, ge=1, le=3, description="최대 크롤링 깊이") max_depth: int = Field(default=2, ge=1, le=3, description="최대 크롤링 깊이")

View File

@ -29,6 +29,9 @@ _SKIP_EXTENSIONS = {
# Type alias for progress callback: (pages_found, current_url) -> None # Type alias for progress callback: (pages_found, current_url) -> None
ProgressCallback = Callable[[int, str], Awaitable[None]] ProgressCallback = Callable[[int, str], Awaitable[None]]
# Safety limit for "unlimited" mode to prevent runaway crawls
_UNLIMITED_SAFETY_CAP = 500
def normalize_url(url: str) -> str: def normalize_url(url: str) -> str:
""" """
@ -112,7 +115,8 @@ class LinkCrawler:
max_depth: int = 2, max_depth: int = 2,
): ):
self.root_url = normalize_url(root_url) self.root_url = normalize_url(root_url)
self.max_pages = max_pages # 0 means unlimited → use safety cap
self.max_pages = max_pages if max_pages > 0 else _UNLIMITED_SAFETY_CAP
self.max_depth = max_depth self.max_depth = max_depth
parsed = urlparse(self.root_url) parsed = urlparse(self.root_url)

View File

@ -12,8 +12,8 @@ import { useInspectionStore } from "@/stores/useInspectionStore";
import { useSiteInspectionStore } from "@/stores/useSiteInspectionStore"; import { useSiteInspectionStore } from "@/stores/useSiteInspectionStore";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
/** 최대 페이지 수 옵션 */ /** 최대 페이지 수 옵션 (0 = 무제한) */
const MAX_PAGES_OPTIONS = [10, 20, 50] as const; const MAX_PAGES_OPTIONS = [10, 20, 50, 0] as const;
/** 크롤링 깊이 옵션 */ /** 크롤링 깊이 옵션 */
const MAX_DEPTH_OPTIONS = [1, 2, 3] as const; const MAX_DEPTH_OPTIONS = [1, 2, 3] as const;
@ -218,7 +218,7 @@ export function UrlInputForm() {
)} )}
onClick={() => setMaxPages(option)} onClick={() => setMaxPages(option)}
> >
{option} {option === 0 ? "무제한" : option}
</Button> </Button>
))} ))}
</div> </div>