본문으로 건너뛰기

JunkBox apps/chess-ui 가이드

1. 역할

  • apps/chess-ui는 종료된 Lichess 대국과 수동 업로드 PGN을 복기하는 React + Vite 화면임.
  • 대국 생성, 실시간 착수, WebSocket 관전 기능은 제공하지 않음.
  • 대국 목록, 보드 복원, Stockfish 수별 분석, 연결 계정 수의 Codex 코칭을 하나의 복기 흐름으로 제공함.
  • react-chessboardchess.js를 사용하며 공통 다크 테마와 jb-chess-* 스타일 자산은 shared-ui를 사용함.

2. 실행과 진입

  • Vite 개발 서버 기본 포트는 15002이며 base path는 /chess-ui/임.
  • 운영 빌드 결과는 chess-api/chess-ui로 서빙함.
  • 사용자 진입 경로는 chess-api/chess임.
  • API 요청은 /api/chess/* 상대 경로를 사용하며 개발 환경에서는 Vite proxy가 API 18002로 전달함.
  • Vite는 Chess WebSocket URL이나 실시간 상태를 주입하지 않음.

3. 화면 구성과 사용자 흐름

3.1 좌측 계정·완료 대국 목록

  • 좌측 상단은 연결 계정 상태, 연동 또는 연동 해제, PGN 업로드, 새로고침, 업로드 정책 안내를 고정 표시함.
  • 미연동 상태에서는 GET /api/chess/oauth/connect로 이동하는 계정 연동 버튼을 표시함.
  • 연동 상태에서는 DELETE /api/chess/account를 호출하는 연동 해제 버튼을 표시함.
  • PGN 업로드는 .pgn 파일을 POST /api/chess/games/upload-pgnpgn_file로 전송함. 성공하면 목록을 새로고침하고 업로드 게임을 선택함.
  • 완료 대국 목록은 계정 영역 아래에서 내부 스크롤함. 등록 시각 최신순이며 새로 업로드하거나 수집한 게임이 최상단에 표시됨.
  • 목록 행은 상대, 결과, 종료 시각, 내 색상 또는 관전 상태, 엔진 분석 상태를 압축된 두 줄 구조로 표시함.

3.2 중앙 복기 보드

  • 선택된 게임의 내 색상을 board orientation으로 사용함. 관전 대국은 백 방향을 사용함.
  • 기본 실제 진행 모드는 선택한 ply의 fen_after를 보드 position으로 사용함.
  • 최선 수 비교 모드는 선택한 ply의 fen_before를 사용하고, 초록 화살표로 엔진 최선 UCI 수, 빨강 화살표로 실제 UCI 수를 함께 표시함.
  • PV 재생 모드는 fen_before에서 principal variation을 단계별 적용하며 이전·다음 버튼으로 보드 position을 변경함.
  • 비교·PV 안내 영역은 항상 동일한 높이를 확보해 모드 전환 중 보드 위치가 변하지 않게 함.
  • 보드는 정사각 영역을 내부 패딩 없이 사용하며 드래그 착수는 허용하지 않음.
  • 보드 하단은 수순, 실제 평가, 평가 손실, 현재 차례·체크 상태를 요약함. PC/FHD 기준 4칸 한 줄, 모바일 기준 2열 grid를 사용함.
  • Lichess 원본 대국 링크는 game id를 이용해 생성함.

3.3 우측 수별 분석

  • GET /api/chess/games/{game_id}의 moves를 ply 순서로 내부 스크롤 목록에 표시함.
  • 수별 카드는 수순, 판정, 실제 평가, 평가 손실, 엔진 제안을 동일한 요약 지표 영역에 표시함. PC/FHD 기준 5칸 한 줄, 좁은 화면에서는 3칸과 2칸으로 줄바꿈함.
  • 연결 계정의 수에는 severity를 최선·좋은 수·부정확·실수·블런더 상태로 표시하고, centipawn_loss를 평가 손실로 표시함.
  • 연결 계정의 수에만 AI 코멘트와 생각해 볼 점을 각각 독립 강조 블록으로 표시함.
  • 관전 대국과 상대 수는 상대 수로 표시하며 코칭·평가 손실을 표시하지 않음.
  • 수별 카드를 선택하면 중앙 보드의 ply를 바꾸고 실제 진행 모드로 초기화함.
  • 엔진 또는 Codex 분석이 아직 없으면 완료를 가장하지 않고 분석 대기 상태를 표시함.

4. 타입과 API 모델

  • Account: { username, connected }임.
  • Game: game id, 내 색상, 상대명, 결과, 시작·종료 시각, engine_status를 가짐. 관전 대국은 result='observed'임.
  • Detail: 게임 메타, PGN, engine_status, Move[]를 가짐.
  • Move: ply, turn number, 색상, SAN, UCI, fen_before, fen_after, 내 수 여부, 엔진 평가·최선 수·PV, 코칭 필드를 가짐.
  • 프런트엔드는 HTTP API 응답만 소비하며 별도 실시간 상태를 병합하지 않음.

5. UI 규칙

  • 공통 jb-panel, jb-button, jb-chip, jb-chess-* 자산을 사용함.
  • 좌측 계정·대국 목록, 중앙 보드, 우측 수별 분석의 3열 책임을 섞지 않음.
  • 긴 대국·분석 목록은 각 패널 내부에서 스크롤하고 데스크톱 화면 전체는 고정 작업 영역으로 유지함.
  • 사용자 노출 문장형 문구는 소스에 한국어로 직접 작성하며 하십시오체와 문장 끝 마침표를 사용함.
  • Tabulator는 공통 운영 그리드에 사용할 수 있으나 Chess 복기 목록과 수별 분석은 React 카드 목록으로 렌더링함.
  • API 오류는 오류 본문을 표시하며 실시간 재연결 상태로 전환하지 않음.

6. 관련 문서

  • 백엔드·SQLite·OAuth·Stockfish 계약은 docs/junkbox/apps/guide-apps-chess-api.md를 따름.
  • 공통 UI 원칙은 docs/junkbox/common/guide-jb-common-ui.md를 따름.
  • Chess 공통 스타일 클래스와 빌드 규칙은 docs/junkbox/libs/guide-lib-shared-ui.md를 따름.