""" Pydantic models for site-wide inspection request/response validation. """ from pydantic import BaseModel, Field, HttpUrl from typing import Optional from datetime import datetime from enum import Enum # --- Enums --- class SiteInspectionStatus(str, Enum): CRAWLING = "crawling" INSPECTING = "inspecting" COMPLETED = "completed" ERROR = "error" class PageStatus(str, Enum): PENDING = "pending" INSPECTING = "inspecting" COMPLETED = "completed" ERROR = "error" # --- Request --- class StartSiteInspectionRequest(BaseModel): url: HttpUrl max_pages: int = Field(default=20, ge=0, le=500, description="최대 크롤링 페이지 수 (0=무제한)") max_depth: int = Field(default=2, ge=1, le=3, description="최대 크롤링 깊이") class InspectPageRequest(BaseModel): url: HttpUrl # --- Core Data Models --- class DiscoveredPage(BaseModel): """크롤링으로 발견된 개별 페이지.""" url: str depth: int = 0 parent_url: Optional[str] = None inspection_id: Optional[str] = None status: PageStatus = PageStatus.PENDING title: Optional[str] = None overall_score: Optional[int] = None grade: Optional[str] = None class AggregateScores(BaseModel): """사이트 전체 집계 점수.""" overall_score: int = Field(ge=0, le=100, default=0) grade: str = "F" html_css: int = Field(ge=0, le=100, default=0) accessibility: int = Field(ge=0, le=100, default=0) seo: int = Field(ge=0, le=100, default=0) performance_security: int = Field(ge=0, le=100, default=0) total_issues: int = 0 pages_inspected: int = 0 pages_total: int = 0 class SiteInspectionConfig(BaseModel): """사이트 검사 설정.""" max_pages: int = 20 max_depth: int = 2 # --- Response Models --- class StartSiteInspectionResponse(BaseModel): site_inspection_id: str status: str = "crawling" root_url: str stream_url: str class SiteInspectionResult(BaseModel): """사이트 검사 전체 결과.""" site_inspection_id: str root_url: str domain: str status: SiteInspectionStatus created_at: datetime completed_at: Optional[datetime] = None config: SiteInspectionConfig discovered_pages: list[DiscoveredPage] = [] aggregate_scores: Optional[AggregateScores] = None class SiteInspectionListItem(BaseModel): """사이트 검사 목록 항목 (요약).""" site_inspection_id: str root_url: str domain: str status: SiteInspectionStatus created_at: datetime pages_total: int = 0 pages_inspected: int = 0 overall_score: Optional[int] = None grade: Optional[str] = None class SiteInspectionPaginatedResponse(BaseModel): """사이트 검사 목록 페이지네이션 응답.""" items: list[SiteInspectionListItem] total: int page: int limit: int total_pages: int