JunkBox apps/chess-ui 가이드
1. 역할
apps/chess-ui는 종료된 Lichess 대국과 수동 업로드 PGN을 복기하는 React + Vite 화면임.
- 대국 생성, 실시간 착수, WebSocket 관전 기능은 제공하지 않음.
- 대국 목록, 보드 복원, Stockfish 수별 분석, 연결 계정 수의 Codex 코칭을 하나의 복기 흐름으로 제공함.
react-chessboard와 chess.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-pgn의 pgn_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를 따름.