feat: 접근성 검사 표준 선택 기능 — WCAG/KWCAG 버전별 선택 지원

3가지 검사 모드(한 페이지, 사이트 크롤링, 목록 업로드) 모두에서 접근성 표준을
선택할 수 있도록 추가. WCAG 2.0 A/AA, 2.1 AA, 2.2 AA와 KWCAG 2.1, 2.2를
지원하며, KWCAG 선택 시 axe-core 결과를 KWCAG 검사항목으로 자동 매핑.

- KWCAG 2.2 (33항목) / 2.1 (24항목) ↔ WCAG 매핑 테이블 (kwcag_mapping.py)
- AccessibilityChecker에 표준 파싱 및 KWCAG 변환 로직 추가
- 전체 API 파이프라인에 accessibility_standard 파라미터 전파
- 프론트엔드 3개 폼에 공용 표준 선택 드롭다운 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jungwoo choi
2026-02-14 08:36:14 +09:00
parent 21259eb40a
commit bffce65aca
19 changed files with 857 additions and 59 deletions

View File

@ -50,6 +50,7 @@ class SiteInspectionService:
max_pages: int = 20,
max_depth: int = 2,
concurrency: int = 4,
accessibility_standard: str = "wcag_2.1_aa",
) -> str:
"""
Start a site-wide inspection.
@ -84,6 +85,7 @@ class SiteInspectionService:
"max_pages": max_pages,
"max_depth": max_depth,
"concurrency": concurrency,
"accessibility_standard": accessibility_standard,
},
"discovered_pages": [],
"aggregate_scores": None,
@ -91,13 +93,16 @@ class SiteInspectionService:
await self.db.site_inspections.insert_one(doc)
logger.info(
"Site inspection started: id=%s, url=%s, max_pages=%d, max_depth=%d, concurrency=%d",
site_inspection_id, url, max_pages, max_depth, concurrency,
"Site inspection started: id=%s, url=%s, max_pages=%d, max_depth=%d, concurrency=%d, standard=%s",
site_inspection_id, url, max_pages, max_depth, concurrency, accessibility_standard,
)
# Launch background task
asyncio.create_task(
self._crawl_and_inspect(site_inspection_id, url, max_pages, max_depth, concurrency)
self._crawl_and_inspect(
site_inspection_id, url, max_pages, max_depth, concurrency,
accessibility_standard=accessibility_standard,
)
)
return site_inspection_id
@ -272,6 +277,7 @@ class SiteInspectionService:
max_pages: int,
max_depth: int,
concurrency: int = 4,
accessibility_standard: str = "wcag_2.1_aa",
) -> None:
"""
Background task that runs in two phases:
@ -366,6 +372,7 @@ class SiteInspectionService:
page_url=page["url"],
page_index=idx,
total_pages=len(discovered_pages),
accessibility_standard=accessibility_standard,
)
for idx, page in enumerate(discovered_pages)
]
@ -428,6 +435,7 @@ class SiteInspectionService:
page_url: str,
page_index: int,
total_pages: int,
accessibility_standard: str = "wcag_2.1_aa",
) -> None:
"""Inspect a single page with semaphore-controlled concurrency."""
async with semaphore:
@ -436,6 +444,7 @@ class SiteInspectionService:
page_url=page_url,
page_index=page_index,
total_pages=total_pages,
accessibility_standard=accessibility_standard,
)
async def _inspect_single_page(
@ -444,6 +453,7 @@ class SiteInspectionService:
page_url: str,
page_index: int,
total_pages: int,
accessibility_standard: str = "wcag_2.1_aa",
) -> None:
"""Run inspection for a single discovered page."""
inspection_id = str(uuid.uuid4())
@ -480,6 +490,7 @@ class SiteInspectionService:
url=page_url,
inspection_id=inspection_id,
progress_callback=page_progress_callback,
accessibility_standard=accessibility_standard,
)
overall_score = result.get("overall_score", 0)