package routes import ( "a301_server/internal/announcement" "a301_server/internal/auth" "a301_server/internal/bossraid" "a301_server/internal/chain" "a301_server/internal/download" "a301_server/internal/player" "a301_server/pkg/middleware" "github.com/gofiber/fiber/v2" "github.com/gofiber/swagger" ) func Register( app *fiber.App, authH *auth.Handler, annH *announcement.Handler, dlH *download.Handler, chainH *chain.Handler, brH *bossraid.Handler, playerH *player.Handler, authLimiter fiber.Handler, apiLimiter fiber.Handler, healthCheck fiber.Handler, readyCheck fiber.Handler, chainUserLimiter fiber.Handler, authMw fiber.Handler, serverAuthMw fiber.Handler, idempotencyReqMw fiber.Handler, refreshLimiter fiber.Handler, ) { // Swagger UI app.Get("/swagger/*", swagger.HandlerDefault) // Health / Ready (rate limiter 밖) app.Get("/health", healthCheck) app.Get("/ready", readyCheck) // Default 1MB body limit for API routes; upload endpoints are excluded apiBodyLimit := middleware.BodyLimit(1*1024*1024, "/api/download/upload") // ── Internal API (Rate Limit 제외, API Key 인증만) ────────────── // 반드시 /api 그룹보다 먼저 등록해야 apiLimiter를 우회함 internalApi := app.Group("/api/internal", apiBodyLimit, serverAuthMw) // Internal - Boss Raid br := internalApi.Group("/bossraid") br.Post("/entry", brH.RequestEntry) br.Post("/start", brH.StartRaid) br.Post("/complete", idempotencyReqMw, brH.CompleteRaid) br.Post("/fail", brH.FailRaid) br.Get("/room", brH.GetRoom) br.Post("/validate-entry", brH.ValidateEntryToken) br.Post("/register", brH.RegisterServer) br.Post("/heartbeat", brH.Heartbeat) br.Post("/reset-room", brH.ResetRoom) br.Get("/server-status", brH.GetServerStatus) // Internal - Auth internalAuth := internalApi.Group("/auth") internalAuth.Post("/verify", authH.VerifyToken) // Internal - Player internalPlayer := internalApi.Group("/player") internalPlayer.Get("/profile", playerH.InternalGetProfile) internalPlayer.Post("/save", playerH.InternalSaveGameData) // Internal - Chain internalChain := internalApi.Group("/chain") internalChain.Post("/reward", idempotencyReqMw, chainH.InternalGrantReward) internalChain.Post("/mint", idempotencyReqMw, chainH.InternalMintAsset) internalChain.Get("/balance", chainH.InternalGetBalance) internalChain.Get("/assets", chainH.InternalGetAssets) internalChain.Get("/inventory", chainH.InternalGetInventory) // ── Public API (Rate Limit 적용) ──────────────────────────────── api := app.Group("/api", apiLimiter, apiBodyLimit) // Auth a := api.Group("/auth") a.Post("/register", authLimiter, authH.Register) a.Post("/login", authLimiter, authH.Login) a.Post("/refresh", refreshLimiter, authH.Refresh) a.Post("/logout", authMw, authH.Logout) // /verify moved to internal API (ServerAuth) — see internal section below a.Get("/ssafy/login", authH.SSAFYLoginURL) a.Post("/ssafy/callback", authLimiter, authH.SSAFYCallback) a.Post("/launch-ticket", authMw, authH.CreateLaunchTicket) a.Post("/redeem-ticket", authLimiter, authH.RedeemLaunchTicket) // Users (admin only) u := api.Group("/users", authMw, middleware.AdminOnly) u.Get("/", authH.GetAllUsers) u.Patch("/:id/role", authH.UpdateRole) u.Delete("/:id", authH.DeleteUser) // Announcements ann := api.Group("/announcements") ann.Get("/", annH.GetAll) ann.Post("/", authMw, middleware.AdminOnly, annH.Create) ann.Put("/:id", authMw, middleware.AdminOnly, annH.Update) ann.Delete("/:id", authMw, middleware.AdminOnly, annH.Delete) // Download dl := api.Group("/download") dl.Get("/info", dlH.GetInfo) dl.Get("/file", dlH.ServeFile) dl.Get("/launcher", dlH.ServeLauncher) dl.Post("/upload/game", authMw, middleware.AdminOnly, dlH.Upload) dl.Post("/upload/launcher", authMw, middleware.AdminOnly, dlH.UploadLauncher) // Chain - Queries (authenticated) ch := api.Group("/chain", authMw) ch.Get("/wallet", chainH.GetWalletInfo) ch.Post("/wallet/export", chainH.ExportWallet) ch.Get("/balance", chainH.GetBalance) ch.Get("/assets", chainH.GetAssets) ch.Get("/asset/:id", chainH.GetAsset) ch.Get("/inventory", chainH.GetInventory) ch.Get("/market", chainH.GetMarketListings) ch.Get("/market/:id", chainH.GetMarketListing) // Chain - User Transactions (authenticated, per-user rate limited, idempotency-protected) ch.Post("/transfer", chainUserLimiter, idempotencyReqMw, chainH.Transfer) ch.Post("/asset/transfer", chainUserLimiter, idempotencyReqMw, chainH.TransferAsset) ch.Post("/market/list", chainUserLimiter, idempotencyReqMw, chainH.ListOnMarket) ch.Post("/market/buy", chainUserLimiter, idempotencyReqMw, chainH.BuyFromMarket) ch.Post("/market/cancel", chainUserLimiter, idempotencyReqMw, chainH.CancelListing) ch.Post("/inventory/equip", chainUserLimiter, idempotencyReqMw, chainH.EquipItem) ch.Post("/inventory/unequip", chainUserLimiter, idempotencyReqMw, chainH.UnequipItem) // Chain - Admin Transactions (admin only, idempotency-protected) chainAdmin := api.Group("/chain/admin", authMw, middleware.AdminOnly) chainAdmin.Post("/mint", idempotencyReqMw, chainH.MintAsset) chainAdmin.Post("/reward", idempotencyReqMw, chainH.GrantReward) chainAdmin.Post("/template", idempotencyReqMw, chainH.RegisterTemplate) // Player Profile (authenticated) p := api.Group("/player", authMw) p.Get("/profile", playerH.GetProfile) p.Put("/profile", playerH.UpdateProfile) }