b006fe77c25999bdaab7c12114c88318db0094f8
CRITICAL: - graceful shutdown 레이스 수정 — Listen을 goroutine으로 이동 - Register 레이스 컨디션 — sentinel error + MySQL duplicate key 처리 HIGH: - 멱등성 키에 method+path 포함 — 엔드포인트 간 캐시 충돌 방지 - 입장 토큰 생성 실패 시 방/슬롯 롤백 추가 MEDIUM: - RequestEntry 슬롯 없음 시 503 반환 - chain ExportWallet/GetWalletInfo/GrantReward 에러 처리 개선 - resolveUsername 에러 타입 구분 (duplicate key vs 기타) - 공지사항 길이 검증 byte→rune (한국어 256자 허용) - Level 검증 범위 MaxLevel(50)로 통일 - admin 자기 강등 방지 - CORS ExposeHeaders 추가 - MySQL DSN loc=Local→loc=UTC - hashGameExeFromZip 100MB 초과 절단 감지 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
One of the plans — Backend Server
Go 기반 REST API 서버. 유저 인증, 공지사항, 게임 파일 배포를 담당합니다.
기술 스택
- Go + Fiber v2 — HTTP 프레임워크
- GORM + MySQL — ORM / 주 데이터베이스
- Redis — JWT 블랙리스트 (로그아웃 처리)
- JWT (
golang-jwt/jwt v5) — 인증
실행
# 로컬 (MySQL, Redis 필요)
go run .
# Docker
docker build -t a301-server .
docker run -p 8080:8080 --env-file .env a301-server
환경 변수
| 변수 | 설명 | 기본값 |
|---|---|---|
APP_PORT |
서버 포트 | 8080 |
DB_HOST |
MySQL 호스트 | localhost |
DB_PORT |
MySQL 포트 | 3306 |
DB_USER |
MySQL 사용자 | root |
DB_PASSWORD |
MySQL 비밀번호 | "" |
DB_NAME |
데이터베이스 이름 | a301 |
REDIS_ADDR |
Redis 주소 | localhost:6379 |
REDIS_PASSWORD |
Redis 비밀번호 | "" |
JWT_SECRET |
JWT 서명 키 | secret |
JWT_EXPIRY_HOURS |
JWT 만료 시간(시) | 24 |
ADMIN_USERNAME |
초기 관리자 계정 | admin |
ADMIN_PASSWORD |
초기 관리자 비밀번호 | admin1234 |
BASE_URL |
외부 접근 URL (파일 URL 생성용) | http://localhost:8080 |
GAME_DIR |
게임 파일 저장 경로 | /data/game |
API 엔드포인트
Auth
| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /api/auth/register |
회원가입 |
| POST | /api/auth/login |
로그인 → JWT 반환 |
| POST | /api/auth/logout |
로그아웃 (토큰 블랙리스트) |
Users (관리자 전용)
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/users/ |
전체 유저 목록 |
| PATCH | /api/users/:id/role |
유저 권한 변경 |
| DELETE | /api/users/:id |
유저 삭제 |
Announcements
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/announcements/ |
공지사항 목록 |
| POST | /api/announcements/ |
공지 생성 (관리자) |
| PUT | /api/announcements/:id |
공지 수정 (관리자) |
| DELETE | /api/announcements/:id |
공지 삭제 (관리자) |
Download
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /api/download/info |
게임/런처 메타데이터 (버전, 크기, SHA256) |
| GET | /api/download/file |
game.zip 다운로드 |
| GET | /api/download/launcher |
launcher.exe 다운로드 |
| POST | /api/download/upload/game |
게임 zip 업로드 (관리자) |
| POST | /api/download/upload/launcher |
launcher.exe 업로드 (관리자) |
업로드 엔드포인트는 raw body 스트리밍으로 대용량 파일을 메모리 없이 디스크에 직접 저장합니다.
게임 zip 업로드 시 내부 A301.exe의 SHA256 해시를 자동 추출합니다.
프로젝트 구조
.
├── main.go
├── routes/routes.go
├── internal/
│ ├── auth/ # handler, service, repository, model
│ ├── announcement/
│ └── download/
└── pkg/
├── config/ # 환경 변수 로드
├── database/ # MySQL, Redis 연결
└── middleware/ # JWT 인증, AdminOnly
Docker / 배포
/data/game 볼륨에 game.zip과 launcher.exe가 저장됩니다.
docker-compose.yml에 named volume game_data:/data/game 마운트 필요.
Description
Languages
Go
99.8%
Dockerfile
0.2%