Im developing web app where users can create skill-sharing session and leave feedbacks to sessions they participated in. Upgrade my implementation to production level and explain how to test it. I already wrote repository files, model files, handlers etc. The problematic parts of my server is presented below:

routes.go:
// Moderator routes
            moderator := api.Group("/moderator")
            moderator.Use(middleware.RoleAuthMiddleware("moderator"))
            {
                moderator.DELETE("/sessions/:id", sessionController.Delete)
                //moderator.DELETE("/feedback/:id", feedbackController.Delete)
            }
    
            // Session routes
            sessions := api.Group("/sessions")
            {
                sessions.GET("", sessionController.GetAll)
                sessions.GET("/:id", sessionController.GetByID)
                sessions.POST("", sessionController.Create)
                sessions.PUT("/:id", sessionController.Update)
                sessions.DELETE("/:id", sessionController.Delete)
                sessions.GET("/:id/participants", sessionController.GetParticipants)

                // Endpoints для Join/Leave сессии
			    sessions.POST("/:id/join", sessionController.JoinSession)
			    sessions.POST("/:id/leave", sessionController.LeaveSession)

			    // Endpoints для отзывов/рейтингов
			    feedback := sessions.Group("/:id/feedback")
			    {
				    feedback.POST("", feedbackController.CreateFeedback)
				    feedback.GET("", feedbackController.GetFeedback)
			    }
            }
        }
    
        return r
    }

jwt_middleware.go:
// JWTAuthMiddleware проверяет валидность JWT токена
func JWTAuthMiddleware() gin.HandlerFunc {
    jwtCfg := config.GetJWTConfig()
    
    return func(c *gin.Context) {
        // Получаем токен из заголовка Authorization
        authHeader := c.GetHeader("Authorization")
        if authHeader == "" {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Authorization header is required"})
            return
        }

        // Проверяем формат "Bearer <token>"
        parts := strings.Split(authHeader, " ")
        if len(parts) != 2 || parts[0] != "Bearer" {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Authorization header format must be Bearer <token>"})
            return
        }

        tokenString := parts[1]

        // Парсим и верифицируем токен
        token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
            // Проверяем, что используется правильный алгоритм
            if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
                return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
            }
            return []byte(jwtCfg.SecretKey), nil
        })

        if err != nil {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid token: " + err.Error()})
            return
        }

        // Проверяем валидность токена
        if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
            // Проверяем срок действия токена
            if float64(time.Now().Unix()) > claims["exp"].(float64) {
                c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Token expired"})
                return
            }

            // Получаем ID пользователя из токена
            userIDStr, ok := claims["user_id"].(string)
            if !ok {
                c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid token claims"})
                return
            }
            
            userID, err := uuid.Parse(userIDStr)
            if err != nil {
                c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid user ID in token"})
                return
            }

            // Сохраняем данные пользователя в контексте Gin
            c.Set("userID", userID)
            c.Set("email", claims["email"].(string))
            c.Set("role", claims["role"].(string))
            
            c.Next()
        } else {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
            return
        }
    }
}

session_controller.go:
// Create handles POST /sessions
func (c *SessionController) Create(ctx *gin.Context) { // ИСПРАВИТЬ МЕТОД
        var req models.SessionRequest
        if err := ctx.ShouldBindJSON(&req); err != nil {
                ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
                return
        }

        // For demo purposes - in a real app, get the user ID from auth context
        creatorID, err := uuid.Parse(ctx.Query("creator_id"))
        if err != nil {
                ctx.JSON(http.StatusBadRequest, gin.H{"error": "Invalid creator ID"})
                return
        }

        session, err := c.repo.Create(creatorID, req)
        if err != nil {
                ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
                return
        }

        ctx.JSON(http.StatusCreated, session)
}

feedback_controller.go:
// CreateFeedback обрабатывает POST /sessions/:id/feedback
func (c *FeedbackController) CreateFeedback(ctx *gin.Context) {
	sessionIDStr := ctx.Param("id")
	sessionID, err := uuid.Parse(sessionIDStr)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "Invalid session ID"})
		return
	}

	// Предположим, что middleware JWT кладёт в контекст идентификатор пользователя под ключом "user_id"
	userIDStr, exists := ctx.Get("user_id") // ЗАМЕНИТЬ НА userID?
	if !exists {
		ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
		return
	}
	userID, err := uuid.Parse(userIDStr.(string))
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
		return
	}

	var req models.FeedbackRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	feedback, err := c.repo.CreateFeedback(req, sessionID, userID)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusCreated, feedback)
}