fix: Codex 리뷰 P1/P2 버그 4건 수정

- [P1] migration runner 도입: schema_migrations 추적, advisory lock,
  단일 트랜잭션 실행, SQL 검증 (기존 DB 업그레이드 대응)
- [P1] eml extract 큐 조건 분기: extract_worker 미지원 포맷 큐 스킵
- [P2] iCalendar escape_ical_text() 추가: RFC 5545 준수
- [P2] 이메일 charset 감지: get_content_charset() 사용 + payload None 방어

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-04-02 15:55:38 +09:00
parent d93e50b55c
commit 46537ee11a
3 changed files with 150 additions and 9 deletions

View File

@@ -139,13 +139,23 @@ async def run():
# 본문 추출 (텍스트 파트)
body = ""
charset = None
if msg.is_multipart():
for part in msg.walk():
if part.get_content_type() == "text/plain":
body = part.get_payload(decode=True).decode("utf-8", errors="replace")
payload = part.get_payload(decode=True)
if payload is not None:
charset = part.get_content_charset() or "utf-8"
body = payload.decode(charset, errors="replace")
break
else:
body = msg.get_payload(decode=True).decode("utf-8", errors="replace")
payload = msg.get_payload(decode=True)
if payload is not None:
charset = msg.get_content_charset() or "utf-8"
body = payload.decode(charset, errors="replace")
if "\ufffd" in body[:1000]:
logger.debug(f"[메일] charset={charset or 'unknown'} 디코딩 중 replacement 발생")
# DB 등록
rel_path = str(eml_path.relative_to(Path(settings.nas_mount_path)))
@@ -164,11 +174,17 @@ async def run():
session.add(doc)
await session.flush()
session.add(ProcessingQueue(
document_id=doc.id, stage="extract", status="pending",
))
safe_subj = subject.replace("\n", " ").replace("\r", " ")[:200]
archived.append(subject)
# TODO: extract_worker가 eml 본문/첨부 파싱 지원 시 이 조건 제거
if doc.file_format != "eml":
session.add(ProcessingQueue(
document_id=doc.id, stage="extract", status="pending",
))
else:
logger.debug(f"[메일] {safe_subj} — eml extract 미지원, 큐 스킵")
archived.append(safe_subj)
max_uid = max(max_uid, uid)
except Exception as e: