개발 문서
Immercy 운영 환경 설정
목표 주소는 https://immercy.eturnalove.com입니다. Next.js는 Vercel에 배포하고 MongoDB Atlas에는 계정·프로젝트·사용량·결제 기록을 저장합니다. 게임 빌드와 표지 원본은 Private Vercel Blob에 저장합니다. Google Drive는 이번 서비스의 파일 전달 경로에 사용하지 않습니다.
저장소의 코드·설정 예제를 준비한 상태입니다. 외부 계정, 결제 수단, DNS, 운영 비밀 값은 아직 만들어지거나 변경되지 않았습니다. 다음 순서대로 준비합니다. 검증은 정적 검토 범위이므로 아래 배포·로그인·실기기 확인을 완료하기 전에는 운영 검증 완료로 보지 않습니다.
1. 저장소와 Vercel 프로젝트
- 이 변경을 검토한 뒤 운영할 GitHub 저장소에 반영합니다. 현재 작업 자체는 커밋·푸시·배포를 실행하지 않습니다.
- Vercel 계정을 만들고 GitHub 저장소 접근을 연결한 뒤 새 프로젝트로 가져옵니다.
- Framework Preset은 Next.js, Root Directory는 저장소 루트로 지정합니다. 플랫폼의
src/app을 배포합니다. 기존server.jsLAN 데모는 운영 진입점이 아닙니다. - Node.js는 저장소
package.json의 24.x 요구사항에 맞추고, Install Command는npm ci, Build Command는npm run build를 사용합니다. Output Directory는 Next.js 기본값으로 둡니다. npm 작업 공간에는 SDK·CLI·MCP가 포함됩니다. - 운영 서비스와 시간별 유지보수 작업을 지원하는 Vercel 요금제를 선택하고 비용 알림을 설정합니다. 계정 결제·플랜 변경은 운영자가 Vercel 화면에서 직접 결정합니다.
종속성 버전은 package.json과 package-lock.json에 고정되어 있습니다. 배포 중 임의로 latest로 바꾸거나 기존 데모의 실행 명령을 사용하지 않습니다.
2. MongoDB Atlas
- Atlas 조직·프로젝트를 만들고 Vercel 함수와 가까운 지역에 클러스터를 준비합니다. 다중 문서 트랜잭션을 지원하는 구성이 필요합니다. 이 구현은 단독
mongod서버를 대상으로 하지 않습니다. - Database Access에서 애플리케이션 전용 DB 사용자를 만듭니다. 대상 DB
immercy의 읽기·쓰기만 허용하고 Atlas 계정 비밀번호와 구분합니다. - Network Access에는 애플리케이션 배포 환경의 송신 경로를 허용합니다. 운영에서는 Vercel에서 고정 송신 IP를 구성한 뒤 해당 IP를 등록하는 구성을 사용합니다. 로컬 인덱스 생성 때는 해당 관리 PC의 IP를 추가합니다. Atlas의 목록은 DB 사용자 인증과 별도로 적용됩니다. Atlas IP 접근 목록
- Connect → Drivers에서 Node.js용 SRV 연결 문자열을 복사합니다. 비밀번호는 URI 인코딩된 실제 DB 비밀번호를 사용하고 Vercel에
MONGODB_URI로 저장합니다.MONGODB_DB=immercy를 함께 등록합니다. - Atlas 백업 정책과 복원 권한을 설정합니다. Preview 개발에는
immercy_preview같은 별도 DB와 별도 DB 사용자를 사용합니다.
인덱스는 서버 시작 시 자동으로 생성하지 않습니다. 저장소 루트에서 .env.local에 관리할 DB 연결 값을 넣은 다음 아래 명령을 한 번 직접 실행합니다. 실행 전 DB 이름이 맞는지 확인합니다.
npm ci
npm run db:indexes
scripts/database-indexes.ts는 인증 세션/시그널 등의 만료 인덱스, 사용량 집계, 결제 등록 번호의 중복 방지 인덱스를 준비합니다. 실패한 경우 배포를 열기 전에 인덱스 오류와 기존 중복 자료를 확인합니다. .env.local은 커밋하지 않습니다.
3. Google 로그인
-
Google Cloud 프로젝트를 생성하고 Google Auth Platform에서 브랜드·대상 사용자·연락처 정보를 입력합니다.
-
외부 사용자가 가입할 서비스라면 대상 사용자 설정과 게시 상태를 그에 맞게 준비합니다. 준비 중에는 테스트 사용자로 운영 담당자의 계정을 등록합니다.
-
OAuth 클라이언트를 웹 애플리케이션으로 만들고 승인된 리디렉션 URI에 아래 값을 정확하게 입력합니다.
https://immercy.eturnalove.com/api/auth/callback -
Google 설정에서 JavaScript 출처를 요구하면
https://immercy.eturnalove.com을 입력합니다. 실제 인증은 서버에서 코드 교환과 토큰 검증을 수행합니다. -
클라이언트 ID와 비밀을
GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET에 등록합니다. 사용 범위는openid email profile입니다. Google Drive 권한은 요청하지 않습니다.
Preview의 로그인도 필요하면 전용 고정 Preview 주소와 별도 OAuth 클라이언트를 준비합니다. 임의의 모든 vercel.app 주소를 운영 콜백으로 허용하지 않습니다. 콜백 URI는 완전히 일치해야 합니다. Google 웹 서버 OAuth 안내
4. Private Vercel Blob
- Vercel 프로젝트의 Storage에서 Blob 저장소를 만들 때 접근 유형을 Private로 선택합니다.
- 운영 프로젝트의 Production 환경에 연결합니다. 빌드와 표지는 이 저장소를 함께 사용합니다.
BLOB_READ_WRITE_TOKEN이 운영 환경에 등록되었는지 확인합니다. 이 구현의 업로드 승인 과정은 서버 토큰이 필요하므로 브라우저나 게임 개발자에게 이 토큰을 공유하지 않습니다.- Preview에는 별도 Private 저장소와 별도 토큰을 연결합니다. 공개 Blob 저장소나 Google Drive 공유 링크로 값을 바꾸면 비공개 게임 접근 제어와 업로드 방식이 맞지 않습니다.
Private Blob 파일은 원본 주소만 알아서 읽을 수 있는 공개 파일로 취급하지 않습니다. 플랫폼이 프로젝트 접근과 게임 세션을 확인한 뒤 전달합니다. Vercel Blob 설정과 SDK 인증
5. 운영 도메인과 공통 환경 변수
Vercel 프로젝트 Settings → Domains에 immercy.eturnalove.com을 추가합니다. eturnalove.com의 DNS 관리 화면에 호스트 immercy의 CNAME을 추가하고, 값은 해당 Vercel 프로젝트가 현재 제시한 값을 사용합니다. 기존 루트 도메인이나 다른 서브도메인의 레코드를 바꾸지 않습니다. Vercel이 도메인과 HTTPS 인증서를 정상으로 표시할 때까지 기다립니다. Vercel 커스텀 도메인 연결
.env.example를 기준으로 다음 값을 Vercel에 입력합니다. 운영 비밀 값에는 NEXT_PUBLIC_ 접두사를 붙이지 않습니다.
| 변수 | 운영 값 / 목적 |
|---|---|
APP_URL | https://immercy.eturnalove.com |
NEXT_PUBLIC_APP_URL | https://immercy.eturnalove.com |
MONGODB_URI | Atlas의 서버 전용 SRV 연결 문자열 |
MONGODB_DB | immercy |
GOOGLE_CLIENT_ID | 웹 OAuth 클라이언트 ID |
GOOGLE_CLIENT_SECRET | 웹 OAuth 비밀 |
BLOB_READ_WRITE_TOKEN | Private Blob 저장소의 서버 토큰 |
ADMIN_EMAILS | 최초 관리자 Google 이메일, 여러 명은 쉼표로 구분 |
CRON_SECRET | 별도로 생성한 충분히 긴 무작위 비밀 |
ADMIN_EMAILS는 첫 가입 때 관리자 역할을 부여하는 목록입니다. 최초 로그인 전에 등록합니다. 기존 계정의 역할은 환경 변수를 바꾼 것만으로 승격되지 않으므로 필요한 경우 권한 있는 운영자가 Atlas에서 정확한 사용자 한 건의 역할을 변경하고 기록합니다. 로그인 세션은 무작위 토큰의 해시로 DB에 저장하며 운영 쿠키는 HttpOnly·Secure입니다.
각 환경의 APP_URL, OAuth URI, Vercel 도메인이 맞아야 로그인 및 변경 요청의 출처 검사가 통과합니다. 값 변경 후에는 해당 환경을 다시 배포합니다.
공개 운영 정보는 LEGAL_BUSINESS_NAME, LEGAL_REPRESENTATIVE, LEGAL_BUSINESS_NUMBER, LEGAL_ADDRESS, LEGAL_SUPPORT_EMAIL, LEGAL_PRIVACY_CONTACT, LEGAL_EFFECTIVE_DATE, LEGAL_RETENTION_NOTICE에 실제 확정 값을 입력합니다. 운영자의 신원·응답 연락처·보존 정책은 임의 값으로 채우지 않습니다. 정식 공개 전 확인 목록에 맞춰 약관과 개인정보 페이지를 최종 검토합니다.
6. 결제·모더레이션·기기 연결
Indie 결제를 열려면 PayApp 연결 문서를 완료합니다. PayApp 미설정 상태에서도 Free 기능을 준비할 수 있지만 결제 버튼에서 실제 가입을 진행할 수는 없습니다.
공개 프로젝트의 자동 검토에는 서버 전용 OPENAI_API_KEY를 등록하고 OPENAI_MODERATION_MODEL=omni-moderation-latest를 설정합니다. 검토 요청에 공개 프로젝트 설명과 표지 이미지가 전달됩니다. API가 없거나 실패하면 관리자 검토 대기로 남기며 자동 승인을 흉내 내지 않습니다. 운영자는 관리자 화면에서 실제 공개 자료를 검토한 뒤 승인·차단합니다.
서로 다른 Wi-Fi나 이동통신망을 지원하려면 별도의 TURN 서비스가 필요할 수 있습니다. MongoDB, Vercel Blob, Google Drive에는 이 중계 기능이 없습니다. TURN은 WebRTC의 직접 연결이 어려울 때 데이터를 중계합니다. 제공자에서 발급한 서버 주소와 인증 정보를 .env.example의 TURN 설정에 등록합니다. 사용량·만료 정책과 모바일망 연결 품질은 실제 기기로 확인해야 합니다. WebRTC TURN 안내
7. 배포와 최초 운영 확인
npm run typecheck로 정적 타입 검사를 수행하고 변경 내용을 검토합니다.- 필요한 환경 변수·인덱스·도메인을 준비한 뒤 Vercel에서 배포합니다. 이 문서의 명령은 실행 안내이며 이번 작업에서 빌드를 실행했다는 뜻이 아닙니다.
- 관리자 이메일로 첫 로그인하여 관리자 메뉴가 열리는지 확인합니다.
- 개발자 도구 안내의 starter를 본인 프로젝트로 업로드하고, 컨트롤러 저장 → PC에서 Play 또는 미리보기 시작 → QR 표시 → 스마트폰에서 연결 → 연결 완료 후 게임 자동 시작 → 실제 입력 → 종료를 확인합니다.
- 프로젝트별 공개/링크 공개/비공개, 공개 검토 대기·승인·차단, API 키 교체, 프로젝트 삭제, 요금별 제한을 별도 사용자로 확인합니다.
- 운영 문서의 유지보수·보존 설정을 확인한 뒤 PayApp 실제 시험 절차를 진행합니다. 정식 공개 전 확인 목록에 확인 결과를 기록하고 개인정보 및 결제 운영 정보를 최종 확정합니다.
실제 브라우저, iPhone 센서 권한, 통신망, 결제사 콜백, Blob 업로드, Atlas 트랜잭션은 외부 계정 설정 후 검증해야 합니다. 정적 타입 검사 통과와 실제 서비스 동작 확인은 서로 다른 증거입니다.