package handlers import ( "net/http" "time" "game-admin/internal/config" "game-admin/internal/models" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/uptrace/bun" ) type InviteHandler struct { db *bun.DB cfg *config.Config } func NewInviteHandler(db *bun.DB, cfg *config.Config) *InviteHandler { return &InviteHandler{db: db, cfg: cfg} } func (h *InviteHandler) Create(c *gin.Context) { adminID, _ := c.Get("user_id") var req models.CreateInviteRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } code := uuid.New().String()[:8] expires := time.Now().Add(7 * 24 * time.Hour) invite := &models.InviteLink{ Code: code, Role: req.Role, MaxUses: req.MaxUses, UsedCount: 0, CreatedByID: adminID.(int64), ExpiresAt: &expires, CreatedAt: time.Now(), } _, err := h.db.NewInsert().Model(invite).Exec(c) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusCreated, gin.H{ "invite": invite, "link": h.cfg.BaseURL + "/register?invite=" + code, }) } func (h *InviteHandler) List(c *gin.Context) { var invites []models.InviteLink err := h.db.NewSelect().Model(&invites). Relation("CreatedBy"). OrderExpr("id DESC"). Scan(c) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, invites) } func (h *InviteHandler) Delete(c *gin.Context) { code := c.Param("code") _, err := h.db.NewDelete().Model((*models.InviteLink)(nil)).Where("code = ?", code).Exec(c) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "Invite deleted"}) } func (h *InviteHandler) Validate(c *gin.Context) { code := c.Param("code") invite := new(models.InviteLink) err := h.db.NewSelect().Model(invite).Where("code = ?", code).Scan(c) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Invalid invite code"}) return } if invite.UsedCount >= invite.MaxUses { c.JSON(http.StatusGone, gin.H{"error": "Invite code exhausted"}) return } if invite.ExpiresAt != nil && invite.ExpiresAt.Before(time.Now()) { c.JSON(http.StatusGone, gin.H{"error": "Invite code expired"}) return } c.JSON(http.StatusOK, gin.H{"valid": true, "role": invite.Role}) }