feat: Swagger API 문서 추가 + 보스레이드/플레이어 레벨 시스템
Some checks failed
Server CI/CD / lint-and-build (push) Failing after 12m3s
Server CI/CD / deploy (push) Has been cancelled

- swaggo/swag 기반 전체 API 엔드포인트 Swagger 어노테이션 (59개)
- /swagger/ 경로에 Swagger UI 제공
- 보스레이드 데디서버 관리 (등록, 하트비트, 슬롯 리셋)
- 플레이어 레벨/경험치 시스템 및 스탯 성장

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-16 17:51:37 +09:00
parent ee2cf332fb
commit befea9dd68
19 changed files with 12692 additions and 62 deletions

4121
docs/docs.go Normal file

File diff suppressed because it is too large Load Diff

4097
docs/swagger.json Normal file

File diff suppressed because it is too large Load Diff

2686
docs/swagger.yaml Normal file

File diff suppressed because it is too large Load Diff

348
docs/swagger_types.go Normal file
View File

@@ -0,0 +1,348 @@
// Package docs contains Swagger DTO types for API documentation.
// These types are only used by swag to generate OpenAPI specs.
package docs
import "time"
// --- Common ---
// ErrorResponse is a standard error response.
type ErrorResponse struct {
Error string `json:"error" example:"오류 메시지"`
}
// MessageResponse is a standard success message response.
type MessageResponse struct {
Message string `json:"message" example:"성공"`
}
// StatusResponse is a simple status response.
type StatusResponse struct {
Status string `json:"status" example:"ok"`
}
// --- Auth ---
type RegisterRequest struct {
Username string `json:"username" example:"player1"`
Password string `json:"password" example:"mypassword"`
}
type LoginRequest struct {
Username string `json:"username" example:"player1"`
Password string `json:"password" example:"mypassword"`
}
type LoginResponse struct {
Token string `json:"token" example:"eyJhbGciOiJIUzI1NiIs..."`
Username string `json:"username" example:"player1"`
Role string `json:"role" example:"user"`
}
type RefreshRequest struct {
RefreshToken string `json:"refreshToken,omitempty"`
}
type RefreshResponse struct {
Token string `json:"token" example:"eyJhbGciOiJIUzI1NiIs..."`
}
type UpdateRoleRequest struct {
Role string `json:"role" example:"admin"`
}
type VerifyTokenRequest struct {
Token string `json:"token" example:"eyJhbGciOiJIUzI1NiIs..."`
}
type VerifyTokenResponse struct {
Username string `json:"username" example:"player1"`
}
type SSAFYLoginURLResponse struct {
URL string `json:"url" example:"https://edu.ssafy.com/oauth/authorize?..."`
}
type SSAFYCallbackRequest struct {
Code string `json:"code" example:"auth_code_123"`
State string `json:"state" example:"random_state_string"`
}
type LaunchTicketResponse struct {
Ticket string `json:"ticket" example:"ticket_abc123"`
}
type RedeemTicketRequest struct {
Ticket string `json:"ticket" example:"ticket_abc123"`
}
type RedeemTicketResponse struct {
Token string `json:"token" example:"eyJhbGciOiJIUzI1NiIs..."`
}
// UserResponse is a user in the admin user list.
type UserResponse struct {
ID uint `json:"id" example:"1"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Username string `json:"username" example:"player1"`
Role string `json:"role" example:"user"`
SsafyID *string `json:"ssafyId,omitempty" example:"ssafy_123"`
}
// --- Announcement ---
type AnnouncementResponse struct {
ID uint `json:"id" example:"1"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Title string `json:"title" example:"서버 점검 안내"`
Content string `json:"content" example:"3월 16일 서버 점검이 예정되어 있습니다."`
}
type CreateAnnouncementRequest struct {
Title string `json:"title" example:"서버 점검 안내"`
Content string `json:"content" example:"3월 16일 서버 점검이 예정되어 있습니다."`
}
type UpdateAnnouncementRequest struct {
Title string `json:"title,omitempty" example:"수정된 제목"`
Content string `json:"content,omitempty" example:"수정된 내용"`
}
// --- Download ---
type DownloadInfoResponse struct {
ID uint `json:"id" example:"1"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
URL string `json:"url" example:"https://a301.api.tolelom.xyz/api/download/file"`
Version string `json:"version" example:"1.0.0"`
FileName string `json:"fileName" example:"A301_v1.0.zip"`
FileSize string `json:"fileSize" example:"1.5 GB"`
FileHash string `json:"fileHash" example:"a1b2c3d4e5f6..."`
LauncherURL string `json:"launcherUrl" example:"https://a301.api.tolelom.xyz/api/download/launcher"`
LauncherSize string `json:"launcherSize" example:"25.3 MB"`
}
// --- Chain ---
type WalletInfoResponse struct {
Address string `json:"address" example:"1a2b3c4d5e6f..."`
PubKeyHex string `json:"pubKeyHex" example:"abcdef012345..."`
}
type TransferRequest struct {
To string `json:"to" example:"1a2b3c4d5e6f..."`
Amount uint64 `json:"amount" example:"100"`
}
type TransferAssetRequest struct {
AssetID string `json:"assetId" example:"asset_001"`
To string `json:"to" example:"1a2b3c4d5e6f..."`
}
type ListOnMarketRequest struct {
AssetID string `json:"assetId" example:"asset_001"`
Price uint64 `json:"price" example:"500"`
}
type BuyFromMarketRequest struct {
ListingID string `json:"listingId" example:"listing_001"`
}
type CancelListingRequest struct {
ListingID string `json:"listingId" example:"listing_001"`
}
type EquipItemRequest struct {
AssetID string `json:"assetId" example:"asset_001"`
Slot string `json:"slot" example:"weapon"`
}
type UnequipItemRequest struct {
AssetID string `json:"assetId" example:"asset_001"`
}
type MintAssetRequest struct {
TemplateID string `json:"templateId" example:"sword_template"`
OwnerPubKey string `json:"ownerPubKey" example:"abcdef012345..."`
Properties map[string]any `json:"properties"`
}
type GrantRewardRequest struct {
RecipientPubKey string `json:"recipientPubKey" example:"abcdef012345..."`
TokenAmount uint64 `json:"tokenAmount" example:"1000"`
Assets []MintAssetPayload `json:"assets"`
}
type RegisterTemplateRequest struct {
ID string `json:"id" example:"sword_template"`
Name string `json:"name" example:"Sword"`
Schema map[string]any `json:"schema"`
Tradeable bool `json:"tradeable" example:"true"`
}
type InternalGrantRewardRequest struct {
Username string `json:"username" example:"player1"`
TokenAmount uint64 `json:"tokenAmount" example:"1000"`
Assets []MintAssetPayload `json:"assets"`
}
type InternalMintAssetRequest struct {
TemplateID string `json:"templateId" example:"sword_template"`
Username string `json:"username" example:"player1"`
Properties map[string]any `json:"properties"`
}
type MintAssetPayload struct {
TemplateID string `json:"template_id" example:"sword_template"`
Owner string `json:"owner" example:"abcdef012345..."`
Properties map[string]any `json:"properties"`
}
// --- Boss Raid ---
type RequestEntryRequest struct {
Usernames []string `json:"usernames" example:"player1,player2"`
BossID int `json:"bossId" example:"1"`
}
type RequestEntryAuthRequest struct {
Usernames []string `json:"usernames,omitempty"`
BossID int `json:"bossId" example:"1"`
}
type RequestEntryResponse struct {
RoomID uint `json:"roomId" example:"1"`
SessionName string `json:"sessionName" example:"Dedi1_Room0"`
BossID int `json:"bossId" example:"1"`
Players []string `json:"players"`
Status string `json:"status" example:"waiting"`
EntryToken string `json:"entryToken,omitempty" example:"token_abc"`
}
type InternalRequestEntryResponse struct {
RoomID uint `json:"roomId" example:"1"`
SessionName string `json:"sessionName" example:"Dedi1_Room0"`
BossID int `json:"bossId" example:"1"`
Players []string `json:"players"`
Status string `json:"status" example:"waiting"`
Tokens map[string]string `json:"tokens"`
}
type SessionNameRequest struct {
SessionName string `json:"sessionName" example:"Dedi1_Room0"`
}
type RoomStatusResponse struct {
RoomID uint `json:"roomId" example:"1"`
SessionName string `json:"sessionName" example:"Dedi1_Room0"`
Status string `json:"status" example:"in_progress"`
}
type PlayerReward struct {
Username string `json:"username" example:"player1"`
TokenAmount uint64 `json:"tokenAmount" example:"100"`
Assets []MintAssetPayload `json:"assets"`
Experience int `json:"experience" example:"500"`
}
type CompleteRaidRequest struct {
SessionName string `json:"sessionName" example:"Dedi1_Room0"`
Rewards []PlayerReward `json:"rewards"`
}
type CompleteRaidResponse struct {
RoomID uint `json:"roomId" example:"1"`
SessionName string `json:"sessionName" example:"Dedi1_Room0"`
Status string `json:"status" example:"completed"`
RewardResults []RewardResult `json:"rewardResults"`
}
type RewardResult struct {
Username string `json:"username" example:"player1"`
Success bool `json:"success" example:"true"`
Error string `json:"error,omitempty"`
}
type ValidateEntryTokenRequest struct {
EntryToken string `json:"entryToken" example:"token_abc"`
}
type ValidateEntryTokenResponse struct {
Valid bool `json:"valid" example:"true"`
Username string `json:"username,omitempty" example:"player1"`
SessionName string `json:"sessionName,omitempty" example:"Dedi1_Room0"`
}
type MyEntryTokenResponse struct {
SessionName string `json:"sessionName" example:"Dedi1_Room0"`
EntryToken string `json:"entryToken" example:"token_abc"`
}
type RegisterServerRequest struct {
ServerName string `json:"serverName" example:"Dedi1"`
InstanceID string `json:"instanceId" example:"container_abc"`
MaxRooms int `json:"maxRooms" example:"10"`
}
type RegisterServerResponse struct {
SessionName string `json:"sessionName" example:"Dedi1_Room0"`
InstanceID string `json:"instanceId" example:"container_abc"`
}
type HeartbeatRequest struct {
InstanceID string `json:"instanceId" example:"container_abc"`
}
type ResetRoomRequest struct {
SessionName string `json:"sessionName" example:"Dedi1_Room0"`
}
type ResetRoomResponse struct {
Status string `json:"status" example:"ok"`
SessionName string `json:"sessionName" example:"Dedi1_Room0"`
}
// --- Player ---
type PlayerProfileResponse struct {
ID uint `json:"id" example:"1"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
UserID uint `json:"userId" example:"1"`
Nickname string `json:"nickname" example:"용사"`
Level int `json:"level" example:"5"`
Experience int `json:"experience" example:"1200"`
NextExp int `json:"nextExp" example:"2000"`
MaxHP float64 `json:"maxHp" example:"150"`
MaxMP float64 `json:"maxMp" example:"75"`
AttackPower float64 `json:"attackPower" example:"25"`
AttackRange float64 `json:"attackRange" example:"3"`
SprintMultiplier float64 `json:"sprintMultiplier" example:"1.8"`
LastPosX float64 `json:"lastPosX" example:"10.5"`
LastPosY float64 `json:"lastPosY" example:"0"`
LastPosZ float64 `json:"lastPosZ" example:"20.3"`
LastRotY float64 `json:"lastRotY" example:"90"`
TotalPlayTime int64 `json:"totalPlayTime" example:"3600"`
}
type UpdateProfileRequest struct {
Nickname string `json:"nickname" example:"용사"`
}
type GameDataRequest struct {
Level *int `json:"level,omitempty" example:"5"`
Experience *int `json:"experience,omitempty" example:"1200"`
MaxHP *float64 `json:"maxHp,omitempty" example:"150"`
MaxMP *float64 `json:"maxMp,omitempty" example:"75"`
AttackPower *float64 `json:"attackPower,omitempty" example:"25"`
AttackRange *float64 `json:"attackRange,omitempty" example:"3"`
SprintMultiplier *float64 `json:"sprintMultiplier,omitempty" example:"1.8"`
LastPosX *float64 `json:"lastPosX,omitempty" example:"10.5"`
LastPosY *float64 `json:"lastPosY,omitempty" example:"0"`
LastPosZ *float64 `json:"lastPosZ,omitempty" example:"20.3"`
LastRotY *float64 `json:"lastRotY,omitempty" example:"90"`
TotalPlayTime *int64 `json:"totalPlayTime,omitempty" example:"3600"`
}