Files
basket_utils/SERVER-SETUP.md
T

14 KiB
Raw Blame History

Fastify · MongoDB 실행 안내

저장소

사용자가 지정한 MongoDB 서버는 172.16.0.7:27017, 프로젝트 DB는 basket_utils다. SQLite 선택은 이 설정으로 대체한다. 서버는 MongoClient 연결 풀을 재사용한다.

프로젝트 루트 .config.json에서 설정을 관리한다. 예시는 .config.json.sample에 있으며 새 환경에서는 복사해 사용한다. 기존 설정 파일이 있으면 덮어쓰지 않는다.

Copy-Item .config.json.sample .config.json
{
  "mongodb": {
    "uri": "mongodb://172.16.0.7:27017",
    "db": "basket_utils"
  },
  "server": {
    "host": "0.0.0.0",
    "port": 3000,
    "mode": "development",
    "allowedOrigins": [
      "http://localhost:5173",
      "http://127.0.0.1:5173",
      "http://192.168.5.10:5173"
    ],
    "secureCookie": false
  },
  "bootstrap": { "password": "" },
  "qa": { "db": "basket_utils_qa", "password": "" }
}

MongoDB 인증 정보가 필요하면 mongodb.uri에 설정한다. 실제 .config.json은 Git 추적에서 제외하고 예시 파일에는 비밀번호를 넣지 않는다. 설정 변경 후 서버를 재시작한다.

개발 실행

npm install
npm run dev

Vite 화면은 PC에서 http://localhost:5173, 같은 네트워크의 휴대폰에서 http://192.168.5.10:5173으로 접근한다. PC의 IP가 바뀌면 주소도 바뀐다. Vite의 /api 요청은 server.port에 지정한 Fastify 포트로 전달된다.

LAN 접속에는 Windows 방화벽과 공유기의 기기 간 통신 허용도 필요하다. MongoDB 주소와 휴대폰이 접속할 웹 주소는 별개다.

최초 운영자

공개 기본 운영자 계정은 만들지 않는다. 사용할 이메일로 회원가입한 뒤, 서버 PC에서 해당 계정을 명시적으로 승격할 수 있다.

node .\server\bootstrap-admin.js --email=your-email@example.com --promote-existing

your-email@example.com을 실제 가입한 이메일로 바꾼다. 기존 비밀번호는 유지된다. 이후 /admin에서 운영자 계정으로 로그인하여 다른 사용자의 가입 신청을 승인한다. 웹에서 최초 운영자 권한을 자동 부여하지 않는다.

PowerShell에서는 npm.ps1을 통해 실행할 때 옵션이 npm 자체 설정으로 해석되어 스크립트에 전달되지 않을 수 있으므로 위처럼 Node로 직접 실행한다. 명령 끝에 역슬래시(\)를 붙이지 않는다.

새 운영자를 직접 만들 때는 .config.jsonbootstrap.password에 사용할 비밀번호를 일시적으로 설정하고 아래 명령을 실행한다. 실행 후 비밀번호 값은 다시 빈 문자열로 바꾼다.

node .\server\bootstrap-admin.js --email=your-email@example.com

사용자 승인과 팀 참여

  1. 최초 방문자는 로그인 화면에서 사용 신청으로 이동해 이메일·비밀번호·표시 이름을 등록한다.
  2. 서비스 운영자는 별도 /admin 페이지에서 승인 대기 사용자를 확인하고 이용을 승인한다. 개발 주소는 http://localhost:5173/admin이며, 운영 환경에서는 서비스 주소 뒤에 /admin을 붙인다.
  3. 승인된 사용자가 다시 로그인하면 내 팀에서 새 팀을 만들거나 기존 팀 이름을 검색할 수 있다. 서비스 이용 승인만으로 기존 팀에 자동 가입되지 않는다.
  4. 기존 팀을 검색해 가입을 신청하면 팀 소유자의 승인을 기다린다.
  5. 팀 소유자는 팀원 관리에서 가입 신청을 승인하고 열람자 또는 편집자 권한을 부여한다. 이후에도 팀원별 권한을 변경할 수 있다.

열람자는 팀 전술을 조회할 수 있고 서버에 저장할 수 없다. 편집자와 소유자는 팀 전술을 서버에 저장할 수 있다. 소유자 권한 이전은 지원하지 않는다. 서비스 운영자 권한과 팀 소유자 권한은 별개이며, 운영자도 다른 팀에 자동으로 참여하지 않는다.

가입 신청은 MongoDB team_join_requests에 저장한다. 서버 시작 시 필요한 컬렉션 인덱스를 준비하며, 기존 계정·팀·전술을 삭제하거나 다시 만들 필요는 없다. 코드 반영 후에는 서버를 재시작하고 운영 화면은 다시 빌드한다.

팀 검색은 이름 두 글자 이상으로 검색하며 한 번에 최대 20개를 표시한다. 가입 대기/승인 상태는 내 가입 요청에서 확인하고, 팀 목록 새로고침으로 최신 상태를 불러온다. 팀 소유자는 내 팀 아래의 팀원 관리에서 승인하고, 기존 팀원의 역할을 선택한 뒤 역할 저장을 누른다.

팀 전술 목록

로그인 → 팀 선택 → 전술 목록 → 저장된 전술 열기 또는 새 전술 시작 → 전술 캔버스 순서로 사용한다. 새 팀을 만든 경우에도 먼저 비어 있는 전술 목록으로 이동한다.

전술 목록에는 해당 팀의 저장된 전술 이름과 수정 시각을 표시한다. 새 전술은 이름과 수비 형태를 정한 뒤 시작하고, 캔버스에서 저장하면 서버 목록에 추가된다. 열람자는 기존 전술을 열 수 있지만 새 전술 생성과 서버 저장은 할 수 없다.

캔버스의 전술 목록으로 돌아오면 다른 전술을 선택할 수 있고, 목록의 팀 목록으로에서 팀을 바꿀 수 있다. 이 기기에 남은 임시 저장본은 별도의 임시 저장 계속하기로 연다. 저장된 전술의 열기 버튼은 서버에 저장된 내용을 불러온다.

2026-09-08 전술 목록 UX 검증: 메모리 QA 서버에서 팀 선택 후 목록 진입, 기존 전술 열기, 임시본 이어서 편집, 서버 저장본과 임시본 구분, 이름·수비 형태를 지정한 새 전술 생성/저장/목록 반영, 새 팀의 빈 목록, 열람자의 생성·저장 제한을 확인했다. PC 및 모바일 화면 크기에서 목록 배치를 확인했고 전체 테스트 115개와 빌드가 통과했다.

운영 실행

.config.jsonserver.modeproduction, server.allowedOrigins를 실제 HTTPS 서비스 주소 배열, server.secureCookietrue로 설정한다.

npm run build
npm run server

Fastify가 dist 화면과 API를 제공한다. 실제 도메인을 허용 출처로 설정하고 HTTPS 프록시 뒤에서 실행한다. 운영 세션 쿠키는 Secure를 사용한다.

휴대폰의 HTTP LAN 화면 접속만으로 OS 파일 공유 조건이 충족되지는 않는다. 카카오톡으로 MP4 파일을 직접 공유하는 실기기 검증에는 지원 브라우저와 신뢰할 수 있는 HTTPS가 필요하다.

검증

npm test
npm run build

테스트 계정은 격리된 테스트 저장소에서 사용한다. 운영 basket_utils DB에 QA용 계정을 임의로 넣거나 기존 컬렉션을 삭제하지 않는다.

2026-09-08 검증 결과: 106개 테스트 및 빌드 통과. 별도 QA DB에서 로그인·승인·다중 팀 저장/전환과 서버 재시작 후 데이터 유지, PC/모바일 화면, MP4 생성·재생을 확인했다. 기존 번들 크기 경고는 남아 있다.

JSON 설정 전환 후에는 설정 로더 검증 5개와 정적 파일 보호 검증 1개를 추가해 총 112개 테스트와 빌드가 통과했다. 설정 파일이 없거나 JSON 구문·값 타입이 잘못되면 시작 시 오류를 안내하며, JSON 구문 오류에 설정 원문을 출력하지 않는다. 운영 모드에서는 Secure 쿠키가 강제되고 개발용 HTTP 출처는 허용하지 않는다.

QA seed 명령은 basket_utils_qa 또는 basket_utils_qa_ 뒤에 영문·숫자·하이픈이 붙은 DB 이름만 허용한다. 이번 검증 DB는 basket_utils_qa_20260908review이며 테스트 데이터는 운영 DB와 분리되어 있다. QA 서버는 검증 후 종료했다.

팀 가입·관리 화면 추가 검증 (2026-09-08)

  • 전체 테스트 115개 통과, 배포 빌드 및 git diff --check 통과. 기존 번들 크기 경고는 유지된다.
  • 이번 화면 검증은 운영 MongoDB와 연결하지 않는 로컬 메모리 QA 서버에서 진행했다.
  • 사용 신청 → 별도 /admin 로그인/승인 → 신청자 로그인 → 팀 검색/가입 신청 → 소유자 승인 → 열람자/편집자 역할 저장을 브라우저에서 확인했다.
  • 가입 대기 상태의 새로고침 유지, 일반 계정의 관리자 페이지 접근 제한, 관리자 직접 로그인/새로고침/뒤로가기, 계정 전환 후 화면 초기화를 확인했다.
  • 새 팀 생성, 편집자의 서버 저장, 열람자의 저장 버튼 비활성화와 서버 가져오기 대상 제외를 확인했다. 서버 테스트에서도 같은 세션의 역할 변경 이후 저장 권한을 검증한다.
  • PC 1280×900 및 모바일 390×844 화면에서 가입 양식·승인·팀원 관리 배치를 확인했다. 모바일은 브라우저 화면 크기 검증이며 실물 휴대폰 검증은 아니다.

기존 편집 화면과 모바일 전체화면

  • 로그인 후 팀을 선택하면 전술 목록을 먼저 표시한다. 저장된 전술을 열거나 이름과 수비 형태를 정해 새 전술을 시작한다.
  • 일반 화면은 기존 선수 목록·행동 도구·단계/재생 UI를 유지한다. 기본 이동 모드에서 선수 드래그는 이동 행동을 기록하며, 명시적으로 배치를 선택했을 때만 시작 위치를 변경한다.
  • 모바일 전체화면은 화면 배치만 바꾸며 현재 단계와 기록된 행동을 유지한다. 도구와 재생 UI는 코트 크기를 줄이지 않는 접이식 오버레이로 표시한다.
  • 브라우저 전체화면은 사용자가 버튼을 눌렀을 때만 요청하고, 성공하면 가로 방향 잠금을 요청한다. 종료 시 잠금을 해제한다. 방향 잠금은 브라우저 지원에 따라 실패할 수 있으므로, 전체화면 편집 중 세로 화면에서는 회전 안내와 종료 버튼을 표시하고 편집 입력을 차단한다. 가로 화면이 되면 안내를 닫는다. 브라우저 자체 종료 안내의 표시 시간은 앱에서 제어하지 않는다.
  • 패스는 현재 단계의 최종 공 소유 선수를 선택했을 때만 표시한다. 패스 후 기존 소유자의 패스·슛은 숨기고, 공을 받은 선수를 선택하면 표시한다.
  • 전체화면 왼쪽은 선수 구성 버튼만 표시한다. 오른쪽 상단에는 저장·전체화면·메뉴, 하단에는 단계·행동 버튼을 배치한다. 행동 도구 모음과 별도의 실행 취소·다시 실행 도구박스는 오른쪽 중앙에 배치한다. 단계 패널은 최대 160px 폭으로 목록, 진행도, 재생 버튼을 세로로 배치하며 코트 크기를 바꾸지 않는다.
  • 세로 일반 화면은 코트와 도구 영역을 실제 레이아웃으로 분리한다. visualViewport.height 변화를 반영해 주소창을 제외한 표시 높이에 화면을 맞추며, 페이지 스크롤 대신 패널 내부 스크롤을 사용한다. 가로 전체화면은 코트 전체를 좌우 도구 사이의 중앙 영역에 맞춰 가로로 늘려 표시한다. 끝선의 작은 안전 여백을 제외하고 중앙 영역을 채우며, 선수·경로·드래그는 같은 카메라 좌표계를 사용한다. 일반 화면과 영상 출력의 비율, 행동 편집의 경로·좌표·시선 설정은 유지한다.
  • 재생 바는 이전·다음 버튼 사이의 폭을 사용하고, 현재 시간 / 전체 시간은 바 아래에 작은 중앙 정렬 자막으로 표시한다.
  • 모바일 전체화면 진입 버튼은 저장 버튼과 구별되는 진한 청록색과 1.8초 주기의 부드러운 확대·축소 및 퍼지는 테두리로 표시한다. 전체화면 진입 후에는 강조 애니메이션을 멈추며, 동작 줄이기 설정에서는 색상만 강조한다. 전체화면 SVG와 선수 구성 아이콘은 버튼 중앙에 정렬한다.

이전의 전체 화면 공통 작전판/움직임 모드 분리는 요구 범위와 달라 철회했다.

2026-09-08 추가 수정 검증: 전체 118개 테스트와 빌드 통과. 메모리 QA 서버에서 390×844 세로 전체화면의 회전 안내·종료·편집 영역 inert 처리, 가로 전환 시 안내 해제, 844×390 및 740×360의 단계/행동 패널 동시 표시와 코트 크기 유지, 단계 추가, 드래그 기록과 실행 취소/다시 실행, 패스 후 공 소유권에 따른 패스·슛 표시를 확인했다. 740px 행동 패널의 가로 넘침도 수정했다. 일반 PC 1280×900과 모바일 화면의 기존 UI를 유지한다. 이 검증은 브라우저 화면 크기 검증이며 실물 휴대폰의 방향 잠금 성공을 보증하지 않는다.

2026-09-08 수정 검증: 전체 118개 테스트, 빌드, git diff --check 통과. 사용하지 않는 이전 모드 전용 함수와 해당 테스트는 제거했다. 메모리 QA 서버에서 연속 드래그로 두 구간 추가 → 한 구간 실행 취소/다시 실행 → 서버 저장 → 목록 복귀 → 재열기 후 같은 경로 유지까지 확인했다. 새 전술도 이동 모드로 시작하며 첫 드래그가 경로를 만든다.

1280×900 일반 화면은 기존 3열 UI를 유지하고 전체화면 버튼을 숨긴다. 390×844 일반 화면의 가로 넘침과 버튼 클릭 영역을 확인했다. 844×390 및 740×360 가로 전체화면에서는 도구·단계 목록을 함께 열어도 코트 영역 크기가 유지되고 선수 10명이 가려지지 않는다. 두 패널을 연 상태의 선수 드래그와 단계 추가, 전체화면 종료 후 현재 단계 유지, 재진입 시 재생 바 닫힘을 확인했다. 브라우저 자체 전체화면 진입과 QA 전용 Permissions-Policy: fullscreen=() 환경의 대체 화면을 각각 확인했다. 실물 휴대폰의 터치 감도와 브라우저 안내 지속 시간은 별도 확인 대상이다. 기존 번들 크기 경고는 유지된다.