165 lines
5.8 KiB
Go
165 lines
5.8 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"log"
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
walletpb "game-admin/gen"
|
|
"game-admin/internal/config"
|
|
"game-admin/internal/grpcserver"
|
|
"game-admin/internal/handlers"
|
|
"game-admin/internal/middleware"
|
|
"game-admin/internal/migrations"
|
|
"game-admin/internal/models"
|
|
"game-admin/internal/wallet"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/uptrace/bun"
|
|
"github.com/uptrace/bun/dialect/pgdialect"
|
|
"github.com/uptrace/bun/driver/pgdriver"
|
|
"github.com/uptrace/bun/extra/bundebug"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
func main() {
|
|
cfg := config.Load()
|
|
|
|
dsn := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=disable",
|
|
cfg.DBUser, cfg.DBPassword, cfg.DBHost, cfg.DBPort, cfg.DBName)
|
|
|
|
connector := pgdriver.NewConnector(pgdriver.WithDSN(dsn))
|
|
sqldb := sql.OpenDB(connector)
|
|
|
|
db := bun.NewDB(sqldb, pgdialect.New())
|
|
db.AddQueryHook(bundebug.NewQueryHook(bundebug.WithVerbose(true)))
|
|
|
|
if err := os.MkdirAll(filepath.Join(cfg.UploadDir, "images"), 0o755); err != nil {
|
|
log.Fatal("Upload directory init failed:", err)
|
|
}
|
|
|
|
if err := migrations.Migrate(context.Background(), db, cfg); err != nil {
|
|
log.Fatal("Migration failed:", err)
|
|
}
|
|
|
|
authH := handlers.NewAuthHandler(db, cfg)
|
|
userH := handlers.NewUserHandler(db, cfg)
|
|
gameH := handlers.NewGameHandler(db, cfg)
|
|
inviteH := handlers.NewInviteHandler(db, cfg)
|
|
languageH := handlers.NewLanguageHandler(db, cfg)
|
|
imageH := handlers.NewImageHandler(cfg)
|
|
walletService := wallet.NewService(db)
|
|
|
|
r := gin.Default()
|
|
r.Static("/uploads", cfg.UploadDir)
|
|
|
|
r.Use(func(c *gin.Context) {
|
|
c.Header("Access-Control-Allow-Origin", "*")
|
|
c.Header("Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE,OPTIONS")
|
|
c.Header("Access-Control-Allow-Headers", "Content-Type,Authorization")
|
|
if c.Request.Method == "OPTIONS" {
|
|
c.AbortWithStatus(204)
|
|
return
|
|
}
|
|
c.Next()
|
|
})
|
|
|
|
api := r.Group("/api")
|
|
{
|
|
api.POST("/auth/login", authH.Login)
|
|
api.POST("/auth/register", authH.Register)
|
|
api.GET("/invites/validate/:code", inviteH.Validate)
|
|
}
|
|
|
|
auth := api.Group("", middleware.AuthRequired(cfg))
|
|
{
|
|
auth.GET("/auth/me", authH.Me)
|
|
|
|
auth.GET("/games", gameH.List)
|
|
auth.GET("/games/:id", gameH.GetByID)
|
|
auth.GET("/modules", gameH.ListModules)
|
|
auth.GET("/languages", languageH.List)
|
|
auth.GET("/languages/:id", languageH.GetByID)
|
|
auth.GET("/games/:id/leaderboards", gameH.ListLeaderboards)
|
|
auth.GET("/games/:id/leaderboards/:leaderboard_id", gameH.GetLeaderboard)
|
|
auth.GET("/leaderboards/:leaderboard_id/groups", gameH.ListLeaderboardGroups)
|
|
auth.GET("/leaderboards/:leaderboard_id/rankings", gameH.GetLeaderboardRankings)
|
|
auth.GET("/games/:id/notifications", gameH.ListNotifications)
|
|
auth.GET("/games/:id/notifications/:notification_id", gameH.GetNotification)
|
|
|
|
admin := auth.Group("", middleware.RoleRequired(models.RoleAdmin, models.RoleModerator))
|
|
{
|
|
admin.GET("/users", userH.List)
|
|
admin.GET("/users/:id", userH.GetByID)
|
|
admin.GET("/games/:id/users", userH.ListByGame)
|
|
admin.PATCH("/users/:id/role", userH.UpdateRole)
|
|
admin.PATCH("/users/:id/toggle-active", userH.ToggleActive)
|
|
|
|
admin.POST("/games", gameH.Create)
|
|
admin.PUT("/games/:id", gameH.Update)
|
|
admin.DELETE("/games/:id", gameH.Delete)
|
|
admin.GET("/games/:id/modules", gameH.ListGameModules)
|
|
admin.POST("/games/:id/modules", gameH.ConnectModule)
|
|
admin.DELETE("/games/:id/modules/:module_key", gameH.DisconnectModule)
|
|
admin.POST("/games/:id/leaderboards", gameH.CreateLeaderboard)
|
|
admin.PUT("/games/:id/leaderboards/:leaderboard_id", gameH.UpdateLeaderboard)
|
|
admin.DELETE("/games/:id/leaderboards/:leaderboard_id", gameH.DeleteLeaderboard)
|
|
admin.POST("/leaderboards/:leaderboard_id/groups", gameH.CreateLeaderboardGroup)
|
|
admin.PUT("/leaderboard-groups/:group_id", gameH.UpdateLeaderboardGroup)
|
|
admin.DELETE("/leaderboard-groups/:group_id", gameH.DeleteLeaderboardGroup)
|
|
admin.POST("/leaderboard-groups/:group_id/members", gameH.AddLeaderboardGroupMember)
|
|
admin.DELETE("/leaderboard-groups/:group_id/members/:user_id", gameH.DeleteLeaderboardGroupMember)
|
|
admin.POST("/leaderboards/:leaderboard_id/scores", gameH.UpsertLeaderboardScore)
|
|
admin.POST("/games/:id/notifications", gameH.CreateNotification)
|
|
admin.PUT("/games/:id/notifications/:notification_id", gameH.UpdateNotification)
|
|
admin.DELETE("/games/:id/notifications/:notification_id", gameH.DeleteNotification)
|
|
admin.GET("/games/:id/variables", gameH.ListVariables)
|
|
admin.POST("/games/:id/variables", gameH.CreateVariable)
|
|
admin.PUT("/games/:id/variables/:var_id", gameH.UpdateVariable)
|
|
admin.DELETE("/games/:id/variables/:var_id", gameH.DeleteVariable)
|
|
admin.POST("/images", imageH.Upload)
|
|
|
|
admin.POST("/languages", languageH.Create)
|
|
admin.PUT("/languages/:id", languageH.Update)
|
|
admin.DELETE("/languages/:id", languageH.Delete)
|
|
|
|
admin.GET("/users/:id/games", gameH.UserGames)
|
|
admin.POST("/users/:id/games", gameH.ConnectGame)
|
|
admin.DELETE("/users/:id/games/:game_id", gameH.DisconnectGame)
|
|
|
|
admin.POST("/user-games/:ug_id/topup", gameH.TopUp)
|
|
admin.GET("/user-games/:ug_id/transactions", gameH.Transactions)
|
|
|
|
admin.POST("/invites", inviteH.Create)
|
|
admin.GET("/invites", inviteH.List)
|
|
admin.DELETE("/invites/:code", inviteH.Delete)
|
|
}
|
|
}
|
|
|
|
grpcListener, err := net.Listen("tcp", ":"+cfg.GRPCPort)
|
|
if err != nil {
|
|
log.Fatal("gRPC listen error:", err)
|
|
}
|
|
|
|
grpcSrv := grpc.NewServer(
|
|
grpc.UnaryInterceptor(grpcserver.HMACUnaryServerInterceptor(cfg.GRPCHMACSecret)),
|
|
)
|
|
walletpb.RegisterWalletServiceServer(grpcSrv, grpcserver.NewWalletServer(walletService))
|
|
|
|
go func() {
|
|
log.Printf("gRPC server starting on :%s", cfg.GRPCPort)
|
|
if err := grpcSrv.Serve(grpcListener); err != nil {
|
|
log.Fatal("gRPC serve error:", err)
|
|
}
|
|
}()
|
|
|
|
log.Printf("HTTP server starting on :%s", cfg.ServerPort)
|
|
if err := r.Run(":" + cfg.ServerPort); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|