Files
a301_server/CLAUDE.md
tolelom 23bec776ab
All checks were successful
Server CI/CD / deploy (push) Successful in 1m36s
fix: 코드 리뷰 기반 보안·안정성 개선 (14건)
- unsafe 타입 단언 → safe assertion (chain handler 11곳, auth Logout)
- Repository 에러 시 nil 반환으로 통일 (chain, auth, announcement)
- string ID → uint 파싱으로 타입 안전성 확보 (auth, announcement)
- CORS AllowHeaders에 Idempotency-Key, X-API-Key 추가
- /verify 엔드포인트 rate limiter 적용
- Redis 호출에 context timeout 적용 (auth, idempotency 미들웨어)
- chain handler 에러 응답에서 내부 정보 노출 방지
- f.Close() 에러 검사 추가 (download service 2곳)
- 공지사항 Delete 404 응답 추가
- 회원가입 롤백 시 Delete 에러 로깅

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 14:47:00 +09:00

5.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

go run .                          # 로컬 실행
go build -o server .              # 빌드
docker build -t a301-server .     # Docker 빌드

Tech Stack

  • Go + Fiber v2 (StreamRequestBody: true — 대용량 업로드용, Body Limit 4GB)
  • GORM + MySQL (AutoMigrate 사용)
  • Redis — JWT 세션 저장(session:{userID}, refresh:{userID}) + 멱등성 캐시
  • JWTgolang-jwt/jwt v5, Access + Refresh 토큰 로테이션

Project Purpose

"One of the plans" 게임 플랫폼 백엔드. 인증 / 공지사항 / 게임 파일 업로드·서빙 / 블록체인(TOL Chain) 연동 담당.

Project Structure

internal/
├── auth/         # User 모델, JWT 발급·검증, 세션 관리(Redis)
├── announcement/ # Announcement CRUD
├── download/     # Info 조회, 파일 업로드(스트리밍), 파일 서빙
└── chain/        # 블록체인 지갑·거래·마켓·인벤토리 (5파일: handler, service, repository, model, client)
pkg/
├── config/       # 환경변수 → Config 구조체
├── database/     # ConnectMySQL(), ConnectRedis()
└── middleware/    # Auth, AdminOnly, ServerAuth, Idempotency
routes/routes.go  # 모든 라우트 등록

Key Patterns

  • 계층 구조: Handler → Service → Repository. 각 도메인 폴더에 4~5파일.
  • 파일 업로드: Fiber StreamRequestBody: true + io.Copy로 raw body를 직접 디스크에 스트리밍. 메모리에 파일 올리지 않음.
  • SHA256 자동 추출: 게임 zip 업로드 시 zip 내 A301.exe를 스트리밍으로 읽어 해시 계산.
  • CORS: AllowMethodsPATCH 포함 필수 (유저 권한 변경 엔드포인트). AllowOrigins: https://a301.tolelom.xyz.
  • 초기 admin 계정: 서버 시작 시 EnsureAdmin()으로 존재 확인 후 없으면 생성.
  • DI 패턴: main.go에서 생성자 함수로 Repo → Service → Handler 주입.
  • 콜백 연결: authSvc.SetWalletCreator() — 회원가입 시 자동 지갑 생성. chainSvc.SetUserResolver() — username → userID 변환.

Middleware

  • Auth: Authorization: Bearer <jwt> 검증 + Redis 세션 확인. c.Locals("userID", "username", "role") 설정.
  • AdminOnly: role == "admin" 확인, 아니면 403.
  • ServerAuth: X-API-Key 헤더 검증. 게임 서버 → API 서버 내부 통신용.
  • Idempotency: Idempotency-Key 헤더로 중복 요청 방지. Redis 캐시 TTL 10분. 블록체인 트랜잭션 이중 지출 방지용.

JWT 토큰 로테이션

  • Access Token: JWT_SECRET으로 서명, 기본 24시간 만료, Redis session:{userID}에 저장.
  • Refresh Token: REFRESH_SECRET으로 서명, 7일 만료, Redis refresh:{userID}에 저장.
  • Refresh 시: 이전 토큰 무효화 + 새 Access/Refresh 쌍 발급 (로테이션).
  • Logout: Redis에서 session + refresh 키 모두 삭제.

Rate Limiting

  • Auth 엔드포인트: IP당 10 req/min
  • 일반 API: IP당 60 req/min

블록체인 연동 (internal/chain/)

TOL Chain 노드와 JSON-RPC 2.0 통신.

  • UserWallet 모델: ed25519 키페어 생성, 개인키는 AES-256-GCM 암호화 후 DB 저장.
  • client.go: Chain 노드 RPC 호출 (10초 타임아웃).
  • service.go: 지갑 생성/암호화, 트랜잭션 서명, 마켓/인벤토리 로직.
  • 내부 API: 게임 서버가 username 기반으로 보상 지급 (/api/internal/chain/*).

Routes

인증: POST /api/auth/{register,login,refresh,logout,verify} (register/login/refresh는 rate limit)

유저 관리 (admin): GET /api/users/, PATCH /api/users/:id/role, DELETE /api/users/:id

공지사항: GET /api/announcements/, POST|PUT|DELETE /api/announcements/:id (CUD는 admin)

다운로드: GET /api/download/{info,file,launcher}, POST /api/download/upload/{game,launcher} (upload는 admin)

체인 조회 (JWT): GET /api/chain/{wallet,balance,assets,asset/:id,inventory,market,market/:id}

체인 트랜잭션 (JWT + Idempotency): POST /api/chain/{transfer,asset/transfer,market/list,market/buy,market/cancel,inventory/equip,inventory/unequip}

체인 관리자 (JWT + Admin + Idempotency): POST /api/chain/admin/{mint,reward,template}

내부 API (X-API-Key + Idempotency): POST /api/internal/chain/{reward,mint}, GET /api/internal/chain/{balance,assets,inventory} (username 쿼리 파라미터)

Environment Variables

APP_PORT=8080
DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME
REDIS_ADDR, REDIS_PASSWORD
JWT_SECRET, REFRESH_SECRET, JWT_EXPIRY_HOURS(기본24)
ADMIN_USERNAME, ADMIN_PASSWORD
BASE_URL=https://a301.api.tolelom.xyz
GAME_DIR=/data/game
CHAIN_NODE_URL=http://localhost:8545
CHAIN_ID=tolchain-dev
OPERATOR_KEY_HEX          # 오퍼레이터 개인키 (블록체인 트랜잭션 서명용)
WALLET_ENCRYPTION_KEY      # 64자 hex = 32바이트 AES-256 키 (지갑 암호화)
INTERNAL_API_KEY           # 게임 서버 인증용 API 키

File Storage

게임 파일은 GAME_DIR(/data/game)에 저장:

  • /data/game/game.zip — 게임 본체
  • /data/game/launcher.exe — 런처

Docker 볼륨 game_data:/data/game 마운트로 컨테이너 재시작 후에도 유지.