Skip to content

feat: AnkiConnect 연결 실패 시 3단계 진단 + 웹 UI 상태 배너 #107

@greenheadHQ

Description

@greenheadHQ

Summary

AnkiConnect 연결 실패 시 원인을 3단계로 진단(네트워크/포트/애드온)하고, 서버 시작 로그 + API 에러 응답 + 웹 UI 배너로 사용자에게 구체적 원인을 알려주는 개선. 현재는 5초 타임아웃 후 504 TimeoutError만 반환하여 Tailscale 꺼짐/Anki 미실행/AnkiConnect 비활성을 구분할 수 없음.

Context

  • 현 상태: ankiConnect() 함수(client.ts:47-81)에서 fetch 실패 시 TimeoutError 또는 AnkiConnectError만 반환. 에러 메시지는 "AnkiConnect 응답 시간 초과. Anki가 실행 중인지 확인하세요"로 고정
  • 문제점: MiniPC(100.79.80.95:8765)에 Tailscale VPN으로 연결하는 구조에서, Tailscale 꺼짐 vs Anki 미실행 vs AnkiConnect 애드온 비활성의 구분이 불가능. 서버 시작 시에도 진단 없이 경고만 출력
  • 트리거: Tailscale 꺼진 상태에서 bun dev 실행 → 서버 시작은 되지만 모든 API 호출이 5초 타임아웃 → 웹 UI에서 무한 로딩 스피너만 표시

Affected Files

File Role Required Change
packages/core/src/anki/diagnostics.ts 신규 3단계 연결 진단 함수 (diagnoseAnkiConnect)
packages/core/src/anki/client.ts AnkiConnect 클라이언트 에러 메시지에 URL/포트 정보 + 에러 코드 기반 분기 추가
packages/core/src/index.ts Core export diagnostics export 추가
packages/server/src/index.ts 서버 엔트리 시작 시 diagnoseAnkiConnect() 호출 + /api/health 확장
packages/web/src/lib/api.ts API 클라이언트 health 응답 타입에 ankiConnect 필드 추가
packages/web/src/hooks/useAnkiStatus.ts 신규 health 엔드포인트 30초 폴링 훅
packages/web/src/components/AnkiStatusBanner.tsx 신규 연결 끊김 시 상단 경고 배너
packages/web/src/components/layout/Layout.tsx 레이아웃 AnkiStatusBanner 배치

Proposed Changes

  • packages/core/src/anki/diagnostics.ts 신규 — diagnoseAnkiConnect() 함수 구현
    • 1단계: TCP 소켓으로 호스트 도달 확인 (ETIMEDOUT/EHOSTUNREACH → "네트워크/Tailscale 연결 확인")
    • 2단계: TCP 소켓으로 포트 열림 확인 (ECONNREFUSED → "Anki가 실행 중이 아닙니다")
    • 3단계: getVersion() HTTP 호출 (실패 → "AnkiConnect 애드온 확인")
  • packages/core/src/anki/client.ts 수정 — catch 블록에서 에러 코드(ETIMEDOUT/ECONNREFUSED) 기반으로 구체적 메시지 + ANKI_CONNECT_URL 정보 포함
  • packages/server/src/index.ts 수정 — runStartupTasks()diagnoseAnkiConnect() 추가 (성공: "✅ AnkiConnect 연결 확인 (v6, 45ms)", 실패: 단계별 경고 메시지)
  • packages/server/src/index.ts 수정 — GET /api/health 응답에 ankiConnect: AnkiConnectStatus 필드 추가
  • packages/web/src/hooks/useAnkiStatus.ts 신규 — useAnkiStatus() 훅 (30초 폴링)
  • packages/web/src/components/AnkiStatusBanner.tsx 신규 — 단계별 배너 (빨강: 네트워크, 주황: Anki 미실행, 노랑: 애드온)
  • packages/web/src/components/layout/Layout.tsx 수정 — AnkiStatusBanner를 메인 콘텐츠 상단에 배치

Notes

  • 서버 시작 시 AnkiConnect 연결 불가해도 서버는 계속 실행 (MiniPC 배포 시 Anki 재시작 대기 필요)
  • Bun의 Bun.connect() TCP 소켓으로 네트워크 vs 앱 레벨 구분 가능
  • ANKI_CONNECT_URL 환경변수에서 hostname/port 파싱: new URL(process.env.ANKI_CONNECT_URL || "http://localhost:8765")

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:core핵심 도메인 로직 및 공통 라이브러리enhancementNew feature or requestpriority:medium다음 작업 주기에 처리할 작업

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions