feat(jamie-journal): implement SpellingChecker (built-in medical dict + optional hanspell)

This commit is contained in:
2026-03-29 07:28:49 +09:00
parent 1d236192b0
commit 311adaf06c

View File

@@ -307,8 +307,82 @@ class ComplianceChecker:
class SpellingChecker: class SpellingChecker:
"""Checks for common spelling/terminology issues in medical/beauty content.""" """Checks for common spelling/terminology issues in medical/beauty content."""
# Format: wrong_term -> (correct_term, category)
MEDICAL_DICT: Dict[str, Tuple[str, str]] = {
'쌍커풀': ('쌍꺼풀', '눈 성형'),
'쌍거풀': ('쌍꺼풀', '눈 성형'),
'안겸하수': ('안검하수', '눈 성형'),
'눈꺼플': ('눈꺼풀', '눈 성형'),
'눈커풀': ('눈꺼풀', '눈 성형'),
'네시경': ('내시경', '이마 성형'),
'거상 술': ('거상술', '이마 성형'),
'앤도타인': ('엔도타인', '이마 성형'),
'봉합 사': ('봉합사', '이마 성형'),
'히알루론 산': ('히알루론산', '필러'),
'히알류론산': ('히알루론산', '필러'),
'지방 이식': ('지방이식', '동안 성형'),
'눈밑지방': ('눈밑 지방', '눈 성형'),
'다크 서클': ('다크서클', '눈 성형'),
'팔자주름': ('팔자 주름', '동안 성형'),
'절게법': ('절개법', '눈 성형'),
'매몰 법': ('매몰법', '눈 성형'),
'눈썹밑절개': ('눈썹밑 절개', '이마 성형'),
}
def check(self, content: str) -> List[ValidationIssue]: def check(self, content: str) -> List[ValidationIssue]:
return [] issues: List[ValidationIssue] = []
lines = content.split('\n')
# Tier 1: built-in medical dictionary scan
for line_idx, line in enumerate(lines, start=1):
for wrong, (correct, category) in self.MEDICAL_DICT.items():
if wrong == correct:
continue
if wrong in line:
issues.append(ValidationIssue(
checker='SpellingChecker',
issue_type='medical_misspelling',
severity='medium',
line_number=line_idx,
matched_text=wrong,
message=f'[{category}] 잘못된 표기: "{wrong}""{correct}"',
suggestion=f'"{wrong}""{correct}"로 수정하세요.',
))
# Tier 2: optional py-hanspell
try:
from hanspell import spell_checker # type: ignore
for line_idx, line in enumerate(lines, start=1):
stripped = line.strip()
# Skip code blocks, short lines, headings
if stripped.startswith('```') or stripped.startswith('#') or len(stripped) < 5:
continue
try:
result = spell_checker.check(stripped)
if result.checked != stripped:
issues.append(ValidationIssue(
checker='SpellingChecker',
issue_type='hanspell_correction',
severity='medium',
line_number=line_idx,
matched_text=stripped[:80],
message=f'맞춤법 교정 제안: {result.result}',
suggestion=result.checked[:200],
))
except Exception:
pass # Network or parse error — skip this line
except ImportError:
issues.append(ValidationIssue(
checker='SpellingChecker',
issue_type='hanspell_unavailable',
severity='info',
line_number=0,
matched_text='',
message='py-hanspell이 설치되어 있지 않아 맞춤법 자동 검사를 건너뜁니다.',
suggestion='pip install py-hanspell 을 실행하면 한국어 맞춤법 자동 검사가 활성화됩니다.',
))
return issues
class LinkRecommender: class LinkRecommender: