# 버그 수정 및 작업 기록 ## 2026-06-19 - Vue 3와 Vite 기본 프로젝트를 생성했다. - Tailwind CSS Vite 플러그인을 적용했다. - 기본 샘플 화면을 프로젝트 안내 화면으로 교체했다. - UGREEN NAS Docker 테스트·운영 배포 문서를 작성했다. - AI 작업 지침과 초기 명세, 화면 구조, 할 일, 의사결정 문서를 추가했다. - Vue 프로덕션 빌드, Docker Compose 설정, Docker 이미지 빌드와 Nginx 헬스체크를 검증했다. - NAS의 기존 `uniare/config/www/images`를 읽기 전용으로 공유하는 Compose 설정과 `/card-assets` Nginx 경로를 추가했다. - 로컬 Socket.IO 기본 포트를 `31873`으로 변경하고 운영 리버스 프록시 원칙을 문서화했다. - NAS HTTP 포트 충돌을 해결하기 위해 테스트·운영 포트를 환경변수로 변경하고 `port is already allocated` 복구 절차를 추가했다. - NAS ACL로 인한 카드 이미지와 favicon의 403 오류를 해결하기 위해 Nginx 워커 UID와 정적 파일 권한을 조정했다. - 테스트는 로컬에서 수행하고 NAS에는 운영 컨테이너만 배포하도록 Compose와 배포 문서를 단순화했다. - 운영 주소 `http://playuniare.sori.studio`와 향후 데이터 마이그레이션 원칙을 문서화했다. - 3840×2160 표준 플레이 보드를 반응형 화면에 적용하고 카드 크기 기준 가이드를 추가했다. - 보드 좌우 여백에 양쪽 플레이어의 라이프와 상태 정보를 표시하는 패널을 배치했다. - `/card-assets`의 실제 카드 한 장을 보드 기준 크기로 표시하고, 보드 정규화 좌표를 사용하는 마우스·터치 드래그를 구현했다. - 로컬 개발에서 운영 카드 자산을 사용할 수 있도록 `.env.local` 예시를 현재 운영 주소로 수정했다. - 화면과 배포 점검에 사용하는 기준 카드를 `ua01/EX02BT_CGH-2-007.png`로 변경했다. - 선택 카드 조작 바를 추가하고 앞면·뒷면, 탭·언탭, 맨 위 레이어 이동을 구현했다. - 카드 뒷면 임시 스타일과 키보드 포커스 선택을 추가했다. - 독립 카드 인스턴스 3장을 겹쳐 배치하고 선택·드래그 시 최상단으로 올리는 레이어 처리를 추가했다. - 선택 카드의 정규화 좌표와 상태를 표시하고 탭 회전 상태의 보드 경계 계산을 보강했다. - 기존 덱 빌더의 `series`와 `cards` 쿼리를 검증해 카드 수량만큼 독립 인스턴스로 확장하는 덱 파서를 추가했다. - 불러온 카드를 내 덱 영역에 뒷면으로 쌓고 잘못된 항목은 오류로 표시한다. - 게임 화면의 고정 헤더를 제거하고 16:9 보드가 뷰포트를 최대한 채우도록 변경했다. - `F` 키 전체화면, 카드 더블클릭 탭·언탭, 우클릭 카드 조작 메뉴를 추가했다. - 내 덱의 1장 드로우와 셔플을 구현하고 손패 카드를 화면 하단에 자동 정렬하도록 했다. - 우클릭 메뉴에 손패, 덱 위, 덱 아래, 무덤 이동 명령을 추가하고 영역별 덱·손패 카운터를 연결했다. - 덱 위에서 1~10장을 공개해 중앙에 정렬하고 각 카드를 기존 우클릭 메뉴로 정리하는 기능을 추가했다. - Vue Router와 Pinia를 도입하고 메인 화면을 비공개 방 대기실로 변경했다. - 덱 URL 등록과 50장·동일 카드 4장·트리거별 4장·AP 분리 검증을 추가했다. - 게임 진입 후 첫 손패 7장, 1회 멀리건, 라이프 7장 세팅을 구현했다. - 턴 시작 시 선후공별 AP·드로우를 처리하고 잠기지 않은 내 필드 카드를 일괄 언탭하도록 했다. - 게임 보드 기능이 커짐에 따라 후속 작업에서 영역 상태와 조작 로직을 composable·store로 분리할 항목을 등록했다. - Socket.IO 서버와 실제 방 생성·참가·덱 등록·준비 동기화를 추가했다. - 두 플레이어가 모두 준비하면 각 좌석에 맞는 게임 시작 정보를 전달하도록 구현했다. - 방을 이동할 때 이전 Socket.IO 채널에서 확실히 나가도록 정리했다. - Nginx의 `/socket.io` 프록시와 Docker 내부 실시간 서버 서비스를 추가했다. - 방 생성부터 양쪽 게임 시작까지 검증하는 2인 통합 테스트를 추가했다. - 온라인 선후공을 서버 무작위 지정으로 변경하고 양쪽의 중복 선공 선택을 제거했다. - 양쪽 손패 확정 후 선공부터 시작하는 현재 차례와 턴 종료 교대를 추가했다. - 필드·공개·무덤·라이프 카드 상태와 비공개 영역 장수를 상대 화면에 동기화했다. - 상대 카드는 반대편 좌표로 표시하고 직접 조작할 수 없도록 했다. - 손패와 덱 카드 목록이 상대에게 전달되지 않도록 서버 공개 상태를 제한했다. - 통합 테스트 범위를 선후공, 초기 준비, 공개 카드 비공개 필터, 턴 교대까지 확장했다. - 플레이매트의 Action Point 영역을 침범하던 손패를 화면 하단 전용 트레이로 분리했다. - 손패 카드를 축소된 한 줄 목록으로 표시하고 가로 스크롤을 지원한다. - 새로고침과 짧은 네트워크 끊김 후 같은 방·좌석·턴을 복구하는 재접속 식별자를 추가했다. - 연결이 끊긴 플레이어의 자리를 60초간 보존하고 재접속 통합 테스트를 추가했다. - 내 덱 순서, 손패, 카드 위치, 멀리건과 준비 상태를 플레이어별 브라우저 저장소에 보관해 새로고침 후 복구하도록 했다. - 로컬에서 Vue만 실행해 웹소켓 오류가 발생하는 문제를 예방하도록 `npm run dev:all` 통합 개발 명령을 추가했다. - macOS 파일 감시 한도에서 Socket.IO 개발 서버가 `EMFILE`로 종료되는 문제를 피하도록 서버 개발 명령의 `--watch`를 제거했다. - 대기실과 게임 화면에 `방 나가기`를 추가하고 한쪽이 나가면 양쪽 모두 대기실 상태로 복귀하도록 했다. - 먹통이 된 방을 정리하고 즉시 새 초대 코드를 만드는 버튼을 추가했다. - 진행 중인 게임에서 대기실로 이동하거나 브라우저를 다시 열어도 게임 화면으로 자동 복귀하도록 재접속 응답을 보강했다. - 방 종료 시 재접속 세션과 플레이어별 게임 스냅샷을 삭제하도록 했다. ## 2026-06-22 - 온라인 덱 셔플을 클라이언트 난수 대신 서버의 암호학적 난수로 변경했다. - 서버가 플레이어별 비공개 덱 인스턴스 순서를 관리하도록 추가했다. - 드로우, 여러 장 공개, 라이프 배치와 덱 위·아래 이동을 서버 순서에 연결했다. - 공개 카드 상태에 리비전 번호를 추가해 늦게 도착한 이전 상태를 무시하도록 했다. - 서버 통합 테스트에 비공개 덱 셔플·드로우·되돌리기와 오래된 리비전 거부를 추가했다.