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

@ -49,7 +49,11 @@ class InspectionService:
self.db = db
self.redis = redis
async def start_inspection(self, url: str) -> str:
async def start_inspection(
self,
url: str,
accessibility_standard: str = "wcag_2.1_aa",
) -> str:
"""
Start an inspection and return the inspection_id.
1. Validate URL accessibility (timeout 10s)
@ -70,7 +74,7 @@ class InspectionService:
# 4. Run inspection as background task
asyncio.create_task(
self._run_inspection(inspection_id, url, response)
self._run_inspection(inspection_id, url, response, accessibility_standard)
)
return inspection_id
@ -80,6 +84,7 @@ class InspectionService:
url: str,
inspection_id: Optional[str] = None,
progress_callback: Optional[object] = None,
accessibility_standard: str = "wcag_2.1_aa",
) -> tuple[str, dict]:
"""
Run a full inspection synchronously (inline) and return the result.
@ -93,6 +98,7 @@ class InspectionService:
inspection_id: Optional pre-generated ID. If None, a new UUID is generated.
progress_callback: Optional async callback(category, progress, current_step).
If None, progress is not reported.
accessibility_standard: Accessibility standard to use for inspection.
Returns:
(inspection_id, result_dict) where result_dict is the MongoDB document.
@ -120,7 +126,10 @@ class InspectionService:
# Create 4 checker engines
checkers = [
HtmlCssChecker(progress_callback=progress_callback),
AccessibilityChecker(progress_callback=progress_callback),
AccessibilityChecker(
progress_callback=progress_callback,
standard=accessibility_standard,
),
SeoChecker(progress_callback=progress_callback),
PerformanceSecurityChecker(progress_callback=progress_callback),
]
@ -190,6 +199,7 @@ class InspectionService:
grade=grade,
categories=categories,
summary=summary,
accessibility_standard=accessibility_standard,
)
# Store in MongoDB
@ -203,14 +213,18 @@ class InspectionService:
await cache_result(inspection_id, doc)
logger.info(
"Inspection %s completed (inline): score=%d, duration=%.1fs",
inspection_id, overall_score, duration,
"Inspection %s completed (inline): score=%d, duration=%.1fs, standard=%s",
inspection_id, overall_score, duration, accessibility_standard,
)
return inspection_id, doc
async def _run_inspection(
self, inspection_id: str, url: str, response: httpx.Response
self,
inspection_id: str,
url: str,
response: httpx.Response,
accessibility_standard: str = "wcag_2.1_aa",
) -> None:
"""
Execute 4 category checks in parallel and store results.
@ -234,7 +248,10 @@ class InspectionService:
# Create 4 checker engines
checkers = [
HtmlCssChecker(progress_callback=progress_callback),
AccessibilityChecker(progress_callback=progress_callback),
AccessibilityChecker(
progress_callback=progress_callback,
standard=accessibility_standard,
),
SeoChecker(progress_callback=progress_callback),
PerformanceSecurityChecker(progress_callback=progress_callback),
]
@ -322,6 +339,7 @@ class InspectionService:
grade=grade,
categories=categories,
summary=summary,
accessibility_standard=accessibility_standard,
)
# Store in MongoDB
@ -347,8 +365,8 @@ class InspectionService:
})
logger.info(
"Inspection %s completed: score=%d, duration=%.1fs",
inspection_id, overall_score, duration,
"Inspection %s completed: score=%d, duration=%.1fs, standard=%s",
inspection_id, overall_score, duration, accessibility_standard,
)
except Exception as e: