diff --git a/internal/admin/enterprise_handler.go b/internal/admin/enterprise_handler.go index 9cd31bfc34..1a605abab2 100644 --- a/internal/admin/enterprise_handler.go +++ b/internal/admin/enterprise_handler.go @@ -31,7 +31,7 @@ import ( func (h *Handler) ListRoles(c *gin.Context) { roles, err := h.service.ListRoles() if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } @@ -39,7 +39,7 @@ func (h *Handler) ListRoles(c *gin.Context) { roles = []map[string]interface{}{} } - success(c, roles, "") + common.SuccessWithData(c, roles, "") } // CreateRoleHTTPRequest create role request @@ -52,34 +52,34 @@ type CreateRoleHTTPRequest struct { func (h *Handler) CreateRole(c *gin.Context) { var req CreateRoleHTTPRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "Role name is required", 400) + common.ErrorWithCode(c, 400, "Role name is required") return } role, err := h.service.CreateRole(req.RoleName, req.Description) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, role, "") + common.SuccessWithData(c, role, "") } // ShowRole handle show role func (h *Handler) ShowRole(c *gin.Context) { roleName := c.Param("role_name") if roleName == "" { - errorResponse(c, "Role name is required", 400) + common.ErrorWithCode(c, 400, "Role name is required") return } role, err := h.service.ShowRole(roleName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, role, "") + common.SuccessWithData(c, role, "") } // UpdateRoleHTTPRequest update role request @@ -91,57 +91,57 @@ type UpdateRoleHTTPRequest struct { func (h *Handler) UpdateRole(c *gin.Context) { roleName := c.Param("role_name") if roleName == "" { - errorResponse(c, "Role name is required", 400) + common.ErrorWithCode(c, 400, "Role name is required") return } var req UpdateRoleHTTPRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "Role description is required", 400) + common.ErrorWithCode(c, 400, "Role description is required") return } role, err := h.service.UpdateRole(roleName, req.Description) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, role, "") + common.SuccessWithData(c, role, "") } // DropRole handle drop role func (h *Handler) DropRole(c *gin.Context) { roleName := c.Param("role_name") if roleName == "" { - errorResponse(c, "Role name is required", 400) + common.ErrorWithCode(c, 400, "Role name is required") return } role, err := h.service.DropRole(roleName) if err != nil { - errorResponse(c, "Role not found", 404) + common.ErrorWithCode(c, 404, "Role not found") return } - success(c, role, "") + common.SuccessWithData(c, role, "") } // ShowRolePermission handle get role permission func (h *Handler) ShowRolePermission(c *gin.Context) { roleName := c.Param("role_name") if roleName == "" { - errorResponse(c, "Role name is required", 400) + common.ErrorWithCode(c, 400, "Role name is required") return } permissions, err := h.service.ShowRolePermission(roleName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, permissions, "") + common.SuccessWithData(c, permissions, "") } // GrantRolePermissionHTTPRequest grant role permission request @@ -154,23 +154,23 @@ type GrantRolePermissionHTTPRequest struct { func (h *Handler) GrantRolePermission(c *gin.Context) { roleName := c.Param("role_name") if roleName == "" { - errorResponse(c, "Role name is required", 400) + common.ErrorWithCode(c, 400, "Role name is required") return } var req GrantRolePermissionHTTPRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "Permission is required", 400) + common.ErrorWithCode(c, 400, "Permission is required") return } result, err := h.service.GrantRolePermission(roleName, req.Actions, req.Resource) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "") + common.SuccessWithData(c, result, "") } // RevokeRolePermissionHTTPRequest revoke role permission request @@ -183,23 +183,23 @@ type RevokeRolePermissionHTTPRequest struct { func (h *Handler) RevokeRolePermission(c *gin.Context) { roleName := c.Param("role_name") if roleName == "" { - errorResponse(c, "Role name is required", 400) + common.ErrorWithCode(c, 400, "Role name is required") return } var req RevokeRolePermissionHTTPRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "Permission is required", 400) + common.ErrorWithCode(c, 400, "Permission is required") return } result, err := h.service.RevokeRolePermission(roleName, req.Actions, req.Resource) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "") + common.SuccessWithData(c, result, "") } // ListResources handle list role resources @@ -207,29 +207,29 @@ func (h *Handler) ListResources(c *gin.Context) { resources, err := h.service.ListResources() if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "Role not found", 404) + common.ErrorWithCode(c, 404, "Role not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, resources, "") + common.SuccessWithData(c, resources, "") } func (h *Handler) ShowRoleDefaultModels(c *gin.Context) { roleName := c.Param("role_name") if roleName == "" { - errorResponse(c, "Role name is required", 400) + common.ErrorWithCode(c, 400, "Role name is required") return } result, err := h.service.ShowRoleDefaultModels(roleName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Role default model set successfully") + common.SuccessWithData(c, result, "Role default model set successfully") } type SetRoleDefaultModelRequest struct { @@ -240,26 +240,21 @@ type SetRoleDefaultModelRequest struct { func (h *Handler) SetRoleDefaultModel(c *gin.Context) { roleName := c.Param("role_name") if roleName == "" { - errorResponse(c, "Role name is required", 400) + common.ErrorWithCode(c, 400, "Role name is required") return } var request SetRoleDefaultModelRequest if err := c.ShouldBindJSON(&request); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": "Invalid request body: " + err.Error(), - }) - return + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) } result, err := h.service.SetRoleDefaultModel(roleName, request.ModelID, request.ModelType) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Role default model set successfully") + common.SuccessWithData(c, result, "Role default model set successfully") } type ResetRoleDefaultModelRequest struct { @@ -269,26 +264,22 @@ type ResetRoleDefaultModelRequest struct { func (h *Handler) ResetRoleDefaultModel(c *gin.Context) { roleName := c.Param("role_name") if roleName == "" { - errorResponse(c, "Role name is required", 400) + common.ErrorWithCode(c, 400, "Role name is required") return } var request ResetRoleDefaultModelRequest if err := c.ShouldBindJSON(&request); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": "Invalid request body: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) return } result, err := h.service.ResetRoleDefaultModel(roleName, request.ModelType) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Role default model set successfully") + common.SuccessWithData(c, result, "Role default model set successfully") } func (h *Handler) ListModelProviders(c *gin.Context) { @@ -303,11 +294,11 @@ func (h *Handler) ListModelProviders(c *gin.Context) { result, err := h.service.ListModelProviders() if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "List model providers successfully") + common.SuccessWithData(c, result, "List model providers successfully") } type AddProviderRequest struct { @@ -317,11 +308,7 @@ type AddProviderRequest struct { func (h *Handler) AddModelProvider(c *gin.Context) { var req AddProviderRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeBadRequest, false, err.Error()) return } @@ -329,36 +316,26 @@ func (h *Handler) AddModelProvider(c *gin.Context) { result, err := h.service.AddModelProvider(req.ProviderName, userID) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Model provider added successfully") + common.SuccessWithData(c, result, "Model provider added successfully") } func (h *Handler) ShowProvider(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } provider, err := dao.GetModelProviderManager().GetProviderByName(providerName) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeNotFound, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeNotFound), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": provider, - }) + common.SuccessWithData(c, provider, "success") } type DeleteProviderRequest struct { @@ -368,10 +345,7 @@ type DeleteProviderRequest struct { func (h *Handler) DeleteModelProvider(c *gin.Context) { var req DeleteProviderRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } @@ -379,76 +353,51 @@ func (h *Handler) DeleteModelProvider(c *gin.Context) { result, err := h.service.DeleteModelProviders(userID, req.ProviderNames) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Model provider deleted successfully") + common.SuccessWithData(c, result, "Model provider deleted successfully") } func (h *Handler) ListModels(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } models, err := dao.GetModelProviderManager().ListModels(providerName) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeNotFound, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeNotFound), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": models, - }) + + common.SuccessWithData(c, models, "success") } func (h *Handler) ShowProviderModel(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } modelName := c.Param("model_name") if modelName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model name is required") return } model, err := dao.GetModelProviderManager().GetModelByName(providerName, modelName) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeNotFound, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeNotFound), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": model, - }) + common.SuccessWithData(c, model, "success") } func (h *Handler) ListModelInstances(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } @@ -456,95 +405,77 @@ func (h *Handler) ListModelInstances(c *gin.Context) { result, err := h.service.ListModelInstances(userID, providerName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Model instances listed successfully") + common.SuccessWithData(c, result, "Model instances listed successfully") } func (h *Handler) ShowProviderInstance(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } userID := c.GetString("user_id") result, err := h.service.ShowProviderInstance(userID, providerName, instanceName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Model instance shown successfully") + common.SuccessWithData(c, result, "Model instance shown successfully") } func (h *Handler) ShowProviderInstanceBalance(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } userID := c.GetString("user_id") result, err := h.service.ShowProviderInstanceBalance(userID, providerName, instanceName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Model instance balance shown successfully") + common.SuccessWithData(c, result, "Model instance balance shown successfully") } func (h *Handler) CheckInstanceConnection(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } userID := c.GetString("user_id") result, err := h.service.CheckInstanceConnection(userID, providerName, instanceName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Model instance connection checked successfully") + common.SuccessWithData(c, result, "Model instance connection checked successfully") } type CheckConnectionRequest struct { @@ -556,19 +487,13 @@ type CheckConnectionRequest struct { func (h *Handler) CheckProviderConnection(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } var req CheckConnectionRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, err.Error()) return } @@ -576,11 +501,11 @@ func (h *Handler) CheckProviderConnection(c *gin.Context) { result, err := h.service.CheckProviderConnection(userID, providerName, req.Region, req.APIKey, req.BaseURL) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Model instance connection checked successfully") + common.SuccessWithData(c, result, "Model instance connection checked successfully") } type AlterProviderInstanceRequest struct { @@ -591,47 +516,35 @@ type AlterProviderInstanceRequest struct { func (h *Handler) AlterProviderInstance(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } var req AlterProviderInstanceRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } userID := c.GetString("user_id") if userID == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeUnauthorized, - "message": "Unauthorized", - }) + common.ErrorWithCode(c, int(common.CodeUnauthorized), "Unauthorized") return } result, err := h.service.AlterProviderInstance(userID, providerName, instanceName, req.InstanceName, req.APIKey) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Model instance altered successfully") + common.SuccessWithData(c, result, "Model instance altered successfully") } type AddModelInstanceRequest struct { @@ -641,20 +554,13 @@ type AddModelInstanceRequest struct { func (h *Handler) AddModelInstance(c *gin.Context) { var req AddModelInstanceRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeBadRequest, false, err.Error()) return } providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } @@ -662,11 +568,11 @@ func (h *Handler) AddModelInstance(c *gin.Context) { result, err := h.service.AddModelInstance(userID, providerName, req.InstanceName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Model instance added successfully") + common.SuccessWithData(c, result, "Model instance added successfully") } type DropModelInstanceRequest struct { @@ -676,19 +582,13 @@ type DropModelInstanceRequest struct { func (h *Handler) DeleteModelInstance(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } var req DropModelInstanceRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } @@ -696,29 +596,23 @@ func (h *Handler) DeleteModelInstance(c *gin.Context) { result, err := h.service.DeleteModelInstances(userID, providerName, req.InstanceNames) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Model provider added successfully") + common.SuccessWithData(c, result, "Model provider added successfully") } func (h *Handler) ListInstanceModels(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } @@ -726,11 +620,11 @@ func (h *Handler) ListInstanceModels(c *gin.Context) { result, err := h.service.ListInstanceModels(userID, providerName, instanceName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Models listed successfully") + common.SuccessWithData(c, result, "Models listed successfully") } type EnableOrDisableModelRequest struct { @@ -741,29 +635,20 @@ type EnableOrDisableModelRequest struct { func (h *Handler) EnableOrDisableModel(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } var req EnableOrDisableModelRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } @@ -771,10 +656,7 @@ func (h *Handler) EnableOrDisableModel(c *gin.Context) { modelName := strings.TrimPrefix(c.Param("model_name"), "/") modelName = strings.TrimSpace(modelName) if modelName == "" && modelID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": "model_name or model_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "model_name or model_id is required") return } @@ -782,11 +664,11 @@ func (h *Handler) EnableOrDisableModel(c *gin.Context) { result, err := h.service.EnableOrDisableModel(userID, providerName, instanceName, modelName, modelID, req.Status) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Models listed successfully") + common.SuccessWithData(c, result, "Models listed successfully") } type AddModelsRequest struct { @@ -796,29 +678,19 @@ type AddModelsRequest struct { func (h *Handler) AddModels(c *gin.Context) { var req AddModelsRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeBadRequest, false, err.Error()) return } providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } @@ -826,11 +698,11 @@ func (h *Handler) AddModels(c *gin.Context) { result, err := h.service.AddModels(userID, providerName, instanceName, req.ModelNames) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Models added successfully") + common.SuccessWithData(c, result, "Models added successfully") } type DropModelsRequest struct { @@ -840,28 +712,19 @@ type DropModelsRequest struct { func (h *Handler) DeleteModels(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } var req DropModelsRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } @@ -869,22 +732,22 @@ func (h *Handler) DeleteModels(c *gin.Context) { result, err := h.service.DeleteModels(userID, providerName, instanceName, req.ModelNames) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Model deleted successfully") + common.SuccessWithData(c, result, "Model deleted successfully") } // GetSystemFingerprint handle get system fingerprint func (h *Handler) GetSystemFingerprint(c *gin.Context) { fingerprint, err := h.service.GetSystemFingerprint() if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, fingerprint, "") + common.SuccessWithData(c, fingerprint, "") } type SetSystemLicenseRequest struct { @@ -896,19 +759,16 @@ func (h *Handler) SetSystemLicense(c *gin.Context) { var req SetSystemLicenseRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } err := h.service.SetSystemLicense(req.License) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, nil, "System license set successfully") + common.SuccessWithData(c, nil, "System license set successfully") } // ShowSystemLicense to get system license @@ -919,16 +779,16 @@ func (h *Handler) ShowSystemLicense(c *gin.Context) { } checkFlag, err := strconv.ParseBool(check) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } systemLicense, err := h.service.ShowSystemLicense(checkFlag) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, systemLicense, "") + common.SuccessWithData(c, systemLicense, "") } type SetSystemLicenseConfigRequest struct { @@ -940,18 +800,15 @@ func (h *Handler) UpdateSystemLicenseConfig(c *gin.Context) { var req SetSystemLicenseConfigRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } result, err := h.service.UpdateSystemLicenseConfig(req.TimeRecordSaveInterval, req.TimeRecordTaskDuration) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "System license config updated successfully") + common.SuccessWithData(c, result, "System license config updated successfully") } type ShowUserActivityRequest struct { @@ -964,23 +821,20 @@ func (h *Handler) ShowUserActivity(c *gin.Context) { var req ShowUserActivityRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } userActivity, err := h.service.ShowUserActivity(req.Email, req.Days) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, userActivity, "") + common.SuccessWithData(c, userActivity, "") } type ShowUserDatasetSummaryRequest struct { @@ -992,35 +846,32 @@ func (h *Handler) ShowUserDatasetSummary(c *gin.Context) { var req ShowUserDatasetSummaryRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } userDatasetSummary, err := h.service.ShowUserDatasetSummary(username, req.Dataset) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, userDatasetSummary, "") + common.SuccessWithData(c, userDatasetSummary, "") } // ShowUserSummary handle show user summary @@ -1028,25 +879,25 @@ func (h *Handler) ShowUserSummary(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } userSummary, err := h.service.ShowUserSummary(username) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, userSummary, "") + common.SuccessWithData(c, userSummary, "") } // ShowUserStorage handle show user storage @@ -1054,25 +905,25 @@ func (h *Handler) ShowUserStorage(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } userStorage, err := h.service.ShowUserStorage(username) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, userStorage, "") + common.SuccessWithData(c, userStorage, "") } // ShowUserQuota handle show user quota @@ -1080,25 +931,25 @@ func (h *Handler) ShowUserQuota(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } userQuota, err := h.service.ShowUserQuota(username) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, userQuota, "") + common.SuccessWithData(c, userQuota, "") } // ShowUserIndex handle show user index @@ -1106,25 +957,25 @@ func (h *Handler) ShowUserIndex(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } userIndex, err := h.service.ShowUserIndex(username) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, userIndex, "") + common.SuccessWithData(c, userIndex, "") } // UpdateUserRoleHTTPRequest update user role request @@ -1137,27 +988,27 @@ func (h *Handler) UpdateUserRole(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } var req UpdateUserRoleHTTPRequest - if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "Role name is required", 400) + if err = c.ShouldBindJSON(&req); err != nil { + common.ErrorWithCode(c, 400, "Role name is required") return } result, err := h.service.UpdateUserRole(username, req.RoleName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "") + common.SuccessWithData(c, result, "") } // ShowUserPermission handle show user permission @@ -1165,21 +1016,21 @@ func (h *Handler) ShowUserPermission(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } permissions, err := h.service.ShowUserPermission(username) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, permissions, "") + common.SuccessWithData(c, permissions, "") } // ListUserDatasets handle show user datasets @@ -1187,21 +1038,21 @@ func (h *Handler) ListUserDatasets(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } datasets, err := h.service.ListUserDatasets(username) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, datasets, "") + common.SuccessWithData(c, datasets, "") } // ListUserAgents handle show user agents @@ -1209,21 +1060,21 @@ func (h *Handler) ListUserAgents(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } agents, err := h.service.ListUserAgents(username) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, agents, "") + common.SuccessWithData(c, agents, "") } // ListUserChats handle show user chats @@ -1231,21 +1082,21 @@ func (h *Handler) ListUserChats(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } chats, err := h.service.ListUserChats(username) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, chats, "") + common.SuccessWithData(c, chats, "") } // ListUserSearches handle show user searches @@ -1253,21 +1104,21 @@ func (h *Handler) ListUserSearches(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } searches, err := h.service.ListUserSearches(username) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, searches, "") + common.SuccessWithData(c, searches, "") } // ListUserModels handle show user models @@ -1275,21 +1126,21 @@ func (h *Handler) ListUserModels(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } models, err := h.service.ListUserModels(username) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, models, "") + common.SuccessWithData(c, models, "") } // ListUserFiles handle show user files @@ -1297,21 +1148,21 @@ func (h *Handler) ListUserFiles(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } files, err := h.service.ListUserFiles(username) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, files, "") + common.SuccessWithData(c, files, "") } // ListUserProviders handle show user providers @@ -1319,21 +1170,21 @@ func (h *Handler) ListUserProviders(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } providers, err := h.service.ListUserProviders(username) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, providers, "") + common.SuccessWithData(c, providers, "") } // ListUserProviderInstances handle show user provider instances @@ -1341,27 +1192,27 @@ func (h *Handler) ListUserProviderInstances(c *gin.Context) { encodedUsername := c.Param("username") userName, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if userName == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } providerName := c.Param("provider_name") if providerName == "" { - errorResponse(c, "Provider name is required", 400) + common.ErrorWithCode(c, 400, "Provider name is required") return } instances, err := h.service.ListUserProviderInstances(userName, providerName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, instances, "") + common.SuccessWithData(c, instances, "") } // ListUserProviderInstanceModels handle show user provider instance models @@ -1369,33 +1220,33 @@ func (h *Handler) ListUserProviderInstanceModels(c *gin.Context) { encodedUsername := c.Param("username") userName, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if userName == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } providerName := c.Param("provider_name") if providerName == "" { - errorResponse(c, "Provider name is required", 400) + common.ErrorWithCode(c, 400, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - errorResponse(c, "Instance name is required", 400) + common.ErrorWithCode(c, 400, "Instance name is required") return } models, err := h.service.ListUserProviderInstanceModels(userName, providerName, instanceName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, models, "") + common.SuccessWithData(c, models, "") } // ListUserDefaultModels handle show user default models @@ -1403,21 +1254,21 @@ func (h *Handler) ListUserDefaultModels(c *gin.Context) { encodedUsername := c.Param("username") userName, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if userName == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } models, err := h.service.ListUserDefaultModels(userName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, models, "") + common.SuccessWithData(c, models, "") } // ShowUsersSummary handle show users summary @@ -1425,14 +1276,14 @@ func (h *Handler) ShowUsersSummary(c *gin.Context) { usersSummary, err := h.service.ShowUsersSummary() if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, usersSummary, "") + common.SuccessWithData(c, usersSummary, "") } type ShowUsersActivityRequest struct { @@ -1445,23 +1296,20 @@ func (h *Handler) ShowUsersActivity(c *gin.Context) { var req ShowUsersActivityRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } usersActivity, err := h.service.ShowUsersActivity(req.Days, req.Window) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, usersActivity, "") + common.SuccessWithData(c, usersActivity, "") } type ListUsersReportsRequest struct { @@ -1475,10 +1323,7 @@ func (h *Handler) ListUsersReports(c *gin.Context) { var req ListUsersReportsRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } @@ -1488,7 +1333,7 @@ func (h *Handler) ListUsersReports(c *gin.Context) { if pageIndexStr != "" { pageIndex, err = strconv.Atoi(pageIndexStr) if err != nil { - errorResponse(c, "Page index must be an integer", 400) + common.ErrorWithCode(c, 400, "Page index must be an integer") return } } @@ -1497,7 +1342,7 @@ func (h *Handler) ListUsersReports(c *gin.Context) { if pageSizeStr != "" { pageSize, err = strconv.Atoi(pageSizeStr) if err != nil { - errorResponse(c, "Page size must be an integer", 400) + common.ErrorWithCode(c, 400, "Page size must be an integer") return } } @@ -1505,14 +1350,14 @@ func (h *Handler) ListUsersReports(c *gin.Context) { usersReports, err := h.service.ListUsersReports(pageIndex, pageSize, req.Status, req.Plan, req.Days) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, usersReports, "") + common.SuccessWithData(c, usersReports, "") } // ListUsersStorage handle show users storage @@ -1524,7 +1369,7 @@ func (h *Handler) ListUsersStorage(c *gin.Context) { if pageIndexStr != "" { pageIndex, err = strconv.Atoi(pageIndexStr) if err != nil { - errorResponse(c, "Page index must be an integer", 400) + common.ErrorWithCode(c, 400, "Page index must be an integer") return } } @@ -1533,7 +1378,7 @@ func (h *Handler) ListUsersStorage(c *gin.Context) { if pageSizeStr != "" { pageSize, err = strconv.Atoi(pageSizeStr) if err != nil { - errorResponse(c, "Page size must be an integer", 400) + common.ErrorWithCode(c, 400, "Page size must be an integer") return } } @@ -1542,21 +1387,21 @@ func (h *Handler) ListUsersStorage(c *gin.Context) { if topStr != "" { top, err = strconv.Atoi(topStr) if err != nil { - errorResponse(c, "Top must be an integer", 400) + common.ErrorWithCode(c, 400, "Top must be an integer") } } usersStorage, err := h.service.ListUsersStorage(pageIndex, pageSize, top) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, usersStorage, "") + common.SuccessWithData(c, usersStorage, "") } // ListUsersDocuments handle show users documents @@ -1568,7 +1413,7 @@ func (h *Handler) ListUsersDocuments(c *gin.Context) { if pageIndexStr != "" { pageIndex, err = strconv.Atoi(pageIndexStr) if err != nil { - errorResponse(c, "Page index must be an integer", 400) + common.ErrorWithCode(c, 400, "Page index must be an integer") return } } @@ -1577,7 +1422,7 @@ func (h *Handler) ListUsersDocuments(c *gin.Context) { if pageSizeStr != "" { pageSize, err = strconv.Atoi(pageSizeStr) if err != nil { - errorResponse(c, "Page size must be an integer", 400) + common.ErrorWithCode(c, 400, "Page size must be an integer") return } } @@ -1586,21 +1431,21 @@ func (h *Handler) ListUsersDocuments(c *gin.Context) { if topStr != "" { top, err = strconv.Atoi(topStr) if err != nil { - errorResponse(c, "Top must be an integer", 400) + common.ErrorWithCode(c, 400, "Top must be an integer") } } usersDocuments, err := h.service.ListUsersDocuments(pageIndex, pageSize, top) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, usersDocuments, "") + common.SuccessWithData(c, usersDocuments, "") } // ListUsersIndex handle show users index @@ -1612,7 +1457,7 @@ func (h *Handler) ListUsersIndex(c *gin.Context) { if pageIndexStr != "" { pageIndex, err = strconv.Atoi(pageIndexStr) if err != nil { - errorResponse(c, "Page index must be an integer", 400) + common.ErrorWithCode(c, 400, "Page index must be an integer") return } } @@ -1621,7 +1466,7 @@ func (h *Handler) ListUsersIndex(c *gin.Context) { if pageSizeStr != "" { pageSize, err = strconv.Atoi(pageSizeStr) if err != nil { - errorResponse(c, "Page size must be an integer", 400) + common.ErrorWithCode(c, 400, "Page size must be an integer") return } } @@ -1630,21 +1475,21 @@ func (h *Handler) ListUsersIndex(c *gin.Context) { if topStr != "" { top, err = strconv.Atoi(topStr) if err != nil { - errorResponse(c, "Top must be an integer", 400) + common.ErrorWithCode(c, 400, "Top must be an integer") } } usersIndex, err := h.service.ListUsersIndex(pageIndex, pageSize, top) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, usersIndex, "") + common.SuccessWithData(c, usersIndex, "") } type ListUsersQuotaRequest struct { @@ -1658,10 +1503,7 @@ func (h *Handler) ListUsersQuota(c *gin.Context) { var request ListUsersQuotaRequest if err := c.ShouldBindJSON(&request); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } @@ -1671,7 +1513,7 @@ func (h *Handler) ListUsersQuota(c *gin.Context) { if pageIndexStr != "" { pageIndex, err = strconv.Atoi(pageIndexStr) if err != nil { - errorResponse(c, "Page index must be an integer", 400) + common.ErrorWithCode(c, 400, "Page index must be an integer") return } } @@ -1680,7 +1522,7 @@ func (h *Handler) ListUsersQuota(c *gin.Context) { if pageSizeStr != "" { pageSize, err = strconv.Atoi(pageSizeStr) if err != nil { - errorResponse(c, "Page size must be an integer", 400) + common.ErrorWithCode(c, 400, "Page size must be an integer") return } } @@ -1689,21 +1531,21 @@ func (h *Handler) ListUsersQuota(c *gin.Context) { if topStr != "" { top, err = strconv.Atoi(topStr) if err != nil { - errorResponse(c, "Top must be an integer", 400) + common.ErrorWithCode(c, 400, "Top must be an integer") } } usersQuota, err := h.service.ListUsersQuota(pageIndex, pageSize, top, request.QuotaThreshold, request.Plan, request.Days) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, usersQuota, "") + common.SuccessWithData(c, usersQuota, "") } // ShowUsersPlanSummary handle show users plan summary @@ -1711,14 +1553,14 @@ func (h *Handler) ShowUsersPlanSummary(c *gin.Context) { usersPlanSummary, err := h.service.ShowUsersPlanSummary() if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, usersPlanSummary, "") + common.SuccessWithData(c, usersPlanSummary, "") } // ShowUsersQuotaSummary handle show users quota summary @@ -1726,14 +1568,14 @@ func (h *Handler) ShowUsersQuotaSummary(c *gin.Context) { usersQuotaSummary, err := h.service.ShowUsersQuotaSummary() if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, usersQuotaSummary, "") + common.SuccessWithData(c, usersQuotaSummary, "") } // ShowIngestionTasksSummary handle show ingestion tasks summary @@ -1741,14 +1583,14 @@ func (h *Handler) ShowIngestionTasksSummary(c *gin.Context) { ingestionTasksSummary, err := h.service.ShowIngestionTasksSummary() if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, ingestionTasksSummary, "") + common.SuccessWithData(c, ingestionTasksSummary, "") } // ShowDataSummary handle show data summary @@ -1756,14 +1598,14 @@ func (h *Handler) ShowDataSummary(c *gin.Context) { dataSummary, err := h.service.ShowDataSummary() if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, dataSummary, "") + common.SuccessWithData(c, dataSummary, "") } // ShowDataOrphan handle show data orphan @@ -1771,14 +1613,14 @@ func (h *Handler) ShowDataOrphan(c *gin.Context) { dataOrphan, err := h.service.ShowDataOrphan() if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, dataOrphan, "") + common.SuccessWithData(c, dataOrphan, "") } // ShowDataStorage handle show data storage @@ -1786,14 +1628,14 @@ func (h *Handler) ShowDataStorage(c *gin.Context) { dataStorage, err := h.service.ShowDataStorage() if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, dataStorage, "") + common.SuccessWithData(c, dataStorage, "") } // ShowDataIndex handle show data index @@ -1801,14 +1643,14 @@ func (h *Handler) ShowDataIndex(c *gin.Context) { dataIndex, err := h.service.ShowDataIndex() if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, dataIndex, "") + common.SuccessWithData(c, dataIndex, "") } type PurgeOrphanDataRequest struct { @@ -1820,23 +1662,20 @@ func (h *Handler) PurgeOrphanData(c *gin.Context) { var request PurgeOrphanDataRequest if err := c.ShouldBindJSON(&request); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } result, err := h.service.PurgeOrphanData(request.Preview) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "Orphan data purged successfully") + common.SuccessWithData(c, result, "Orphan data purged successfully") } type PurgeUserDataRequest struct { @@ -1848,34 +1687,31 @@ func (h *Handler) PurgeUserData(c *gin.Context) { var request PurgeUserDataRequest if err := c.ShouldBindJSON(&request); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } result, err := h.service.PurgeUserData(username, request.Preview) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "") + common.SuccessWithData(c, result, "") } type PurgeUsersDataRequest struct { @@ -1890,24 +1726,21 @@ func (h *Handler) PurgeUsersData(c *gin.Context) { var request PurgeUsersDataRequest if err := c.ShouldBindJSON(&request); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } result, err := h.service.PurgeUsersData(request.Preview, request.Days, request.Plan, request.UserStatus) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "") + common.SuccessWithData(c, result, "") } // GenerateUserAPIKey handle create tenant API key @@ -1915,17 +1748,17 @@ func (h *Handler) GenerateUserAPIKey(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } apiKey, err := h.service.GenerateUserAPIKey(username) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, apiKey, "API key generated successfully") + common.SuccessWithData(c, apiKey, "API key generated successfully") } // DeleteUserAPIKey handle delete user API key @@ -1933,22 +1766,22 @@ func (h *Handler) DeleteUserAPIKey(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } key := c.Param("key") if username == "" || key == "" { - errorResponse(c, "Username and key are required", 400) + common.ErrorWithCode(c, 400, "Username and key are required") return } result, err := h.service.DeleteUserAPIKey(username, key) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "API key deleted successfully") + common.SuccessWithData(c, result, "API key deleted successfully") } // ListUserAPIKeys handle list user API keys @@ -1956,19 +1789,19 @@ func (h *Handler) ListUserAPIKeys(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } result, err := h.service.ListUserAPIKeys(username) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "API keys listed successfully") + common.SuccessWithData(c, result, "API keys listed successfully") } diff --git a/internal/admin/handler.go b/internal/admin/handler.go index 9cfc65bd93..b278ba64e3 100644 --- a/internal/admin/handler.go +++ b/internal/admin/handler.go @@ -47,59 +47,12 @@ func NewHandler(svc *Service) *Handler { } } -// SuccessResponse success response -type SuccessResponse struct { - Code int `json:"code"` - Message string `json:"message"` - Data interface{} `json:"data"` -} - // ErrorResponse error response type ErrorResponse struct { Code int `json:"code"` Message string `json:"message"` } -// success returns success response -func success(c *gin.Context, data interface{}, message string) { - c.JSON(200, SuccessResponse{ - Code: 0, - Message: message, - Data: data, - }) -} - -// successNoData returns success response without data -func successNoData(c *gin.Context, message string) { - c.JSON(200, SuccessResponse{ - Code: 0, - Message: message, - Data: nil, - }) -} - -// error returns error response -func errorResponse(c *gin.Context, message string, code int) { - c.JSON(code, ErrorResponse{ - Code: code, - Message: message, - }) -} - -func responseWithCode(c *gin.Context, message string, httpCode int, errorCode common.ErrorCode) { - if message == "" { - c.JSON(httpCode, ErrorResponse{ - Code: int(errorCode), - Message: errorCode.Message(), - }) - } else { - c.JSON(httpCode, ErrorResponse{ - Code: int(errorCode), - Message: message, - }) - } -} - // Health check func (h *Handler) Health(c *gin.Context) { c.JSON(200, gin.H{"status": "ok"}) @@ -107,7 +60,7 @@ func (h *Handler) Health(c *gin.Context) { // Ping ping endpoint func (h *Handler) Ping(c *gin.Context) { - successNoData(c, "pong") + common.SuccessNoData(c, "pong") } // Login handle admin login @@ -122,10 +75,7 @@ func (h *Handler) Ping(c *gin.Context) { func (h *Handler) Login(c *gin.Context) { var req service.EmailLoginRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, err.Error()) return } @@ -133,37 +83,25 @@ func (h *Handler) Login(c *gin.Context) { // This allows default admin account to log in admin system user, code, err := h.userService.LoginByEmail(&req) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(code), err.Error()) return } // Check if user is superuser (admin) if user.IsSuperuser == nil || !*user.IsSuperuser { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeForbidden, - "message": "Only superuser can login admin system", - }) + common.ErrorWithCode(c, int(common.CodeForbidden), "Only superuser can login admin system") return } secretKey, err := server.GetSecretKey(redis.Get()) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": fmt.Sprintf("Failed to get secret key: %s", err.Error()), - }) + common.ErrorWithCode(c, int(common.CodeServerError), fmt.Sprintf("Failed to get secret key: %s", err.Error())) return } authToken, err := utility.DumpAccessToken(*user.AccessToken, secretKey) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": fmt.Sprintf("Failed to generate auth token: %s", err.Error()), - }) + common.ErrorWithCode(c, int(common.CodeServerError), fmt.Sprintf("Failed to generate auth token: %s", err.Error())) return } @@ -175,32 +113,28 @@ func (h *Handler) Login(c *gin.Context) { c.Header("Access-Control-Allow-Headers", "*") c.Header("Access-Control-Expose-Headers", "Authorization") - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "Welcome back!", - "data": user, - }) + common.SuccessWithData(c, user, "Welcome back!") } // Logout handle logout func (h *Handler) Logout(c *gin.Context) { user, exists := c.Get("user") if !exists { - errorResponse(c, "Not authenticated", 401) + common.ErrorWithCode(c, 401, "Not authenticated") return } if err := h.service.Logout(user); err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - successNoData(c, "Logout successful") + common.SuccessNoData(c, "Logout successful") } // AuthCheck check admin auth func (h *Handler) AuthCheck(c *gin.Context) { - successNoData(c, "Admin is authorized") + common.SuccessNoData(c, "Admin is authorized") } // ListUsersRequest list users request @@ -225,7 +159,7 @@ func (h *Handler) ListUsers(c *gin.Context) { } else { pageInt, err = strconv.Atoi(page) if err != nil { - errorResponse(c, "Page must be an integer", 400) + common.ErrorWithCode(c, 400, "Page must be an integer") return } } @@ -237,7 +171,7 @@ func (h *Handler) ListUsers(c *gin.Context) { } else { pageSizeInt, err = strconv.Atoi(pageSize) if err != nil { - errorResponse(c, "Page size must be an integer", 400) + common.ErrorWithCode(c, 400, "Page size must be an integer") return } } @@ -247,19 +181,19 @@ func (h *Handler) ListUsers(c *gin.Context) { if err = c.ShouldBindJSON(&req); err != nil { users, err = h.service.ListUsers(pageInt, pageSizeInt) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, users, "Get all users") + common.SuccessWithData(c, users, "Get all users") } else { users, err = h.service.ListUsersEnterprise(pageInt, pageSizeInt, req.UserStatus, req.OrderBy, req.Plan, req.Top, req.Days, req.Quota) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, users, "list users") + common.SuccessWithData(c, users, "List users") } } @@ -275,7 +209,7 @@ type CreateUserHTTPRequest struct { func (h *Handler) CreateUser(c *gin.Context) { var req CreateUserHTTPRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "Username and password are required", 400) + common.ErrorWithCode(c, 400, "Username and password are required") return } @@ -285,11 +219,11 @@ func (h *Handler) CreateUser(c *gin.Context) { userInfo, err := h.service.CreateUser(req.Username, req.Password, req.Role) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, userInfo, "User created successfully") + common.SuccessWithData(c, userInfo, "User created successfully") } // GetUser handle get user @@ -297,25 +231,25 @@ func (h *Handler) GetUser(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } userDetails, err := h.service.GetUserDetails(username) if err != nil { if errors.Is(err, common.ErrUserNotFound) { - errorResponse(c, "User not found", 404) + common.ErrorWithCode(c, 404, "User not found") return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, userDetails, "") + common.SuccessWithData(c, userDetails, "") } // DeleteUser handle delete user @@ -323,17 +257,17 @@ func (h *Handler) DeleteUser(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } result, err := h.service.DeleteUser(username) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } @@ -342,7 +276,7 @@ func (h *Handler) DeleteUser(c *gin.Context) { detailsMsg += detail + "\n" } - successNoData(c, detailsMsg) + common.SuccessNoData(c, detailsMsg) } // ChangePasswordHTTPRequest change password request @@ -355,26 +289,26 @@ func (h *Handler) ChangePassword(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } var req ChangePasswordHTTPRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "New password is required", 400) + common.ErrorWithCode(c, 400, "New password is required") return } if err := h.service.ChangePassword(username, req.NewPassword); err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - successNoData(c, "Password updated successfully") + common.SuccessNoData(c, "Password updated successfully") } // UpdateActivateStatusHTTPRequest update activate status request @@ -387,32 +321,32 @@ func (h *Handler) UpdateUserActivateStatus(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } var req UpdateActivateStatusHTTPRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "Activation status is required", 400) + common.ErrorWithCode(c, 400, "Activation status is required") return } if req.ActivateStatus != "on" && req.ActivateStatus != "off" { - errorResponse(c, "Activation status must be 'on' or 'off'", 400) + common.ErrorWithCode(c, 400, "Activation status must be 'on' or 'off'") return } isActive := req.ActivateStatus == "on" if err := h.service.UpdateUserActivateStatus(username, isActive); err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - successNoData(c, "Activation status updated") + common.SuccessNoData(c, "Activation status updated") } // GrantAdmin handle grant admin role @@ -420,27 +354,27 @@ func (h *Handler) GrantAdmin(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } // Get current user email from context email, _ := c.Get("email") if email != nil && email.(string) == username { - errorResponse(c, "can't grant current user: "+username, 409) + common.ErrorWithCode(c, 409, "can't grant current user: "+username) return } if err := h.service.GrantAdmin(username); err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - successNoData(c, "Admin role granted") + common.SuccessNoData(c, "Admin role granted") } // RevokeAdmin handle revoke admin role @@ -448,27 +382,27 @@ func (h *Handler) RevokeAdmin(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } // Get current user email from context email, _ := c.Get("email") if email != nil && email.(string) == username { - errorResponse(c, "can't revoke current user: "+username, 409) + common.ErrorWithCode(c, 409, "can't revoke current user: "+username) return } - if err := h.service.RevokeAdmin(username); err != nil { - errorResponse(c, err.Error(), 500) + if err = h.service.RevokeAdmin(username); err != nil { + common.ErrorWithCode(c, 500, err.Error()) return } - successNoData(c, "Admin role revoked") + common.SuccessNoData(c, "Admin role revoked") } // ListUserAPITokens handle get user API keys @@ -476,21 +410,21 @@ func (h *Handler) ListUserAPITokens(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } apiKeys, err := h.service.ListUserAPITokens(username) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, apiKeys, "Get user API keys") + common.SuccessWithData(c, apiKeys, "Get user API keys") } // GenerateUserAPIToken handle generate user API key @@ -498,21 +432,21 @@ func (h *Handler) GenerateUserAPIToken(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if username == "" { - errorResponse(c, "Username is required", 400) + common.ErrorWithCode(c, 400, "Username is required") return } apiKey, err := h.service.GenerateUserAPIToken(username) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, apiKey, "API key generated successfully") + common.SuccessWithData(c, apiKey, "API key generated successfully") } // DeleteUserAPIToken handle delete user API key @@ -520,59 +454,56 @@ func (h *Handler) DeleteUserAPIToken(c *gin.Context) { encodedUsername := c.Param("username") username, err := common.DecodeFromBase64(encodedUsername) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } key := c.Param("token") if username == "" || key == "" { - errorResponse(c, "Username and key are required", 400) + common.ErrorWithCode(c, 400, "Username and key are required") return } - if err := h.service.DeleteUserAPIToken(username, key); err != nil { - errorResponse(c, err.Error(), 404) + if err = h.service.DeleteUserAPIToken(username, key); err != nil { + common.ErrorWithCode(c, 400, err.Error()) return } - successNoData(c, "API key deleted successfully") + common.SuccessNoData(c, "API key deleted successfully") } // GetServices handle get all services func (h *Handler) GetServices(c *gin.Context) { services, err := h.service.ListServices() if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": common.CodeServerError, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeBadRequest, nil, err.Error()) return } - success(c, services, "Get all services") + common.SuccessWithData(c, services, "Get all services") } // GetServicesByType handle get services by type func (h *Handler) GetServicesByType(c *gin.Context) { serviceType := c.Param("service_type") if serviceType == "" { - errorResponse(c, "Service type is required", 400) + common.ErrorWithCode(c, 400, "Service type is required") return } services, err := h.service.GetServicesByType(serviceType) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, services, "") + common.SuccessWithData(c, services, "") } // GetService handle get service details func (h *Handler) GetService(c *gin.Context) { serviceID := c.Param("service_id") if serviceID == "" { - errorResponse(c, "Service ID is required", 400) + common.ErrorWithCode(c, 400, "Service ID is required") return } @@ -590,68 +521,68 @@ func (h *Handler) GetService(c *gin.Context) { } if targetService == nil { - errorResponse(c, "Service not found", 404) + common.ErrorWithCode(c, 404, "Service not found") return } serviceStatus, err := h.service.GetServiceDetails(targetService) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, serviceStatus, "") + common.SuccessWithData(c, serviceStatus, "") } // ShutdownService handle shutdown service func (h *Handler) ShutdownService(c *gin.Context) { serviceID := c.Param("service_id") if serviceID == "" { - errorResponse(c, "Service ID is required", 400) + common.ErrorWithCode(c, 400, "Service ID is required") return } result, err := h.service.ShutdownService(serviceID) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "") + common.SuccessWithData(c, result, "") } // StartService handle start service func (h *Handler) StartService(c *gin.Context) { serviceID := c.Param("service_id") if serviceID == "" { - errorResponse(c, "Service ID is required", 400) + common.ErrorWithCode(c, 400, "Service ID is required") return } result, err := h.service.StartService(serviceID) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "") + common.SuccessWithData(c, result, "") } // RestartService handle restart service func (h *Handler) RestartService(c *gin.Context) { serviceID := c.Param("service_id") if serviceID == "" { - errorResponse(c, "Service ID is required", 400) + common.ErrorWithCode(c, 400, "Service ID is required") return } result, err := h.service.RestartService(serviceID) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, result, "") + common.SuccessWithData(c, result, "") } // ListVariables handle list variables @@ -661,10 +592,10 @@ func (h *Handler) ListVariables(c *gin.Context) { // List all variables variables, err := h.service.ListAllVariables() if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, variables, "") + common.SuccessWithData(c, variables, "") return } @@ -673,12 +604,12 @@ func (h *Handler) ListVariables(c *gin.Context) { VarName string `json:"var_name"` } if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "Invalid request body", 400) + common.ErrorWithCode(c, 400, "Invalid request body") return } if req.VarName == "" { - errorResponse(c, "Var name is required", 400) + common.ErrorWithCode(c, 400, "Var name is required") return } @@ -686,14 +617,14 @@ func (h *Handler) ListVariables(c *gin.Context) { if err != nil { // Check if it's an AdminException if adminErr, ok := err.(*AdminException); ok { - errorResponse(c, adminErr.Message, 400) + common.ErrorWithCode(c, 400, adminErr.Message) return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, variable, "") + common.SuccessWithData(c, variable, "") } // ShowVariable handle show variable @@ -701,21 +632,21 @@ func (h *Handler) ShowVariable(c *gin.Context) { encodedVarName := c.Param("var_name") varName, err := common.DecodeFromBase64(encodedVarName) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if varName == "" { - errorResponse(c, "Var name is required", 400) + common.ErrorWithCode(c, 400, "Var name is required") return } variable, err := h.service.GetVariable(varName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, variable, "") + common.SuccessWithData(c, variable, "") } // SetVariableHTTPRequest set variable request @@ -729,67 +660,64 @@ type SetVariableHTTPRequest struct { func (h *Handler) SetVariable(c *gin.Context) { var req SetVariableHTTPRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "Var name is required", 400) + common.ErrorWithCode(c, 400, "Var name is required") return } if req.VarName == "" { - errorResponse(c, "Var name is required", 400) + common.ErrorWithCode(c, 400, "Var name is required") return } if req.VarValue == "" { - errorResponse(c, "Var value is required", 400) + common.ErrorWithCode(c, 400, "Var value is required") return } if err := h.service.SetVariable(req.VarName, req.VarValue); err != nil { // Check if it's an AdminException if adminErr, ok := err.(*AdminException); ok { - errorResponse(c, adminErr.Message, 400) + common.ErrorWithCode(c, 400, adminErr.Message) return } - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - successNoData(c, "Set variable successfully") + common.SuccessNoData(c, "Set variable successfully") } // ListConfigs handle list configs func (h *Handler) ListConfigs(c *gin.Context) { configs, err := h.service.ListAllConfigs() if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, configs, "") + common.SuccessWithData(c, configs, "") } // ListEnvironments handle list environments func (h *Handler) ListEnvironments(c *gin.Context) { environments, err := h.service.ListEnvironments() if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, environments, "") + common.SuccessWithData(c, environments, "") } // GetVersion handle get version func (h *Handler) GetVersion(c *gin.Context) { version := h.service.GetVersion() - success(c, gin.H{"version": version}, "") + common.SuccessWithData(c, gin.H{"version": version}, "") } // GetFingerprint handle get system fingerprint func (h *Handler) GetFingerprint(c *gin.Context) { - c.JSON(http.StatusNotImplemented, gin.H{ - "code": common.CodeServerError, - "message": "method not implemented", - }) + common.ResponseWithHttpCodeData(c, http.StatusNotImplemented, common.CodeBadRequest, nil, "method not implemented") return } @@ -799,10 +727,7 @@ type SetLicenseHTTPRequest struct { // SetLicense to set system license func (h *Handler) SetLicense(c *gin.Context) { - c.JSON(http.StatusNotImplemented, gin.H{ - "code": common.CodeServerError, - "message": "method not implemented", - }) + common.ResponseWithHttpCodeData(c, http.StatusNotImplemented, common.CodeBadRequest, nil, "method not implemented") return } @@ -812,19 +737,13 @@ type SetLicenseConfigHTTPRequest struct { } func (h *Handler) UpdateLicenseConfig(c *gin.Context) { - c.JSON(http.StatusNotImplemented, gin.H{ - "code": common.CodeServerError, - "message": "method not implemented", - }) + common.ResponseWithHttpCodeData(c, http.StatusNotImplemented, common.CodeBadRequest, nil, "method not implemented") return } // ShowLicense to get system license func (h *Handler) ShowLicense(c *gin.Context) { - c.JSON(http.StatusNotImplemented, gin.H{ - "code": common.CodeServerError, - "message": "method not implemented", - }) + common.ResponseWithHttpCodeData(c, http.StatusNotImplemented, common.CodeBadRequest, nil, "method not implemented") return } @@ -832,39 +751,39 @@ func (h *Handler) ShowLicense(c *gin.Context) { func (h *Handler) ListSandboxProviders(c *gin.Context) { providers, err := h.service.ListSandboxProviders() if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } - success(c, providers, "") + common.SuccessWithData(c, providers, "") } // GetSandboxProviderSchema handle get sandbox provider schema func (h *Handler) GetSandboxProviderSchema(c *gin.Context) { providerID := c.Param("provider_id") if providerID == "" { - errorResponse(c, "Provider ID is required", 400) + common.ErrorWithCode(c, 400, "Provider ID is required") return } schema, err := h.service.GetSandboxProviderSchema(providerID) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } - success(c, schema, "") + common.SuccessWithData(c, schema, "") } // GetSandboxConfig handle get sandbox config func (h *Handler) GetSandboxConfig(c *gin.Context) { config, err := h.service.GetSandboxConfig() if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } - success(c, config, "") + common.SuccessWithData(c, config, "") } // SetSandboxConfigHTTPRequest set sandbox config request @@ -878,12 +797,12 @@ type SetSandboxConfigHTTPRequest struct { func (h *Handler) SetSandboxConfig(c *gin.Context) { var req SetSandboxConfigHTTPRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "Request body is required", 400) + common.ErrorWithCode(c, 400, "Request body is required") return } if req.ProviderType == "" { - errorResponse(c, "provider_type is required", 400) + common.ErrorWithCode(c, 400, "Provider type is required") return } @@ -893,11 +812,11 @@ func (h *Handler) SetSandboxConfig(c *gin.Context) { result, err := h.service.SetSandboxConfig(req.ProviderType, req.Config, req.SetActive) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } - success(c, result, "Sandbox configuration updated successfully") + common.SuccessWithData(c, result, "Sandbox configuration updated successfully") } // TestSandboxConnectionHTTPRequest test sandbox connection request @@ -910,25 +829,22 @@ type TestSandboxConnectionHTTPRequest struct { func (h *Handler) TestSandboxConnection(c *gin.Context) { var req TestSandboxConnectionHTTPRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "Request body is required", 400) + common.ErrorWithCode(c, 400, "Request body is required") return } if req.ProviderType == "" { - errorResponse(c, "provider_type is required", 400) + common.ErrorWithCode(c, 400, "Provider type is required") return } result, err := h.service.TestSandboxConnection(req.ProviderType, req.Config) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": "Invalid access token", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid access token") return } - success(c, result, "") + common.SuccessWithData(c, result, "") } // AuthMiddleware JWT auth middleware @@ -937,7 +853,7 @@ func (h *Handler) AuthMiddleware() gin.HandlerFunc { return func(c *gin.Context) { token := c.GetHeader("Authorization") if token == "" { - errorResponse(c, "missing authorization header", 401) + common.ErrorWithCode(c, 401, "Missing authorization header") c.Abort() return } @@ -945,19 +861,14 @@ func (h *Handler) AuthMiddleware() gin.HandlerFunc { // Get user by access token user, code, err := h.userService.GetUserByToken(token) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{ - "code": code, - "message": "Invalid access token", - }) + common.ResponseWithHttpCodeData(c, http.StatusUnauthorized, code, nil, "Invalid access token") c.Abort() return } if !*user.IsSuperuser { - c.JSON(http.StatusForbidden, gin.H{ - "code": common.CodeForbidden, - "message": "Permission denied", - }) + common.ResponseWithHttpCodeData(c, http.StatusForbidden, common.CodeForbidden, nil, "Permission denied") + c.Abort() return } @@ -970,16 +881,13 @@ func (h *Handler) AuthMiddleware() gin.HandlerFunc { // HandleNoRoute handle undefined routes func (h *Handler) HandleNoRoute(c *gin.Context) { - c.JSON(http.StatusNotFound, ErrorResponse{ - Code: 404, - Message: "The requested resource was not found", - }) + common.ResponseWithHttpCodeData(c, http.StatusNotFound, 404, nil, "The requested resource was not found") } // GetLogLevel returns the current log level func (h *Handler) GetLogLevel(c *gin.Context) { level := common.GetLevel() - success(c, gin.H{"level": level}, "SUCCESS") + common.SuccessWithData(c, gin.H{"level": level}, "SUCCESS") } // SetLogLevelRequest set log level request @@ -991,16 +899,16 @@ type SetLogLevelRequest struct { func (h *Handler) SetLogLevel(c *gin.Context) { var req SetLogLevelRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "level is required", 400) + common.ErrorWithCode(c, 400, "Level is required") return } if err := common.SetLevel(req.Level); err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } - success(c, gin.H{"level": req.Level}, "SUCCESS") + common.SuccessWithData(c, gin.H{"level": req.Level}, "SUCCESS") } func (h *Handler) ListMessagesFromQueue(c *gin.Context) { @@ -1008,7 +916,7 @@ func (h *Handler) ListMessagesFromQueue(c *gin.Context) { msgQueueEngine := engine.GetMessageQueueEngine() messages, err := msgQueueEngine.ListMessages("ingestion", false) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } var result []map[string]string @@ -1025,7 +933,7 @@ func (h *Handler) ListMessagesFromQueue(c *gin.Context) { }) } - success(c, result, "List messages from queue successfully") + common.SuccessWithData(c, result, "List messages from queue successfully") } type PublishMessageToQueueRequest struct { @@ -1035,7 +943,7 @@ type PublishMessageToQueueRequest struct { func (h *Handler) PublishMessageToQueue(c *gin.Context) { var req PublishMessageToQueueRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "message is required", 400) + common.ErrorWithCode(c, 400, "Message is required") return } @@ -1047,18 +955,18 @@ func (h *Handler) PublishMessageToQueue(c *gin.Context) { // convert task taskMessageStr, err := json.Marshal(taskMessage) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } msgQueueEngine := engine.GetMessageQueueEngine() err = msgQueueEngine.PublishTask("tasks.RAGFLOW", taskMessageStr) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } - success(c, nil, "Publish message successfully") + common.SuccessWithData(c, nil, "Publish message successfully") } type PullMessageFromQueueRequest struct { @@ -1069,14 +977,14 @@ type PullMessageFromQueueRequest struct { func (h *Handler) PullMessageFromQueue(c *gin.Context) { var req PullMessageFromQueueRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, fmt.Sprintf("message count and ack_policy are required, error: %s", err.Error()), 400) + common.ErrorWithCode(c, 400, fmt.Sprintf("Message count error: %s", err.Error())) return } msgQueueEngine := engine.GetMessageQueueEngine() err := msgQueueEngine.InitConsumer("tasks.RAGFLOW") if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } messages, err := msgQueueEngine.GetMessages(req.MessageCount) @@ -1112,7 +1020,7 @@ func (h *Handler) PullMessageFromQueue(c *gin.Context) { } } - success(c, result, "Pull messages from queue successfully") + common.SuccessWithData(c, result, "Pull messages from queue successfully") } func (h *Handler) ShowMessageQueue(c *gin.Context) { @@ -1120,11 +1028,11 @@ func (h *Handler) ShowMessageQueue(c *gin.Context) { msgQueueEngine := engine.GetMessageQueueEngine() result, err := msgQueueEngine.ShowMessageQueue() if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } - success(c, result, "show message queue successfully") + common.SuccessWithData(c, result, "show message queue successfully") } type RemoveIngestionTaskRequest struct { @@ -1136,25 +1044,25 @@ type RemoveIngestionTaskRequest struct { func (h *Handler) RemoveIngestionTasks(c *gin.Context) { var req RemoveIngestionTaskRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "task id is required", 400) + common.ErrorWithCode(c, 400, "Task ID is required") return } if req.Email == nil && req.Status == nil { tasks, err := h.service.RemoveIngestionTasks(req.Tasks) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } - success(c, tasks, "Remove tasks successfully") + common.SuccessWithData(c, tasks, "Remove tasks successfully") } else { tasks, err := h.service.RemoveIngestionTasksByCondition(req.Tasks, req.Email, req.Status) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } - success(c, tasks, "Remove tasks successfully") + common.SuccessWithData(c, tasks, "Remove tasks successfully") } } @@ -1167,14 +1075,14 @@ type StopIngestionTaskRequest struct { func (h *Handler) StopIngestionTasks(c *gin.Context) { var req StopIngestionTaskRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "task id and from is required", 400) + common.ErrorWithCode(c, 400, "Task ID is required") return } if req.Email == nil && req.Status == nil { tasks, err := h.service.StopIngestionTasks(req.Tasks) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } var result []map[string]string @@ -1185,14 +1093,14 @@ func (h *Handler) StopIngestionTasks(c *gin.Context) { }) } - success(c, result, "Stop tasks successfully") + common.SuccessWithData(c, result, "Stop tasks successfully") } else { tasks, err := h.service.StopIngestionTasksByCondition(req.Tasks, req.Email, req.Status) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } - success(c, tasks, "Stop tasks successfully") + common.SuccessWithData(c, tasks, "Stop tasks successfully") } } @@ -1213,9 +1121,9 @@ func (h *Handler) ListIngestionTasks(c *gin.Context) { } if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) } - success(c, tasks, "Get all tasks") + common.SuccessWithData(c, tasks, "Get all tasks") } func (h *Handler) ListIngestors(c *gin.Context) { @@ -1236,7 +1144,7 @@ func (h *Handler) ListIngestors(c *gin.Context) { ingestorResults = append(ingestorResults, ingestorResult) } } - success(c, ingestorResults, "Get all tasks") + common.SuccessWithData(c, ingestorResults, "Get all tasks") } type ShutdownIngestorRequest struct { @@ -1246,7 +1154,7 @@ type ShutdownIngestorRequest struct { func (h *Handler) ShutdownIngestor(c *gin.Context) { var req ShutdownIngestorRequest if err := c.ShouldBindJSON(&req); err != nil { - errorResponse(c, "file uri is required", 400) + common.ErrorWithCode(c, 400, "Ingestor ID is required") return } @@ -1257,17 +1165,14 @@ func (h *Handler) ShutdownIngestor(c *gin.Context) { // AssignedTo: req.IngestorID, //}) - success(c, gin.H{"task_id": taskID, "ingestor_id": req.IngestorID}, "Shutdown ingestor") + common.SuccessWithData(c, gin.H{"task_id": taskID, "ingestor_id": req.IngestorID}, "Shutdown ingestor") } // Reports handle heartbeat reports from servers func (h *Handler) Reports(c *gin.Context) { var req common.BaseMessage if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": "Invalid request body: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) return } @@ -1278,21 +1183,18 @@ func (h *Handler) Reports(c *gin.Context) { // Only process heartbeat messages for now if req.MessageType != common.MessageHeartbeat { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": "Unsupported report type: " + string(req.MessageType), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Unsupported report type: "+string(req.MessageType)) return } // Handle the heartbeat errCode, message := h.service.HandleHeartbeat(&req) if errCode != common.CodeLicenseValid { - responseWithCode(c, message, 500, errCode) + common.ErrorWithCode(c, int(errCode), message) return } - responseWithCode(c, message, http.StatusOK, errCode) + common.ErrorWithCode(c, int(errCode), message) } func (h *Handler) ListAllModels(c *gin.Context) { @@ -1314,40 +1216,37 @@ func (h *Handler) ListAllModels(c *gin.Context) { // List models models, err := h.service.ListAllModels(page, pageSize) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, models, "") + common.SuccessWithData(c, models, "") } func (h *Handler) ShowModel(c *gin.Context) { encodedModelName := c.Param("model_name") if encodedModelName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Encoded model name is empty", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Encoded model name is empty") return } decodedModelName, err := common.DecodeFromBase64(encodedModelName) if err != nil { - errorResponse(c, err.Error(), 400) + common.ErrorWithCode(c, 400, err.Error()) return } if decodedModelName == "" { - errorResponse(c, "Decoded model name is empty", 400) + common.ErrorWithCode(c, 400, "Decoded model name is empty") return } // Get model model, err := h.service.GetModelByModelName(decodedModelName) if err != nil { - errorResponse(c, err.Error(), 500) + common.ErrorWithCode(c, 500, err.Error()) return } - success(c, model, "") + common.SuccessWithData(c, model, "") } diff --git a/internal/cli/filesystem/skill_hub/source/clawhub.go b/internal/cli/filesystem/skill_hub/source/clawhub.go index ed3151cb7b..d62a74a216 100644 --- a/internal/cli/filesystem/skill_hub/source/clawhub.go +++ b/internal/cli/filesystem/skill_hub/source/clawhub.go @@ -46,7 +46,7 @@ func (l *progressLogger) error(format string, args ...interface{}) { fmt.Printf(" ✗ "+format+"\n", args...) } -func (l *progressLogger) success(format string, args ...interface{}) { +func (l *progressLogger) SuccessWithData(format string, args ...interface{}) { fmt.Printf(" ✓ "+format+"\n", args...) } @@ -176,7 +176,7 @@ func (s *ClawHubSource) Fetch(identifier string) (*SkillBundle, error) { s.logger.error("Cannot find skill '%s' on ClawHub: %v", slug, err) return nil, fmt.Errorf("skill '%s' not found on ClawHub: %w", slug, err) } - s.logger.success("Found skill: %s", skillData.DisplayName) + s.logger.SuccessWithData("Found skill: %s", skillData.DisplayName) // Determine version to download var version string @@ -195,7 +195,7 @@ func (s *ClawHubSource) Fetch(identifier string) (*SkillBundle, error) { s.logger.error("No versions available for skill '%s'", slug) return nil, fmt.Errorf("no version found for skill %s", slug) } - s.logger.success("Latest version: %s", version) + s.logger.SuccessWithData("Latest version: %s", version) } // Try to get files from version metadata endpoint first (avoids rate-limited /download) @@ -205,7 +205,7 @@ func (s *ClawHubSource) Fetch(identifier string) (*SkillBundle, error) { if err == nil { files = s.extractFiles(versionData) if len(files) > 0 { - s.logger.success("Fetched %d files from metadata", len(files)) + s.logger.SuccessWithData("Fetched %d files from metadata", len(files)) } } @@ -220,7 +220,7 @@ func (s *ClawHubSource) Fetch(identifier string) (*SkillBundle, error) { return nil, fmt.Errorf("failed to download skill '%s': %w", slug, err2) } files = zipFiles - s.logger.success("Downloaded %d files via ZIP", len(files)) + s.logger.SuccessWithData("Downloaded %d files via ZIP", len(files)) } // Validate: must have SKILL.md diff --git a/internal/common/error_code.go b/internal/common/error_code.go index d19e461d5e..568313102a 100644 --- a/internal/common/error_code.go +++ b/internal/common/error_code.go @@ -47,6 +47,7 @@ const ( CodeNotFound ErrorCode = 404 CodeConflict ErrorCode = 409 CodeServerError ErrorCode = 500 + CodeNotImplemented ErrorCode = 501 ) var errorMessages = map[ErrorCode]string{ diff --git a/internal/common/response.go b/internal/common/response.go new file mode 100644 index 0000000000..62c4df302e --- /dev/null +++ b/internal/common/response.go @@ -0,0 +1,93 @@ +// +// Copyright 2026 The InfiniFlow Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package common + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +type response struct { + Code int `json:"code"` + Message interface{} `json:"message"` + Data interface{} `json:"data"` +} + +// errorResponse error response +type errorResponse struct { + Code int `json:"code"` + Message interface{} `json:"message"` +} + +// SuccessWithData returns success response with data +func SuccessWithData(c *gin.Context, data interface{}, message interface{}) { + c.JSON(http.StatusOK, response{ + Code: int(CodeSuccess), + Data: data, + Message: message, + }) +} + +// SuccessNoMessage returns success response without message +func SuccessNoMessage(c *gin.Context, data interface{}) { + c.JSON(http.StatusOK, response{ + Code: int(CodeSuccess), + Data: data, + }) +} + +// SuccessNoData returns success response without data +func SuccessNoData(c *gin.Context, message interface{}) { + c.JSON(http.StatusOK, response{ + Code: int(CodeSuccess), + Data: nil, + Message: message, + }) +} + +// SuccessWithMessage returns success response with message only +func SuccessWithMessage(c *gin.Context, message string) { + c.JSON(http.StatusOK, response{ + Code: int(CodeSuccess), + Message: message, + }) +} + +// ErrorWithCode returns error response with code and message +func ErrorWithCode(c *gin.Context, code int, message string) { + c.JSON(http.StatusOK, errorResponse{ + Code: code, + Message: message, + }) +} + +func ResponseWithCodeData(c *gin.Context, code ErrorCode, data interface{}, message string) { + c.JSON(http.StatusOK, response{ + Code: int(code), + Data: data, + Message: message, + }) +} + +func ResponseWithHttpCodeData(c *gin.Context, httpCode int, code ErrorCode, data interface{}, message string) { + c.JSON(httpCode, response{ + Code: int(code), + Data: data, + Message: message, + }) +} diff --git a/internal/handler/admin_runtime.go b/internal/handler/admin_runtime.go index dc608e4c3d..635cee0fc0 100644 --- a/internal/handler/admin_runtime.go +++ b/internal/handler/admin_runtime.go @@ -68,19 +68,19 @@ var ErrSelectorNotConfigured = errors.New("admin runtime: selector not configure // this endpoint publicly. func (h *AdminRuntimeHandler) SetTenantRuntime(c *gin.Context) { if h.selector == nil { - jsonError(c, common.CodeExceptionError, ErrSelectorNotConfigured.Error()) + common.ResponseWithCodeData(c, common.CodeExceptionError, nil, ErrSelectorNotConfigured.Error()) return } tenantID := c.Param("tenant_id") if tenantID == "" { - jsonError(c, common.CodeArgumentError, "tenant_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "tenant_id is required") return } var req setRuntimeRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeArgumentError, "Invalid request body: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request body: "+err.Error()) return } @@ -89,13 +89,12 @@ func (h *AdminRuntimeHandler) SetTenantRuntime(c *gin.Context) { case runtime.RuntimeGo, runtime.RuntimePython, runtime.RuntimeAuto: // allowed default: - jsonError(c, common.CodeArgumentError, - "runtime must be one of: go, python, auto") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "runtime must be one of: go, python, auto") return } if err := h.selector.Set(c.Request.Context(), tenantID, mode); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } diff --git a/internal/handler/agent.go b/internal/handler/agent.go index 7ed78d1b37..b18ee958a9 100644 --- a/internal/handler/agent.go +++ b/internal/handler/agent.go @@ -23,7 +23,6 @@ import ( "fmt" "io" "mime/multipart" - "net/http" "ragflow/internal/engine/redis" "strconv" "strings" @@ -131,7 +130,7 @@ func NewAgentHandler(agentService *service.AgentService, fileService *service.Fi func (h *AgentHandler) ListAgents(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -192,19 +191,11 @@ func (h *AgentHandler) ListAgents(c *gin.Context) { tags, ) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "data": false, - "message": err.Error(), - }) + common.ResponseWithCodeData(c, code, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } // mapAgentError normalises service-layer errors onto the existing @@ -250,25 +241,21 @@ func mapAgentError(err error) (common.ErrorCode, string) { func (h *AgentHandler) CreateAgent(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req service.CreateAgentRequest if err := c.ShouldBindJSON(&req); err != nil && !errors.Is(err, io.EOF) { - jsonError(c, common.CodeArgumentError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request: "+err.Error()) return } req.UserID = user.ID row, code, err := h.agentService.CreateAgent(c.Request.Context(), &req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": row, - "message": "success", - }) + common.SuccessWithData(c, row, "success") } // GetAgent returns one canvas by ID. @@ -281,14 +268,14 @@ func (h *AgentHandler) CreateAgent(c *gin.Context) { func (h *AgentHandler) GetAgent(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") row, err := h.agentService.GetAgent(c.Request.Context(), user.ID, canvasID) if err != nil { ec, em := mapAgentError(err) - jsonError(c, ec, em) + common.ResponseWithCodeData(c, ec, nil, em) return } // Defensive: any historical v1 / Go-v2-only row in user_canvas.dsl @@ -298,11 +285,7 @@ func (h *AgentHandler) GetAgent(c *gin.Context) { if row != nil { row.DSL = dslpkg.NormalizeForCanvas(row.DSL) } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": row, - "message": "success", - }) + common.SuccessWithData(c, row, "success") } // updateAgentRequest is the wire shape for PUT /api/v1/agents/:canvas_id. @@ -320,13 +303,13 @@ type updateAgentRequest map[string]interface{} func (h *AgentHandler) UpdateAgent(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") var req updateAgentRequest if err := c.ShouldBindJSON(&req); err != nil && !errors.Is(err, io.EOF) { - jsonError(c, common.CodeArgumentError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request: "+err.Error()) return } if req == nil { @@ -334,14 +317,10 @@ func (h *AgentHandler) UpdateAgent(c *gin.Context) { } if err := h.agentService.UpdateAgent(c.Request.Context(), user.ID, canvasID, map[string]interface{}(req)); err != nil { ec, em := mapAgentError(err) - jsonError(c, ec, em) + common.ResponseWithCodeData(c, ec, nil, em) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": "success", - }) + common.SuccessWithData(c, true, "success") } // DeleteAgent removes the canvas and cascades to its versions. @@ -354,20 +333,16 @@ func (h *AgentHandler) UpdateAgent(c *gin.Context) { func (h *AgentHandler) DeleteAgent(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") if err := h.agentService.DeleteAgent(c.Request.Context(), user.ID, canvasID); err != nil { ec, em := mapAgentError(err) - jsonError(c, ec, em) + common.ResponseWithCodeData(c, ec, nil, em) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": "success", - }) + common.SuccessWithData(c, true, "success") } // ListTemplates lists every canvas template available to authenticated users. @@ -380,7 +355,7 @@ func (h *AgentHandler) DeleteAgent(c *gin.Context) { // @Router /api/v1/agents/templates [get] func (h *AgentHandler) ListTemplates(c *gin.Context) { if _, errorCode, errorMessage := GetUser(c); errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -394,11 +369,7 @@ func (h *AgentHandler) ListTemplates(c *gin.Context) { templates = []*entity.CanvasTemplate{} } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": templates, - "message": "success", - }) + common.SuccessWithData(c, templates, "success") } // RunAgent returns an SSE stream of execution events. The Phase 5 stub emits @@ -414,7 +385,7 @@ func (h *AgentHandler) ListTemplates(c *gin.Context) { func (h *AgentHandler) RunAgent(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") @@ -425,7 +396,7 @@ func (h *AgentHandler) RunAgent(c *gin.Context) { events, err := h.chatRunner.RunAgent(c.Request.Context(), user.ID, canvasID, sessionID, version, userInput) if err != nil { ec, em := mapAgentError(err) - jsonError(c, ec, em) + common.ResponseWithCodeData(c, ec, nil, em) return } c.Writer.Header().Set("Content-Type", "text/event-stream") @@ -496,20 +467,16 @@ func sanitiseRunEventError(data string) string { func (h *AgentHandler) CancelAgent(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") if err := h.agentService.CancelAgent(c.Request.Context(), user.ID, canvasID); err != nil { ec, em := mapAgentError(err) - jsonError(c, ec, em) + common.ResponseWithCodeData(c, ec, nil, em) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": "success", - }) + common.SuccessWithData(c, true, "success") } // publishAgentRequest is the wire shape for POST /api/v1/agents/:canvas_id/publish. @@ -531,13 +498,13 @@ type publishAgentRequest struct { func (h *AgentHandler) PublishAgent(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") var req publishAgentRequest if err := c.ShouldBindJSON(&req); err != nil && !errors.Is(err, io.EOF) { - jsonError(c, common.CodeArgumentError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request: "+err.Error()) return } row, err := h.agentService.PublishAgent(c.Request.Context(), user.ID, canvasID, &service.PublishAgentRequest{ @@ -547,17 +514,13 @@ func (h *AgentHandler) PublishAgent(c *gin.Context) { }) if err != nil { ec, em := mapAgentError(err) - jsonError(c, ec, em) + common.ResponseWithCodeData(c, ec, nil, em) return } if row != nil { row.DSL = dslpkg.NormalizeForCanvas(row.DSL) } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": row, - "message": "success", - }) + common.SuccessWithData(c, row, "success") } // ListVersions returns every version of a canvas, newest first. @@ -570,14 +533,14 @@ func (h *AgentHandler) PublishAgent(c *gin.Context) { func (h *AgentHandler) ListVersions(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") rows, err := h.agentService.ListVersions(c.Request.Context(), user.ID, canvasID) if err != nil { ec, em := mapAgentError(err) - jsonError(c, ec, em) + common.ResponseWithCodeData(c, ec, nil, em) return } if rows == nil { @@ -589,11 +552,7 @@ func (h *AgentHandler) ListVersions(c *gin.Context) { } row.DSL = dslpkg.NormalizeForCanvas(row.DSL) } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": rows, - "message": "success", - }) + common.SuccessWithData(c, rows, "success") } // GetVersion returns a single version. @@ -607,7 +566,7 @@ func (h *AgentHandler) ListVersions(c *gin.Context) { func (h *AgentHandler) GetVersion(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") @@ -615,17 +574,13 @@ func (h *AgentHandler) GetVersion(c *gin.Context) { row, err := h.agentService.GetVersion(c.Request.Context(), user.ID, canvasID, versionID) if err != nil { ec, em := mapAgentError(err) - jsonError(c, ec, em) + common.ResponseWithCodeData(c, ec, nil, em) return } if row != nil { row.DSL = dslpkg.NormalizeForCanvas(row.DSL) } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": row, - "message": "success", - }) + common.SuccessWithData(c, row, "success") } // DeleteVersion removes a single version by id. @@ -639,21 +594,17 @@ func (h *AgentHandler) GetVersion(c *gin.Context) { func (h *AgentHandler) DeleteVersion(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") versionID := c.Param("version_id") if err := h.agentService.DeleteVersion(c.Request.Context(), user.ID, canvasID, versionID); err != nil { ec, em := mapAgentError(err) - jsonError(c, ec, em) + common.ResponseWithCodeData(c, ec, nil, em) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": "success", - }) + common.SuccessWithData(c, true, "success") } // --- PR2: missing routes wired up to the existing service layer --- @@ -661,19 +612,15 @@ func (h *AgentHandler) DeleteVersion(c *gin.Context) { // ListAgentTemplates GET /api/v1/agents/templates func (h *AgentHandler) ListAgentTemplates(c *gin.Context) { if _, code, msg := GetUser(c); code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } rows, err := h.agentService.ListTemplates() if err != nil { - jsonError(c, common.CodeServerError, err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": rows, - "message": "success", - }) + common.SuccessWithData(c, rows, "success") } // Prompts GET /api/v1/agents/prompts — returns the four hardcoded @@ -681,47 +628,39 @@ func (h *AgentHandler) ListAgentTemplates(c *gin.Context) { // returns these from a module-level constant; we keep the same shape. func (h *AgentHandler) Prompts(c *gin.Context) { if _, code, msg := GetUser(c); code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": gin.H{ - "task_analysis": "As an AI agent designer, your role is to engage users by understanding their objectives and creating effective agent designs. Begin by analyzing the user's request to determine the appropriate actions.", - "output_format": "For each agent you create, detail its components and explain how they collaborate to achieve the user's goal.", - "citation_guidelines": "If the agent uses external sources, cite them in the final output. Use the format: [index] document_id, which corresponds to the document identifier in the database.", - "few_shots_examples": "", - }, - "message": "success", - }) + common.SuccessWithData(c, gin.H{ + "task_analysis": "As an AI agent designer, your role is to engage users by understanding their objectives and creating effective agent designs. Begin by analyzing the user's request to determine the appropriate actions.", + "output_format": "For each agent you create, detail its components and explain how they collaborate to achieve the user's goal.", + "citation_guidelines": "If the agent uses external sources, cite them in the final output. Use the format: [index] document_id, which corresponds to the document identifier in the database.", + "few_shots_examples": "", + }, "success") } // ListAgentTags list agent tags. func (h *AgentHandler) ListAgentTags(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } rows, errCode, err := h.agentService.ListAgentTags(user.ID, strings.TrimSpace(c.Query("canvas_category"))) if err != nil { - jsonError(c, errCode, err.Error()) + common.ResponseWithCodeData(c, errCode, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": rows, - "message": "success", - }) + common.SuccessWithData(c, rows, "success") } // UpdateAgentTags PUT /api/v1/agents/:canvas_id/tags func (h *AgentHandler) UpdateAgentTags(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") @@ -729,26 +668,22 @@ func (h *AgentHandler) UpdateAgentTags(c *gin.Context) { Tags interface{} `json:"tags"` } if err := c.ShouldBindJSON(&body); err != nil && !errors.Is(err, io.EOF) { - jsonError(c, common.CodeArgumentError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request: "+err.Error()) return } ok, errCode, errMsg := h.agentService.UpdateAgentTags(user.ID, canvasID, body.Tags) if !ok { - jsonError(c, errCode, errMsg.Error()) + common.ResponseWithCodeData(c, errCode, nil, errMsg.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": "success", - }) + common.SuccessWithData(c, true, "success") } // ListAgentSessions GET /api/v1/agents/:canvas_id/sessions func (h *AgentHandler) ListAgentSessions(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") @@ -777,21 +712,17 @@ func (h *AgentHandler) ListAgentSessions(c *gin.Context) { IncludeDSL: includeDSL, }) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": resp.Data, - "message": "success", - }) + common.SuccessWithData(c, resp.Data, "success") } // CreateAgentSession POST /api/v1/agents/:canvas_id/sessions func (h *AgentHandler) CreateAgentSession(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") @@ -801,7 +732,7 @@ func (h *AgentHandler) CreateAgentSession(c *gin.Context) { DSL json.RawMessage `json:"dsl"` } if err := c.ShouldBindJSON(&body); err != nil && !errors.Is(err, io.EOF) { - jsonError(c, common.CodeArgumentError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request: "+err.Error()) return } row, code, err := h.agentService.CreateAgentSession(&service.CreateAgentSessionRequest{ @@ -812,35 +743,27 @@ func (h *AgentHandler) CreateAgentSession(c *gin.Context) { DSL: body.DSL, }) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": row, - "message": "success", - }) + common.SuccessWithData(c, row, "success") } // GetAgentSession GET /api/v1/agents/:canvas_id/sessions/:session_id func (h *AgentHandler) GetAgentSession(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") sessionID := c.Param("session_id") row, code, err := h.agentService.GetAgentSession(user.ID, canvasID, sessionID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": row, - "message": "success", - }) + common.SuccessWithData(c, row, "success") } // DeleteAgentSession DELETE /api/v1/agents/:canvas_id/sessions[/:session_id] @@ -851,7 +774,7 @@ func (h *AgentHandler) GetAgentSession(c *gin.Context) { func (h *AgentHandler) DeleteAgentSession(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") @@ -859,14 +782,10 @@ func (h *AgentHandler) DeleteAgentSession(c *gin.Context) { if sessionID != "" { ok, code, err := h.agentService.DeleteAgentSessionItem(user.ID, canvasID, sessionID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": ok, - "message": "success", - }) + common.SuccessWithData(c, ok, "success") return } idsParam := c.Query("ids") @@ -881,14 +800,10 @@ func (h *AgentHandler) DeleteAgentSession(c *gin.Context) { } result, code, err := h.agentService.DeleteAgentSessions(user.ID, canvasID, ids, deleteAll) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } // AgentChatCompletions POST /api/v1/agents/chat/completions @@ -1011,20 +926,20 @@ func userInputMeta(userInput any) []zap.Field { func (h *AgentHandler) AgentChatCompletions(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } var req agentChatCompletionsRequest if err := c.ShouldBindJSON(&req); err != nil && !errors.Is(err, io.EOF) { - jsonError(c, common.CodeArgumentError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request: "+err.Error()) return } if req.AgentID == "" { - jsonError(c, common.CodeArgumentError, "`agent_id` is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "`agent_id` is required.") return } if req.OpenAICompat && len(req.Messages) == 0 { - jsonError(c, common.CodeDataError, "at least one message is required in openai-compatible mode.") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "at least one message is required in openai-compatible mode.") return } common.Debug("agent chat completions: request received", @@ -1048,13 +963,11 @@ func (h *AgentHandler) AgentChatCompletions(c *gin.Context) { // terminator, `reference` attached to the final choice. Land that // once the chat path needs to interop with OpenAI clients. if req.OpenAICompat { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, + common.SuccessWithData(c, gin.H{ "choices": []map[string]interface{}{ {"message": gin.H{"content": "hello"}}, }, - "message": "success", - }) + }, "success") return } @@ -1087,7 +1000,7 @@ func (h *AgentHandler) AgentChatCompletions(c *gin.Context) { }, userInputMeta(userInput)...)..., ) ec, em := mapAgentError(err) - jsonError(c, ec, em) + common.ResponseWithCodeData(c, ec, nil, em) return } @@ -1168,7 +1081,7 @@ func (h *AgentHandler) AgentChatCompletions(c *gin.Context) { func (h *AgentHandler) RerunAgent(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } var body struct { @@ -1177,7 +1090,7 @@ func (h *AgentHandler) RerunAgent(c *gin.Context) { ComponentID string `json:"component_id"` } if err := c.ShouldBindJSON(&body); err != nil && !errors.Is(err, io.EOF) { - jsonError(c, common.CodeArgumentError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request: "+err.Error()) return } missing := make([]string, 0, 3) @@ -1191,8 +1104,7 @@ func (h *AgentHandler) RerunAgent(c *gin.Context) { missing = append(missing, "component_id") } if len(missing) > 0 { - jsonError(c, common.CodeArgumentError, - "required argument are missing: "+strings.Join(missing, ",")+"; ") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "required argument are missing: "+strings.Join(missing, ",")+"; ") return } // Fail closed on missing dependency: a nil documentService @@ -1202,42 +1114,34 @@ func (h *AgentHandler) RerunAgent(c *gin.Context) { // dependency is loud, not silent. if h.documentService == nil { zap.L().Error("RerunAgent: documentService is nil; refusing request to prevent auth bypass") - jsonError(c, common.CodeServerError, "server misconfiguration: document service not wired") + common.ResponseWithCodeData(c, common.CodeServerError, nil, "server misconfiguration: document service not wired") return } if !h.documentService.Accessible(body.ID, user.ID) { - jsonError(c, common.CodeDataError, "Document not found.") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Document not found.") return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": "success", - }) + common.SuccessWithData(c, true, "success") } // TestDBConnection POST /api/v1/agents/test_db_connection func (h *AgentHandler) TestDBConnection(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } var req service.TestDBConnectionRequest if err := c.ShouldBindJSON(&req); err != nil && !errors.Is(err, io.EOF) { - jsonError(c, common.CodeArgumentError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request: "+err.Error()) return } code, err := h.agentService.TestDBConnection(user.ID, &req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": "success", - }) + common.SuccessWithData(c, true, "success") } // GetAgentLogs GET /api/v1/agents/:canvas_id/logs/:message_id @@ -1249,14 +1153,14 @@ func (h *AgentHandler) TestDBConnection(c *gin.Context) { func (h *AgentHandler) GetAgentLogs(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") messageID := c.Param("message_id") ok, errCode, errMsg := h.checkCanvasAccessForHandler(c, user.ID, canvasID) if !ok { - jsonError(c, errCode, errMsg) + common.ResponseWithCodeData(c, errCode, nil, errMsg) return } @@ -1266,11 +1170,7 @@ func (h *AgentHandler) GetAgentLogs(c *gin.Context) { if rerr == nil && payload != "" { _ = json.Unmarshal([]byte(payload), &data) } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": data, - "message": "success", - }) + common.SuccessWithData(c, data, "success") } // GetAgentWebhookLogs GET /api/v1/agents/:canvas_id/webhook/logs @@ -1283,7 +1183,7 @@ func (h *AgentHandler) GetAgentLogs(c *gin.Context) { func (h *AgentHandler) GetAgentWebhookLogs(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") @@ -1294,21 +1194,17 @@ func (h *AgentHandler) GetAgentWebhookLogs(c *gin.Context) { // indistinguishable for missing vs foreign, so collapse // both into 102 "Canvas not found." here. if err != nil && !errors.Is(err, dao.ErrUserCanvasNotFound) { - jsonError(c, common.CodeServerError, err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } - jsonError(c, common.CodeDataError, "Canvas not found.") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Canvas not found.") return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": gin.H{ - "events": []interface{}{}, - "finished": false, - "next_since_ts": 0, - }, - "message": "success", - }) + common.SuccessWithData(c, gin.H{ + "events": []interface{}{}, + "finished": false, + "next_since_ts": 0, + }, "success") } // checkCanvasAccessForHandler is the shared 103 envelope helper for @@ -1362,19 +1258,15 @@ func (h *AgentHandler) checkCanvasAccessForHandler(c *gin.Context, userID, canva func (h *AgentHandler) ResetAgent(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") dsl, err := h.agentService.ResetAgent(c.Request.Context(), user.ID, canvasID) if err != nil { ec, em := mapAgentError(err) - jsonError(c, ec, em) + common.ResponseWithCodeData(c, ec, nil, em) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": dsl, - "message": "success", - }) + common.SuccessWithData(c, dsl, "success") } diff --git a/internal/handler/agent_attachment.go b/internal/handler/agent_attachment.go index a6a3208067..a06154a63b 100644 --- a/internal/handler/agent_attachment.go +++ b/internal/handler/agent_attachment.go @@ -77,13 +77,13 @@ func attachmentRequestMeta(c *gin.Context) attachmentRequestMetadata { // _stream_agent_attachment(). func (h *AgentHandler) streamAgentAttachment(c *gin.Context, tenantID, attachmentID string, inline bool) { if h.fileService == nil { - jsonError(c, common.CodeServerError, "file service not configured") + common.ResponseWithCodeData(c, common.CodeServerError, nil, "file service not configured") return } blob, err := h.fileService.DownloadAgentFile(tenantID, attachmentID) if err != nil { - jsonError(c, common.CodeDataError, "Attachment not found!") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Attachment not found!") return } @@ -109,12 +109,12 @@ func (h *AgentHandler) streamAgentAttachment(c *gin.Context, tenantID, attachmen func (h *AgentHandler) DownloadAttachment(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } attachmentID := c.Param("attachment_id") if attachmentID == "" { - jsonError(c, common.CodeArgumentError, "`attachment_id` is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "`attachment_id` is required.") return } // Note (review F9): the plan explicitly defers attachment-id @@ -129,7 +129,7 @@ func (h *AgentHandler) DownloadAttachment(c *gin.Context) { // never crosses the service boundary. safe := filepath.Base(attachmentID) if safe == "" || safe == "." || safe == "/" || strings.ContainsAny(safe, "\r\n\"") { - jsonError(c, common.CodeArgumentError, "invalid attachment id.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "invalid attachment id.") return } @@ -148,17 +148,17 @@ func (h *AgentHandler) DownloadAttachment(c *gin.Context) { func (h *AgentHandler) PreviewAttachment(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } attachmentID := c.Param("attachment_id") if attachmentID == "" { - jsonError(c, common.CodeArgumentError, "`attachment_id` is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "`attachment_id` is required.") return } safe := filepath.Base(attachmentID) if safe == "" || safe == "." || safe == "/" || strings.ContainsAny(safe, "\r\n\"") { - jsonError(c, common.CodeArgumentError, "invalid attachment id.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "invalid attachment id.") return } diff --git a/internal/handler/agent_component.go b/internal/handler/agent_component.go index 3698a48bde..7022c76a75 100644 --- a/internal/handler/agent_component.go +++ b/internal/handler/agent_component.go @@ -47,23 +47,23 @@ import ( func (h *AgentHandler) GetComponentInputForm(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") componentID := c.Param("component_id") if canvasID == "" || componentID == "" { - jsonError(c, common.CodeArgumentError, "`canvas_id` and `component_id` are required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "`canvas_id` and `component_id` are required.") return } cv, err := h.loader.LoadCanvasByID(c.Request.Context(), user.ID, canvasID) if err != nil { if err == dao.ErrUserCanvasNotFound { - jsonError(c, common.CodeOperatingError, canvasNoAccessMessage) + common.ResponseWithCodeData(c, common.CodeOperatingError, nil, canvasNoAccessMessage) return } - jsonError(c, common.CodeServerError, err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } @@ -124,13 +124,13 @@ func (h *AgentHandler) componentInputForm(ctx context.Context, dslMap map[string func (h *AgentHandler) DebugComponent(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") componentID := c.Param("component_id") if canvasID == "" || componentID == "" { - jsonError(c, common.CodeArgumentError, "`canvas_id` and `component_id` are required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "`canvas_id` and `component_id` are required.") return } @@ -138,21 +138,21 @@ func (h *AgentHandler) DebugComponent(c *gin.Context) { Params map[string]map[string]any `json:"params"` } if err := c.ShouldBindJSON(&body); err != nil { - jsonError(c, common.CodeArgumentError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request: "+err.Error()) return } if body.Params == nil { - jsonError(c, common.CodeArgumentError, "`params` is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "`params` is required.") return } cv, err := h.loader.LoadCanvasByID(c.Request.Context(), user.ID, canvasID) if err != nil { if err == dao.ErrUserCanvasNotFound { - jsonError(c, common.CodeOperatingError, canvasNoAccessMessage) + common.ResponseWithCodeData(c, common.CodeOperatingError, nil, canvasNoAccessMessage) return } - jsonError(c, common.CodeServerError, err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } @@ -175,12 +175,14 @@ func (h *AgentHandler) DebugComponent(c *gin.Context) { inputs := make(map[string]any, len(body.Params)) for k, v := range body.Params { if v == nil { - jsonError(c, common.CodeArgumentError, "`params."+k+".value` is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "`params."+k+".value` is required.") return } value, ok := v["value"] if !ok { - jsonError(c, common.CodeArgumentError, "`params."+k+".value` is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "`params."+k+".value` is required.") return } inputs[k] = value @@ -188,12 +190,12 @@ func (h *AgentHandler) DebugComponent(c *gin.Context) { factory := runtime.DefaultFactory() if factory == nil { - jsonError(c, common.CodeServerError, "component factory not initialised") + common.ResponseWithCodeData(c, common.CodeServerError, nil, "component factory not initialised") return } comp, err := factory(name, dslParams) if err != nil { - jsonError(c, common.CodeDataError, "component factory: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "component factory: "+err.Error()) return } @@ -221,7 +223,7 @@ func (h *AgentHandler) DebugComponent(c *gin.Context) { outputs, err := comp.Invoke(invokeCtx, inputs) if err != nil { - jsonError(c, common.CodeServerError, "invoke: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, "invoke: "+err.Error()) return } @@ -240,12 +242,12 @@ func (h *AgentHandler) DebugComponent(c *gin.Context) { func mapDSLError(c *gin.Context, componentID string, err error) { switch { case errors.Is(err, dsl.ErrComponentNotFound): - jsonError(c, common.CodeDataError, "component not found: "+componentID) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "component not found: "+componentID) case errors.Is(err, dsl.ErrMissingInputForm): - jsonError(c, common.CodeDataError, "component has no input_form: "+componentID) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "component has no input_form: "+componentID) case errors.Is(err, dsl.ErrMalformedDSL): - jsonError(c, common.CodeDataError, "malformed dsl: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "malformed dsl: "+err.Error()) default: - jsonError(c, common.CodeServerError, "internal: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, "internal: "+err.Error()) } } diff --git a/internal/handler/agent_download.go b/internal/handler/agent_download.go index 2b18e6f0b0..e4f155f286 100644 --- a/internal/handler/agent_download.go +++ b/internal/handler/agent_download.go @@ -44,12 +44,13 @@ import ( func (h *AgentHandler) DownloadAgentFile(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } fileID := c.Query("id") if fileID == "" { - jsonError(c, common.CodeArgumentError, "`id` is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "`id` is required.") return } @@ -63,7 +64,7 @@ func (h *AgentHandler) DownloadAgentFile(c *gin.Context) { // both the python and Go code paths. blob, err := h.fileService.DownloadAgentFile(user.ID, fileID) if err != nil { - jsonError(c, common.CodeServerError, err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } @@ -75,7 +76,8 @@ func (h *AgentHandler) DownloadAgentFile(c *gin.Context) { // value. safe := filepath.Base(fileID) if safe == "" || safe == "." || safe == "/" || strings.ContainsAny(safe, "\r\n\"") { - jsonError(c, common.CodeArgumentError, "invalid file id.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "invalid file id.") return } c.Header("Content-Disposition", fmt.Sprintf( diff --git a/internal/handler/agent_test.go b/internal/handler/agent_test.go index ec86f0b530..bb67dfc7eb 100644 --- a/internal/handler/agent_test.go +++ b/internal/handler/agent_test.go @@ -332,31 +332,31 @@ type agentHandlerTestable struct { func (h *agentHandlerTestable) listAgents(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } result, code, err := h.svc.ListAgents(user.ID, "", 0, 0, "create_time", true, nil, "", nil) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": code, "data": false, "message": err.Error()}) + common.ResponseWithCodeData(c, code, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{"code": common.CodeSuccess, "data": result, "message": "success"}) + common.SuccessWithData(c, result, "success") } func (h *agentHandlerTestable) listTemplates(c *gin.Context) { if _, errorCode, errorMessage := GetUser(c); errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } templates, err := h.svc.ListTemplates() if err != nil { - jsonError(c, common.CodeServerError, err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } if templates == nil { templates = []*entity.CanvasTemplate{} } - c.JSON(http.StatusOK, gin.H{"code": common.CodeSuccess, "data": templates, "message": "success"}) + common.SuccessWithData(c, templates, "success") } func (f *fakeAgentService) ListAgents(userID, keywords string, page, pageSize int, orderby string, desc bool, ownerIDs []string, canvasCategory string, tags []string) (*service.ListAgentsResponse, common.ErrorCode, error) { @@ -555,7 +555,7 @@ func TestAgentHandler_NotFoundOnUnknownCanvas(t *testing.T) { r2.Use(setUser()) g2 := r2.Group("/api/v1/agents") g2.GET("/:canvas_id", func(c *gin.Context) { - jsonError(c, common.CodeNotFound, "agent unknown: not found") + common.ResponseWithCodeData(c, common.CodeNotFound, nil, "agent unknown: not found") }) w := httptest.NewRecorder() diff --git a/internal/handler/agent_upload.go b/internal/handler/agent_upload.go index 728c01832e..09e8c11bb6 100644 --- a/internal/handler/agent_upload.go +++ b/internal/handler/agent_upload.go @@ -57,12 +57,13 @@ const canvasNoAccessMessage = "Make sure you have permission to access the agent func (h *AgentHandler) UploadAgentFile(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } canvasID := c.Param("canvas_id") if canvasID == "" { - jsonError(c, common.CodeArgumentError, "`canvas_id` is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "`canvas_id` is required.") return } @@ -74,10 +75,10 @@ func (h *AgentHandler) UploadAgentFile(c *gin.Context) { // still pattern-match the text. if _, err := h.loader.LoadCanvasByID(c.Request.Context(), user.ID, canvasID); err != nil { if err == dao.ErrUserCanvasNotFound { - jsonError(c, common.CodeOperatingError, canvasNoAccessMessage) + common.ResponseWithCodeData(c, common.CodeOperatingError, nil, canvasNoAccessMessage) return } - jsonError(c, common.CodeServerError, err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } @@ -86,11 +87,13 @@ func (h *AgentHandler) UploadAgentFile(c *gin.Context) { // into memory by ParseMultipartForm before any size check fires. c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, uploadMaxBytes) if cl := c.Request.ContentLength; cl > uploadMaxBytes { - jsonError(c, common.CodeArgumentError, "request body too large.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "request body too large.") return } if err := c.Request.ParseMultipartForm(uploadMaxBytes); err != nil { - jsonError(c, common.CodeArgumentError, "invalid multipart form: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "invalid multipart form: "+err.Error()) return } defer func() { @@ -100,7 +103,8 @@ func (h *AgentHandler) UploadAgentFile(c *gin.Context) { }() form := c.Request.MultipartForm if form == nil { - jsonError(c, common.CodeArgumentError, "missing multipart form.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "missing multipart form.") return } files := form.File["file"] @@ -115,7 +119,7 @@ func (h *AgentHandler) UploadAgentFile(c *gin.Context) { if url := c.Query("url"); url != "" && len(files) == 1 { uploaded, err := h.fileService.UploadFromURL(user.ID, url) if err != nil { - jsonError(c, common.CodeServerError, err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } c.JSON(200, gin.H{ @@ -127,13 +131,14 @@ func (h *AgentHandler) UploadAgentFile(c *gin.Context) { } if len(files) == 0 { - jsonError(c, common.CodeArgumentError, "`file` field is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "`file` field is required.") return } results, err := h.fileService.UploadInfos(user.ID, files) if err != nil { - jsonError(c, common.CodeServerError, err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } diff --git a/internal/handler/agent_wait_for_user_test.go b/internal/handler/agent_wait_for_user_test.go index 28d15f1815..9360ad8083 100644 --- a/internal/handler/agent_wait_for_user_test.go +++ b/internal/handler/agent_wait_for_user_test.go @@ -155,7 +155,7 @@ func waitForUserRoutes(svc *waitFakeAgentService) *gin.Engine { if err != nil { // We never expect a non-nil err from the fake, // but be defensive. - c.JSON(http.StatusInternalServerError, gin.H{"code": common.CodeServerError, "message": err.Error()}) + common.ErrorWithCode(c, int(common.CodeServerError), err.Error()) return } c.Writer.Header().Set("Content-Type", "text/event-stream") diff --git a/internal/handler/agent_webhook.go b/internal/handler/agent_webhook.go index 1e1a1a550c..942f33baf2 100644 --- a/internal/handler/agent_webhook.go +++ b/internal/handler/agent_webhook.go @@ -104,7 +104,7 @@ type canvasLoader interface { func (h *AgentHandler) Webhook(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } @@ -124,7 +124,7 @@ func (h *AgentHandler) Webhook(c *gin.Context) { cv, err := h.loader.LoadCanvasByID(c.Request.Context(), user.ID, canvasID) if err != nil { if errors.Is(err, dao.ErrUserCanvasNotFound) || errors.Is(err, dao.ErrUserCanvasVersionNotFound) { - jsonError(c, common.CodeDataError, "Canvas not found.") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Canvas not found.") return } jsonInternalError(c, err) @@ -133,7 +133,7 @@ func (h *AgentHandler) Webhook(c *gin.Context) { // 2. Reject DataFlow. if cv.CanvasCategory == "DataFlow" { - jsonError(c, common.CodeDataError, "Dataflow can not be triggered by webhook.") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Dataflow can not be triggered by webhook.") return } @@ -148,21 +148,20 @@ func (h *AgentHandler) Webhook(c *gin.Context) { // 4. Find Begin component with mode=="Webhook". webhookCfg := findWebhookBegin(dsl) if webhookCfg == nil { - jsonError(c, common.CodeDataError, "Webhook not configured for this agent.") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Webhook not configured for this agent.") return } // 5. Method gate. if !methodAllowed(webhookCfg["methods"], c.Request.Method) { - jsonError(c, common.CodeDataError, - fmt.Sprintf("HTTP method '%s' not allowed for this webhook.", c.Request.Method)) + common.ResponseWithCodeData(c, common.CodeDataError, nil, fmt.Sprintf("HTTP method '%s' not allowed for this webhook.", c.Request.Method)) return } // 6. Security gate (strict; surfaces all errors as 102). securityCfg := stringMap(webhookCfg["security"]) if err := validateWebhookSecurity(securityCfg, c, canvasID); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } @@ -193,17 +192,13 @@ func (h *AgentHandler) Webhook(c *gin.Context) { // 501 — multipart/form-data uploads are not yet // supported. Body is short so operators see exactly what // is missing. - c.JSON(http.StatusNotImplemented, gin.H{ - "code": http.StatusNotImplemented, - "data": false, - "message": parseErr.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusNotImplemented, common.CodeNotImplemented, nil, parseErr.Error()) return case errors.Is(parseErr, ErrWebhookContentTypeMismatch): - jsonError(c, common.CodeDataError, parseErr.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, parseErr.Error()) return default: - jsonError(c, common.CodeDataError, parseErr.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, parseErr.Error()) return } } @@ -212,7 +207,7 @@ func (h *AgentHandler) Webhook(c *gin.Context) { schema, _ := webhookCfg["schema"].(map[string]any) clean, schemaErr := applyWebhookSchema(parsed, schema) if schemaErr != nil { - jsonError(c, common.CodeDataError, schemaErr.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, schemaErr.Error()) return } @@ -224,7 +219,7 @@ func (h *AgentHandler) Webhook(c *gin.Context) { if mode == "Immediately" { status, contentType, payload, perr := renderImmediatelyResponse(stringMap(webhookCfg["response"])) if perr != nil { - jsonError(c, common.CodeDataError, perr.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, perr.Error()) return } // Detached background run — does NOT inherit c.Request.Context() diff --git a/internal/handler/api_token.go b/internal/handler/api_token.go index 4e0d700c56..a41240f05f 100644 --- a/internal/handler/api_token.go +++ b/internal/handler/api_token.go @@ -18,6 +18,7 @@ package handler import ( "net/http" + "ragflow/internal/common" "ragflow/internal/dao" "ragflow/internal/entity" @@ -30,19 +31,13 @@ func (h *SystemHandler) ListAPIKeys(c *gin.Context) { // Get current user from context user, exists := c.Get("user") if !exists { - c.JSON(http.StatusUnauthorized, gin.H{ - "code": 401, - "message": "Unauthorized", - }) + common.ResponseWithHttpCodeData(c, http.StatusUnauthorized, 401, nil, "Unauthorized") return } userModel, ok := user.(*entity.User) if !ok { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": "Invalid user data", - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, "Invalid user data") return } @@ -50,10 +45,7 @@ func (h *SystemHandler) ListAPIKeys(c *gin.Context) { userTenantDAO := dao.NewUserTenantDAO() tenants, err := userTenantDAO.GetByUserIDAndRole(userModel.ID, "owner") if err != nil || len(tenants) == 0 { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Tenant not found", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Tenant not found") return } @@ -62,37 +54,24 @@ func (h *SystemHandler) ListAPIKeys(c *gin.Context) { // Get keys for the tenant keys, err := h.systemService.ListAPIKeys(tenantID) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": "Failed to list keys", - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, "Failed to list keys") return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": keys, - }) + common.SuccessWithData(c, keys, "success") } func (h *SystemHandler) CreateKey(c *gin.Context) { // Get current user from context user, exists := c.Get("user") if !exists { - c.JSON(http.StatusUnauthorized, gin.H{ - "code": 401, - "message": "Unauthorized", - }) + common.ResponseWithHttpCodeData(c, http.StatusUnauthorized, 401, nil, "Unauthorized") return } userModel, ok := user.(*entity.User) if !ok { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": "Invalid user data", - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, "Invalid user data") return } @@ -100,10 +79,7 @@ func (h *SystemHandler) CreateKey(c *gin.Context) { userTenantDAO := dao.NewUserTenantDAO() tenants, err := userTenantDAO.GetByUserIDAndRole(userModel.ID, "owner") if err != nil || len(tenants) == 0 { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Tenant not found", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Tenant not found") return } @@ -111,48 +87,32 @@ func (h *SystemHandler) CreateKey(c *gin.Context) { // Parse request var req service.CreateAPIKeyRequest - if err := c.ShouldBind(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Invalid request", - }) + if err = c.ShouldBind(&req); err != nil { + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Invalid request") return } // Create key key, err := h.systemService.CreateAPIKey(tenantID, &req) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": "Failed to create key", - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, "Failed to create key") return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": key, - }) + common.SuccessWithData(c, key, "success") } func (h *SystemHandler) DeleteKey(c *gin.Context) { // Get current user from context user, exists := c.Get("user") if !exists { - c.JSON(http.StatusUnauthorized, gin.H{ - "code": 401, - "message": "Unauthorized", - }) + common.ResponseWithHttpCodeData(c, http.StatusUnauthorized, 401, nil, "Unauthorized") return } userModel, ok := user.(*entity.User) if !ok { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": "Invalid user data", - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, "Invalid user data") return } @@ -160,10 +120,7 @@ func (h *SystemHandler) DeleteKey(c *gin.Context) { userTenantDAO := dao.NewUserTenantDAO() tenants, err := userTenantDAO.GetByUserIDAndRole(userModel.ID, "owner") if err != nil || len(tenants) == 0 { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Tenant not found", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Tenant not found") return } @@ -172,25 +129,15 @@ func (h *SystemHandler) DeleteKey(c *gin.Context) { // Get key from path parameter key := c.Param("key") if key == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Key is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Key is required") return } // Delete key if err = h.systemService.DeleteAPIKey(tenantID, key); err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": "Failed to delete key", - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, "Failed to delete key") return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": true, - }) + common.SuccessWithData(c, true, "success") } diff --git a/internal/handler/auth.go b/internal/handler/auth.go index 6ea1dd4156..55d9ebbe4c 100644 --- a/internal/handler/auth.go +++ b/internal/handler/auth.go @@ -77,7 +77,7 @@ func (h *AuthHandler) BetaAuthMiddleware() gin.HandlerFunc { } if auth == "" { - jsonError(c, common.CodeUnauthorized, "Authorization required") + common.ResponseWithCodeData(c, common.CodeUnauthorized, nil, "Authorization required") c.Abort() return } @@ -117,7 +117,7 @@ func (h *AuthHandler) BetaAuthMiddleware() gin.HandlerFunc { c.Next() return } - jsonError(c, common.CodeUnauthorized, "Invalid auth credentials") + common.ResponseWithCodeData(c, common.CodeUnauthorized, nil, "Invalid auth credentials") c.Abort() } } @@ -128,10 +128,7 @@ func (h *AuthHandler) AuthMiddleware() gin.HandlerFunc { return func(c *gin.Context) { token := c.GetHeader("Authorization") if token == "" { - c.JSON(http.StatusUnauthorized, gin.H{ - "code": 401, - "message": "Missing Authorization header", - }) + common.ResponseWithHttpCodeData(c, http.StatusUnauthorized, 401, nil, "Missing Authorization header") c.Abort() return } @@ -143,10 +140,7 @@ func (h *AuthHandler) AuthMiddleware() gin.HandlerFunc { if err != nil { user, code, err = h.userService.GetUserByAPIToken(token) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{ - "code": code, - "message": "Invalid access token", - }) + common.ResponseWithHttpCodeData(c, http.StatusUnauthorized, code, nil, "Invalid access token") c.Abort() return } @@ -154,10 +148,7 @@ func (h *AuthHandler) AuthMiddleware() gin.HandlerFunc { } if user.IsSuperuser != nil && *user.IsSuperuser { - c.JSON(http.StatusForbidden, gin.H{ - "code": common.CodeForbidden, - "message": "Super user shouldn't access the URL", - }) + common.ResponseWithHttpCodeData(c, http.StatusForbidden, common.CodeForbidden, nil, "Super user shouldn't access the URL") c.Abort() return } @@ -166,11 +157,7 @@ func (h *AuthHandler) AuthMiddleware() gin.HandlerFunc { license := local.GetAdminStatus() errMsg := fmt.Sprintf("server license %s", license.Reason) common.Warn(errMsg) - c.JSON(http.StatusServiceUnavailable, gin.H{ - "code": common.CodeUnauthorized, - "message": errMsg, - "data": "No", - }) + common.ResponseWithHttpCodeData(c, http.StatusServiceUnavailable, common.CodeUnauthorized, "No", errMsg) c.Abort() return } diff --git a/internal/handler/bot.go b/internal/handler/bot.go index c020ae9112..a63bac3818 100644 --- a/internal/handler/bot.go +++ b/internal/handler/bot.go @@ -64,18 +64,18 @@ func NewBotHandler(svc *service.BotService) *BotHandler { func (h *BotHandler) ChatbotInfo(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } dialogID := c.Param("dialog_id") if dialogID == "" { - jsonError(c, common.CodeArgumentError, "`dialog_id` is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "`dialog_id` is required.") return } title, avatar, prologue, llmID, hasTavily, ec, err := h.botService.ChatbotInfo( c.Request.Context(), user.ID, dialogID) if err != nil { - jsonError(c, ec, err.Error()) + common.ResponseWithCodeData(c, ec, nil, err.Error()) return } c.JSON(200, gin.H{ @@ -98,18 +98,18 @@ func (h *BotHandler) ChatbotInfo(c *gin.Context) { func (h *BotHandler) AgentbotInputs(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } agentID := c.Param("agent_id") if agentID == "" { - jsonError(c, common.CodeArgumentError, "`agent_id` is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "`agent_id` is required.") return } title, avatar, prologue, mode, inputs, ec, err := h.botService.AgentbotInputs( c.Request.Context(), user.ID, agentID) if err != nil { - jsonError(c, ec, err.Error()) + common.ResponseWithCodeData(c, ec, nil, err.Error()) return } c.JSON(200, gin.H{ @@ -138,12 +138,12 @@ func (h *BotHandler) AgentbotInputs(c *gin.Context) { func (h *BotHandler) AgentbotCompletion(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } agentID := c.Param("agent_id") if agentID == "" { - jsonError(c, common.CodeArgumentError, "`agent_id` is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "`agent_id` is required.") return } var body service.AgentbotCompletionRequest @@ -153,14 +153,15 @@ func (h *BotHandler) AgentbotCompletion(c *gin.Context) { // then ran with empty inputs. if c.Request.ContentLength != 0 { if err := c.ShouldBindJSON(&body); err != nil { - jsonError(c, common.CodeArgumentError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "Invalid request: "+err.Error()) return } } events, ec, err := h.botService.AgentbotCompletion( c.Request.Context(), user.ID, agentID, body) if err != nil { - jsonError(c, ec, err.Error()) + common.ResponseWithCodeData(c, ec, nil, err.Error()) return } c.Writer.Header().Set("Content-Type", "text/event-stream") @@ -221,12 +222,12 @@ func (h *BotHandler) AgentbotCompletion(c *gin.Context) { func (h *BotHandler) ChatbotCompletion(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } dialogID := c.Param("dialog_id") if dialogID == "" { - jsonError(c, common.CodeArgumentError, "`dialog_id` is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "`dialog_id` is required.") return } var body service.ChatbotCompletionRequest @@ -236,14 +237,15 @@ func (h *BotHandler) ChatbotCompletion(c *gin.Context) { // then ran with empty session_id/question. if c.Request.ContentLength != 0 { if err := c.ShouldBindJSON(&body); err != nil { - jsonError(c, common.CodeArgumentError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "Invalid request: "+err.Error()) return } } frames, ec, err := h.botService.ChatbotCompletion( c.Request.Context(), user.ID, dialogID, body) if err != nil { - jsonError(c, ec, err.Error()) + common.ResponseWithCodeData(c, ec, nil, err.Error()) return } c.Writer.Header().Set("Content-Type", "text/event-stream") @@ -281,18 +283,18 @@ func (h *BotHandler) ChatbotCompletion(c *gin.Context) { // read another agent's logs. func (h *BotHandler) GetAgentbotLogs(c *gin.Context) { if _, code, msg := GetUser(c); code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } agentID, _ := c.Get("agent_id") agentIDStr, _ := agentID.(string) if agentIDStr == "" { - jsonError(c, common.CodeDataError, "API token is not bound to an agent.") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "API token is not bound to an agent.") return } messageID := c.Param("message_id") if messageID == "" { - jsonError(c, common.CodeArgumentError, "message_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "message_id is required") return } key := fmt.Sprintf("%s-%s-logs", agentIDStr, messageID) @@ -303,13 +305,13 @@ func (h *BotHandler) GetAgentbotLogs(c *gin.Context) { // real outages and corrupted payloads from operators (PR review // round 5, Major #6). if rerr != nil { - jsonError(c, common.CodeServerError, "failed to read agent logs") + common.ResponseWithCodeData(c, common.CodeServerError, nil, "failed to read agent logs") return } data := map[string]interface{}{} if payload != "" { if uerr := json.Unmarshal([]byte(payload), &data); uerr != nil { - jsonError(c, common.CodeServerError, "failed to decode agent logs") + common.ResponseWithCodeData(c, common.CodeServerError, nil, "failed to decode agent logs") return } } diff --git a/internal/handler/bot_test.go b/internal/handler/bot_test.go index 8ba4137c1e..5febcaceef 100644 --- a/internal/handler/bot_test.go +++ b/internal/handler/bot_test.go @@ -878,7 +878,7 @@ func TestBotRoutes_NoRegularAuthRequired(t *testing.T) { // production AuthMiddleware is exercised separately; // here we just need to assert "the path resolves to // something that is NOT a BotHandler". - jsonError(c, common.CodeUnauthorized, "no bot route on v1") + common.ResponseWithCodeData(c, common.CodeUnauthorized, nil, "no bot route on v1") }) // (1) regular JWT on apiNoAuth bot path -> 200. @@ -947,12 +947,12 @@ func TestDownloadAttachment_Unauth(t *testing.T) { g.Use(func(c *gin.Context) { auth := c.GetHeader("Authorization") if auth == "" { - jsonError(c, common.CodeUnauthorized, "Authorization required") + common.ResponseWithCodeData(c, common.CodeUnauthorized, nil, "Authorization required") c.Abort() return } if u, code, err := stub.GetUserByToken(auth); err != nil || code != common.CodeSuccess { - jsonError(c, common.CodeUnauthorized, "Invalid auth credentials") + common.ResponseWithCodeData(c, common.CodeUnauthorized, nil, "Invalid auth credentials") c.Abort() return } else { diff --git a/internal/handler/chat.go b/internal/handler/chat.go index c4f998eac0..b2271dcc3a 100644 --- a/internal/handler/chat.go +++ b/internal/handler/chat.go @@ -73,7 +73,7 @@ type ChatMindMapRequest struct { func (h *ChatHandler) ListChats(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -105,18 +105,11 @@ func (h *ChatHandler) ListChats(c *gin.Context) { // List chats - default to valid status "1" (same as Python StatusEnum.VALID.value) result, err := h.chatService.ListChats(userID, "1", keywords, page, pageSize, orderby, desc) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } // Create creates a chat. @@ -131,7 +124,7 @@ func (h *ChatHandler) ListChats(c *gin.Context) { func (h *ChatHandler) Create(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -139,7 +132,7 @@ func (h *ChatHandler) Create(c *gin.Context) { decoder := json.NewDecoder(c.Request.Body) decoder.UseNumber() if err := decoder.Decode(&req); err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } if req == nil { @@ -148,15 +141,11 @@ func (h *ChatHandler) Create(c *gin.Context) { result, code, err := h.chatService.Create(user.ID, req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } // MindMap generates a query mind map for chat search results. @@ -171,17 +160,17 @@ func (h *ChatHandler) Create(c *gin.Context) { func (h *ChatHandler) MindMap(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req ChatMindMapRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeArgumentError, "data": nil, "message": err.Error()}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, err.Error()) return } if strings.TrimSpace(req.Question) == "" { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeArgumentError, "data": nil, "message": "kb_ids and question are required"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "kb_ids and question are required") return } @@ -205,7 +194,7 @@ func (h *ChatHandler) MindMap(c *gin.Context) { kbIDs := mergeMindMapKbIDs(stringSliceFromConfig(searchConfig, "kb_ids"), req.KbIDs) if len(kbIDs) == 0 { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeArgumentError, "data": nil, "message": "kb_ids and question are required"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "kb_ids and question are required") return } @@ -224,75 +213,51 @@ func (h *ChatHandler) MindMap(c *gin.Context) { jsonInternalError(c, err) return } - jsonResponse(c, common.CodeSuccess, mindMap, "success") + common.SuccessWithData(c, mindMap, "success") } func (h *ChatHandler) DeleteChat(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID chatID := c.Param("chat_id") if chatID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": "chat_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "chat_id is required") return } if err := h.chatService.DeleteChat(userID, chatID); err != nil { if err.Error() == "no authorization" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeAuthenticationError, - "data": false, - "message": "No authorization.", - }) + common.ResponseWithCodeData(c, common.CodeDataError, false, "No authorization") return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeDataError), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": "success", - }) + common.SuccessWithData(c, true, "success") } // BulkDeleteChats soft deletes multiple chats owned by the current user. func (h *ChatHandler) BulkDeleteChats(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID if c.Request.Body == nil || c.Request.ContentLength == 0 { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": map[string]interface{}{}, - "message": "success", - }) + common.SuccessWithData(c, map[string]interface{}{}, "success") return } var req service.BulkDeleteChatsRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": "Invalid request body: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) return } @@ -300,44 +265,24 @@ func (h *ChatHandler) BulkDeleteChats(c *gin.Context) { if req.ChatID != "" { if err := h.chatService.DeleteChat(userID, req.ChatID); err != nil { if err.Error() == "no authorization" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeAuthenticationError, - "data": false, - "message": "No authorization.", - }) + common.ResponseWithCodeData(c, common.CodeAuthenticationError, false, "No authorization.") return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": err.Error(), - }) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": "success", - }) + common.SuccessWithData(c, true, "success") return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": map[string]interface{}{}, - "message": "success", - }) + common.SuccessWithData(c, map[string]interface{}{}, "success") return } result, err := h.chatService.BulkDeleteChats(userID, &req) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeDataError), err.Error()) return } @@ -348,11 +293,7 @@ func (h *ChatHandler) BulkDeleteChats(c *gin.Context) { } } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": message, - }) + common.SuccessWithData(c, result, message) } // GetChat get chat detail @@ -371,7 +312,7 @@ func (h *ChatHandler) GetChat(c *gin.Context) { // Get current user from context (same as Python current_user) user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -379,11 +320,7 @@ func (h *ChatHandler) GetChat(c *gin.Context) { // Get chat_id from path parameter (same as Python ) chatID := c.Param("chat_id") if chatID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": "chat_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "chat_id is required") return } @@ -393,19 +330,11 @@ func (h *ChatHandler) GetChat(c *gin.Context) { errMsg := err.Error() // Check if it's an authorization error if errMsg == "no authorization" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeAuthenticationError, - "data": false, - "message": "No authorization.", - }) + common.ResponseWithCodeData(c, common.CodeDataError, false, "No authorization") return } // Not found error - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeDataError), err.Error()) return } @@ -441,11 +370,7 @@ func (h *ChatHandler) GetChat(c *gin.Context) { } // Return success response - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } // UpdateChat updates a chat by ID using REST PUT semantics. @@ -461,19 +386,19 @@ func (h *ChatHandler) PatchChat(c *gin.Context) { func (h *ChatHandler) updateChatByMethod(c *gin.Context, patch bool) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } chatID := c.Param("chat_id") if chatID == "" { - jsonError(c, common.CodeBadRequest, "chat_id is required") + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "chat_id is required") return } var req map[string]interface{} if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } @@ -488,16 +413,12 @@ func (h *ChatHandler) updateChatByMethod(c *gin.Context, patch bool) { } if err != nil { if err.Error() == "no authorization" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeAuthenticationError, - "data": false, - "message": "No authorization.", - }) + common.ResponseWithCodeData(c, common.CodeDataError, false, "No authorization") return } - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } diff --git a/internal/handler/chat_channel.go b/internal/handler/chat_channel.go index 4417685996..e100d29866 100644 --- a/internal/handler/chat_channel.go +++ b/internal/handler/chat_channel.go @@ -15,7 +15,6 @@ package handler import ( - "net/http" "strings" "github.com/gin-gonic/gin" @@ -57,13 +56,13 @@ type CreateChatChannelRequest struct { func (h *ChatChannelHandler) CreateChatChannel(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req CreateChatChannelRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Invalid request: "+err.Error()) return } @@ -75,45 +74,45 @@ func (h *ChatChannelHandler) CreateChatChannel(c *gin.Context) { req.ChatID, ) if err != nil { - jsonError(c, common.CodeServerError, err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } - jsonResponse(c, common.CodeSuccess, row, "success") + common.SuccessWithData(c, row, "success") } // ListChatChannel handles GET /chat-channels. func (h *ChatChannelHandler) ListChatChannel(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } rows, err := h.chatChannelService.List(user.ID) if err != nil { - jsonError(c, common.CodeServerError, err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } - jsonResponse(c, common.CodeSuccess, rows, "success") + common.SuccessWithData(c, rows, "success") } // GetChatChannel handles GET /chat-channels/:channel_id. func (h *ChatChannelHandler) GetChatChannel(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeArgumentError, "user_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "user_id is required") return } channelID := strings.TrimSpace(c.Param("channel_id")) if channelID == "" { - jsonError(c, common.CodeArgumentError, "channel_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "channel_id is required") return } @@ -123,36 +122,32 @@ func (h *ChatChannelHandler) GetChatChannel(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": channel, - "message": "success", - }) + common.SuccessWithData(c, channel, "success") } // UpdateChatChannel handles PATCH /chat-channels/:channel_id. func (h *ChatChannelHandler) UpdateChatChannel(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeArgumentError, "user_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "user_id is required") return } channelID := strings.TrimSpace(c.Param("channel_id")) if channelID == "" { - jsonError(c, common.CodeArgumentError, "channel_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "channel_id is required") return } var request map[string]interface{} if err := c.ShouldBindJSON(&request); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } @@ -162,30 +157,26 @@ func (h *ChatChannelHandler) UpdateChatChannel(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } // DeleteChatChannel handles DELETE /chat-channels/:channel_id. func (h *ChatChannelHandler) DeleteChatChannel(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeArgumentError, "user_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "user_id is required") return } channelID := strings.TrimSpace(c.Param("channel_id")) if channelID == "" { - jsonError(c, common.CodeArgumentError, "channel_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "channel_id is required") return } @@ -195,11 +186,7 @@ func (h *ChatChannelHandler) DeleteChatChannel(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } func unwrapChatChannelPayload(payload map[string]interface{}) map[string]interface{} { @@ -211,14 +198,10 @@ func unwrapChatChannelPayload(payload map[string]interface{}) map[string]interfa func writeChatChannelError(c *gin.Context, code common.ErrorCode, message string) { if code == common.CodeAuthenticationError && message == "No authorization." { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "data": false, - "message": message, - }) + common.ResponseWithCodeData(c, code, false, message) return } - jsonError(c, code, message) + common.ResponseWithCodeData(c, code, nil, message) } func chatChannelErrMsg(code common.ErrorCode, err error) string { diff --git a/internal/handler/chat_recommendation.go b/internal/handler/chat_recommendation.go index 1650af6581..db761ff04c 100644 --- a/internal/handler/chat_recommendation.go +++ b/internal/handler/chat_recommendation.go @@ -17,7 +17,6 @@ package handler import ( - "net/http" "strings" "github.com/gin-gonic/gin" @@ -44,17 +43,17 @@ type ChatRecommendationRequest struct { func (h *ChatHandler) Recommendation(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req ChatRecommendationRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{"code": common.CodeArgumentError, "data": nil, "message": "question is required"}) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "question is required") return } if strings.TrimSpace(req.Question) == "" { - c.JSON(http.StatusOK, gin.H{"code": common.CodeArgumentError, "data": nil, "message": "question is required"}) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "question is required") return } questions, err := service.GenerateRelatedQuestions(user.ID, req.Question, req.SearchID, h.searchSvc, h.tenantSvc, h.llm) @@ -63,5 +62,5 @@ func (h *ChatHandler) Recommendation(c *gin.Context) { return } - jsonResponse(c, common.CodeSuccess, questions, "success") + common.SuccessWithData(c, questions, "success") } diff --git a/internal/handler/chat_session.go b/internal/handler/chat_session.go index 26f9c493ab..8f4a3669ce 100644 --- a/internal/handler/chat_session.go +++ b/internal/handler/chat_session.go @@ -55,7 +55,7 @@ func NewChatSessionHandler(chatSessionService *service.ChatSessionService, userS func (h *ChatSessionHandler) ListChatSessions(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -63,10 +63,7 @@ func (h *ChatSessionHandler) ListChatSessions(c *gin.Context) { // Get chat_id from query parameter chatID := c.Param("chat_id") if chatID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "chat_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "chat_id is required") return } @@ -75,25 +72,14 @@ func (h *ChatSessionHandler) ListChatSessions(c *gin.Context) { if err != nil { // Check if it's an authorization error if err.Error() == "Only owner of dialog authorized for this operation" { - c.JSON(http.StatusForbidden, gin.H{ - "code": 403, - "data": false, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusForbidden, 403, false, err.Error()) return } - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": result.Sessions, - "message": "success", - }) + common.SuccessWithData(c, result.Sessions, "success") } type ChatCompletionsRequest struct { @@ -129,25 +115,25 @@ type ChatCompletionsRequest struct { func (h *ChatSessionHandler) ChatCompletions(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID var rawBody map[string]interface{} if err := c.ShouldBindJSON(&rawBody); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()}) + common.ErrorWithCode(c, 400, err.Error()) return } var req ChatCompletionsRequest b, err := json.Marshal(rawBody) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()}) + common.ErrorWithCode(c, 400, err.Error()) return } - if err := json.Unmarshal(b, &req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": err.Error()}) + if err = json.Unmarshal(b, &req); err != nil { + common.ErrorWithCode(c, 400, err.Error()) return } @@ -234,7 +220,8 @@ func (h *ChatSessionHandler) ChatCompletions(c *gin.Context) { return true }) } else { - result, err := h.chatSessionService.ChatCompletions( + var result map[string]interface{} + result, err = h.chatSessionService.ChatCompletions( c.Request.Context(), userID, req.ChatID, sessionID, req.Messages, req.Question, req.Files, @@ -243,24 +230,17 @@ func (h *ChatSessionHandler) ChatCompletions(c *gin.Context) { false, nil, ) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": result, - "message": "", - }) + common.SuccessWithData(c, result, "") } } func (h *ChatSessionHandler) GetSession(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -269,29 +249,29 @@ func (h *ChatSessionHandler) GetSession(c *gin.Context) { result, code, err := h.chatSessionService.GetSession(userID, chatID, sessionID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // CreateSession create a session in a dialog func (h *ChatSessionHandler) CreateSession(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeBadRequest, "user_id is required") + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "user_id is required") return } chatID := strings.TrimSpace(c.Param("chat_id")) if chatID == "" { - jsonError(c, common.CodeBadRequest, "chat_id is required") + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "chat_id is required") return } @@ -300,7 +280,7 @@ func (h *ChatSessionHandler) CreateSession(c *gin.Context) { if errors.Is(err, io.EOF) { req = map[string]interface{}{} } else { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } } @@ -311,33 +291,33 @@ func (h *ChatSessionHandler) CreateSession(c *gin.Context) { result, code, err := h.chatSessionService.CreateSession(userID, chatID, req) if err != nil { if code == common.CodeAuthenticationError { - jsonResponse(c, code, false, err.Error()) + common.ResponseWithCodeData(c, code, false, err.Error()) return } - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // DeleteSessions delete a session in a dialog func (h *ChatSessionHandler) DeleteSessions(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } chatID := strings.TrimSpace(c.Param("chat_id")) if chatID == "" { - jsonError(c, common.CodeBadRequest, "chat_id is required") + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "chat_id is required") return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeBadRequest, "user_id is required") + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "user_id is required") return } @@ -346,7 +326,7 @@ func (h *ChatSessionHandler) DeleteSessions(c *gin.Context) { if errors.Is(err, io.EOF) { req = map[string]interface{}{} } else { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } } @@ -357,20 +337,20 @@ func (h *ChatSessionHandler) DeleteSessions(c *gin.Context) { result, message, code, err := h.chatSessionService.DeleteSessions(userID, chatID, req) if err != nil { if code == common.CodeAuthenticationError { - jsonResponse(c, code, false, err.Error()) + common.ResponseWithCodeData(c, code, false, err.Error()) return } - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, message) + common.SuccessWithData(c, result, message) } func (h *ChatSessionHandler) UpdateSession(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -380,29 +360,30 @@ func (h *ChatSessionHandler) UpdateSession(c *gin.Context) { req := map[string]any{} if err := c.ShouldBindJSON(&req); err != nil { if errors.Is(err, io.EOF) { - jsonError(c, common.CodeArgumentError, "Request body cannot be empty") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "Request body cannot be empty") return } - jsonError(c, common.CodeArgumentError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request: "+err.Error()) return } if len(req) == 0 { - jsonError(c, common.CodeArgumentError, "Request body cannot be empty") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Request body cannot be empty") return } result, code, err := h.chatSessionService.UpdateSession(userID, chatID, sessionID, req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } func (h *ChatSessionHandler) DeleteSessionMessage(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -411,19 +392,19 @@ func (h *ChatSessionHandler) DeleteSessionMessage(c *gin.Context) { result, code, err := h.chatSessionService.DeleteSessionMessage(userID, chatID, sessionID, msgID) if err != nil { if code == common.CodeAuthenticationError { - jsonResponse(c, code, false, err.Error()) + common.ResponseWithCodeData(c, code, false, err.Error()) return } - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } func (h *ChatSessionHandler) UpdateMessageFeedback(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -433,25 +414,26 @@ func (h *ChatSessionHandler) UpdateMessageFeedback(c *gin.Context) { req := map[string]interface{}{} if err := c.ShouldBindJSON(&req); err != nil { if errors.Is(err, io.EOF) { - jsonError(c, common.CodeArgumentError, "Request body cannot be empty") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "Request body cannot be empty") return } - jsonError(c, common.CodeArgumentError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request: "+err.Error()) return } if len(req) == 0 { - jsonError(c, common.CodeArgumentError, "Request body cannot be empty") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Request body cannot be empty") return } result, code, err := h.chatSessionService.UpdateMessageFeedback(c.Request.Context(), userID, chatID, sessionID, msgID, req) if err != nil { if code == common.CodeAuthenticationError { - jsonResponse(c, code, false, err.Error()) + common.ResponseWithCodeData(c, code, false, err.Error()) return } - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } diff --git a/internal/handler/chunk.go b/internal/handler/chunk.go index 6d54a296cb..ed74e5efee 100644 --- a/internal/handler/chunk.go +++ b/internal/handler/chunk.go @@ -69,18 +69,14 @@ func NewChunkHandler(chunkService chunkService, userService *service.UserService func (h *ChunkHandler) RetrievalTest(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } // Bind JSON request var req service.RetrievalTestRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "data": nil, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) return } @@ -105,42 +101,26 @@ func (h *ChunkHandler) RetrievalTest(c *gin.Context) { // Strip and validate question. Matching Python chunk_api.py which returns // an empty result for blank questions rather than an error. if strings.TrimSpace(req.Question) == "" { - c.JSON(http.StatusOK, gin.H{ - "code": int(common.CodeSuccess), - "data": &service.RetrievalTestResponse{ - Chunks: []map[string]interface{}{}, - DocAggs: []map[string]interface{}{}, - Total: 0, - }, - "message": "success", - }) + common.SuccessWithData(c, &service.RetrievalTestResponse{ + Chunks: []map[string]interface{}{}, + DocAggs: []map[string]interface{}{}, + Total: 0, + }, "success") return } // Validate required fields if req.Datasets == nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "data": nil, - "message": "kb_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "kb_id is required") return } if len(req.Datasets) == 0 { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "data": nil, - "message": "kb_id array cannot be empty", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "kb_id array cannot be empty") return } if req.TopK != nil && *req.TopK <= 0 { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "data": nil, - "message": "top_k must be greater than 0", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "top_k must be greater than 0") return } @@ -148,19 +128,11 @@ func (h *ChunkHandler) RetrievalTest(c *gin.Context) { resp, err := h.chunkService.RetrievalTest(&req, user.ID) if err != nil { common.Warn("dataset search failed", zap.String("error", err.Error())) - c.JSON(http.StatusInternalServerError, gin.H{ - "code": common.CodeServerError, - "data": nil, - "message": "dataset search failed", - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeServerError, nil, "dataset search failed") return } - c.JSON(http.StatusOK, gin.H{ - "code": int(common.CodeSuccess), - "data": resp, - "message": "success", - }) + common.SuccessWithData(c, resp, "success") } // Get retrieves a chunk by ID. @@ -177,16 +149,13 @@ func (h *ChunkHandler) RetrievalTest(c *gin.Context) { func (h *ChunkHandler) Get(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } chunkID := c.Param("chunk_id") if chunkID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "chunk_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "chunk_id is required") return } @@ -196,105 +165,70 @@ func (h *ChunkHandler) Get(c *gin.Context) { resp, err := h.chunkService.Get(req, user.ID) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": resp.Chunk, - "message": "success", - }) + common.SuccessWithData(c, resp.Chunk, "success") } // Parse reparse the datasets' files func (h *ChunkHandler) Parse(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "data": nil, - "message": "user_id is required", - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "user_id is required") return } datasetId := strings.TrimSpace(c.Param("dataset_id")) if datasetId == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": "dataset_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "dataset_id is required") return } var req service.ParseFileRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "data": nil, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) return } data, code, err := h.chunkService.Parse(userID, datasetId, &req) if code != common.CodeSuccess { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "data": data, - "message": err.Error(), - }) + common.ResponseWithCodeData(c, code, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": code, - "data": data, - "message": "success", - }) + common.ResponseWithCodeData(c, code, data, "success") } // ListChunks retrieves chunks for a document from path/query parameters. func (h *ChunkHandler) ListChunks(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := c.Param("dataset_id") documentID := c.Param("document_id") if datasetID == "" || documentID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "message": "dataset_id and document_id are required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "dataset_id and document_id are required") return } page, err := parsePositiveQueryInt(c, "page", 1) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, err.Error()) return } size, err := parsePositiveQueryInt(c, "page_size", 30) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, err.Error()) return } @@ -307,10 +241,7 @@ func (h *ChunkHandler) ListChunks(c *gin.Context) { } available, ok, err := parseAvailableQuery(c.Query("available")) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, err.Error()) return } if ok { @@ -319,18 +250,11 @@ func (h *ChunkHandler) ListChunks(c *gin.Context) { resp, err := h.chunkService.List(&req, user.ID) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": common.CodeServerError, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeServerError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": int(common.CodeSuccess), - "data": resp, - "message": "success", - }) + common.SuccessWithData(c, resp, "success") } func parsePositiveQueryInt(c *gin.Context, name string, defaultValue int) (int, error) { @@ -361,23 +285,23 @@ func parseAvailableQuery(raw string) (int, bool, error) { func (h *ChunkHandler) StopParsing(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := c.Param("dataset_id") if datasetID == "" { - jsonError(c, common.CodeDataError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset_id is required") return } var req service.StopParsingRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } if len(req.DocumentIDs) == 0 { - jsonError(c, common.CodeDataError, "`document_ids` is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "`document_ids` is required") return } @@ -387,11 +311,7 @@ func (h *ChunkHandler) StopParsing(c *gin.Context) { if resp != nil { data = resp.Data } - c.JSON(http.StatusOK, gin.H{ - "code": code, - "data": data, - "message": err.Error(), - }) + common.ResponseWithCodeData(c, code, data, err.Error()) return } @@ -404,11 +324,7 @@ func (h *ChunkHandler) StopParsing(c *gin.Context) { data = resp.Data } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": data, - "message": message, - }) + common.SuccessWithData(c, data, message) } // List retrieves chunks for a document. @@ -423,17 +339,14 @@ func (h *ChunkHandler) StopParsing(c *gin.Context) { func (h *ChunkHandler) List(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } // Bind JSON request var req service.ListChunksRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, err.Error()) return } @@ -449,104 +362,69 @@ func (h *ChunkHandler) List(c *gin.Context) { resp, err := h.chunkService.List(&req, user.ID) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": resp, - "message": "success", - }) + common.SuccessWithData(c, resp, "success") } // SwitchChunks enable or disable a chunk func (h *ChunkHandler) SwitchChunks(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeAuthenticationError, - "message": "user_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeAuthenticationError, nil, "user_id is required") return } // Get required ID datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "message": "dataset_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "dataset_id is required") return } documentID := strings.TrimSpace(c.Param("document_id")) if documentID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "message": "document_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "document_id is required") return } var rawBody map[string]interface{} if err := json.NewDecoder(c.Request.Body).Decode(&rawBody); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, err.Error()) return } chunkIDs, ok := parseStringSlice(rawBody["chunk_ids"]) if !ok || len(chunkIDs) == 0 { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": "`chunk_ids` is required.", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "`chunk_ids` is required.") return } if rawBody["available_int"] == nil && rawBody["available"] == nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": "`available_int` or `available` is required.", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "`available_int` or `available` is required.") return } availableInt, err := parseAvailableBody(rawBody) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, err.Error()) return } - if err := h.chunkService.SwitchChunks(userID, datasetID, documentID, availableInt, chunkIDs); err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": common.CodeServerError, - "message": err.Error(), - }) + if err = h.chunkService.SwitchChunks(userID, datasetID, documentID, availableInt, chunkIDs); err != nil { + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeServerError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": "success", - }) + common.SuccessWithData(c, true, "success") } func parseStringSlice(raw interface{}) ([]string, bool) { @@ -612,46 +490,34 @@ func parseAvailableBody(rawBody map[string]interface{}) (int, error) { func (h *ChunkHandler) UpdateChunk(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } // Validate allowed update fields and get IDs from body var rawBody map[string]interface{} if err := json.NewDecoder(c.Request.Body).Decode(&rawBody); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "invalid JSON body: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "invalid JSON body: "+err.Error()) return } // Get required ID fields datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "message": "dataset_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "dataset_id is required") return } chunkID := strings.TrimSpace(c.Param("chunk_id")) if chunkID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "message": "chunk_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "chunk_id is required") return } // Get document_id from request documentID := strings.TrimSpace(c.Param("document_id")) if documentID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "message": "document_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "document_id is required") return } @@ -667,10 +533,7 @@ func (h *ChunkHandler) UpdateChunk(c *gin.Context) { } for field := range rawBody { if field != "dataset_id" && field != "document_id" && field != "chunk_id" && !allowedFields[field] { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Update field '" + field + "' is not supported. Updatable fields: content, important_keywords, questions, available, positions, tag_kwd, tag_feas", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Update field '"+field+"' is not supported. Updatable fields: content, important_keywords, questions, available, positions, tag_kwd, tag_feas") return } } @@ -725,6 +588,7 @@ func (h *ChunkHandler) UpdateChunk(c *gin.Context) { if errors.As(err, &coded) { switch coded.Code() { case common.CodeArgumentError, common.CodeBadRequest, common.CodeDataError: + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, coded.Code(), nil, err.Error()) c.JSON(http.StatusBadRequest, gin.H{ "code": coded.Code(), "message": err.Error(), @@ -732,17 +596,12 @@ func (h *ChunkHandler) UpdateChunk(c *gin.Context) { return } } - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": err.Error(), - }) + + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "chunk updated successfully", - }) + common.SuccessWithMessage(c, "chunk updated successfully") } // RemoveChunks handles chunk removal requests @@ -757,53 +616,37 @@ func (h *ChunkHandler) UpdateChunk(c *gin.Context) { func (h *ChunkHandler) RemoveChunks(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } // Get document_id from URL path docID := c.Param("document_id") if docID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "document_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "document_id is required") return } var req service.RemoveChunksRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, err.Error()) return } req.DocID = docID if req.DocID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "doc_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "doc_id is required") return } deletedCount, err := h.chunkService.RemoveChunks(&req, user.ID) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": deletedCount, - "message": "success", - }) + common.SuccessWithData(c, deletedCount, "success") } func addChunkStringField(rawBody map[string]json.RawMessage, field string) (string, error) { @@ -861,7 +704,7 @@ func addChunkResponseMessage(code common.ErrorCode, err error) string { func (h *ChunkHandler) AddChunk(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -870,38 +713,38 @@ func (h *ChunkHandler) AddChunk(c *gin.Context) { var rawBody map[string]json.RawMessage if err := json.NewDecoder(c.Request.Body).Decode(&rawBody); err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } content, err := addChunkStringField(rawBody, "content") if err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } importantKeywords, err := addChunkStringListField(rawBody, "important_keywords", "`important_keywords` is required to be a list", "`important_keywords` must be a list of strings") if err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } questions, err := addChunkStringListField(rawBody, "questions", "`questions` is required to be a list", "`questions` must be a list of strings") if err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } tagKwd, err := addChunkStringListField(rawBody, "tag_kwd", "`tag_kwd` is required to be a list", "`tag_kwd` must be a list of strings") if err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } imageBase64, err := addChunkStringPtrField(rawBody, "image_base64") if err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } var tagFeas interface{} if raw, ok := rawBody["tag_feas"]; ok { - if err := json.Unmarshal(raw, &tagFeas); err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + if err = json.Unmarshal(raw, &tagFeas); err != nil { + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } } @@ -919,17 +762,14 @@ func (h *ChunkHandler) AddChunk(c *gin.Context) { resp, err := h.chunkService.AddChunk(&req, userID) if err != nil { - if codedErr, ok := err.(service.ErrorCoder); ok { - jsonError(c, codedErr.Code(), addChunkResponseMessage(codedErr.Code(), err)) + var codedErr service.ErrorCoder + if errors.As(err, &codedErr) { + common.ResponseWithCodeData(c, codedErr.Code(), nil, addChunkResponseMessage(codedErr.Code(), err)) return } - jsonError(c, common.CodeServerError, addChunkResponseMessage(common.CodeServerError, err)) + common.ResponseWithCodeData(c, common.CodeServerError, nil, addChunkResponseMessage(common.CodeServerError, err)) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": resp, - "message": "success", - }) + common.SuccessWithData(c, resp, "success") } diff --git a/internal/handler/components.go b/internal/handler/components.go index a69774790c..35e4fd0c2d 100644 --- a/internal/handler/components.go +++ b/internal/handler/components.go @@ -27,6 +27,7 @@ package handler import ( "net/http" + "ragflow/internal/common" "strings" "github.com/gin-gonic/gin" @@ -67,29 +68,17 @@ func (h *ComponentsHandler) Get(c *gin.Context) { raw := c.Query("category") cats, err := parseCategories(raw) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, err.Error()) return } out, err := h.svc.List(cats...) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": out, - }) + common.SuccessWithData(c, out, "success") } // parseCategories splits a comma-separated category query string into diff --git a/internal/handler/connector.go b/internal/handler/connector.go index 1117e8bffd..685c0bfe29 100644 --- a/internal/handler/connector.go +++ b/internal/handler/connector.go @@ -72,7 +72,7 @@ func NewConnectorHandler(connectorService *service.ConnectorService, userService func (h *ConnectorHandler) ListConnectors(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -80,18 +80,11 @@ func (h *ConnectorHandler) ListConnectors(c *gin.Context) { // List connectors result, err := h.connectorService.ListConnectors(userID) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": result.Connectors, - "message": "success", - }) + common.SuccessWithData(c, result.Connectors, "success") } // connectorErrorResponse maps service sentinel errors to the response codes used @@ -102,13 +95,13 @@ func connectorErrorResponse(c *gin.Context, err error) bool { case err == nil: return false case errors.Is(err, service.ErrConnectorNoAuth): - c.JSON(http.StatusOK, gin.H{"code": common.CodeAuthenticationError, "data": false, "message": "No authorization."}) + common.ResponseWithCodeData(c, common.CodeAuthenticationError, false, "No authorization.") case errors.Is(err, service.ErrConnectorNotFound): - c.JSON(http.StatusOK, gin.H{"code": common.CodeDataError, "data": nil, "message": "Can't find this Connector!"}) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Can't find this Connector!") case errors.Is(err, service.ErrConnectorTestUnsupported): - c.JSON(http.StatusOK, gin.H{"code": common.CodeArgumentError, "data": false, "message": err.Error()}) + common.ResponseWithCodeData(c, common.CodeArgumentError, false, err.Error()) default: - c.JSON(http.StatusInternalServerError, gin.H{"code": common.CodeServerError, "data": nil, "message": err.Error()}) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeServerError, nil, err.Error()) } return true } @@ -124,48 +117,40 @@ func connectorErrorResponse(c *gin.Context, err error) bool { func (h *ConnectorHandler) GetConnector(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } connector, code, err := h.connectorService.GetConnector(c.Param("connector_id"), user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": connector, - "message": "success", - }) + common.SuccessWithData(c, connector, "success") } // UpdateConnector Update an accessible connector's polling configuration. func (h *ConnectorHandler) UpdateConnector(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } req, err := decodeUpdateConnectorRequest(c) if err != nil { - jsonError(c, common.CodeBadRequest, err.Error()) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } connector, code, err := h.connectorService.UpdateConnector(c.Param("connector_id"), user.ID, req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": connector, - "message": "success", - }) + common.SuccessWithData(c, connector, "success") } func decodeUpdateConnectorRequest(c *gin.Context) (*service.UpdateConnectorRequest, error) { @@ -188,7 +173,7 @@ func decodeUpdateConnectorRequest(c *gin.Context) (*service.UpdateConnectorReque } var req service.UpdateConnectorRequest - if err := json.Unmarshal(data, &req); err != nil { + if err = json.Unmarshal(data, &req); err != nil { return nil, err } @@ -206,7 +191,7 @@ func decodeUpdateConnectorRequest(c *gin.Context) (*service.UpdateConnectorReque func (h *ConnectorHandler) ListLogs(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -214,7 +199,7 @@ func (h *ConnectorHandler) ListLogs(c *gin.Context) { if rawPage := strings.TrimSpace(c.DefaultQuery("page", "1")); rawPage != "" { parsedPage, err := strconv.Atoi(rawPage) if err != nil { - jsonError(c, common.CodeArgumentError, "page must be an integer") + common.ErrorWithCode(c, int(common.CodeArgumentError), "page must be an integer") return } page = parsedPage @@ -224,7 +209,7 @@ func (h *ConnectorHandler) ListLogs(c *gin.Context) { if rawPageSize := strings.TrimSpace(c.DefaultQuery("page_size", "15")); rawPageSize != "" { parsedPageSize, err := strconv.Atoi(rawPageSize) if err != nil { - jsonError(c, common.CodeArgumentError, "page_size must be an integer") + common.ErrorWithCode(c, int(common.CodeArgumentError), "page_size must be an integer") return } pageSize = parsedPageSize @@ -232,18 +217,14 @@ func (h *ConnectorHandler) ListLogs(c *gin.Context) { logs, total, code, err := h.connectorService.ListLog(c.Param("connector_id"), user.ID, page, pageSize) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } if logs == nil { logs = []*entity.ConnectorSyncLog{} } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": gin.H{"total": total, "logs": logs}, - "message": "success", - }) + common.SuccessWithData(c, gin.H{"total": total, "logs": logs}, "success") } // CreateConnector create connector @@ -257,60 +238,36 @@ func (h *ConnectorHandler) ListLogs(c *gin.Context) { func (h *ConnectorHandler) CreateConnector(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req service.CreateConnectorRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": "Invalid request body: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) return } if strings.TrimSpace(req.Name) == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": "name is required", - }) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "name is required") return } if strings.TrimSpace(req.Source) == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": "source is required", - }) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "source is required") return } if req.Config == nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": "config is required", - }) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "config is required") return } connector, err := h.connectorService.CreateConnector(user.ID, &req) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": common.CodeServerError, - "data": nil, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeServerError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": connector, - "message": "success", - }) + common.SuccessWithData(c, connector, "success") } // TestConnector validates an accessible connector's stored credentials. @@ -323,13 +280,13 @@ func (h *ConnectorHandler) CreateConnector(c *gin.Context) { func (h *ConnectorHandler) TestConnector(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } connectorID := c.Param("connector_id") if connectorID == "" { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeBadRequest, "data": nil, "message": "connector_id is required"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "connector_id is required") return } @@ -340,14 +297,14 @@ func (h *ConnectorHandler) TestConnector(c *gin.Context) { } if err != nil && !errors.Is(err, service.ErrConnectorNoAuth) && !errors.Is(err, service.ErrConnectorNotFound) { // Validation failure (e.g. missing credentials): mirror Python's DATA_ERROR with data=false. - c.JSON(http.StatusOK, gin.H{"code": common.CodeDataError, "data": false, "message": err.Error()}) + common.ResponseWithCodeData(c, common.CodeDataError, false, err.Error()) return } if connectorErrorResponse(c, err) { return } - c.JSON(http.StatusOK, gin.H{"code": common.CodeSuccess, "data": true, "message": "success"}) + common.SuccessWithData(c, true, "success") } // DeleteConnector delete connector @@ -358,21 +315,17 @@ func (h *ConnectorHandler) TestConnector(c *gin.Context) { func (h *ConnectorHandler) DeleteConnector(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } ok, code, err := h.connectorService.DeleteConnector(c.Param("connector_id"), user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": ok, - "message": "success", - }) + common.SuccessWithData(c, ok, "success") } // RebuildConnector rebuild connector @@ -386,7 +339,7 @@ func (h *ConnectorHandler) DeleteConnector(c *gin.Context) { func (h *ConnectorHandler) RebuildConnector(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -395,94 +348,66 @@ func (h *ConnectorHandler) RebuildConnector(c *gin.Context) { KbID string `json:"kb_id" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": "required argument is missing: kb_id", - }) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "required argument is missing: kb_id") return } if strings.TrimSpace(req.KbID) == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": "kb_id cannot be empty", - }) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "kb_id cannot be empty") return } ok, code, err := h.connectorService.RebuildConnector(c.Param("connector_id"), user.ID, req.KbID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": ok, - "message": "success", - }) + common.SuccessWithData(c, ok, "success") } func (h *ConnectorHandler) StartGoogleWebOAuth(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req service.StartGoogleWebOAuthRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": err.Error(), - }) + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, err.Error()) return } data, code, err := h.connectorService.StartGoogleWebOAuth(user.ID, c.DefaultQuery("type", "google-drive"), &req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": data, - "message": "success", - }) + common.SuccessWithData(c, data, "success") } func (h *ConnectorHandler) PollGoogleWebOAuthResult(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req service.PollGoogleWebOAuthResultRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, err.Error()) return } data, code, err := h.connectorService.PollGoogleWebOAuthResult(user.ID, c.Query("type"), &req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": data, - "message": "success", - }) + common.SuccessWithData(c, data, "success") } func (h *ConnectorHandler) GoogleWebOAuthCallback(c *gin.Context) { @@ -511,20 +436,20 @@ func (h *ConnectorHandler) googleWebOAuthCallback(c *gin.Context, source string) func (h *ConnectorHandler) StartBoxWebOAuth(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req service.StartBoxWebOAuthRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeBadRequest, err.Error()) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } resp, code, err := h.connectorService.StartBoxWebOAuth(user.ID, &req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, code, resp, "success") + common.ResponseWithCodeData(c, code, resp, "success") } func (h *ConnectorHandler) BoxWebOAuthCallback(c *gin.Context) { @@ -541,18 +466,18 @@ func (h *ConnectorHandler) BoxWebOAuthCallback(c *gin.Context) { func (h *ConnectorHandler) PollBoxWebOAuthResult(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req service.PollBoxWebOAuthResultRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeBadRequest, err.Error()) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } resp, code, err := h.connectorService.PollBoxWebOAuthResult(user.ID, &req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, code, resp, "success") + common.ResponseWithCodeData(c, code, resp, "success") } diff --git a/internal/handler/dataset.go b/internal/handler/dataset.go index 009989272e..ed376ad554 100644 --- a/internal/handler/dataset.go +++ b/internal/handler/dataset.go @@ -40,24 +40,6 @@ type DatasetsHandler struct { searchDatasetService searchDatasetService } -// jsonResponse sends a JSON response with code and message -func jsonResponse(c *gin.Context, code common.ErrorCode, data interface{}, message string) { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "data": data, - "message": message, - }) -} - -// jsonError sends a JSON error response -func jsonError(c *gin.Context, code common.ErrorCode, message string) { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "data": nil, - "message": message, - }) -} - type searchDatasetsService interface { SearchDatasets(req *service.SearchDatasetsRequest, userID string) (*service.SearchDatasetsResponse, error) } @@ -89,7 +71,7 @@ func NewDatasetsHandler(datasetsService *service.DatasetService, metadataService func (h *DatasetsHandler) ListDatasets(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -125,7 +107,7 @@ func (h *DatasetsHandler) ListDatasets(c *gin.Context) { if extStr := c.Query("ext"); extStr != "" { var ext listDatasetsExt if err := json.Unmarshal([]byte(extStr), &ext); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } keywords = ext.Keywords @@ -146,7 +128,7 @@ func (h *DatasetsHandler) ListDatasets(c *gin.Context) { user.ID, ) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } @@ -161,160 +143,145 @@ func (h *DatasetsHandler) ListDatasets(c *gin.Context) { func (h *DatasetsHandler) CreateDataset(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req service.CreateDatasetRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } result, code, err := h.datasetsService.CreateDataset(&req, user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - }) + common.SuccessNoMessage(c, result) } // GetDataset handles GET /api/v1/datasets/:dataset_id. func (h *DatasetsHandler) GetDataset(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := c.Param("dataset_id") result, code, err := h.datasetsService.GetDataset(datasetID, user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - }) + common.SuccessNoMessage(c, result) } // UpdateDataset Update a dataset. func (h *DatasetsHandler) UpdateDataset(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeDataError, "user id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "user id is required") return } datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - jsonError(c, common.CodeBadRequest, "dataset id is required") + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "dataset id is required") return } var req service.UpdateDatasetRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } result, code, err := h.datasetsService.UpdateDataset(datasetID, userID, req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } if code != common.CodeSuccess { - jsonError(c, code, "dataset updated failed") + common.ResponseWithCodeData(c, code, nil, "dataset updated failed") return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - }) + common.SuccessNoMessage(c, result) } func (h *DatasetsHandler) GetMetadataConfig(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := c.Param("dataset_id") result, code, err := h.datasetsService.GetMetadataConfig(datasetID, user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - }) + common.SuccessNoMessage(c, result) } func (h *DatasetsHandler) UpdateMetadataConfig(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := c.Param("dataset_id") var req service.MetadataConfigRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } result, code, err := h.datasetsService.UpdateMetadataConfig(datasetID, user.ID, &req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - }) + common.SuccessNoMessage(c, result) } // GetIngestionSummary handles GET /api/v1/datasets/:dataset_id/ingestions/summary. func (h *DatasetsHandler) GetIngestionSummary(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := c.Param("dataset_id") result, code, err := h.datasetsService.GetIngestionSummary(datasetID, user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // ListIngestionLogs handles GET /api/v1/datasets/:dataset_id/ingestions. func (h *DatasetsHandler) ListIngestionLogs(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -324,7 +291,8 @@ func (h *DatasetsHandler) ListIngestionLogs(c *gin.Context) { if pageStr := c.Query("page"); pageStr != "" { p, err := strconv.Atoi(pageStr) if err != nil { - jsonError(c, common.CodeArgumentError, "page must be an integer") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "page must be an integer") return } page = p @@ -334,7 +302,8 @@ func (h *DatasetsHandler) ListIngestionLogs(c *gin.Context) { if pageSizeStr := c.Query("page_size"); pageSizeStr != "" { ps, err := strconv.Atoi(pageSizeStr) if err != nil { - jsonError(c, common.CodeArgumentError, "page_size must be an integer") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "page_size must be an integer") return } pageSize = ps @@ -351,18 +320,18 @@ func (h *DatasetsHandler) ListIngestionLogs(c *gin.Context) { result, code, err := h.datasetsService.ListIngestionLogs(datasetID, user.ID, page, pageSize, orderby, desc, operationStatus, createDateFrom, createDateTo, logType, keywords) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // GetIngestionLog handles GET /api/v1/datasets/:dataset_id/ingestions/:log_id. func (h *DatasetsHandler) GetIngestionLog(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -370,18 +339,18 @@ func (h *DatasetsHandler) GetIngestionLog(c *gin.Context) { logID := c.Param("log_id") result, code, err := h.datasetsService.GetIngestionLog(datasetID, user.ID, logID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // DeleteDatasets handles DELETE /api/v1/datasets. func (h *DatasetsHandler) DeleteDatasets(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -391,7 +360,7 @@ func (h *DatasetsHandler) DeleteDatasets(c *gin.Context) { } if c.Request.ContentLength > 0 { if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } } @@ -403,45 +372,42 @@ func (h *DatasetsHandler) DeleteDatasets(c *gin.Context) { result, code, err := h.datasetsService.DeleteDatasets(ids, req.DeleteAll, user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - }) + common.SuccessNoMessage(c, result) } // GetKnowledgeGraph handles GET /api/v1/datasets/:dataset_id/graph. func (h *DatasetsHandler) GetKnowledgeGraph(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - jsonError(c, common.CodeDataError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset_id is required") return } dataset, code, err := h.datasetsService.GetDataset(datasetID, user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } tenantID, _ := dataset["tenant_id"].(string) if tenantID == "" { - jsonError(c, common.CodeDataError, "tenant_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "tenant_id is required") return } docEngine := engine.Get() if docEngine == nil { - jsonError(c, common.CodeServerError, "Document engine is not initialized") + common.ResponseWithCodeData(c, common.CodeServerError, nil, "Document engine is not initialized") return } @@ -457,7 +423,7 @@ func (h *DatasetsHandler) GetKnowledgeGraph(c *gin.Context) { "mind_map": map[string]interface{}{}, } if !exists { - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") return } @@ -477,7 +443,7 @@ func (h *DatasetsHandler) GetKnowledgeGraph(c *gin.Context) { return } if searchResult == nil || len(searchResult.Chunks) == 0 { - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") return } @@ -485,17 +451,17 @@ func (h *DatasetsHandler) GetKnowledgeGraph(c *gin.Context) { graphType := firstStringValue(chunk["knowledge_graph_kwd"]) contentWithWeight, _ := chunk["content_with_weight"].(string) if strings.TrimSpace(contentWithWeight) == "" { - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") return } var graphData map[string]interface{} if err := json.Unmarshal([]byte(contentWithWeight), &graphData); err != nil { - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") return } if len(graphData) == 0 { - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") return } @@ -509,7 +475,7 @@ func (h *DatasetsHandler) GetKnowledgeGraph(c *gin.Context) { result[graphType] = graphData } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // ListTags handles GET /api/v1/datasets/:dataset_id/tags. @@ -524,18 +490,18 @@ func (h *DatasetsHandler) GetKnowledgeGraph(c *gin.Context) { func (h *DatasetsHandler) ListTags(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := strings.TrimSpace(c.Param("dataset_id")) result, code, err := h.datasetsService.ListTags(datasetID, user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } type renameTagRequest struct { @@ -546,72 +512,72 @@ type renameTagRequest struct { func (h *DatasetsHandler) RenameTag(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := strings.TrimSpace(c.Param("dataset_id")) var payload map[string]interface{} if err := c.ShouldBindJSON(&payload); err != nil { - jsonError(c, common.CodeDataError, "Lack of from_tag or to_tag in request body") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Lack of from_tag or to_tag in request body") return } fromTagValue, hasFrom := payload["from_tag"] toTagValue, hasTo := payload["to_tag"] if !hasFrom || !hasTo { - jsonError(c, common.CodeDataError, "Lack of from_tag or to_tag in request body") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Lack of from_tag or to_tag in request body") return } fromTag, okFrom := fromTagValue.(string) toTag, okTo := toTagValue.(string) if !okFrom || !okTo { - jsonError(c, common.CodeArgumentError, "from_tag and to_tag must be strings") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "from_tag and to_tag must be strings") return } req := renameTagRequest{FromTag: fromTag, ToTag: toTag} if strings.TrimSpace(req.FromTag) == "" || strings.TrimSpace(req.ToTag) == "" { - jsonError(c, common.CodeArgumentError, "from_tag and to_tag must not be empty") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "from_tag and to_tag must not be empty") return } result, code, err := h.datasetsService.RenameTag(datasetID, user.ID, req.FromTag, req.ToTag) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // DeleteKnowledgeGraph handles DELETE /api/v1/datasets/:dataset_id/graph. func (h *DatasetsHandler) DeleteKnowledgeGraph(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - jsonError(c, common.CodeDataError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset_id is required") return } dataset, code, err := h.datasetsService.GetDataset(datasetID, user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } tenantID, _ := dataset["tenant_id"].(string) if tenantID == "" { - jsonError(c, common.CodeDataError, "tenant_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "tenant_id is required") return } docEngine := engine.Get() if docEngine == nil { - jsonError(c, common.CodeServerError, "Document engine is not initialized") + common.ResponseWithCodeData(c, common.CodeServerError, nil, "Document engine is not initialized") return } @@ -624,7 +590,7 @@ func (h *DatasetsHandler) DeleteKnowledgeGraph(c *gin.Context) { return } - jsonResponse(c, common.CodeSuccess, true, "success") + common.SuccessWithData(c, true, "success") } // RemoveTags handles DELETE /api/v1/datasets/:dataset_id/tags. @@ -641,25 +607,25 @@ func (h *DatasetsHandler) DeleteKnowledgeGraph(c *gin.Context) { func (h *DatasetsHandler) RemoveTags(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - jsonError(c, common.CodeDataError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset_id is required") return } dataset, code, err := h.datasetsService.GetDataset(datasetID, user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } tenantID, _ := dataset["tenant_id"].(string) if tenantID == "" { - jsonError(c, common.CodeDataError, "tenant_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "tenant_id is required") return } @@ -667,14 +633,14 @@ func (h *DatasetsHandler) RemoveTags(c *gin.Context) { Tags []string `json:"tags" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } indexName := fmt.Sprintf("ragflow_%s", tenantID) docEngine := engine.Get() if docEngine == nil { - jsonError(c, common.CodeServerError, "Document engine is not initialized") + common.ResponseWithCodeData(c, common.CodeServerError, nil, "Document engine is not initialized") return } @@ -689,41 +655,41 @@ func (h *DatasetsHandler) RemoveTags(c *gin.Context) { }, } if err := docEngine.UpdateChunks(c.Request.Context(), condition, newValue, indexName, datasetID); err != nil { - jsonError(c, common.CodeServerError, "Failed to remove tag: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, "Failed to remove tag: "+err.Error()) return } } - jsonResponse(c, common.CodeSuccess, true, "success") + common.SuccessWithData(c, true, "success") } // RunEmbedding Run embedding for all documents in a dataset. func (h *DatasetsHandler) RunEmbedding(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeAuthenticationError, "user_id is required") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "user_id is required") return } datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - jsonError(c, common.CodeDataError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset_id is required") return } result, errorCode, err := h.datasetsService.RunEmbedding(userID, datasetID) if err != nil { - jsonError(c, errorCode, err.Error()) + common.ResponseWithCodeData(c, errorCode, nil, err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // CheckEmbedding Check embedding model compatibility by sampling random chunks, @@ -731,42 +697,42 @@ func (h *DatasetsHandler) RunEmbedding(c *gin.Context) { func (h *DatasetsHandler) CheckEmbedding(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - jsonError(c, common.CodeDataError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset_id is required") return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeDataError, "user_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "user_id is required") return } var req service.CheckEmbeddingRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } if strings.TrimSpace(req.EmbeddingID) == "" { - jsonError(c, common.CodeDataError, "`embd_id` is required.") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "`embd_id` is required.") return } data, code, err := h.datasetsService.CheckEmbedding(userID, datasetID, &req) if err != nil { if code == common.CodeNotEffective { - jsonResponse(c, code, data, err.Error()) + common.ResponseWithCodeData(c, code, data, err.Error()) return } - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, data, "success") + common.SuccessWithData(c, data, "success") } // AggregateTags handles GET /api/v1/datasets/tags/aggregation. @@ -781,7 +747,7 @@ func (h *DatasetsHandler) CheckEmbedding(c *gin.Context) { func (h *DatasetsHandler) AggregateTags(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -795,103 +761,99 @@ func (h *DatasetsHandler) AggregateTags(c *gin.Context) { } } if len(datasetIDs) == 0 { - jsonError(c, common.CodeDataError, "Lack of dataset_ids in query parameters") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Lack of dataset_ids in query parameters") return } result, code, err := h.datasetsService.AggregateTags(datasetIDs, user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // RunIndex Run an indexing task (graph/raptor/mindmap) for a dataset. func (h *DatasetsHandler) RunIndex(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - jsonError(c, common.CodeDataError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset_id is required") return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeDataError, "user_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "user_id is required") return } indexType := strings.ToLower(strings.TrimSpace(c.Query("type"))) data, code, err := h.datasetsService.RunIndex(userID, datasetID, indexType) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, data, "success") + common.SuccessWithData(c, data, "success") } // TraceIndex Trace an indexing task (graph/raptor/mindmap) for a dataset. func (h *DatasetsHandler) TraceIndex(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - jsonError(c, common.CodeDataError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset_id is required") return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeDataError, "user_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "user_id is required") return } indexType := strings.ToLower(strings.TrimSpace(c.Query("type"))) result, code, err := h.datasetsService.TraceIndex(datasetID, userID, indexType) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } if result == nil { - jsonResponse(c, common.CodeSuccess, map[string]interface{}{}, "success") + common.SuccessWithData(c, map[string]interface{}{}, "success") return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } // DeleteIndex Delete an indexing task (graph/raptor/mindmap) for a dataset. func (h *DatasetsHandler) DeleteIndex(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - jsonError(c, common.CodeDataError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset_id is required") return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeDataError, "user_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "user_id is required") return } @@ -909,11 +871,11 @@ func (h *DatasetsHandler) DeleteIndex(c *gin.Context) { code, err := h.datasetsService.DeleteIndex(userID, datasetID, indexType, wipe) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, map[string]interface{}{}, "success") + common.SuccessWithData(c, map[string]interface{}{}, "success") } // ListMetadataFlattened handles GET /api/v1/datasets/metadata/flattened. @@ -928,13 +890,13 @@ func (h *DatasetsHandler) DeleteIndex(c *gin.Context) { func (h *DatasetsHandler) ListMetadataFlattened(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetIDsStr := c.Query("dataset_ids") if datasetIDsStr == "" { - jsonError(c, common.CodeDataError, "dataset_ids is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset_ids is required") return } @@ -947,67 +909,63 @@ func (h *DatasetsHandler) ListMetadataFlattened(c *gin.Context) { } } if len(datasetIDs) == 0 { - jsonError(c, common.CodeDataError, "dataset_ids is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset_ids is required") return } // Check access for each dataset for _, datasetID := range datasetIDs { if !h.datasetsService.Accessible(datasetID, user.ID) { - jsonError(c, common.CodeAuthenticationError, "No authorization for dataset: "+datasetID) + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "No authorization for dataset: "+datasetID) return } } flattenedMeta, err := h.metadataService.GetFlattedMetaByKBs(datasetIDs) if err != nil { - jsonError(c, common.CodeServerError, "Failed to get metadata: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, "Failed to get metadata: "+err.Error()) return } - jsonResponse(c, common.CodeSuccess, flattenedMeta, "success") + common.SuccessWithData(c, flattenedMeta, "success") } func (h *DatasetsHandler) UpdateDocumentMetadataConfig(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - jsonError(c, common.CodeArgumentError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "dataset_id is required") return } documentID := strings.TrimSpace(c.Param("document_id")) if documentID == "" { - jsonError(c, common.CodeArgumentError, "document_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "document_id is required") return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeArgumentError, "user_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "user_id is required") return } var req map[string]interface{} if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } data, code, err := h.datasetsService.UpdateDocumentMetadataConfig(userID, datasetID, documentID, req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": code, - "data": data, - "message": "success", - }) + common.ResponseWithCodeData(c, code, data, "success") } // SearchDatasets searches chunks across datasets based on a question @@ -1022,13 +980,13 @@ func (h *DatasetsHandler) UpdateDocumentMetadataConfig(c *gin.Context) { func (h *DatasetsHandler) SearchDatasets(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req service.SearchDatasetsRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } @@ -1051,20 +1009,20 @@ func (h *DatasetsHandler) SearchDatasets(c *gin.Context) { req.Question = strings.TrimSpace(req.Question) if req.Question == "" { - jsonError(c, common.CodeArgumentError, "question is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "question is required") return } if req.DatasetIDs == nil { - jsonError(c, common.CodeArgumentError, "kb_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "kb_id is required") return } if len(req.DatasetIDs) == 0 { - jsonError(c, common.CodeArgumentError, "kb_id array cannot be empty") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "kb_id array cannot be empty") return } if err := validateSearchDatasetsRequest(&req); err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } @@ -1073,20 +1031,17 @@ func (h *DatasetsHandler) SearchDatasets(c *gin.Context) { searchService = h.datasetsService } if searchService == nil { - jsonError(c, common.CodeDataError, "dataset service is not initialized") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset service is not initialized") return } resp, err := searchService.SearchDatasets(&req, user.ID) if err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": resp, - }) + common.SuccessNoMessage(c, resp) } // SearchDataset searches chunks within a single dataset based on a question. @@ -1102,28 +1057,28 @@ func (h *DatasetsHandler) SearchDatasets(c *gin.Context) { func (h *DatasetsHandler) SearchDataset(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := c.Param("dataset_id") if datasetID == "" { - jsonError(c, common.CodeDataError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset_id is required") return } var req service.SearchDatasetRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } req.Question = strings.TrimSpace(req.Question) if req.Question == "" { - jsonError(c, common.CodeArgumentError, "question is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "question is required") return } if err := validateSearchDatasetRequest(&req); err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } @@ -1132,20 +1087,17 @@ func (h *DatasetsHandler) SearchDataset(c *gin.Context) { searchService = h.datasetsService } if searchService == nil { - jsonError(c, common.CodeDataError, "dataset service is not initialized") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "dataset service is not initialized") return } resp, err := searchService.SearchDataset(datasetID, user.ID, &req) if err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": resp, - }) + common.SuccessNoMessage(c, resp) } func validateSearchDatasetsRequest(req *service.SearchDatasetsRequest) error { diff --git a/internal/handler/dify_retrieval_handler.go b/internal/handler/dify_retrieval_handler.go index 2047c3d1e5..4f7a0c7843 100644 --- a/internal/handler/dify_retrieval_handler.go +++ b/internal/handler/dify_retrieval_handler.go @@ -24,8 +24,6 @@ import ( "strconv" "strings" - "go.uber.org/zap" - "gorm.io/gorm" "ragflow/internal/common" "ragflow/internal/engine" "ragflow/internal/entity" @@ -34,6 +32,9 @@ import ( "ragflow/internal/service/graph" "ragflow/internal/service/nlp" + "go.uber.org/zap" + "gorm.io/gorm" + "github.com/gin-gonic/gin" ) @@ -162,14 +163,14 @@ func NewDifyRetrievalHandler( func (h *DifyRetrievalHandler) Retrieval(c *gin.Context) { user, errCode, errMsg := GetUser(c) if errCode != common.CodeSuccess { - c.JSON(http.StatusUnauthorized, gin.H{"code": errCode, "message": errMsg}) + common.ResponseWithHttpCodeData(c, http.StatusUnauthorized, errCode, nil, errMsg) return } var req difyRetrievalRequest if c.Request.Method == http.MethodGet { if err := c.ShouldBindQuery(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeArgumentError, "message": "invalid query parameters"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "invalid query parameters") return } // Manually extract top_k and score_threshold from query (flat params, not nested) @@ -191,28 +192,28 @@ func (h *DifyRetrievalHandler) Retrieval(c *gin.Context) { } } else { if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeArgumentError, "message": "invalid request body"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "invalid request body") return } } if req.KnowledgeID == "" || req.Query == "" { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeArgumentError, "message": "knowledge_id and query are required"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "knowledge_id and query are required") return } kb, err := h.kbSvc.GetByID(req.KnowledgeID) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - c.JSON(http.StatusNotFound, gin.H{"code": common.CodeNotFound, "message": "Knowledgebase not found!"}) + common.ResponseWithHttpCodeData(c, http.StatusNotFound, common.CodeNotFound, nil, "Knowledge base not found!") } else { - c.JSON(http.StatusInternalServerError, gin.H{"code": common.CodeServerError, "message": "failed to query knowledgebase"}) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeServerError, nil, "failed to query knowledge base") } return } if !h.kbSvc.Accessible(req.KnowledgeID, user.ID) { - c.JSON(http.StatusUnauthorized, gin.H{"code": common.CodeAuthenticationError, "message": "No authorization."}) + common.ResponseWithHttpCodeData(c, http.StatusUnauthorized, common.CodeAuthenticationError, nil, "No authorization") return } @@ -233,7 +234,7 @@ func (h *DifyRetrievalHandler) Retrieval(c *gin.Context) { // Get embedding model embModel, err := h.modelSvc.GetEmbeddingModel(kb.TenantID, kb.EmbdID) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"code": common.CodeServerError, "message": fmt.Sprintf("failed to get embedding model: %v", err)}) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeServerError, nil, fmt.Sprintf("failed to get embedding model: %v", err)) return } @@ -275,10 +276,10 @@ func (h *DifyRetrievalHandler) Retrieval(c *gin.Context) { result, err := h.retrievalSvc.Retrieval(c.Request.Context(), sr) if err != nil { if strings.Contains(err.Error(), "not_found") { - c.JSON(http.StatusNotFound, gin.H{"code": common.CodeNotFound, "message": "No chunk found! Check the chunk status please!"}) + common.ResponseWithHttpCodeData(c, http.StatusNotFound, common.CodeNotFound, nil, "No chunk found! Check the chunk status please!") return } - c.JSON(http.StatusInternalServerError, gin.H{"code": common.CodeServerError, "message": err.Error()}) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeServerError, nil, err.Error()) return } @@ -321,9 +322,10 @@ func (h *DifyRetrievalHandler) Retrieval(c *gin.Context) { docMap := make(map[string]*entity.Document) if len(allDocIDs) > 0 { - docs, err := h.docDAO.GetByIDs(allDocIDs) + var docs []*entity.Document + docs, err = h.docDAO.GetByIDs(allDocIDs) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"code": common.CodeServerError, "message": fmt.Sprintf("failed to load documents: %v", err)}) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeServerError, nil, fmt.Sprintf("failed to load documents: %v", err)) return } for _, d := range docs { @@ -367,7 +369,7 @@ func (h *DifyRetrievalHandler) Retrieval(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"records": records}) } -// HealthCheck returns a simple health check response. +// HealthCheck Health check returns a simple health check response. func (h *DifyRetrievalHandler) HealthCheck(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{"code": 0, "data": true}) + common.SuccessNoMessage(c, true) } diff --git a/internal/handler/document.go b/internal/handler/document.go index e7d9a32cce..2ccec89a42 100644 --- a/internal/handler/document.go +++ b/internal/handler/document.go @@ -109,7 +109,7 @@ func NewDocumentHandler(documentService documentServiceIface, datasetService *se func (h *DocumentHandler) CreateDocument(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -129,10 +129,7 @@ func (h *DocumentHandler) CreateDocument(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "message": "created successfully", - "data": document, - }) + common.SuccessWithData(c, document, "created successfully") } // GetDocumentByID get document by ID @@ -147,7 +144,7 @@ func (h *DocumentHandler) CreateDocument(c *gin.Context) { func (h *DocumentHandler) GetDocumentByID(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -176,27 +173,23 @@ func (h *DocumentHandler) GetDocumentByID(c *gin.Context) { func (h *DocumentHandler) GetThumbnail(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } docIDs := parseThumbnailDocIDs(c) if len(docIDs) == 0 { - jsonError(c, common.CodeArgumentError, `Lack of "Document ID"`) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, `Lack of "Document ID"`) return } result, err := h.documentService.GetThumbnails(user.ID, docIDs) if err != nil { - jsonError(c, common.CodeServerError, err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } func parseThumbnailDocIDs(c *gin.Context) []string { @@ -224,7 +217,7 @@ func (h *DocumentHandler) GetDocumentImage(c *gin.Context) { imageID := c.Param("image_id") data, err := h.documentService.GetDocumentImage(imageID) if err != nil { - jsonError(c, common.CodeDataError, "Image not found.") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Image not found.") return } @@ -255,7 +248,7 @@ func documentImageContentType(imageID string, data []byte) string { func (h *DocumentHandler) GetDocumentArtifact(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } filename := c.Param("filename") @@ -265,16 +258,10 @@ func (h *DocumentHandler) GetDocumentArtifact(c *gin.Context) { case errors.Is(err, service.ErrArtifactInvalidFilename), errors.Is(err, service.ErrArtifactInvalidFileType), errors.Is(err, service.ErrArtifactNotFound): - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeDataError), err.Error()) + default: - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeExceptionError, - "data": nil, - "message": err.Error(), - }) + common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error()) } return } @@ -293,16 +280,13 @@ func (h *DocumentHandler) GetDocumentPreview(c *gin.Context) { docID := c.Param("id") if docID == "" { - jsonError(c, common.CodeParamError, "id is required") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "id is required") return } preview, err := h.documentService.GetDocumentPreview(docID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "message": "Document not found!", - }) + common.ErrorWithCode(c, int(common.CodeDataError), "Document not found!") return } @@ -330,7 +314,7 @@ func (h *DocumentHandler) GetDocumentPreview(c *gin.Context) { func (h *DocumentHandler) UpdateDocument(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -344,35 +328,30 @@ func (h *DocumentHandler) UpdateDocument(c *gin.Context) { doc, err := h.documentService.GetDocumentByID(id) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": "document not found", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "document not found!") return } if !h.datasetService.Accessible(doc.KbID, user.ID) { - jsonError(c, common.CodeAuthenticationError, "No authorization.") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "No authorization.") return } var req service.UpdateDocumentRequest - if err := c.ShouldBindJSON(&req); err != nil { + if err = c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) return } - if err := h.documentService.UpdateDocument(id, &req); err != nil { + if err = h.documentService.UpdateDocument(id, &req); err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": err.Error(), }) return } - c.JSON(http.StatusOK, gin.H{ - "message": "updated successfully", - }) + common.SuccessWithMessage(c, "updated successfully") } // DeleteDocument delete document @@ -387,7 +366,7 @@ func (h *DocumentHandler) UpdateDocument(c *gin.Context) { func (h *DocumentHandler) DeleteDocument(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -401,18 +380,15 @@ func (h *DocumentHandler) DeleteDocument(c *gin.Context) { doc, err := h.documentService.GetDocumentByID(id) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": "document not found", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "document not found!") return } if !h.datasetService.Accessible(doc.KbID, user.ID) { - jsonError(c, common.CodeAuthenticationError, "No authorization.") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "No authorization.") return } - if err := h.documentService.DeleteDocument(id); err != nil { + if err = h.documentService.DeleteDocument(id); err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": err.Error(), }) @@ -428,13 +404,13 @@ func (h *DocumentHandler) DeleteDocument(c *gin.Context) { func (h *DocumentHandler) DeleteDocuments(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := c.Param("dataset_id") if datasetID == "" { - jsonError(c, common.CodeArgumentError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "dataset_id is required") return } @@ -444,7 +420,7 @@ func (h *DocumentHandler) DeleteDocuments(c *gin.Context) { } if c.Request.ContentLength > 0 { if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } } @@ -454,41 +430,41 @@ func (h *DocumentHandler) DeleteDocuments(c *gin.Context) { ids = *req.IDs } if len(ids) > 0 && req.DeleteAll { - jsonError(c, common.CodeArgumentError, "should not provide both ids and delete_all") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "should not provide both ids and delete_all") return } if len(ids) == 0 && !req.DeleteAll { - jsonError(c, common.CodeArgumentError, "should either provide doc ids or set delete_all(true)") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "should either provide doc ids or set delete_all(true)") return } userID := c.GetString("user_id") deleted, err := h.documentService.DeleteDocuments(ids, req.DeleteAll, datasetID, userID) if err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } - jsonResponse(c, common.CodeSuccess, map[string]interface{}{"deleted": deleted}, "success") + common.SuccessWithData(c, map[string]interface{}{"deleted": deleted}, "success") } // BatchUpdateDocumentStatus Batch update status of documents within a dataset. func (h *DocumentHandler) BatchUpdateDocumentStatus(c *gin.Context) { user, code, errorMessage := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, errorMessage) + common.ResponseWithCodeData(c, code, nil, errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeArgumentError, "invalid user id") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "invalid user id") return } datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - jsonError(c, common.CodeArgumentError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "dataset_id is required") return } @@ -497,19 +473,20 @@ func (h *DocumentHandler) BatchUpdateDocumentStatus(c *gin.Context) { Status interface{} `json:"status"` } if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } if req.DocumentIDs == nil || len(req.DocumentIDs) == 0 { - jsonError(c, common.CodeArgumentError, `"doc_ids" must be a non-empty list.`) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, `"doc_ids" must be a non-empty list.`) return } documentIDs := make([]string, 0, len(req.DocumentIDs)) for _, rawDocID := range req.DocumentIDs { docID, ok := rawDocID.(string) if !ok || strings.TrimSpace(docID) == "" { - jsonError(c, common.CodeArgumentError, `"doc_ids" must contain non-empty document IDs.`) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + `"doc_ids" must contain non-empty document IDs.`) return } documentIDs = append(documentIDs, docID) @@ -520,7 +497,7 @@ func (h *DocumentHandler) BatchUpdateDocumentStatus(c *gin.Context) { status = fmt.Sprint(req.Status) } if status != "0" && status != "1" { - jsonError(c, common.CodeArgumentError, fmt.Sprintf(`"Status" must be either 0 or 1:%s!`, status)) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, fmt.Sprintf(`"Status" must be either 0 or 1:%s!`, status)) return } @@ -530,19 +507,11 @@ func (h *DocumentHandler) BatchUpdateDocumentStatus(c *gin.Context) { if code == common.CodeServerError { message = "Partial failure" } - c.JSON(http.StatusOK, gin.H{ - "code": code, - "data": result, - "message": message, - }) + common.ResponseWithCodeData(c, code, result, message) return } - c.JSON(http.StatusOK, gin.H{ - "code": code, - "data": result, - "message": "success", - }) + common.ResponseWithCodeData(c, code, result, "success") } // ListDocuments document list @@ -557,7 +526,7 @@ func (h *DocumentHandler) ListDocuments(c *gin.Context) { userID := c.GetString("user_id") if !h.datasetService.Accessible(datasetID, userID) { - jsonError(c, common.CodeAuthenticationError, "No authorization to access the dataset.") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "No authorization to access the dataset.") return } @@ -570,52 +539,29 @@ func (h *DocumentHandler) ListDocuments(c *gin.Context) { opts, errMsg := parseDocumentListOptions(c, datasetID) if errMsg != "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "message": errMsg, - "data": map[string]interface{}{"total": 0, "docs": []interface{}{}}, - }) + common.ResponseWithCodeData(c, common.CodeDataError, map[string]interface{}{"total": 0, "docs": []interface{}{}}, errMsg) return } opts, errMsg = h.applyDocumentMetadataFilter(c, opts) if errMsg != "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "message": errMsg, - "data": map[string]interface{}{"total": 0, "docs": []interface{}{}}, - }) + common.ResponseWithCodeData(c, common.CodeDataError, map[string]interface{}{"total": 0, "docs": []interface{}{}}, errMsg) return } if c.Query("type") == "filter" { filters, total, err := h.documentService.GetDocumentFiltersByDatasetID(opts) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeExceptionError, - "message": "failed to get document filters", - "data": map[string]interface{}{"total": 0, "filter": map[string]interface{}{}}, - }) + common.ResponseWithCodeData(c, common.CodeExceptionError, map[string]interface{}{"total": 0, "filter": map[string]interface{}{}}, "failed to get document filters") return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": gin.H{ - "total": total, - "filter": filters, - }, - }) + common.SuccessWithData(c, gin.H{"total": total, "filter": filters}, "success") return } // Use kbID to filter documents documents, total, err := h.documentService.ListDocumentsByDatasetIDWithOptions(opts, page, pageSize) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": 1, - "message": "failed to get documents", - "data": map[string]interface{}{"total": 0, "docs": []interface{}{}}, - }) + common.ResponseWithCodeData(c, 1, map[string]interface{}{"total": 0, "docs": []interface{}{}}, "failed to get documents") return } @@ -629,14 +575,7 @@ func (h *DocumentHandler) ListDocuments(c *gin.Context) { docs = append(docs, mapDocumentListItem(doc, metaFields)) } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": gin.H{ - "total": total, - "docs": docs, - }, - }) + common.SuccessWithData(c, gin.H{"total": total, "docs": docs}, "success") } func parseDocumentListOptions(c *gin.Context, datasetID string) (dao.DocumentListOptions, string) { @@ -893,7 +832,7 @@ func normalizeRunStatusFilter(statuses []string) []string { func (h *DocumentHandler) UploadDocuments(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } tenantID := user.ID @@ -902,11 +841,11 @@ func (h *DocumentHandler) UploadDocuments(c *gin.Context) { kb, err := h.datasetService.GetKnowledgebaseByID(datasetID) if err != nil || kb == nil { - jsonError(c, common.CodeDataError, fmt.Sprintf("Can't find the dataset with ID %s!", datasetID)) + common.ResponseWithCodeData(c, common.CodeDataError, nil, fmt.Sprintf("Can't find the dataset with ID %s!", datasetID)) return } if !h.datasetService.CheckKBTeamPermission(kb, tenantID) { - jsonError(c, common.CodeAuthenticationError, "No authorization.") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "No authorization.") return } @@ -918,24 +857,26 @@ func (h *DocumentHandler) UploadDocuments(c *gin.Context) { case "local": h.uploadLocalDocuments(c, kb, tenantID) default: - jsonError(c, common.CodeArgumentError, `"type" must be one of "local", "web", or "empty".`) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, `"type" must be one of "local", "web", or "empty".`) } } func (h *DocumentHandler) uploadLocalDocuments(c *gin.Context, kb *entity.Knowledgebase, tenantID string) { form, err := c.MultipartForm() if err != nil || form == nil || len(form.File["file"]) == 0 { - jsonError(c, common.CodeArgumentError, "No file part!") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "No file part!") return } files := form.File["file"] for _, fh := range files { if fh == nil || fh.Filename == "" { - jsonError(c, common.CodeArgumentError, "No file selected!") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "No file selected!") return } if len([]byte(fh.Filename)) > 255 { - jsonError(c, common.CodeArgumentError, "File name must be 255 bytes or less.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "File name must be 255 bytes or less.") return } } @@ -946,7 +887,7 @@ func (h *DocumentHandler) uploadLocalDocuments(c *gin.Context, kb *entity.Knowle var override map[string]interface{} if raw := strings.TrimSpace(c.PostForm("parser_config")); raw != "" { var parsed map[string]interface{} - if err := json.Unmarshal([]byte(raw), &parsed); err == nil && parsed != nil { + if err = json.Unmarshal([]byte(raw), &parsed); err == nil && parsed != nil { override = map[string]interface{}{} for _, k := range []string{"table_column_mode", "table_column_roles"} { if v, ok := parsed[k]; ok { @@ -961,20 +902,20 @@ func (h *DocumentHandler) uploadLocalDocuments(c *gin.Context, kb *entity.Knowle data, errMsgs := h.documentService.UploadLocalDocuments(kb, tenantID, files, c.PostForm("parent_path"), override) if len(data) == 0 && len(errMsgs) > 0 { - jsonError(c, common.CodeServerError, strings.Join(errMsgs, "\n")) + common.ResponseWithCodeData(c, common.CodeServerError, nil, strings.Join(errMsgs, "\n")) return } if len(data) == 0 { - jsonError(c, common.CodeDataError, "There seems to be an issue with your file format. please verify it is correct and not corrupted.") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "There seems to be an issue with your file format. please verify it is correct and not corrupted.") return } if strings.ToLower(c.DefaultQuery("return_raw_files", "false")) == "true" { if len(errMsgs) > 0 { - jsonSuccess(c, gin.H{"documents": data, "errors": errMsgs}) + common.SuccessNoMessage(c, gin.H{"documents": data, "errors": errMsgs}) return } - jsonSuccess(c, data) + common.SuccessNoMessage(c, data) return } mapped := make([]map[string]interface{}, len(data)) @@ -982,10 +923,10 @@ func (h *DocumentHandler) uploadLocalDocuments(c *gin.Context, kb *entity.Knowle mapped[i] = mapDocKeysWithRunStatus(d) } if len(errMsgs) > 0 { - jsonSuccess(c, gin.H{"documents": mapped, "errors": errMsgs}) + common.SuccessNoMessage(c, gin.H{"documents": mapped, "errors": errMsgs}) return } - jsonSuccess(c, mapped) + common.SuccessNoMessage(c, mapped) } func (h *DocumentHandler) uploadEmptyDocument(c *gin.Context, kb *entity.Knowledgebase, tenantID string) { @@ -996,60 +937,51 @@ func (h *DocumentHandler) uploadEmptyDocument(c *gin.Context, kb *entity.Knowled // a non-empty but malformed body should report the syntax error, not a // misleading "File name can't be empty." if err := c.ShouldBindJSON(&req); err != nil && !errors.Is(err, io.EOF) { - jsonError(c, common.CodeArgumentError, "Invalid JSON body: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid JSON body: "+err.Error()) return } name := strings.TrimSpace(req.Name) if name == "" { - jsonError(c, common.CodeArgumentError, "File name can't be empty.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "File name can't be empty.") return } if len([]byte(name)) > 255 { - jsonError(c, common.CodeArgumentError, "File name must be 255 bytes or less.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "File name must be 255 bytes or less.") return } data, code, err := h.documentService.UploadEmptyDocument(kb, tenantID, name) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonSuccess(c, mapDocKeysWithRunStatus(data)) + common.SuccessNoMessage(c, mapDocKeysWithRunStatus(data)) } func (h *DocumentHandler) uploadWebDocument(c *gin.Context, kb *entity.Knowledgebase, tenantID string) { name := strings.TrimSpace(c.PostForm("name")) rawURL := c.PostForm("url") if name == "" { - jsonError(c, common.CodeArgumentError, `Lack of "name"`) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, `Lack of "name"`) return } if rawURL == "" { - jsonError(c, common.CodeArgumentError, `Lack of "url"`) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, `Lack of "url"`) return } if len([]byte(name)) > 255 { - jsonError(c, common.CodeArgumentError, "File name must be 255 bytes or less.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "File name must be 255 bytes or less.") return } if !isValidHTTPURL(rawURL) { - jsonError(c, common.CodeArgumentError, "The URL format is invalid") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "The URL format is invalid") return } data, code, err := h.documentService.UploadWebDocument(kb, tenantID, name, rawURL) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonSuccess(c, mapDocKeysWithRunStatus(data)) -} - -// jsonSuccess writes the standard {code:0,message:"success",data} envelope. -func jsonSuccess(c *gin.Context, data interface{}) { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": data, - }) + common.SuccessNoMessage(c, mapDocKeysWithRunStatus(data)) } // mapDocKeysWithRunStatus renames a freshly-created document's raw keys to the @@ -1086,27 +1018,18 @@ func (h *DocumentHandler) DownloadDocument(c *gin.Context) { docID := c.Param("document_id") if docID == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "message": "Specify document_id please.", - }) + common.ErrorWithCode(c, int(common.CodeDataError), "Specify document_id please.") return } if datasetID == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "message": fmt.Sprintf("The dataset not own the document %s.", docID), - }) + common.ErrorWithCode(c, int(common.CodeDataError), fmt.Sprintf("The dataset not own the document %s.", docID)) return } res, err := h.documentService.DownloadDocument(datasetID, docID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeDataError), err.Error()) return } @@ -1217,7 +1140,7 @@ func stringValue(value *string) string { func (h *DocumentHandler) MetadataSummary(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -1227,38 +1150,23 @@ func (h *DocumentHandler) MetadataSummary(c *gin.Context) { } if err := c.ShouldBindJSON(&requestBody); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": "kb_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "kb_id is required") return } kbID := requestBody.KBID if kbID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": "kb_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "kb_id is required") return } summary, err := h.documentService.GetMetadataSummary(kbID, requestBody.DocIDs) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 1, - "message": "Failed to get metadata summary: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 1, nil, "Failed to get metadata summary: "+err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": gin.H{ - "summary": summary, - }, - }) + common.SuccessWithData(c, gin.H{"summary": summary}, "success") } // SetMetaRequest represents the request for setting document metadata @@ -1280,42 +1188,30 @@ type SetMetaRequest struct { func (h *DocumentHandler) SetMeta(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req SetMetaRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, err.Error()) return } if req.DocID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": "doc_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "doc_id is required") return } // Parse meta JSON string var meta map[string]interface{} if err := json.Unmarshal([]byte(req.Meta), &meta); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": "Json syntax error: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "Json syntax error: "+err.Error()) return } if meta == nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": "meta is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "meta is required") return } @@ -1327,20 +1223,14 @@ func (h *DocumentHandler) SetMeta(c *gin.Context) { case []interface{}: for _, item := range val { if _, ok := item.(string); !ok { - if _, ok := item.(float64); !ok { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": fmt.Sprintf("Unsupported type in list for key %s: %T", k, item), - }) + if _, ok = item.(float64); !ok { + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, fmt.Sprintf("Unsupported type in list for key %s: %T", k, item)) return } } } default: - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": fmt.Sprintf("Unsupported type for key %s: %T", k, v), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, fmt.Sprintf("Unsupported type for key %s: %T", k, v)) return } } @@ -1348,14 +1238,11 @@ func (h *DocumentHandler) SetMeta(c *gin.Context) { // Authorization: user must be able to access the document's dataset. doc, err := h.documentService.GetDocumentByID(req.DocID) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": "document not found", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "document not found") return } if !h.datasetService.Accessible(doc.KbID, user.ID) { - jsonError(c, common.CodeAuthenticationError, "No authorization.") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "No authorization.") return } @@ -1363,55 +1250,41 @@ func (h *DocumentHandler) SetMeta(c *gin.Context) { if err != nil { errMsg := err.Error() if strings.Contains(errMsg, "no such document") || strings.Contains(errMsg, "document not found") { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": errMsg, - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, errMsg) } else { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 1, - "message": "Failed to set metadata: " + errMsg, - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 1, nil, "Failed to set metadata: "+errMsg) } return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": true, - }) + common.SuccessWithData(c, true, "success") } func (h *DocumentHandler) Ingest(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeAuthenticationError, "No Authentication") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "No Authentication") return } var req service.IngestDocumentRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeBadRequest, err.Error()) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } if code, err := h.documentService.Ingest(userID, &req); err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": true, - }) + common.SuccessWithData(c, true, "success") } // DeleteMetaRequest represents the request for deleting document metadata @@ -1434,38 +1307,29 @@ type DeleteMetaRequest struct { func (h *DocumentHandler) DeleteMeta(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req DeleteMetaRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, err.Error()) return } if req.DocID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": "doc_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "doc_id is required") return } // Authorization: user must be able to access the document's dataset. doc, err := h.documentService.GetDocumentByID(req.DocID) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": "document not found", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "document not found") return } if !h.datasetService.Accessible(doc.KbID, user.ID) { - jsonError(c, common.CodeAuthenticationError, "No authorization.") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "No authorization.") return } @@ -1473,63 +1337,41 @@ func (h *DocumentHandler) DeleteMeta(c *gin.Context) { if req.Keys != "" { // Parse keys JSON string - expected to be a list of key names to delete var keys []string - if err := json.Unmarshal([]byte(req.Keys), &keys); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": "Json syntax error: " + err.Error(), - }) + if err = json.Unmarshal([]byte(req.Keys), &keys); err != nil { + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "Json syntax error: "+err.Error()) return } if keys == nil || len(keys) == 0 { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": "keys list is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "keys list is required") return } - err := h.documentService.DeleteDocumentMetadata(req.DocID, keys) + err = h.documentService.DeleteDocumentMetadata(req.DocID, keys) if err != nil { errMsg := err.Error() if strings.Contains(errMsg, "no such document") || strings.Contains(errMsg, "document not found") { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": errMsg, - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, errMsg) } else { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 1, - "message": "Failed to delete metadata: " + errMsg, - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 1, nil, "Failed to delete metadata: "+errMsg) } return } } else { // Delete entire document metadata - err := h.documentService.DeleteDocumentAllMetadata(req.DocID) + err = h.documentService.DeleteDocumentAllMetadata(req.DocID) if err != nil { errMsg := err.Error() if strings.Contains(errMsg, "no such document") || strings.Contains(errMsg, "document not found") { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 1, - "message": errMsg, - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, errMsg) } else { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 1, - "message": "Failed to delete metadata: " + errMsg, - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 1, nil, "Failed to delete metadata: "+errMsg) } return } } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": true, - }) + common.SuccessWithData(c, true, "success") } type ListIngestionsRequest struct { @@ -1539,10 +1381,7 @@ type ListIngestionsRequest struct { func (h *DocumentHandler) ListIngestionTasks(c *gin.Context) { var req ListIngestionsRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } @@ -1552,22 +1391,18 @@ func (h *DocumentHandler) ListIngestionTasks(c *gin.Context) { var err error if req.DatasetID != nil { if !h.datasetService.Accessible(*req.DatasetID, userID) { - jsonError(c, common.CodeAuthenticationError, "No authorization to access the dataset.") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "No authorization to access the dataset.") return } } parseResult, err = h.documentService.ListIngestionTasks(userID, req.DatasetID, 0, 0) if err != nil { - jsonError(c, common.CodeExceptionError, err.Error()) + common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": parseResult, - }) + common.SuccessWithData(c, parseResult, "success") } type StartParseDocumentsRequest struct { @@ -1578,31 +1413,24 @@ type StartParseDocumentsRequest struct { func (h *DocumentHandler) StartIngestionTask(c *gin.Context) { var req StartParseDocumentsRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } userID := c.GetString("user_id") if !h.datasetService.Accessible(req.DatasetID, userID) { - jsonError(c, common.CodeAuthenticationError, "No authorization to access the dataset.") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "No authorization to access the dataset.") return } parseResult, err := h.documentService.IngestDocuments(req.DatasetID, userID, req.Documents) if err != nil { - jsonError(c, common.CodeExceptionError, err.Error()) + common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": parseResult, - }) + common.SuccessWithData(c, parseResult, "success") } type StopIngestionsRequest struct { @@ -1612,10 +1440,7 @@ type StopIngestionsRequest struct { func (h *DocumentHandler) StopIngestionTasks(c *gin.Context) { var req StopIngestionsRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } @@ -1623,14 +1448,10 @@ func (h *DocumentHandler) StopIngestionTasks(c *gin.Context) { parseResult, err := h.documentService.StopIngestionTasks(req.Tasks, userID) if err != nil { - jsonError(c, common.CodeExceptionError, err.Error()) + common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": parseResult, - }) + common.SuccessWithData(c, parseResult, "success") } type RemoveIngestionsRequest struct { @@ -1640,18 +1461,12 @@ type RemoveIngestionsRequest struct { func (h *DocumentHandler) RemoveIngestionTasks(c *gin.Context) { var req RemoveIngestionsRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } if req.Tasks == nil || len(req.Tasks) == 0 { - c.JSON(http.StatusOK, gin.H{ - "code": 1, - "message": "task_ids is required", - }) + common.ErrorWithCode(c, 1, "task_ids is required") return } @@ -1659,14 +1474,10 @@ func (h *DocumentHandler) RemoveIngestionTasks(c *gin.Context) { deletedTasks, err := h.documentService.RemoveIngestionTasks(req.Tasks, userID) if err != nil { - jsonError(c, common.CodeExceptionError, err.Error()) + common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": deletedTasks, - }) + common.SuccessWithData(c, deletedTasks, "success") } type ParseDocumentRequest struct { @@ -1678,30 +1489,23 @@ func (h *DocumentHandler) ParseDocuments(c *gin.Context) { var req ParseDocumentRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } userID := c.GetString("user_id") if !h.datasetService.Accessible(datasetID, userID) { - jsonError(c, common.CodeAuthenticationError, "No authorization to access the dataset.") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "No authorization to access the dataset.") return } parseResult, err := h.documentService.ParseDocuments(datasetID, userID, req.Documents) if err != nil { - jsonError(c, common.CodeExceptionError, err.Error()) + common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": parseResult, - }) + common.SuccessWithData(c, parseResult, "success") } type StopParseDocumentRequest struct { @@ -1713,60 +1517,44 @@ func (h *DocumentHandler) StopParseDocuments(c *gin.Context) { var req StopParseDocumentRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } if len(req.DocumentIDs) == 0 { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": "`document_ids` is required", - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), "`document_ids` is required") return } userID := c.GetString("user_id") if !h.datasetService.Accessible(datasetID, userID) { - jsonError(c, common.CodeAuthenticationError, "You don't own the dataset.") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "You don't own the dataset.") return } result, err := h.documentService.StopParseDocuments(datasetID, req.DocumentIDs) if err != nil { - jsonError(c, common.CodeExceptionError, err.Error()) + common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": result, - }) + common.SuccessWithData(c, result, "success") } func (h *DocumentHandler) MetadataSummaryByDataset(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := c.Param("dataset_id") if datasetID == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": "dataset_id is required", - }) + common.ErrorWithCode(c, int(common.CodeServerError), "dataset_id is required") return } if !h.datasetService.Accessible(datasetID, user.ID) { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": "You don't own the dataset " + datasetID, - }) + common.ErrorWithCode(c, int(common.CodeServerError), "You don't own the dataset "+datasetID) return } @@ -1777,46 +1565,39 @@ func (h *DocumentHandler) MetadataSummaryByDataset(c *gin.Context) { summary, err := h.documentService.GetMetadataSummary(datasetID, docIDS) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": common.CodeServerError, - "message": "Failed to get metadata summary" + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeServerError, nil, "Failed to get metadata summary"+err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": gin.H{"summary": summary}, - }) + common.SuccessWithData(c, gin.H{"summary": summary}, "success") } func (h *DocumentHandler) UpdateDatasetDocument(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - jsonError(c, common.CodeArgumentError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "dataset_id is required") return } documentID := strings.TrimSpace(c.Param("document_id")) if documentID == "" { - jsonError(c, common.CodeArgumentError, "document_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "document_id is required") return } body, err := c.GetRawData() if err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } var raw map[string]json.RawMessage if err := json.Unmarshal(body, &raw); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } present := make(map[string]bool, len(raw)) @@ -1824,33 +1605,30 @@ func (h *DocumentHandler) UpdateDatasetDocument(c *gin.Context) { present[key] = true } var req service.UpdateDatasetDocumentRequest - if err := json.Unmarshal(body, &req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + if err = json.Unmarshal(body, &req); err != nil { + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } data, code, err := h.documentService.UpdateDatasetDocument(user.ID, datasetID, documentID, &req, present) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": data, - }) + common.SuccessNoMessage(c, data) } func (h *DocumentHandler) UploadInfo(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } form, err := c.MultipartForm() if err != nil && !strings.Contains(err.Error(), "request Content-Type isn't multipart/form-data") { - jsonError(c, common.CodeArgumentError, "Failed to parse multipart form: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Failed to parse multipart form: "+err.Error()) return } @@ -1861,31 +1639,27 @@ func (h *DocumentHandler) UploadInfo(c *gin.Context) { rawURL := strings.TrimSpace(c.Query("url")) if len(fileHeaders) > 0 && rawURL != "" { - jsonError(c, common.CodeArgumentError, "Provide either multipart file(s) or ?url=..., not both.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Provide either multipart file(s) or ?url=..., not both.") return } if len(fileHeaders) == 0 && rawURL == "" { - jsonError(c, common.CodeArgumentError, "Missing input: provide multipart file(s) or url") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Missing input: provide multipart file(s) or url") return } if rawURL != "" { data, code, err := h.documentService.UploadDocumentInfoByURL(user.ID, rawURL) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": data, - "message": "success", - }) + common.SuccessWithData(c, data, "success") return } data, code, err := h.documentService.UploadDocumentInfos(user.ID, fileHeaders) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } @@ -1895,11 +1669,7 @@ func (h *DocumentHandler) UploadInfo(c *gin.Context) { } else { payload = data } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": payload, - "message": "success", - }) + common.SuccessWithData(c, payload, "success") } type documentMetadataBatchRequest struct { @@ -1919,23 +1689,23 @@ func (h *DocumentHandler) UpdateDocumentMetadatas(c *gin.Context) { func (h *DocumentHandler) handleBatchUpdateDocumentMetadatas(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } datasetID := strings.TrimSpace(c.Param("dataset_id")) if datasetID == "" { - jsonError(c, common.CodeArgumentError, "dataset_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "dataset_id is required") return } if !h.datasetService.Accessible(datasetID, user.ID) { - jsonError(c, common.CodeDataError, "You don't own the dataset "+datasetID+".") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "You don't own the dataset "+datasetID+".") return } var req documentMetadataBatchRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } if req.Selector == nil { @@ -1950,13 +1720,8 @@ func (h *DocumentHandler) handleBatchUpdateDocumentMetadatas(c *gin.Context) { resp, code, err := h.documentService.BatchUpdateDocumentMetadatas(datasetID, req.Selector, req.Updates, req.Deletes) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": resp, - "message": "success", - }) + common.SuccessWithData(c, resp, "success") } diff --git a/internal/handler/error.go b/internal/handler/error.go index 2194b793e5..a488234dec 100644 --- a/internal/handler/error.go +++ b/internal/handler/error.go @@ -33,7 +33,7 @@ func jsonInternalError(c *gin.Context, err error) { zap.String("method", c.Request.Method), zap.String("path", c.Request.URL.Path), ) - jsonError(c, common.CodeServerError, common.CodeServerError.Message()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, common.CodeServerError.Message()) } // HandleNoRoute handles requests to undefined routes @@ -45,11 +45,7 @@ func HandleNoRoute(c *gin.Context) { // NoRoute, so emit the same body here to keep the auth error paths // byte-for-byte aligned. if c.Request.Method == http.MethodGet && c.Request.URL.Path == "/api/v1/auth/login/" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeExceptionError, - "data": nil, - "message": "", - }) + common.ResponseWithCodeData(c, common.CodeExceptionError, false, "") return } diff --git a/internal/handler/file.go b/internal/handler/file.go index 140569e961..a6ea6591ac 100644 --- a/internal/handler/file.go +++ b/internal/handler/file.go @@ -65,7 +65,7 @@ func NewFileHandler(fileService *service.FileService, userService *service.UserS func (h *FileHandler) ListFiles(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -78,7 +78,7 @@ func (h *FileHandler) ListFiles(c *gin.Context) { if p, err := strconv.Atoi(pageStr); err == nil && p >= 1 { page = p } else if err != nil { - jsonError(c, common.CodeParamError, "Invalid page parameter: must be a positive integer") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "Invalid page parameter: must be a positive integer") return } } @@ -87,7 +87,7 @@ func (h *FileHandler) ListFiles(c *gin.Context) { if pageSizeStr := c.Query("page_size"); pageSizeStr != "" { if ps, err := strconv.Atoi(pageSizeStr); err == nil { if ps < 1 { - jsonError(c, common.CodeParamError, "Invalid page_size parameter: must be at least 1") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "Invalid page_size parameter: must be at least 1") return } if ps > 100 { @@ -95,7 +95,7 @@ func (h *FileHandler) ListFiles(c *gin.Context) { } pageSize = ps } else { - jsonError(c, common.CodeParamError, "Invalid page_size parameter: must be a positive integer") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "Invalid page_size parameter: must be a positive integer") return } } @@ -112,11 +112,7 @@ func (h *FileHandler) ListFiles(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, result, "success") } // GetRootFolder gets root folder for current user @@ -130,7 +126,7 @@ func (h *FileHandler) ListFiles(c *gin.Context) { func (h *FileHandler) GetRootFolder(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -142,11 +138,7 @@ func (h *FileHandler) GetRootFolder(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": gin.H{"root_folder": rootFolder}, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, gin.H{"root_folder": rootFolder}, common.CodeSuccess.Message()) } // GetParentFolder gets parent folder of a file @@ -161,7 +153,7 @@ func (h *FileHandler) GetRootFolder(c *gin.Context) { func (h *FileHandler) GetParentFolder(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -169,7 +161,7 @@ func (h *FileHandler) GetParentFolder(c *gin.Context) { // Get file_id from query fileID := c.Query("file_id") if fileID == "" { - jsonError(c, common.CodeBadRequest, "file_id is required") + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "file_id is required") return } @@ -180,11 +172,7 @@ func (h *FileHandler) GetParentFolder(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": gin.H{"parent_folder": parentFolder}, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, gin.H{"parent_folder": parentFolder}, common.CodeSuccess.Message()) } // GetAllParentFolders gets all parent folders in path @@ -199,7 +187,7 @@ func (h *FileHandler) GetParentFolder(c *gin.Context) { func (h *FileHandler) GetAllParentFolders(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -207,7 +195,7 @@ func (h *FileHandler) GetAllParentFolders(c *gin.Context) { // Get file_id from query fileID := c.Query("file_id") if fileID == "" { - jsonError(c, common.CodeBadRequest, "file_id is required") + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "file_id is required") return } @@ -218,11 +206,7 @@ func (h *FileHandler) GetAllParentFolders(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": gin.H{"parent_folders": parentFolders}, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, gin.H{"parent_folders": parentFolders}, common.CodeSuccess.Message()) } // GetFileAncestors gets all ancestor folders of a file (matches Python /files//ancestors) @@ -237,14 +221,14 @@ func (h *FileHandler) GetAllParentFolders(c *gin.Context) { func (h *FileHandler) GetFileAncestors(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID fileID := c.Param("id") if fileID == "" { - jsonError(c, common.CodeBadRequest, "file id is required") + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "file id is required") return } @@ -255,11 +239,7 @@ func (h *FileHandler) GetFileAncestors(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": gin.H{"parent_folders": parentFolders}, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, gin.H{"parent_folders": parentFolders}, common.CodeSuccess.Message()) } type CreateFolderRequest struct { @@ -282,7 +262,7 @@ type CreateFolderRequest struct { func (h *FileHandler) UploadFile(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -292,13 +272,13 @@ func (h *FileHandler) UploadFile(c *gin.Context) { if strings.Contains(contentType, "multipart/form-data") { if err := c.Request.ParseMultipartForm(32 << 20); err != nil { - jsonError(c, common.CodeBadRequest, "Failed to parse multipart form: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "Failed to parse multipart form: "+err.Error()) return } form := c.Request.MultipartForm if form == nil { - jsonError(c, common.CodeBadRequest, "No file part!") + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "No file part!") return } parentID := c.PostForm("parent_id") @@ -313,38 +293,31 @@ func (h *FileHandler) UploadFile(c *gin.Context) { files := form.File["file"] if len(files) == 0 { - jsonError(c, common.CodeBadRequest, "No file selected!") + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "No file selected!") return } for _, fileHeader := range files { if fileHeader.Filename == "" { - jsonError(c, common.CodeBadRequest, "No file selected!") + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "No file selected!") return } } result, err := h.fileService.UploadFile(userID, parentID, files) if err != nil { - jsonError(c, common.CodeBadRequest, err.Error()) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, result, common.CodeSuccess.Message()) return } if strings.Contains(contentType, "application/json") { var req CreateFolderRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, err.Error()) return } @@ -360,19 +333,15 @@ func (h *FileHandler) UploadFile(c *gin.Context) { result, err := h.fileService.CreateFolder(userID, req.Name, parentID, req.Type) if err != nil { - jsonError(c, common.CodeBadRequest, err.Error()) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, result, common.CodeSuccess.Message()) return } - jsonError(c, common.CodeBadRequest, "Unsupported content type") + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "Unsupported content type") return } @@ -392,27 +361,23 @@ type DeleteFileRequest struct { func (h *FileHandler) DeleteFiles(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req DeleteFileRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeBadRequest, err.Error()) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } success, message := h.fileService.DeleteFiles(c.Request.Context(), user.ID, req.IDs) if !success { - jsonError(c, common.CodeBadRequest, message) + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, message) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, true, common.CodeSuccess.Message()) } // MoveFileRequest represents the request body for move files operation @@ -438,39 +403,35 @@ type MoveFileRequest struct { func (h *FileHandler) MoveFiles(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req MoveFileRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeBadRequest, err.Error()) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } // Validate: at least one of dest_file_id or new_name must be provided if req.DestFileID == "" && req.NewName == "" { - jsonError(c, common.CodeParamError, "At least one of dest_file_id or new_name must be provided") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "At least one of dest_file_id or new_name must be provided") return } // Validate: new_name can only be used with a single file if req.NewName != "" && len(req.SrcFileIDs) > 1 { - jsonError(c, common.CodeParamError, "new_name can only be used with a single file") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "new_name can only be used with a single file") return } success, message := h.fileService.MoveFiles(user.ID, req.SrcFileIDs, req.DestFileID, req.NewName) if !success { - jsonError(c, common.CodeBadRequest, message) + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, message) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, true, common.CodeSuccess.Message()) } // Download handles file download @@ -485,28 +446,28 @@ func (h *FileHandler) MoveFiles(c *gin.Context) { func (h *FileHandler) Download(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID fileID := c.Param("id") if fileID == "" { - jsonError(c, common.CodeParamError, "id is required") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "id is required") return } // Get file metadata and check permission file, err := h.fileService.GetFileContent(userID, fileID) if err != nil { - jsonError(c, common.CodeUnauthorized, err.Error()) + common.ResponseWithCodeData(c, common.CodeUnauthorized, nil, err.Error()) return } // Get storage storageImpl := storage.GetStorageFactory().GetStorage() if storageImpl == nil { - jsonError(c, common.CodeServerError, "storage not initialized") + common.ResponseWithCodeData(c, common.CodeServerError, nil, "storage not initialized") return } @@ -521,7 +482,7 @@ func (h *FileHandler) Download(c *gin.Context) { if len(blob) == 0 { storageAddr, err := h.fileService.GetStorageAddress(fileID) if err != nil { - jsonError(c, common.CodeServerError, "Failed to get file storage address: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, "Failed to get file storage address: "+err.Error()) return } blob, getErr = storageImpl.Get(storageAddr.Bucket, storageAddr.Name) @@ -533,7 +494,7 @@ func (h *FileHandler) Download(c *gin.Context) { if getErr != nil { errMsg += ": " + getErr.Error() } - jsonError(c, common.CodeServerError, errMsg) + common.ResponseWithCodeData(c, common.CodeServerError, nil, errMsg) return } @@ -572,7 +533,7 @@ func (h *FileHandler) Download(c *gin.Context) { func (h *FileHandler) LinkToDatasets(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -592,20 +553,16 @@ func (h *FileHandler) LinkToDatasets(c *gin.Context) { missing = append(missing, "kb_ids") } if len(missing) > 0 { - jsonError(c, common.CodeArgumentError, fmt.Sprintf("required argument are missing: %s; ", strings.Join(missing, ","))) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, fmt.Sprintf("required argument are missing: %s; ", strings.Join(missing, ","))) return } if err := h.file2DocumentService.LinkToDatasets(user.ID, &req); err != nil { - jsonError(c, linkToDatasetsErrorCode(err), err.Error()) + common.ResponseWithCodeData(c, linkToDatasetsErrorCode(err), nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": "success", - }) + common.SuccessWithData(c, true, "success") } // linkToDatasetsErrorCode maps File2DocumentService sentinel errors to diff --git a/internal/handler/file_commit.go b/internal/handler/file_commit.go index 6b553fe5a4..4ce4731a42 100644 --- a/internal/handler/file_commit.go +++ b/internal/handler/file_commit.go @@ -18,7 +18,6 @@ package handler import ( "fmt" - "net/http" "ragflow/internal/common" "ragflow/internal/dao" "ragflow/internal/entity" @@ -77,13 +76,13 @@ func CommitFolderResolver(h *FileCommitHandler, entityType, urlParam string) gin return func(c *gin.Context) { id := c.Param(urlParam) if id == "" { - jsonError(c, common.CodeParamError, fmt.Sprintf("%s is required", urlParam)) + common.ResponseWithCodeData(c, common.CodeParamError, nil, fmt.Sprintf("%s is required", urlParam)) c.Abort() return } folderID, err := h.ResolveFolderID(entityType, id) if err != nil { - jsonError(c, common.CodeNotFound, fmt.Sprintf("%s folder not found", entityType)) + common.ResponseWithCodeData(c, common.CodeNotFound, nil, fmt.Sprintf("%s folder not found", entityType)) c.Abort() return } @@ -125,19 +124,19 @@ type CreateCommitRequest struct { func (h *FileCommitHandler) CreateCommit(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } folderID := c.Param("folder_id") if folderID == "" { - jsonError(c, common.CodeParamError, "folder_id is required") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "folder_id is required") return } var req CreateCommitRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeBadRequest, err.Error()) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } @@ -152,20 +151,16 @@ func (h *FileCommitHandler) CreateCommit(c *gin.Context) { ct = *commit.CreateTime } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": entity.CommitResponse{ - ID: commit.ID, - FolderID: commit.FolderID, - ParentID: commit.ParentID, - Message: commit.Message, - AuthorID: commit.AuthorID, - FileCount: commit.FileCount, - TreeState: commit.TreeState, - CreateTime: &ct, - }, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, entity.CommitResponse{ + ID: commit.ID, + FolderID: commit.FolderID, + ParentID: commit.ParentID, + Message: commit.Message, + AuthorID: commit.AuthorID, + FileCount: commit.FileCount, + TreeState: commit.TreeState, + CreateTime: &ct, + }, common.CodeSuccess.Message()) } // ListCommits lists commits for a workspace folder @@ -184,13 +179,13 @@ func (h *FileCommitHandler) CreateCommit(c *gin.Context) { func (h *FileCommitHandler) ListCommits(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } folderID := c.Param("folder_id") if folderID == "" { - jsonError(c, common.CodeParamError, "folder_id is required") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "folder_id is required") return } @@ -240,16 +235,12 @@ func (h *FileCommitHandler) ListCommits(c *gin.Context) { }) } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": gin.H{ - "total": total, - "page": page, - "page_size": pageSize, - "commits": commitList, - }, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, gin.H{ + "total": total, + "page": page, + "page_size": pageSize, + "commits": commitList, + }, common.CodeSuccess.Message()) } // GetCommit gets details of a single commit @@ -265,25 +256,25 @@ func (h *FileCommitHandler) ListCommits(c *gin.Context) { func (h *FileCommitHandler) GetCommit(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } folderID := c.Param("folder_id") commitID := c.Param("commit_id") if commitID == "" { - jsonError(c, common.CodeParamError, "commit_id is required") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "commit_id is required") return } commit, err := h.commitService.GetCommit(commitID) if err != nil { - jsonError(c, common.CodeNotFound, "Commit not found") + common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Commit not found") return } if commit.FolderID != folderID { - jsonError(c, common.CodeNotFound, "Commit not found in workspace") + common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Commit not found in workspace") return } @@ -297,20 +288,16 @@ func (h *FileCommitHandler) GetCommit(c *gin.Context) { ct = *commit.CreateTime } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": gin.H{ - "id": commit.ID, - "folder_id": commit.FolderID, - "parent_id": commit.ParentID, - "message": commit.Message, - "author_id": commit.AuthorID, - "file_count": commit.FileCount, - "create_time": ct, - "files": items, - }, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, gin.H{ + "id": commit.ID, + "folder_id": commit.FolderID, + "parent_id": commit.ParentID, + "message": commit.Message, + "author_id": commit.AuthorID, + "file_count": commit.FileCount, + "create_time": ct, + "files": items, + }, common.CodeSuccess.Message()) } // ListCommitFiles lists all file changes in a commit @@ -326,24 +313,24 @@ func (h *FileCommitHandler) GetCommit(c *gin.Context) { func (h *FileCommitHandler) ListCommitFiles(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } folderID := c.Param("folder_id") commitID := c.Param("commit_id") if commitID == "" { - jsonError(c, common.CodeParamError, "commit_id is required") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "commit_id is required") return } commit, err := h.commitService.GetCommit(commitID) if err != nil { - jsonError(c, common.CodeNotFound, "Commit not found") + common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Commit not found") return } if commit.FolderID != folderID { - jsonError(c, common.CodeNotFound, "Commit not found in workspace") + common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Commit not found in workspace") return } @@ -353,11 +340,7 @@ func (h *FileCommitHandler) ListCommitFiles(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": items, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, items, common.CodeSuccess.Message()) } // DiffCommits compares two commits @@ -374,7 +357,7 @@ func (h *FileCommitHandler) ListCommitFiles(c *gin.Context) { func (h *FileCommitHandler) DiffCommits(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -382,22 +365,22 @@ func (h *FileCommitHandler) DiffCommits(c *gin.Context) { fromID := c.Query("from") toID := c.Query("to") if fromID == "" || toID == "" { - jsonError(c, common.CodeParamError, "'from' and 'to' query parameters are required") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "'from' and 'to' query parameters are required") return } fromCommit, err := h.commitService.GetCommit(fromID) if err != nil { - jsonError(c, common.CodeNotFound, "Commit not found") + common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Commit not found") return } toCommit, err := h.commitService.GetCommit(toID) if err != nil { - jsonError(c, common.CodeNotFound, "Commit not found") + common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Commit not found") return } if fromCommit.FolderID != folderID || toCommit.FolderID != folderID { - jsonError(c, common.CodeNotFound, "Commit not found in workspace") + common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Commit not found in workspace") return } @@ -407,11 +390,7 @@ func (h *FileCommitHandler) DiffCommits(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": diff, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, diff, common.CodeSuccess.Message()) } // GetUncommittedChanges gets uncommitted changes @@ -426,13 +405,13 @@ func (h *FileCommitHandler) DiffCommits(c *gin.Context) { func (h *FileCommitHandler) GetUncommittedChanges(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } folderID := c.Param("folder_id") if folderID == "" { - jsonError(c, common.CodeParamError, "folder_id is required") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "folder_id is required") return } @@ -442,11 +421,7 @@ func (h *FileCommitHandler) GetUncommittedChanges(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": changes, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, changes, common.CodeSuccess.Message()) } // GetCommitTree gets the folder tree snapshot for a commit @@ -462,24 +437,24 @@ func (h *FileCommitHandler) GetUncommittedChanges(c *gin.Context) { func (h *FileCommitHandler) GetCommitTree(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } folderID := c.Param("folder_id") commitID := c.Param("commit_id") if commitID == "" { - jsonError(c, common.CodeParamError, "commit_id is required") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "commit_id is required") return } commit, err := h.commitService.GetCommit(commitID) if err != nil { - jsonError(c, common.CodeNotFound, "Commit not found") + common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Commit not found") return } if commit.FolderID != folderID { - jsonError(c, common.CodeNotFound, "Commit not found in workspace") + common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Commit not found in workspace") return } @@ -489,11 +464,7 @@ func (h *FileCommitHandler) GetCommitTree(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": tree, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, tree, common.CodeSuccess.Message()) } // GetCommitFileContent gets file content as it existed in a given commit @@ -510,7 +481,7 @@ func (h *FileCommitHandler) GetCommitTree(c *gin.Context) { func (h *FileCommitHandler) GetCommitFileContent(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -519,33 +490,27 @@ func (h *FileCommitHandler) GetCommitFileContent(c *gin.Context) { fileID := c.Param("file_id") if folderID == "" || commitID == "" || fileID == "" { - jsonError(c, common.CodeParamError, "folder_id, commit_id, and file_id are required") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "folder_id, commit_id, and file_id are required") return } commit, err := h.commitService.GetCommit(commitID) if err != nil { - jsonError(c, common.CodeNotFound, "Commit not found") + common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Commit not found") return } if commit.FolderID != folderID { - jsonError(c, common.CodeNotFound, "Commit not found in workspace") + common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Commit not found in workspace") return } content, err := h.commitService.GetCommitFileContent(folderID, commitID, fileID) if err != nil { - jsonError(c, common.CodeNotFound, err.Error()) + common.ResponseWithCodeData(c, common.CodeNotFound, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": gin.H{ - "content": string(content), - }, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, gin.H{"content": string(content)}, common.CodeSuccess.Message()) } // GetFileVersionHistory gets version history for a specific file @@ -560,13 +525,13 @@ func (h *FileCommitHandler) GetCommitFileContent(c *gin.Context) { func (h *FileCommitHandler) GetFileVersionHistory(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } fileID := c.Param("id") if fileID == "" { - jsonError(c, common.CodeParamError, "file_id is required") + common.ResponseWithCodeData(c, common.CodeParamError, nil, "file_id is required") return } @@ -576,9 +541,5 @@ func (h *FileCommitHandler) GetFileVersionHistory(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": versions, - "message": common.CodeSuccess.Message(), - }) + common.SuccessWithData(c, versions, common.CodeSuccess.Message()) } diff --git a/internal/handler/langfuse.go b/internal/handler/langfuse.go index 72403f19c2..6aa424d8ee 100644 --- a/internal/handler/langfuse.go +++ b/internal/handler/langfuse.go @@ -59,24 +59,24 @@ type SetLangfuseRequest struct { func (h *LangfuseHandler) SetAPIKey(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req SetLangfuseRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, "Invalid request: "+err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Invalid request: "+err.Error()) return } row, code, err := h.langfuseService.SetAPIKey(user.ID, req.SecretKey, req.PublicKey, req.Host) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } // Echo back the stored keys, matching the Python langfuse_keys payload. - jsonResponse(c, common.CodeSuccess, gin.H{ + common.SuccessWithData(c, gin.H{ "tenant_id": row.TenantID, "secret_key": row.SecretKey, "public_key": row.PublicKey, @@ -88,35 +88,35 @@ func (h *LangfuseHandler) SetAPIKey(c *gin.Context) { func (h *LangfuseHandler) GetAPIKey(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } data, code, message, err := h.langfuseService.GetAPIKey(user.ID) if err != nil { - jsonError(c, code, message) + common.ResponseWithCodeData(c, code, nil, message) return } - jsonResponse(c, code, data, message) + common.ResponseWithCodeData(c, code, data, message) } // DeleteAPIKey handles DELETE /langfuse/api-key. func (h *LangfuseHandler) DeleteAPIKey(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } ok, code, message, err := h.langfuseService.DeleteAPIKey(user.ID) if err != nil { - jsonError(c, code, message) + common.ResponseWithCodeData(c, code, nil, message) return } // No record: mirror get_json_result(message=...) with data=nil. if message != "" { - jsonResponse(c, common.CodeSuccess, nil, message) + common.SuccessWithData(c, nil, message) return } - jsonResponse(c, common.CodeSuccess, ok, "success") + common.SuccessWithData(c, ok, "success") } diff --git a/internal/handler/llm.go b/internal/handler/llm.go index 49c83dc170..d744ad8945 100644 --- a/internal/handler/llm.go +++ b/internal/handler/llm.go @@ -17,8 +17,6 @@ package handler import ( - "net/http" - "github.com/gin-gonic/gin" "ragflow/internal/common" @@ -62,7 +60,7 @@ func NewLLMHandler(llmService *service.LLMService, userService *service.UserServ func (h *LLMHandler) GetMyLLMs(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -72,19 +70,11 @@ func (h *LLMHandler) GetMyLLMs(c *gin.Context) { llms, err := h.llmService.GetMyLLMs(tenantID, includeDetails) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeExceptionError, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeExceptionError, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": llms, - }) + common.SuccessWithData(c, llms, "success") } // SetAPIKey set API key for a LLM factory @@ -100,45 +90,29 @@ func (h *LLMHandler) GetMyLLMs(c *gin.Context) { func (h *LLMHandler) SetAPIKey(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req service.SetAPIKeyRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": "Invalid request: " + err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, false, "Invalid request: "+err.Error()) return } tenantID := user.ID result, err := h.llmService.SetAPIKey(tenantID, &req) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeDataError, false, err.Error()) return } if req.Verify { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": result, - }) + common.SuccessWithData(c, result, "success") return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": true, - }) + common.SuccessWithData(c, true, "success") } // ListApp lists LLMs grouped by factory @@ -154,7 +128,7 @@ func (h *LLMHandler) SetAPIKey(c *gin.Context) { func (h *LLMHandler) ListApp(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -164,17 +138,9 @@ func (h *LLMHandler) ListApp(c *gin.Context) { llms, err := h.llmService.ListLLMs(tenantID, modelType) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeExceptionError, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeExceptionError, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": llms, - }) + common.SuccessWithData(c, llms, "success") } diff --git a/internal/handler/mcp.go b/internal/handler/mcp.go index b78f320e2a..b338291428 100644 --- a/internal/handler/mcp.go +++ b/internal/handler/mcp.go @@ -71,45 +71,41 @@ func NewMCPHandler(mcpService *service.MCPService) *MCPHandler { func (h *MCPHandler) CreateMCPServer(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req service.CreateMCPServerRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } result, code, err := h.mcpService.CreateMCPServer(user.ID, req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": result, - }) + common.SuccessWithData(c, result, "success") } // ListMCPServers lists MCP servers for the current user. func (h *MCPHandler) ListMCPServers(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } page, err := parseMCPServerPage(c.Query("page")) if err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } pageSize, err := parseMCPServerPageSize(c.Query("page_size")) if err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } @@ -121,28 +117,20 @@ func (h *MCPHandler) ListMCPServers(c *gin.Context) { result, code, err := h.mcpService.ListMCPServers(user.ID, mcpIDs, keywords, page, pageSize, orderby, desc) if err != nil { if code == common.CodeServerError { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": code, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, code, nil, err.Error()) return } - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": result, - }) + common.SuccessWithData(c, result, "success") } func (h *MCPHandler) GetMCPServer(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -153,11 +141,7 @@ func (h *MCPHandler) GetMCPServer(c *gin.Context) { mcpDetailError(c, code, err) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": result, - }) + common.SuccessWithData(c, result, "success") return } @@ -166,75 +150,56 @@ func (h *MCPHandler) GetMCPServer(c *gin.Context) { mcpDetailError(c, code, err) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": newMCPServerResponse(result), - }) + common.SuccessWithData(c, newMCPServerResponse(result), "success") } func mcpDetailError(c *gin.Context, code common.ErrorCode, err error) { if code == common.CodeDataError { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeExceptionError, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error()) } // UpdateMCPServer updates an MCP server for the current user. func (h *MCPHandler) UpdateMCPServer(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } mcpID := c.Param("mcp_id") var req service.UpdateMCPServerRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } result, code, err := h.mcpService.UpdateMCPServer(user.ID, mcpID, req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": newMCPServerResponse(result), - }) + common.SuccessWithData(c, newMCPServerResponse(result), "success") } // DeleteMCPServer deletes an MCP server for the current user. func (h *MCPHandler) DeleteMCPServer(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } result, code, err := h.mcpService.DeleteMCPServer(user.ID, c.Param("mcp_id")) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": result, - }) + common.SuccessWithData(c, result, "success") } // mcpErrorResponse maps the import / test sentinel errors to the response @@ -248,9 +213,9 @@ func mcpErrorResponse(c *gin.Context, err error) bool { errors.Is(err, service.ErrMCPInvalidName), errors.Is(err, service.ErrMCPInvalidURL), errors.Is(err, service.ErrMCPTestFailed): - c.JSON(http.StatusOK, gin.H{"code": common.CodeDataError, "data": nil, "message": mcpErrorMessage(err)}) + common.ResponseWithCodeData(c, common.CodeDataError, nil, mcpErrorMessage(err)) default: - c.JSON(http.StatusInternalServerError, gin.H{"code": common.CodeServerError, "data": nil, "message": err.Error()}) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) } return true } @@ -313,19 +278,19 @@ type ImportMCPRequest struct { func (h *MCPHandler) ImportMCPServers(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } body, err := io.ReadAll(c.Request.Body) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeBadRequest, "data": nil, "message": "Invalid request body: " + err.Error()}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) return } var raw map[string]json.RawMessage if len(body) > 0 { - if err := json.Unmarshal(body, &raw); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeBadRequest, "data": nil, "message": "Invalid request body: " + err.Error()}) + if err = json.Unmarshal(body, &raw); err != nil { + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) return } } @@ -334,21 +299,17 @@ func (h *MCPHandler) ImportMCPServers(c *gin.Context) { if !hasServers { // Match Python validate_request: code 101, message includes the // trailing "; " separator the Python decorator emits. - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "data": nil, - "message": "required argument are missing: mcpServers; ", - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "required argument are missing: mcpServers; ") return } var servers map[string]map[string]interface{} - if err := json.Unmarshal(rawServers, &servers); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeBadRequest, "data": nil, "message": "Invalid request body: " + err.Error()}) + if err = json.Unmarshal(rawServers, &servers); err != nil { + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) return } if len(servers) == 0 { - c.JSON(http.StatusOK, gin.H{"code": common.CodeDataError, "data": nil, "message": "No MCP servers provided."}) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "No MCP servers provided.") return } @@ -362,11 +323,11 @@ func (h *MCPHandler) ImportMCPServers(c *gin.Context) { results, err := h.mcpService.ImportServers(user.ID, servers, timeout) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"code": common.CodeServerError, "data": nil, "message": err.Error()}) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeBadRequest, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{"code": common.CodeSuccess, "data": gin.H{"results": results}, "message": "success"}) + common.SuccessWithData(c, gin.H{"results": results}, "success") } // TestMCPServer opens a live MCP session and returns the tools the server advertises. @@ -380,19 +341,19 @@ func (h *MCPHandler) ImportMCPServers(c *gin.Context) { func (h *MCPHandler) TestMCPServer(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } mcpID := c.Param("mcp_id") if mcpID == "" { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeBadRequest, "data": nil, "message": "mcp_id is required"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "mcp_id is required") return } var req service.TestServerRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeBadRequest, "data": nil, "message": "Invalid request body: " + err.Error()}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) return } @@ -404,11 +365,7 @@ func (h *MCPHandler) TestMCPServer(c *gin.Context) { missingFields = append(missingFields, "server_type") } if len(missingFields) > 0 { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "data": nil, - "message": "required argument are missing: " + strings.Join(missingFields, ", ") + "; ", - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "required argument are missing: "+strings.Join(missingFields, ", ")+"; ") return } @@ -416,7 +373,7 @@ func (h *MCPHandler) TestMCPServer(c *gin.Context) { if mcpErrorResponse(c, err) { return } - c.JSON(http.StatusOK, gin.H{"code": common.CodeSuccess, "data": tools, "message": "success"}) + common.SuccessWithData(c, tools, "success") } func newMCPServerResponse(server *entity.MCPServer) *mcpServerResponse { diff --git a/internal/handler/mcp_server.go b/internal/handler/mcp_server.go index bba0fbf9e9..6d4de5af12 100644 --- a/internal/handler/mcp_server.go +++ b/internal/handler/mcp_server.go @@ -72,7 +72,7 @@ func NewMCPServerHandler( func (h *MCPServerHandler) HandleMCP(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -80,10 +80,7 @@ func (h *MCPServerHandler) HandleMCP(c *gin.Context) { c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, maxMCPBodyBytes) body, err := io.ReadAll(c.Request.Body) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": "Failed to read request body: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Failed to read request body: "+err.Error()) return } @@ -99,10 +96,7 @@ func (h *MCPServerHandler) HandleMCP(c *gin.Context) { server := mcp.NewServer(connector) respBody, hasResponse, err := server.HandleRequest(body) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": common.CodeServerError, - "message": "MCP server error: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeBadRequest, nil, "MCP server error: "+err.Error()) return } diff --git a/internal/handler/memory.go b/internal/handler/memory.go index 3c8a4c8288..e6a8b5589b 100644 --- a/internal/handler/memory.go +++ b/internal/handler/memory.go @@ -93,7 +93,7 @@ func (h *MemoryHandler) CreateMemory(c *gin.Context) { // GetUser is a context value set by the authentication middleware user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -101,51 +101,31 @@ func (h *MemoryHandler) CreateMemory(c *gin.Context) { // Parse JSON request body var req service.CreateMemoryRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, err.Error()) return } // Validate required field: name if req.Name == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": "name is required", - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "name is required") return } // Validate required field: memory_type (must be non-empty array) if len(req.MemoryType) == 0 { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": "memory_type is required and must be a list", - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "memory type is required and must be a list") return } // Validate required field: embd_id if req.EmbdID == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": "embd_id is required", - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "embedding model ID is required") return } // Validate required field: llm_id if req.LLMID == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": "llm_id is required", - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "language model ID is required") return } @@ -166,20 +146,12 @@ func (h *MemoryHandler) CreateMemory(c *gin.Context) { errMsg := err.Error() // Determine if it's an argument error and return appropriate error code if isArgumentError(errMsg) { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": errMsg, - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, errMsg) return } // Other errors return server error - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": errMsg, - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeServerError, nil, errMsg) return } @@ -194,11 +166,7 @@ func (h *MemoryHandler) CreateMemory(c *gin.Context) { } // Return success response - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": result, - }) + common.SuccessWithData(c, result, "success") } // UpdateMemory handles PUT request for updating Memory @@ -232,18 +200,14 @@ func (h *MemoryHandler) UpdateMemory(c *gin.Context) { // Get memory_id from URL path memoryID := c.Param("memory_id") if memoryID == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": "memory_id is required", - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "memory ID is required") return } // Get current logged-in user information user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -251,11 +215,7 @@ func (h *MemoryHandler) UpdateMemory(c *gin.Context) { // Parse JSON request body var req service.UpdateMemoryRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeBadRequest, nil, err.Error()) return } @@ -265,39 +225,23 @@ func (h *MemoryHandler) UpdateMemory(c *gin.Context) { errMsg := err.Error() // Check if it's a "not found" error if strings.Contains(errMsg, "not found") { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeNotFound, - "message": errMsg, - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeNotFound, nil, errMsg) return } // Check if it's an argument error if isArgumentError(errMsg) { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": errMsg, - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, errMsg) return } // Other errors return server error - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": errMsg, - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeServerError, nil, errMsg) return } // Return success response - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": result, - }) + common.SuccessWithData(c, result, "success") } // DeleteMemory handles DELETE request for deleting Memory @@ -315,11 +259,7 @@ func (h *MemoryHandler) DeleteMemory(c *gin.Context) { // Get memory_id from URL path memoryID := c.Param("memory_id") if memoryID == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": "memory_id is required", - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "memory ID is required") return } @@ -329,29 +269,17 @@ func (h *MemoryHandler) DeleteMemory(c *gin.Context) { errMsg := err.Error() // Check if it's a "not found" error if strings.Contains(errMsg, "not found") { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeNotFound, - "message": errMsg, - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeNotFound, nil, errMsg) return } // Other errors return server error - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": errMsg, - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeServerError, nil, errMsg) return } // Return success response - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": nil, - }) + common.SuccessNoData(c, "success") } // ListMemories handles GET request for listing Memories @@ -379,7 +307,7 @@ func (h *MemoryHandler) ListMemories(c *gin.Context) { // Get current logged-in user information user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -427,20 +355,12 @@ func (h *MemoryHandler) ListMemories(c *gin.Context) { // Call service layer to get memory list result, err := h.memoryService.ListMemories(user.ID, tenantIDs, memoryTypes, storageType, keywords, page, pageSize) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } // Return success response - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": result, - }) + common.SuccessWithData(c, result, "success") } // GetMemoryConfig handles GET request for getting Memory configuration @@ -458,11 +378,7 @@ func (h *MemoryHandler) GetMemoryConfig(c *gin.Context) { // Get memory_id from URL path memoryID := c.Param("memory_id") if memoryID == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": "memory_id is required", - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "memory ID is required") return } @@ -472,29 +388,17 @@ func (h *MemoryHandler) GetMemoryConfig(c *gin.Context) { errMsg := err.Error() // Check if it's a "not found" error if strings.Contains(errMsg, "not found") { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeNotFound, - "message": errMsg, - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeNotFound, nil, errMsg) return } // Other errors return server error - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": errMsg, - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeServerError, nil, errMsg) return } // Return success response - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": result, - }) + common.SuccessWithData(c, result, "success") } // GetMemoryMessages handles GET request for getting Memory messages @@ -519,19 +423,19 @@ func (h *MemoryHandler) GetMemoryConfig(c *gin.Context) { func (h *MemoryHandler) GetMemoryMessages(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeAuthenticationError, "user id is required") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "user id is required") return } memoryID := strings.TrimSpace(c.Param("memory_id")) if memoryID == "" { - jsonError(c, common.CodeArgumentError, "memory_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "memory_id is required") return } @@ -550,34 +454,30 @@ func (h *MemoryHandler) GetMemoryMessages(c *gin.Context) { keywords := strings.TrimSpace(c.DefaultQuery("keywords", "")) page, err := strconv.Atoi(c.DefaultQuery("page", "1")) if err != nil || page <= 0 { - jsonError(c, common.CodeArgumentError, "page must be a positive integer") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "page must be a positive integer") return } pageSize, err := strconv.Atoi(c.DefaultQuery("page_size", "50")) if err != nil || pageSize <= 0 { - jsonError(c, common.CodeArgumentError, "page_size must be a positive integer") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "page_size must be a positive integer") return } if pageSize > 100 { - jsonError(c, common.CodeArgumentError, "page_size must be less than or equal to 100") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "page_size must be less than or equal to 100") return } data, err := h.memoryService.GetMemoryMessages(c.Request.Context(), userID, memoryID, agentIDs, keywords, page, pageSize) if err != nil { if isMemoryServiceNotFound(err) { - jsonError(c, common.CodeNotFound, err.Error()) + common.ResponseWithCodeData(c, common.CodeNotFound, nil, err.Error()) return } - jsonError(c, common.CodeServerError, "Internal server error") + common.ResponseWithCodeData(c, common.CodeServerError, nil, "Internal server error") return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": true, - "data": data, - }) + common.SuccessWithData(c, data, true) } type messageMemoryIDs []string @@ -626,23 +526,23 @@ type AddMessageRequest struct { func (h *MemoryHandler) AddMessage(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } currentUserID := strings.TrimSpace(user.ID) if currentUserID == "" { - jsonError(c, common.CodeArgumentError, "user_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "user_id is required") return } var reqBody AddMessageRequest if err := c.ShouldBindJSON(&reqBody); err != nil { - jsonError(c, common.CodeArgumentError, "body arguments is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "body arguments is required") return } if len(reqBody.MemoryIDs) == 0 { - jsonError(c, common.CodeArgumentError, "memory_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "memory_id is required") return } @@ -651,7 +551,8 @@ func (h *MemoryHandler) AddMessage(c *gin.Context) { if authViaAPIToken, ok := v.(bool); authViaAPIToken && ok { effectiveUserID = strings.TrimSpace(reqBody.UserID) if effectiveUserID == "" { - jsonError(c, common.CodeArgumentError, "user_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "user_id is required") return } } @@ -667,19 +568,11 @@ func (h *MemoryHandler) AddMessage(c *gin.Context) { ok, message, err := h.memoryService.AddMessage(c.Request.Context(), currentUserID, []string(reqBody.MemoryIDs), msg) if err != nil || !ok { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": "Some messages failed to add. Detail:" + message, - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeServerError, nil, "Some messages failed to add. Detail:"+message) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": message, - "data": nil, - }) + common.SuccessNoData(c, message) } // ForgetMessage handles DELETE request for forgetting messages. @@ -695,44 +588,28 @@ func (h *MemoryHandler) AddMessage(c *gin.Context) { func (h *MemoryHandler) ForgetMessage(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } memoryID, messageID, err := parseMemoryMessagePath(c.Param("memory_message")) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } - if err := h.memoryService.ForgetMessage(c.Request.Context(), user.ID, memoryID, messageID); err != nil { + if err = h.memoryService.ForgetMessage(c.Request.Context(), user.ID, memoryID, messageID); err != nil { errMsg := err.Error() if isMemoryServiceNotFound(err) { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeNotFound, - "message": errMsg, - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeNotFound, nil, errMsg) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": "Internal server error", - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeServerError, nil, "Internal server error:"+errMsg) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": true, - "data": nil, - }) + common.SuccessNoData(c, true) } func isMemoryServiceNotFound(err error) bool { @@ -780,67 +657,45 @@ func parseMemoryMessagePath(memoryMessage string) (string, int64, error) { func (h *MemoryHandler) UpdateMessage(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeAuthenticationError, "user id is required") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "user id is required") return } memoryID, messageID, err := parseMemoryMessagePath(c.Param("memory_message")) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeArgumentError), err.Error()) return } var req map[string]interface{} if err = json.NewDecoder(c.Request.Body).Decode(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeArgumentError, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, err.Error()) return } status, ok := req["status"].(bool) if !ok { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": "Status must be a boolean.", - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Status must be a boolean.") return } ok, err = h.memoryService.UpdateMessageStatus(c.Request.Context(), userID, memoryID, messageID, status) if err != nil || !ok { if isMemoryServiceNotFound(err) { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeNotFound, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeNotFound, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": "Internal server error", - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeServerError, nil, "Internal server error:"+err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": true, - "data": nil, - }) + common.SuccessNoData(c, true) } // GetMessageContent handles GET request for getting message content @@ -858,40 +713,33 @@ func (h *MemoryHandler) UpdateMessage(c *gin.Context) { func (h *MemoryHandler) GetMessageContent(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeAuthenticationError, "user id is required") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "user id is required") return } memoryID, messageID, err := parseMemoryMessagePath(c.Param("memory_message")) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeArgumentError), err.Error()) return } data, err := h.memoryService.GetMessageContent(c.Request.Context(), userID, memoryID, messageID) if err != nil { if _, ok := err.(*service.ResourceNotFoundError); ok { - jsonError(c, common.CodeNotFound, err.Error()) + common.ResponseWithCodeData(c, common.CodeNotFound, nil, err.Error()) return } - jsonError(c, common.CodeServerError, err.Error()) + common.ResponseWithCodeData(c, common.CodeServerError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": true, - "data": data, - }) + common.SuccessWithData(c, data, true) } // SearchMessage handles GET request for searching messages @@ -914,13 +762,13 @@ func (h *MemoryHandler) GetMessageContent(c *gin.Context) { func (h *MemoryHandler) SearchMessage(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeAuthenticationError, "user id is required") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "user id is required") return } @@ -961,15 +809,11 @@ func (h *MemoryHandler) SearchMessage(c *gin.Context) { res, code, err := h.memoryService.SearchMessage(c.Request.Context(), userID, filterDict, params) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": true, - "data": res, - }) + common.SuccessWithData(c, res, true) } // GetMessages handles GET request for getting message list @@ -987,13 +831,13 @@ func (h *MemoryHandler) SearchMessage(c *gin.Context) { func (h *MemoryHandler) GetMessages(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := strings.TrimSpace(user.ID) if userID == "" { - jsonError(c, common.CodeAuthenticationError, "user id is required") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "user id is required") return } @@ -1013,21 +857,17 @@ func (h *MemoryHandler) GetMessages(c *gin.Context) { sessionID := c.DefaultQuery("session_id", "") limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10")) if len(memoryIDs) == 0 { - jsonError(c, common.CodeArgumentError, "memory_ids is required.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "memory_ids is required.") return } data, code, err := h.memoryService.GetMessages(c.Request.Context(), memoryIDs, userID, agentID, sessionID, limit) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": true, - "data": data, - }) + common.SuccessWithData(c, data, true) } // isArgumentError determines if an error message is an argument error diff --git a/internal/handler/models.go b/internal/handler/models.go index d37d0c70cc..cae287fafd 100644 --- a/internal/handler/models.go +++ b/internal/handler/models.go @@ -17,7 +17,6 @@ package handler import ( - "net/http" "ragflow/internal/common" "ragflow/internal/service" "strconv" @@ -56,63 +55,37 @@ func (h *ModelHandler) ListAllModels(c *gin.Context) { // list tenant models models, err := h.modelProviderService.ListAllModels(page, pageSize) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": models, - }) - + common.SuccessWithData(c, models, "success") return } func (h *ModelHandler) ShowModel(c *gin.Context) { encodedModelName := c.Param("model_name") if encodedModelName == "" { - c.JSON(http.StatusOK, gin.H{ - "code": 400, - "message": "Encoded model name is empty", - }) + common.ErrorWithCode(c, 400, "Encoded model name is empty") return } decodedModelName, err := common.DecodeFromBase64(encodedModelName) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": 400, - "message": err.Error(), - }) + common.ErrorWithCode(c, 400, err.Error()) return } if decodedModelName == "" { - c.JSON(http.StatusOK, gin.H{ - "code": 400, - "message": "Decoded model name is empty", - }) + common.ErrorWithCode(c, 400, "Decoded model name is empty") return } // Get model model, err := h.modelProviderService.ShowModel(decodedModelName) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": model, - }) + common.SuccessWithData(c, model, "success") } diff --git a/internal/handler/oauth_login.go b/internal/handler/oauth_login.go index 310421cd6c..68c1b29271 100644 --- a/internal/handler/oauth_login.go +++ b/internal/handler/oauth_login.go @@ -55,10 +55,7 @@ const oauthAuthCookie = "ragflow_auth" func (h *UserHandler) OAuthLogin(c *gin.Context) { channel := c.Param("channel") if channel == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": "channel is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "channel is required") return } @@ -68,17 +65,10 @@ func (h *UserHandler) OAuthLogin(c *gin.Context) { // server_error_response, which replies HTTP 200 with code 100 and // the exception's repr() as the message (no short error code). if errors.Is(err, service.ErrOAuthInvalidChannel) { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeExceptionError, - "data": nil, - "message": fmt.Sprintf("ValueError('Invalid channel name: %s')", channel), - }) + common.ResponseWithCodeData(c, common.CodeExceptionError, nil, fmt.Sprintf("ValueError('Invalid channel name: %s')", channel)) return } - c.JSON(http.StatusInternalServerError, gin.H{ - "code": code, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, code, nil, err.Error()) return } diff --git a/internal/handler/openai_chat.go b/internal/handler/openai_chat.go index c2ef962756..626d65d310 100644 --- a/internal/handler/openai_chat.go +++ b/internal/handler/openai_chat.go @@ -46,39 +46,39 @@ func NewOpenAIChatHandler(svc *service.OpenAIChatService) *OpenAIChatHandler { func (h *OpenAIChatHandler) OpenAIChatCompletions(c *gin.Context) { chatID := c.Param("chat_id") if chatID == "" { - jsonError(c, common.CodeDataError, "You don't own the chat "+chatID) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "You don't own the chat "+chatID) return } user, code, msg := GetUser(c) if code != common.CodeSuccess { - jsonError(c, code, msg) + common.ResponseWithCodeData(c, code, nil, msg) return } bodyBytes, err := io.ReadAll(c.Request.Body) if err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } // Parse body into the typed request var req service.OpenAIChatRequest if err := json.Unmarshal(bodyBytes, &req); err != nil { - jsonError(c, common.CodeArgumentError, err.Error()) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } // Messages presence if len(req.Messages) == 0 { - jsonError(c, common.CodeDataError, "You have to provide messages.") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "You have to provide messages.") return } // extra_body shape validation extraBody, extraBodyOK := req.ExtraBody.(map[string]interface{}) if req.ExtraBody != nil && !extraBodyOK { - jsonError(c, common.CodeArgumentError, "extra_body must be an object.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "extra_body must be an object.") return } @@ -87,12 +87,14 @@ func (h *OpenAIChatHandler) OpenAIChatCompletions(c *gin.Context) { if rm, ok := extraBody["reference_metadata"].(map[string]interface{}); ok { if rawFields, has := rm["fields"]; has { if rawArr, ok := rawFields.([]interface{}); !ok { - jsonError(c, common.CodeArgumentError, "reference_metadata.fields must be an array.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "reference_metadata.fields must be an array.") return } else { for _, item := range rawArr { if _, ok := item.(string); !ok { - jsonError(c, common.CodeArgumentError, "reference_metadata.fields must be an array.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "reference_metadata.fields must be an array.") return } } @@ -105,7 +107,8 @@ func (h *OpenAIChatHandler) OpenAIChatCompletions(c *gin.Context) { if extraBody != nil { if mc, ok := extraBody["metadata_condition"]; ok && mc != nil { if _, ok := mc.(map[string]interface{}); !ok { - jsonError(c, common.CodeArgumentError, "metadata_condition must be an object.") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "metadata_condition must be an object.") return } } @@ -114,7 +117,7 @@ func (h *OpenAIChatHandler) OpenAIChatCompletions(c *gin.Context) { // Last message must be from the user if last := req.Messages[len(req.Messages)-1]; last != nil { if role, _ := last["role"].(string); role != "user" { - jsonError(c, common.CodeDataError, "The last content of this conversation is not from user.") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "The last content of this conversation is not from user.") return } } diff --git a/internal/handler/plugin.go b/internal/handler/plugin.go index 191db75b99..51f570e730 100644 --- a/internal/handler/plugin.go +++ b/internal/handler/plugin.go @@ -17,8 +17,6 @@ package handler import ( - "net/http" - "github.com/gin-gonic/gin" "ragflow/internal/common" @@ -49,13 +47,9 @@ func NewPluginHandler(pluginService *service.PluginService) *PluginHandler { // @Router /v1/plugin/tools [get] func (h *PluginHandler) ListLLMTools(c *gin.Context) { if _, errorCode, errorMessage := GetUser(c); errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": h.pluginService.ListLLMTools(), - }) + common.SuccessWithData(c, h.pluginService.ListLLMTools(), "SUCCESS") } diff --git a/internal/handler/providers.go b/internal/handler/providers.go index 290555ca1b..b9d3a99cf4 100644 --- a/internal/handler/providers.go +++ b/internal/handler/providers.go @@ -58,10 +58,7 @@ func (h *ProviderHandler) ListProviders(c *gin.Context) { // list pool providers providers, err := dao.GetModelProviderManager().ListProviders() if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeNotFound, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeNotFound), err.Error()) return } @@ -70,11 +67,7 @@ func (h *ProviderHandler) ListProviders(c *gin.Context) { delete(provider, "tags") } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": providers, - }) + common.SuccessWithData(c, providers, "success") return } @@ -83,19 +76,11 @@ func (h *ProviderHandler) ListProviders(c *gin.Context) { // list tenant providers providers, errorCode, err := h.modelProviderService.ListProvidersOfTenant(userID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithCodeData(c, errorCode, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": providers, - }) + common.SuccessWithData(c, providers, "success") return } @@ -107,11 +92,7 @@ func (h *ProviderHandler) AddProvider(c *gin.Context) { var req AddProviderRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeBadRequest, false, err.Error()) return } @@ -119,26 +100,17 @@ func (h *ProviderHandler) AddProvider(c *gin.Context) { errorCode, err := h.modelProviderService.AddModelProvider(req.ProviderName, userID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - }) + common.SuccessWithMessage(c, "success") } func (h *ProviderHandler) DeleteProvider(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } @@ -146,98 +118,60 @@ func (h *ProviderHandler) DeleteProvider(c *gin.Context) { errorCode, err := h.modelProviderService.DeleteModelProvider(userID, providerName) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - }) + common.SuccessWithMessage(c, "success") } func (h *ProviderHandler) ShowProvider(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } provider, err := dao.GetModelProviderManager().GetProviderByName(providerName) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeNotFound, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeNotFound), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": provider, - }) + common.SuccessWithData(c, provider, "success") } func (h *ProviderHandler) ListModels(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } providerModels, err := dao.GetModelProviderManager().ListModels(providerName) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeNotFound, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeNotFound), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": providerModels, - }) + common.SuccessWithData(c, providerModels, "success") } func (h *ProviderHandler) ShowModel(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } modelName := c.Param("model_name") if modelName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model name is required") return } model, err := dao.GetModelProviderManager().GetModelByName(providerName, modelName) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeNotFound, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeNotFound), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": model, - }) + + common.SuccessWithData(c, model, "success") } type CreateProviderInstanceRequest struct { @@ -250,19 +184,13 @@ type CreateProviderInstanceRequest struct { func (h *ProviderHandler) CreateProviderInstance(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } var req CreateProviderInstanceRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } @@ -270,26 +198,17 @@ func (h *ProviderHandler) CreateProviderInstance(c *gin.Context) { _, err := h.modelProviderService.CreateProviderInstance(providerName, req.InstanceName, req.APIKey, req.BaseURL, req.Region, userID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeServerError), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - }) + common.SuccessWithMessage(c, "success") } func (h *ProviderHandler) ListProviderInstances(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } @@ -297,36 +216,23 @@ func (h *ProviderHandler) ListProviderInstances(c *gin.Context) { instances, errorCode, err := h.modelProviderService.ListProviderInstances(providerName, userID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": instances, - }) + common.SuccessWithData(c, instances, "success") } func (h *ProviderHandler) ShowProviderInstance(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } @@ -335,36 +241,23 @@ func (h *ProviderHandler) ShowProviderInstance(c *gin.Context) { // Get tenant ID from user instance, errorCode, err := h.modelProviderService.ShowProviderInstance(providerName, instanceName, userID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": instance, - }) + common.SuccessWithData(c, instance, "success") } func (h *ProviderHandler) ShowInstanceBalance(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } @@ -373,71 +266,46 @@ func (h *ProviderHandler) ShowInstanceBalance(c *gin.Context) { // Get tenant ID from user balance, errorCode, err := h.modelProviderService.ShowInstanceBalance(providerName, instanceName, userID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": balance, - }) + common.SuccessWithData(c, balance, "success") } func (h *ProviderHandler) CheckConnection(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } var req service.CheckConnectionRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, err.Error()) return } userID := c.GetString("user_id") errCode, err := h.modelProviderService.CheckConnection(providerName, req.APIKey, req.Region, req.BaseURL, userID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - }) + common.SuccessWithMessage(c, "success") } func (h *ProviderHandler) CheckInstanceConnection(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } @@ -445,10 +313,7 @@ func (h *ProviderHandler) CheckInstanceConnection(c *gin.Context) { instanceInfo, code, err := h.modelProviderService.ShowProviderInstance(providerName, instanceName, userID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(code), err.Error()) return } @@ -459,35 +324,23 @@ func (h *ProviderHandler) CheckInstanceConnection(c *gin.Context) { // Get tenant ID from user errorCode, err := h.modelProviderService.CheckConnection(providerName, apikey, region, baseURL, userID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - }) + common.SuccessWithMessage(c, "success") } func (h *ProviderHandler) ListTasks(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } @@ -496,45 +349,29 @@ func (h *ProviderHandler) ListTasks(c *gin.Context) { // Get tenant ID from user listTaskResponse, errorCode, err := h.modelProviderService.ListTasks(providerName, instanceName, userID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": listTaskResponse, - }) + common.SuccessWithData(c, listTaskResponse, "success") } func (h *ProviderHandler) ShowTask(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } taskID := c.Param("task_id") if taskID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Task id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Task ID is required") return } @@ -543,18 +380,11 @@ func (h *ProviderHandler) ShowTask(c *gin.Context) { // Get tenant ID from user taskResponse, errorCode, err := h.modelProviderService.ShowTask(providerName, instanceName, taskID, userID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": taskResponse, - }) + common.SuccessWithData(c, taskResponse, "success") } type AlterProviderInstanceRequest struct { @@ -565,53 +395,35 @@ type AlterProviderInstanceRequest struct { func (h *ProviderHandler) AlterProviderInstance(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } var req AlterProviderInstanceRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, err.Error()) return } userID := c.GetString("user_id") if userID == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeUnauthorized, - "message": "Unauthorized", - }) + common.ErrorWithCode(c, int(common.CodeUnauthorized), "Unauthorized") return } code, err := h.modelProviderService.AlterProviderInstance(userID, providerName, instanceName, req.InstanceName, req.APIKey) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - }) + common.SuccessWithMessage(c, "success") } type DropProviderInstanceRequest struct { @@ -621,18 +433,12 @@ type DropProviderInstanceRequest struct { func (h *ProviderHandler) DropProviderInstance(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } var req DropProviderInstanceRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } @@ -640,34 +446,22 @@ func (h *ProviderHandler) DropProviderInstance(c *gin.Context) { code, err := h.modelProviderService.DropProviderInstances(providerName, userID, req.Instances) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - }) + common.SuccessWithMessage(c, "success") } func (h *ProviderHandler) ListInstanceModels(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } @@ -683,34 +477,20 @@ func (h *ProviderHandler) ListInstanceModels(c *gin.Context) { modelList, err := h.modelProviderService.ListSupportedModels(providerName, instanceName, c.GetString("user_id")) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeServerError), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": modelList, - }) + common.SuccessWithData(c, modelList, "success") return } modelInstances, err := h.modelProviderService.ListInstanceModels(providerName, instanceName, c.GetString("user_id")) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeNotFound, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeNotFound), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": modelInstances, - }) + common.SuccessWithData(c, modelInstances, "success") } type EnableOrDisableModelRequest struct { @@ -721,29 +501,20 @@ type EnableOrDisableModelRequest struct { func (h *ProviderHandler) EnableOrDisableModel(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } var req EnableOrDisableModelRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } @@ -752,35 +523,23 @@ func (h *ProviderHandler) EnableOrDisableModel(c *gin.Context) { modelName := strings.TrimPrefix(c.Param("model_name"), "/") modelName = strings.TrimSpace(modelName) if modelName == "" && modelID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": "model_name or model_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "model_name or model_id is required") return } status := strings.TrimSpace(req.Status) if status != "active" && status != "inactive" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": "Status must be active or inactive", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Status must be active or inactive") return } code, err := h.modelProviderService.UpdateModelStatus(providerName, instanceName, modelName, userID, modelID, status) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - }) + common.SuccessWithMessage(c, "success") } func prepareProviderInstance(providerName, instanceName, reqProviderName, reqInstanceName string) error { @@ -831,18 +590,12 @@ func (h *ProviderHandler) AddModel(c *gin.Context) { var req service.AddModelRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, err.Error()) return } if err := prepareAddModelRequest(&req, c.Param("provider_name"), c.Param("instance_name")); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeDataError, nil, err.Error()) return } @@ -850,17 +603,11 @@ func (h *ProviderHandler) AddModel(c *gin.Context) { code, err := h.modelProviderService.AddModel(&req, userID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": "success", - }) + common.ErrorWithCode(c, int(code), "success") } type DropInstanceModelRequest struct { @@ -871,34 +618,22 @@ type DropInstanceModelRequest struct { func (h *ProviderHandler) DropInstanceModels(c *gin.Context) { providerName := c.Param("provider_name") if providerName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } instanceName := c.Param("instance_name") if instanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } var req DropInstanceModelRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } if len(req.ModelIDs) == 0 && len(req.Models) == 0 { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "message": "model_ids or models is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "model_ids or models is required") return } @@ -906,17 +641,11 @@ func (h *ProviderHandler) DropInstanceModels(c *gin.Context) { code, err := h.modelProviderService.DropInstanceModels(providerName, instanceName, userID, req.ModelIDs, req.Models) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - }) + common.SuccessWithMessage(c, "success") } type ChatToModelRequest struct { @@ -935,43 +664,28 @@ func (h *ProviderHandler) ChatToModel(c *gin.Context) { var req ChatToModelRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } if req.ModelID == nil { if req.ProviderName == nil || *req.ProviderName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } if req.InstanceName == nil || *req.InstanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } if req.ModelName == nil || *req.ModelName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model name is required") return } } else { if *req.ModelID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model ID is empty", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model ID is empty") return } } @@ -1066,10 +780,7 @@ func (h *ProviderHandler) ChatToModel(c *gin.Context) { response, errorCode, err = h.modelProviderService.ChatToModelWithMessages(req.ProviderName, req.InstanceName, req.ModelName, req.ModelID, userID, messages, &apiConfig, &chatConfig) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } @@ -1093,43 +804,28 @@ func (h *ProviderHandler) EmbedText(c *gin.Context) { var req EmbedTextRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } if req.ModelID == nil { if req.ProviderName == nil || *req.ProviderName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } if req.InstanceName == nil || *req.InstanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } if req.ModelName == nil || *req.ModelName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model name is required") return } } else { if *req.ModelID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model ID is empty", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model ID is empty") return } } @@ -1152,18 +848,11 @@ func (h *ProviderHandler) EmbedText(c *gin.Context) { response, errorCode, err = h.modelProviderService.EmbedText(req.ProviderName, req.InstanceName, req.ModelName, req.ModelID, userID, req.Texts, &apiConfig, &embeddingConfig) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": response, - "message": "success", - }) + common.SuccessWithData(c, response, "success") } type RerankDocumentRequest struct { @@ -1180,43 +869,28 @@ func (h *ProviderHandler) RerankDocument(c *gin.Context) { var req RerankDocumentRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } if req.ModelID == nil { if req.ProviderName == nil || *req.ProviderName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } if req.InstanceName == nil || *req.InstanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } if req.ModelName == nil || *req.ModelName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model name is required") return } } else { if *req.ModelID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model ID is empty", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model ID is empty") return } } @@ -1239,18 +913,10 @@ func (h *ProviderHandler) RerankDocument(c *gin.Context) { response, errorCode, err = h.modelProviderService.RerankDocument(req.ProviderName, req.InstanceName, req.ModelName, req.ModelID, userID, req.Query, req.Documents, &apiConfig, &rerankConfig) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": response.Data, - "message": "success", - }) + common.SuccessWithData(c, response.Data, "success") } type TranscribeAudioRequest struct { @@ -1269,43 +935,28 @@ func (h *ProviderHandler) TranscribeAudio(c *gin.Context) { var req TranscribeAudioRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } if req.ModelID == nil { if req.ProviderName == nil || *req.ProviderName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } if req.InstanceName == nil || *req.InstanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } if req.ModelName == nil || *req.ModelName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model name is required") return } } else { if *req.ModelID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model ID is empty", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model ID is empty") return } } @@ -1370,18 +1021,11 @@ func (h *ProviderHandler) TranscribeAudio(c *gin.Context) { response, errorCode, err = h.modelProviderService.TranscribeAudio(req.ProviderName, req.InstanceName, req.ModelName, req.ModelID, userID, req.File, &apiConfig, &asrConfig) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": response, - "message": "success", - }) + common.SuccessWithData(c, response, "success") } type AudioSpeechRequest struct { @@ -1398,43 +1042,28 @@ func (h *ProviderHandler) AudioSpeech(c *gin.Context) { var req AudioSpeechRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } if req.ModelID == nil { if req.ProviderName == nil || *req.ProviderName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } if req.InstanceName == nil || *req.InstanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } if req.ModelName == nil || *req.ModelName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model name is required") return } } else { if *req.ModelID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model ID is empty", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model ID is empty") return } } @@ -1499,18 +1128,11 @@ func (h *ProviderHandler) AudioSpeech(c *gin.Context) { response, errorCode, err = h.modelProviderService.AudioSpeech(req.ProviderName, req.InstanceName, req.ModelName, req.ModelID, userID, req.Text, &apiConfig, &ttsConfig) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": response, - "message": "success", - }) + common.SuccessWithData(c, response, "success") } type OCRFileRequest struct { @@ -1526,43 +1148,28 @@ func (h *ProviderHandler) OCRFile(c *gin.Context) { var req OCRFileRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } if req.ModelID == nil { if req.ProviderName == nil || *req.ProviderName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } if req.InstanceName == nil || *req.InstanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } if req.ModelName == nil || *req.ModelName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model name is required") return } } else { if *req.ModelID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model ID is empty", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model ID is empty") return } } @@ -1583,18 +1190,11 @@ func (h *ProviderHandler) OCRFile(c *gin.Context) { response, errorCode, err = h.modelProviderService.OCRFile(req.ProviderName, req.InstanceName, req.ModelName, req.ModelID, userID, req.Content, req.URL, &apiConfig, &OCRConfig) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": response, - "message": "success", - }) + common.SuccessWithData(c, response, "success") } type ParseFileRequest struct { @@ -1610,43 +1210,28 @@ func (h *ProviderHandler) ParseFile(c *gin.Context) { var req ParseFileRequest if err := c.ShouldBindJSON(&req); err != nil { println("JSON bind error: %v (type: %T)", err, err) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeBadRequest), err.Error()) return } if req.ModelID == nil { if req.ProviderName == nil || *req.ProviderName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Provider name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required") return } if req.InstanceName == nil || *req.InstanceName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Instance name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required") return } if req.ModelName == nil || *req.ModelName == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model name is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model name is required") return } } else { if *req.ModelID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "Model ID is empty", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Model ID is empty") return } } @@ -1667,18 +1252,11 @@ func (h *ProviderHandler) ParseFile(c *gin.Context) { response, errorCode, err = h.modelProviderService.ParseFile(req.ProviderName, req.InstanceName, req.ModelName, req.ModelID, userID, req.Content, req.URL, &apiConfig, &parseFileConfig) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errorCode, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(errorCode), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": response, - "message": "success", - }) + common.SuccessWithData(c, response, "success") } // ListTenantAddedModels is the response handler for GET /api/v1/models. @@ -1699,7 +1277,7 @@ func (h *ProviderHandler) ParseFile(c *gin.Context) { func (h *ProviderHandler) ListTenantAddedModels(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -1707,13 +1285,9 @@ func (h *ProviderHandler) ListTenantAddedModels(c *gin.Context) { addedModels, code, err := h.modelProviderService.ListTenantAddedModels(user.ID, modelType) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": addedModels, - "message": "success", - }) + common.SuccessWithData(c, addedModels, "success") } diff --git a/internal/handler/search.go b/internal/handler/search.go index 37303339a7..2f850e4a45 100644 --- a/internal/handler/search.go +++ b/internal/handler/search.go @@ -85,7 +85,7 @@ func getSearchOwnerIDs(c *gin.Context) []string { func (h *SearchHandler) ListSearches(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -121,10 +121,7 @@ func (h *SearchHandler) ListSearches(c *gin.Context) { var req service.ListSearchAppsRequest if len(ownerIDs) == 0 && c.Request.ContentLength > 0 { if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, err.Error()) return } ownerIDs = req.OwnerIDs @@ -133,18 +130,11 @@ func (h *SearchHandler) ListSearches(c *gin.Context) { // List search apps with filtering result, err := h.searchService.ListSearches(userID, keywords, page, pageSize, orderby, desc, ownerIDs) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } // CreateSearch create a new search app @@ -166,7 +156,7 @@ func (h *SearchHandler) CreateSearch(c *gin.Context) { // Get current user from context (same as Python current_user) user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -174,40 +164,24 @@ func (h *SearchHandler) CreateSearch(c *gin.Context) { // Parse request body (same as Python get_request_json()) var req CreateSearchRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": "Invalid request body: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) return } if err := common.ValidateName(req.Name); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeDataError), err.Error()) return } // Create search (same as Python SearchService.save within DB.atomic()) result, err := h.searchService.CreateSearch(userID, req.Name, req.Description) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": common.CodeServerError, - "data": nil, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, common.CodeBadRequest, nil, err.Error()) return } // Return success response (same as Python get_json_result(data={"search_id": req["id"]})) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } // GetSearch get search app detail @@ -223,7 +197,7 @@ func (h *SearchHandler) GetSearch(c *gin.Context) { // Get current user from context (same as Python current_user) user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -231,11 +205,7 @@ func (h *SearchHandler) GetSearch(c *gin.Context) { // Get search_id from path parameter (same as Python ) searchID := c.Param("search_id") if searchID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": "search_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "search_id is required") return } @@ -244,19 +214,11 @@ func (h *SearchHandler) GetSearch(c *gin.Context) { if err != nil { // Check if it's a permission error if err.Error() == "has no permission for this operation" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeOperatingError, - "data": false, - "message": "Has no permission for this operation.", - }) + common.ResponseWithCodeData(c, common.CodeOperatingError, false, "Has no permission for this operation.") return } // Not found error - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeDataError), err.Error()) return } @@ -277,11 +239,7 @@ func (h *SearchHandler) GetSearch(c *gin.Context) { } // Return success response - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } // DeleteSearch delete a search app @@ -297,7 +255,7 @@ func (h *SearchHandler) DeleteSearch(c *gin.Context) { // Get current user from context (same as Python current_user) user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -305,11 +263,7 @@ func (h *SearchHandler) DeleteSearch(c *gin.Context) { // Get search_id from path parameter (same as Python ) searchID := c.Param("search_id") if searchID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": "search_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "search_id is required") return } @@ -318,28 +272,16 @@ func (h *SearchHandler) DeleteSearch(c *gin.Context) { if err != nil { // Check if it's an authorization error if err.Error() == "no authorization" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeAuthenticationError, - "data": false, - "message": "No authorization.", - }) + common.ResponseWithCodeData(c, common.CodeDataError, false, "No authorization") return } // Delete failed error - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeDataError), err.Error()) return } // Return success response (same as Python get_json_result(data=True)) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": "success", - }) + common.SuccessWithData(c, true, "success") } // UpdateSearch update a search app @@ -356,7 +298,7 @@ func (h *SearchHandler) UpdateSearch(c *gin.Context) { // Get current user from context (same as Python current_user) user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } userID := user.ID @@ -364,32 +306,20 @@ func (h *SearchHandler) UpdateSearch(c *gin.Context) { // Get search_id from path parameter (same as Python ) searchID := c.Param("search_id") if searchID == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": "search_id is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "search_id is required") return } // Parse request body var req service.UpdateSearchRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": "Invalid request body: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) return } // Validate name (same as Python validation) if err := common.ValidateName(req.Name); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(common.CodeDataError), err.Error()) return } @@ -399,31 +329,15 @@ func (h *SearchHandler) UpdateSearch(c *gin.Context) { errMsg := err.Error() switch errMsg { case "no authorization": - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeAuthenticationError, - "data": false, - "message": "No authorization.", - }) + common.ResponseWithCodeData(c, common.CodeDataError, false, "No authorization") case "duplicated search name": - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": "Duplicated search name.", - }) + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Duplicated search name.") default: // Check if it's a "cannot find search" error if len(errMsg) > 18 && errMsg[:18] == "cannot find search" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": false, - "message": errMsg, - }) + common.ResponseWithCodeData(c, common.CodeDataError, false, errMsg) } else { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": errMsg, - }) + common.ResponseWithCodeData(c, common.CodeDataError, nil, errMsg) } } return @@ -447,23 +361,20 @@ func (h *SearchHandler) UpdateSearch(c *gin.Context) { } // Return success response - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } func (h *SearchHandler) Completion(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req service.SearchCompletionsRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeArgumentError, "question is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, + "question is required") return } @@ -475,22 +386,18 @@ func (h *SearchHandler) Completion(c *gin.Context) { plan, code, err := searchSvc.PrepareCompletion(user.ID, c.Param("search_id"), &req) if err != nil { if code == common.CodeAuthenticationError { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "data": false, - "message": err.Error(), - }) + common.ResponseWithCodeData(c, code, false, err.Error()) return } if code == common.CodeServerError { jsonInternalError(c, err) return } - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } if plan == nil { - jsonError(c, common.CodeServerError, "completion plan is nil") + common.ResponseWithCodeData(c, common.CodeServerError, nil, "completion plan is nil") return } diff --git a/internal/handler/searchbot.go b/internal/handler/searchbot.go index dd386d6c6d..7a1a15181b 100644 --- a/internal/handler/searchbot.go +++ b/internal/handler/searchbot.go @@ -133,45 +133,29 @@ func (h *SearchBotHandler) SetAskService(svc *service.AskService) { h.askSvc = s func (h *SearchBotHandler) Handle(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req SearchBotRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "data": nil, - "message": "question is required", - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, err.Error()) return } if req.Question == "" { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "data": nil, - "message": "question is required", - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "question is required") return } questions, err := service.GenerateRelatedQuestions(user.ID, req.Question, req.SearchID, h.searchSvc, h.tenantSvc, h.llm) if err != nil { common.Warn("searchbot related questions failed", zap.String("error", err.Error())) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeOperatingError, - "data": nil, - "message": "LLM call failed", - }) + common.ResponseWithCodeData(c, common.CodeOperatingError, nil, "LLM call failed") return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": questions, - "message": "success", - }) + common.SuccessWithData(c, questions, "success") } // RetrievalTest performs a retrieval test against specified knowledge bases. @@ -186,13 +170,13 @@ func (h *SearchBotHandler) Handle(c *gin.Context) { func (h *SearchBotHandler) RetrievalTest(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - c.JSON(http.StatusUnauthorized, gin.H{"code": errorCode, "data": nil, "message": errorMessage}) + common.ResponseWithHttpCodeData(c, http.StatusUnauthorized, errorCode, nil, errorMessage) return } var req SearchBotRetrievalTestRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeArgumentError, "data": nil, "message": err.Error()}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, err.Error()) return } @@ -206,14 +190,14 @@ func (h *SearchBotHandler) RetrievalTest(c *gin.Context) { req.KbIDs = filtered if len(req.KbIDs) == 0 || req.Question == "" { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeArgumentError, "data": nil, "message": "kb_id and question are required"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "kb_id and question are required") return } applyRetrievalDefaults(&req) if req.TopK != nil && *req.TopK <= 0 { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeArgumentError, "data": nil, "message": "top_k must be greater than 0"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "top_k must be greater than 0") return } @@ -221,12 +205,12 @@ func (h *SearchBotHandler) RetrievalTest(c *gin.Context) { result, err := h.chunkSvc.RetrievalTest(svcReq, user.ID) if err != nil { - common.Warn("searchbot retrieval test failed", zap.String("error", err.Error())) - c.JSON(http.StatusInternalServerError, gin.H{"code": common.CodeServerError, "data": nil, "message": "retrieval test failed"}) + common.Warn("search bot retrieval test failed", zap.String("error", err.Error())) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeServerError, nil, "retrieval test failed") return } - c.JSON(http.StatusOK, gin.H{"code": int(common.CodeSuccess), "data": result, "message": "success"}) + common.SuccessWithData(c, result, "success") } // Ask performs a retrieval-augmented Q&A with streaming SSE response. @@ -241,13 +225,13 @@ func (h *SearchBotHandler) RetrievalTest(c *gin.Context) { func (h *SearchBotHandler) Ask(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req SearchBotAskRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeArgumentError, "data": nil, "message": err.Error()}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, err.Error()) return } @@ -260,7 +244,7 @@ func (h *SearchBotHandler) Ask(c *gin.Context) { filtered = append(filtered, id) } if len(filtered) == 0 || strings.TrimSpace(req.Question) == "" { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeArgumentError, "data": nil, "message": "kb_ids and question are required"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "kb_ids and question are required") return } @@ -332,13 +316,13 @@ func (h *SearchBotHandler) Ask(c *gin.Context) { func (h *SearchBotHandler) MindMap(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req SearchBotMindMapRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeArgumentError, "data": nil, "message": err.Error()}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, err.Error()) return } @@ -349,7 +333,7 @@ func (h *SearchBotHandler) MindMap(c *gin.Context) { } } if len(filtered) == 0 || strings.TrimSpace(req.Question) == "" { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeArgumentError, "data": nil, "message": "kb_ids and question are required"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeArgumentError, nil, "kb_ids and question are required") return } if h.chunkSvc == nil { @@ -391,7 +375,7 @@ func (h *SearchBotHandler) MindMap(c *gin.Context) { jsonInternalError(c, err) return } - jsonResponse(c, common.CodeSuccess, mindMap, "success") + common.SuccessWithData(c, mindMap, "success") } // SearchbotDetail returns the public share-page bootstrap payload for a @@ -400,14 +384,14 @@ func (h *SearchBotHandler) MindMap(c *gin.Context) { func (h *SearchBotHandler) SearchbotDetail(c *gin.Context) { searchID := strings.TrimSpace(c.Query("search_id")) if searchID == "" { - jsonError(c, common.CodeArgumentError, "search_id is required") + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "search_id is required") return } userSvc := service.NewUserService() user, code, err := userSvc.GetUserByBetaAPIToken(c.GetHeader("Authorization")) if err != nil { - jsonError(c, code, "Authentication error: API key is invalid!") + common.ResponseWithCodeData(c, code, nil, "Authentication error: API key is invalid!") return } @@ -415,16 +399,16 @@ func (h *SearchBotHandler) SearchbotDetail(c *gin.Context) { if err != nil { switch err.Error() { case "has no permission for this operation": - jsonError(c, common.CodeOperatingError, "Has no permission for this operation.") + common.ResponseWithCodeData(c, common.CodeOperatingError, nil, "Has no permission for this operation.") case "can't find this Search App!": - jsonError(c, common.CodeDataError, "Can't find this Search App!") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "Can't find this Search App!") default: jsonInternalError(c, err) } return } - jsonResponse(c, common.CodeSuccess, detail, "success") + common.SuccessWithData(c, detail, "success") } // ---- SSE helpers ---- diff --git a/internal/handler/skill_search.go b/internal/handler/skill_search.go index 5a4c6beb53..686ec5c66f 100644 --- a/internal/handler/skill_search.go +++ b/internal/handler/skill_search.go @@ -59,7 +59,7 @@ func NewSkillSearchHandler(docEngine engine.DocEngine) *SkillSearchHandler { func (h *SkillSearchHandler) GetConfig(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -68,11 +68,11 @@ func (h *SkillSearchHandler) GetConfig(c *gin.Context) { result, code, err := h.searchService.GetConfig(user.ID, spaceID, embdID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // UpdateConfig handles the update skill search config request @@ -88,13 +88,13 @@ func (h *SkillSearchHandler) GetConfig(c *gin.Context) { func (h *SkillSearchHandler) UpdateConfig(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req service.UpdateConfigRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } @@ -102,11 +102,11 @@ func (h *SkillSearchHandler) UpdateConfig(c *gin.Context) { result, code, err := h.searchService.UpdateConfig(&req) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // Search handles the skill search request @@ -122,13 +122,13 @@ func (h *SkillSearchHandler) UpdateConfig(c *gin.Context) { func (h *SkillSearchHandler) Search(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req service.SearchRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } @@ -136,11 +136,11 @@ func (h *SkillSearchHandler) Search(c *gin.Context) { result, code, err := h.searchService.Search(c.Request.Context(), &req, h.docEngine) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // IndexSkillsRequest represents the request to index skills @@ -163,13 +163,13 @@ type IndexSkillsRequest struct { func (h *SkillSearchHandler) IndexSkills(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req IndexSkillsRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } @@ -178,12 +178,12 @@ func (h *SkillSearchHandler) IndexSkills(c *gin.Context) { if embdID == "" { config, code, err := h.searchService.GetConfig(user.ID, req.SpaceID, "") if err != nil { - jsonError(c, code, "failed to get skill search config: "+err.Error()) + common.ResponseWithCodeData(c, code, nil, "failed to get skill search config: "+err.Error()) return } val, ok := config["embd_id"].(string) if !ok || val == "" { - jsonError(c, common.CodeDataError, "no embedding model configured in skill search config") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "no embedding model configured in skill search config") return } embdID = val @@ -198,14 +198,14 @@ func (h *SkillSearchHandler) IndexSkills(c *gin.Context) { if h.docEngine.GetType() == "elasticsearch" { if err := h.indexerService.EnsureIndex(c.Request.Context(), user.ID, req.SpaceID, h.docEngine, embdID); err != nil { - jsonError(c, common.CodeOperatingError, err.Error()) + common.ResponseWithCodeData(c, common.CodeOperatingError, nil, err.Error()) return } } if err := h.indexerService.BatchIndexSkills(c.Request.Context(), user.ID, req.SpaceID, req.Skills, h.docEngine, embdID); err != nil { common.Error(fmt.Sprintf("Failed to batch index skills: tenantID=%s, spaceID=%s, error=%v", user.ID, req.SpaceID, err), err) - jsonError(c, common.CodeOperatingError, err.Error()) + common.ResponseWithCodeData(c, common.CodeOperatingError, nil, err.Error()) return } @@ -214,7 +214,7 @@ func (h *SkillSearchHandler) IndexSkills(c *gin.Context) { zap.String("spaceID", req.SpaceID), zap.Int("indexedCount", len(req.Skills))) - jsonResponse(c, common.CodeSuccess, gin.H{ + common.SuccessWithData(c, gin.H{ "indexed_count": len(req.Skills), }, "success") } @@ -238,13 +238,13 @@ type ReindexRequest struct { func (h *SkillSearchHandler) Reindex(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req ReindexRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } @@ -253,12 +253,12 @@ func (h *SkillSearchHandler) Reindex(c *gin.Context) { if embdID == "" { config, code, err := h.searchService.GetConfig(user.ID, req.SpaceID, "") if err != nil { - jsonError(c, code, "failed to get skill search config: "+err.Error()) + common.ResponseWithCodeData(c, code, nil, "failed to get skill search config: "+err.Error()) return } val, ok := config["embd_id"].(string) if !ok || val == "" { - jsonError(c, common.CodeDataError, "no embedding model configured in skill search config") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "no embedding model configured in skill search config") return } embdID = val @@ -266,11 +266,11 @@ func (h *SkillSearchHandler) Reindex(c *gin.Context) { result, err := h.indexerService.ReindexAll(c.Request.Context(), user.ID, req.SpaceID, h.docEngine, embdID) if err != nil { - jsonError(c, common.CodeOperatingError, err.Error()) + common.ResponseWithCodeData(c, common.CodeOperatingError, nil, err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // DeleteSkillIndex handles the delete skill index request @@ -287,24 +287,24 @@ func (h *SkillSearchHandler) Reindex(c *gin.Context) { func (h *SkillSearchHandler) DeleteSkillIndex(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } skillID := c.Query("skill_id") spaceID := c.Query("space_id") if skillID == "" { - jsonError(c, common.CodeDataError, "skill_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "skill_id is required") return } err := h.indexerService.DeleteSkillIndex(c.Request.Context(), user.ID, spaceID, skillID, h.docEngine) if err != nil { - jsonError(c, common.CodeOperatingError, "failed to delete skill index") + common.ResponseWithCodeData(c, common.CodeOperatingError, nil, "failed to delete skill index") return } - jsonResponse(c, common.CodeSuccess, true, "success") + common.SuccessWithData(c, true, "success") } // InitializeIndex handles the initialize skill search index request @@ -321,23 +321,23 @@ func (h *SkillSearchHandler) DeleteSkillIndex(c *gin.Context) { func (h *SkillSearchHandler) InitializeIndex(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } embdID := c.Query("embd_id") spaceID := c.Query("space_id") if embdID == "" { - jsonError(c, common.CodeDataError, "embd_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "embd_id is required") return } if err := h.indexerService.InitializeIndex(c.Request.Context(), user.ID, spaceID, h.docEngine, embdID); err != nil { - jsonError(c, common.CodeOperatingError, err.Error()) + common.ResponseWithCodeData(c, common.CodeOperatingError, nil, err.Error()) return } - jsonResponse(c, common.CodeSuccess, gin.H{"initialized": true}, "success") + common.SuccessWithData(c, gin.H{"initialized": true}, "success") } // ==================== Skill Space Management ==================== @@ -354,17 +354,17 @@ func (h *SkillSearchHandler) InitializeIndex(c *gin.Context) { func (h *SkillSearchHandler) ListSpaces(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } result, code, err := h.spaceService.ListSpaces(user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // CreateSpaceRequest represents the request to create a skill space @@ -388,13 +388,13 @@ type CreateSpaceRequest struct { func (h *SkillSearchHandler) CreateSpace(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req CreateSpaceRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } @@ -406,11 +406,11 @@ func (h *SkillSearchHandler) CreateSpace(c *gin.Context) { RerankID: req.RerankID, }) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // GetSpace handles the get skill space request @@ -426,23 +426,23 @@ func (h *SkillSearchHandler) CreateSpace(c *gin.Context) { func (h *SkillSearchHandler) GetSpace(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } spaceID := c.Param("space_id") if spaceID == "" { - jsonError(c, common.CodeDataError, "space_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "space_id is required") return } result, code, err := h.spaceService.GetSpace(spaceID, user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // UpdateSpaceRequest represents the request to update a skill space @@ -468,19 +468,19 @@ type UpdateSpaceRequest struct { func (h *SkillSearchHandler) UpdateSpace(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } spaceID := c.Param("space_id") if spaceID == "" { - jsonError(c, common.CodeDataError, "space_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "space_id is required") return } var req UpdateSpaceRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } @@ -492,11 +492,11 @@ func (h *SkillSearchHandler) UpdateSpace(c *gin.Context) { TopK: req.TopK, }) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } // DeleteSpace handles the delete skill space request @@ -512,19 +512,19 @@ func (h *SkillSearchHandler) UpdateSpace(c *gin.Context) { func (h *SkillSearchHandler) DeleteSpace(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } spaceID := c.Param("space_id") if spaceID == "" { - jsonError(c, common.CodeDataError, "space_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "space_id is required") return } code, err := h.spaceService.DeleteSpace(spaceID, user.ID, h.docEngine, c.Request.Context()) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } @@ -549,21 +549,21 @@ func (h *SkillSearchHandler) DeleteSpace(c *gin.Context) { func (h *SkillSearchHandler) GetSpaceByFolder(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } folderID := c.Query("folder_id") if folderID == "" { - jsonError(c, common.CodeDataError, "folder_id is required") + common.ResponseWithCodeData(c, common.CodeDataError, nil, "folder_id is required") return } result, code, err := h.spaceService.GetSpaceByFolderID(folderID, user.ID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - jsonResponse(c, common.CodeSuccess, result, "success") + common.SuccessWithData(c, result, "success") } diff --git a/internal/handler/stats.go b/internal/handler/stats.go index e586a7f7f8..ce4c91847a 100644 --- a/internal/handler/stats.go +++ b/internal/handler/stats.go @@ -18,7 +18,6 @@ package handler import ( "errors" - "net/http" "time" "ragflow/internal/common" @@ -31,7 +30,7 @@ import ( func (h *SystemHandler) GetStats(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -54,16 +53,9 @@ func (h *SystemHandler) GetStats(c *gin.Context) { if errors.Is(err, service.ErrTenantNotFound) { code = common.CodeDataError } - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - }) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": stats, - }) + common.SuccessWithData(c, stats, "success") } diff --git a/internal/handler/system.go b/internal/handler/system.go index 7d25525b64..c5347bfdde 100644 --- a/internal/handler/system.go +++ b/internal/handler/system.go @@ -76,18 +76,11 @@ func (h *SystemHandler) Healthz(c *gin.Context) { func (h *SystemHandler) GetConfig(c *gin.Context) { config, err := h.systemService.GetConfig() if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": "Failed to get system configuration", - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, "Failed to get system configuration") return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": config, - }) + common.SuccessWithData(c, config, "success") } // GetConfigs get all system configurations @@ -101,25 +94,18 @@ func (h *SystemHandler) GetConfig(c *gin.Context) { func (h *SystemHandler) GetConfigs(c *gin.Context) { cfg := server.GetConfig() if cfg == nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": "Configuration not initialized", - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, "Configuration not initialized") return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": cfg, - }) + common.SuccessWithData(c, cfg, "success") } // GetStatus get RAGFlow status func (h *SystemHandler) GetStatus(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -129,11 +115,7 @@ func (h *SystemHandler) GetStatus(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": status, - "message": "success", - }) + common.SuccessWithData(c, status, "success") } // GetVersion get RAGFlow version @@ -148,18 +130,11 @@ func (h *SystemHandler) GetStatus(c *gin.Context) { func (h *SystemHandler) GetVersion(c *gin.Context) { version, err := h.systemService.GetVersion() if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": "Failed to get version", - }) + common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, "Failed to get version") return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": version.Version, - }) + common.SuccessWithData(c, version.Version, "success") } // GetLogLevel returns the current log level. The response uses the @@ -169,11 +144,7 @@ func (h *SystemHandler) GetVersion(c *gin.Context) { // table carried (e.g. "peewee", "pdfminer") were inert for the Go // side and are no longer returned. func (h *SystemHandler) GetLogLevel(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": gin.H{"level": common.GetLevel()}, - }) + common.SuccessWithData(c, gin.H{"level": common.GetLevel()}, "success") } // SetLogLevelRequest set log level request. PkgName is accepted for @@ -197,18 +168,12 @@ type SetLogLevelRequest struct { func (h *SystemHandler) SetLogLevel(c *gin.Context) { var req SetLogLevelRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "message": "pkg_name and level are required", - }) + common.ErrorWithCode(c, int(common.CodeDataError), "pkg_name and level are required") return } if err := common.SetLevel(req.Level); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "message": "Invalid log level: " + req.Level, - }) + common.ErrorWithCode(c, int(common.CodeDataError), "Invalid log level: "+req.Level) return } @@ -216,29 +181,18 @@ func (h *SystemHandler) SetLogLevel(c *gin.Context) { config.Log.Level = common.GetLevel() } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": gin.H{"level": req.Level}, - }) + common.SuccessWithData(c, gin.H{"level": req.Level}, "SUCCESS") } // ListVariables handle list variables func (h *SystemHandler) ListVariables(c *gin.Context) { variables, err := h.systemService.ListAllVariables() if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": 500, - "message": err.Error(), - }) + common.ErrorWithCode(c, 500, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": variables, - }) + common.SuccessWithData(c, variables, "SUCCESS") } // SetVariableHTTPRequest set variable request @@ -252,41 +206,26 @@ type SetVariableHTTPRequest struct { func (h *SystemHandler) SetVariable(c *gin.Context) { var req SetVariableHTTPRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": 400, - "message": "Var name is required", - }) + common.ErrorWithCode(c, 400, "Var name is required") return } if req.VarName == "" { - c.JSON(http.StatusOK, gin.H{ - "code": 400, - "message": "Var name is required", - }) + common.ErrorWithCode(c, 400, "Var name is required") return } if req.VarValue == "" { - c.JSON(http.StatusOK, gin.H{ - "code": 400, - "message": "Var value is required", - }) + common.ErrorWithCode(c, 400, "Var value is required") return } if err := h.systemService.SetVariable(req.VarName, req.VarValue); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": 500, - "message": err.Error(), - }) + common.ErrorWithCode(c, 500, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "SUCCESS", - }) + common.SuccessNoData(c, "SUCCESS") } func (h *SystemHandler) ShowVariable(c *gin.Context) { @@ -294,50 +233,30 @@ func (h *SystemHandler) ShowVariable(c *gin.Context) { varName, err := common.DecodeFromBase64(encodedVarName) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": 400, - "message": err.Error(), - }) + common.ErrorWithCode(c, 400, err.Error()) return } if varName == "" { - c.JSON(http.StatusOK, gin.H{ - "code": 400, - "message": "Var name is required", - }) + common.ErrorWithCode(c, 400, "Var name is required") return } variable, err := h.systemService.ShowVariable(varName) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": 500, - "message": err.Error(), - }) + common.ErrorWithCode(c, 500, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "SUCCESS", - "data": variable, - }) + common.SuccessWithData(c, variable, "SUCCESS") } // ListEnvironments handle list environments func (h *SystemHandler) ListEnvironments(c *gin.Context) { environments, err := h.systemService.ListEnvironments() if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": 500, - "message": err.Error(), - }) + common.ErrorWithCode(c, 500, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "message": "success", - "data": environments, - }) + common.SuccessWithData(c, environments, "SUCCESS") } diff --git a/internal/handler/tenant.go b/internal/handler/tenant.go index 7cc135ffb0..e422d897dd 100644 --- a/internal/handler/tenant.go +++ b/internal/handler/tenant.go @@ -63,45 +63,29 @@ type SetModelRequest struct { func (h *TenantHandler) setDefaultModels(c *gin.Context, wrapModels bool) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } // Parse request body (same as Python get_request_json()) var req SetModelRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": common.CodeBadRequest, - "data": nil, - "message": "Invalid request body: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "Invalid request body: "+err.Error()) return } err := h.tenantService.SetTenantDefaultModels(user.ID, req.ModelProvider, req.ModelInstance, req.ModelName, req.ModelType, req.ModelID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeExceptionError, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeExceptionError, false, err.Error()) return } if wrapModels { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": map[string]interface{}{"models": []service.ModelItem{}}, - }) + common.SuccessWithData(c, map[string]interface{}{"models": []service.ModelItem{}}, "success") return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": nil, - }) + common.SuccessNoData(c, "success") } // GetDefaultModels returns the tenant's default model selections. The @@ -112,17 +96,13 @@ func (h *TenantHandler) setDefaultModels(c *gin.Context, wrapModels bool) { func (h *TenantHandler) GetDefaultModels(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } defaultModels, err := h.tenantService.ListTenantDefaultModels(user.ID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeExceptionError, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeExceptionError, false, err.Error()) return } @@ -133,11 +113,7 @@ func (h *TenantHandler) GetDefaultModels(c *gin.Context) { if defaultModels == nil { defaultModels = []service.ModelItem{} } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": map[string]interface{}{"models": defaultModels}, - }) + common.SuccessWithData(c, map[string]interface{}{"models": defaultModels}, "success") } // TenantInfo get tenant information @@ -152,34 +128,22 @@ func (h *TenantHandler) GetDefaultModels(c *gin.Context) { func (h *TenantHandler) TenantInfo(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } tenantInfo, err := h.tenantService.GetTenantInfo(user.ID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeExceptionError, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeExceptionError, false, err.Error()) return } if tenantInfo == nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "message": "Tenant not found!", - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeDataError, false, "Tenant not found!") return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": tenantInfo, - }) + common.SuccessWithData(c, tenantInfo, "success") } // TenantList get tenant list for current user @@ -194,25 +158,17 @@ func (h *TenantHandler) TenantInfo(c *gin.Context) { func (h *TenantHandler) TenantList(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } tenantList, err := h.tenantService.GetTenantList(user.ID) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeExceptionError, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeExceptionError, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": tenantList, - }) + common.SuccessWithData(c, tenantList, "success") } // CreateMetadataStore handles the create metadata store request @@ -227,7 +183,7 @@ func (h *TenantHandler) TenantList(c *gin.Context) { func (h *TenantHandler) CreateMetadataStore(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -236,15 +192,11 @@ func (h *TenantHandler) CreateMetadataStore(c *gin.Context) { code, err := h.tenantService.CreateMetadataStore(tenantID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": nil, - }) + common.SuccessNoData(c, "success") } // DeleteMetadataStore handles the delete metadata store request @@ -259,7 +211,7 @@ func (h *TenantHandler) CreateMetadataStore(c *gin.Context) { func (h *TenantHandler) DeleteMetadataStore(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -268,15 +220,11 @@ func (h *TenantHandler) DeleteMetadataStore(c *gin.Context) { code, err := h.tenantService.DeleteMetadataStore(tenantID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": nil, - }) + common.SuccessNoData(c, "success") } // CreateChunkTableRequest represents the request for creating a chunk table @@ -298,19 +246,19 @@ type CreateChunkTableRequest struct { func (h *TenantHandler) CreateChunkStore(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req CreateChunkTableRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } // Check authorization - user must have access to this kb if !h.datasetService.Accessible(req.KBID, user.ID) { - jsonError(c, common.CodeAuthenticationError, "No authorization.") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "No authorization.") return } @@ -320,15 +268,11 @@ func (h *TenantHandler) CreateChunkStore(c *gin.Context) { } result, code, err := h.tenantService.CreateChunkStore(serviceReq) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": result, - }) + common.SuccessWithData(c, result, "success") } // DeleteChunkTableRequest represents the request for deleting a chunk table @@ -349,33 +293,29 @@ type DeleteChunkTableRequest struct { func (h *TenantHandler) DeleteChunkStore(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req DeleteChunkTableRequest if err := c.ShouldBindJSON(&req); err != nil { - jsonError(c, common.CodeDataError, err.Error()) + common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error()) return } // Check authorization if !h.datasetService.Accessible(req.KBID, user.ID) { - jsonError(c, common.CodeAuthenticationError, "No authorization.") + common.ResponseWithCodeData(c, common.CodeAuthenticationError, nil, "No authorization.") return } code, err := h.tenantService.DeleteChunkStore(req.KBID) if err != nil { - jsonError(c, code, err.Error()) + common.ErrorWithCode(c, int(code), err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": nil, - }) + common.SuccessNoData(c, "success") } // InsertChunksFromFileRequest request for inserting chunks from file @@ -395,24 +335,18 @@ type InsertChunksFromFileRequest struct { func (h *TenantHandler) InsertChunksFromFile(c *gin.Context) { _, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req InsertChunksFromFileRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, err.Error()) return } if req.FilePath == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "file_path is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "file_path is required") return } @@ -423,10 +357,7 @@ func (h *TenantHandler) InsertChunksFromFile(c *gin.Context) { // to admin/owner roles upstream. data, err := os.ReadFile(req.FilePath) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "failed to read file: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "failed to read file: "+err.Error()) return } @@ -438,19 +369,13 @@ func (h *TenantHandler) InsertChunksFromFile(c *gin.Context) { Chunks []map[string]interface{} `json:"chunks"` } - if err := json.Unmarshal(data, &debugFormat); err != nil || debugFormat.Chunks == nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "invalid JSON format: expected {\"index_name\"/\"table_name\": ..., \"knowledgebase_id\": ..., \"chunks\": [...]}", - }) + if err = json.Unmarshal(data, &debugFormat); err != nil || debugFormat.Chunks == nil { + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "invalid JSON format: expected {\"index_name\"/\"table_name\": ..., \"knowledgebase_id\": ..., \"chunks\": [...]}") return } if len(debugFormat.Chunks) == 0 { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "no chunks found in file", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "no chunks found in file") return } @@ -464,18 +389,11 @@ func (h *TenantHandler) InsertChunksFromFile(c *gin.Context) { docEngine := engine.Get() result, err := docEngine.InsertChunks(c.Request.Context(), debugFormat.Chunks, indexName, debugFormat.KnowledgebaseID) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": "failed to insert into dataset: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "failed to insert into dataset: "+err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } // InsertMetadataFromFileRequest request for inserting metadata from file @@ -495,24 +413,18 @@ type InsertMetadataFromFileRequest struct { func (h *TenantHandler) InsertMetadataFromFile(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } var req InsertMetadataFromFileRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, err.Error()) return } if req.FilePath == "" { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "file_path is required", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "file_path is required") return } @@ -523,10 +435,7 @@ func (h *TenantHandler) InsertMetadataFromFile(c *gin.Context) { // codeql[go/path-injection] False positive: req.FilePath is the data, err := os.ReadFile(req.FilePath) if err != nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "failed to read file: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "failed to read file: "+err.Error()) return } @@ -535,19 +444,13 @@ func (h *TenantHandler) InsertMetadataFromFile(c *gin.Context) { Chunks []map[string]interface{} `json:"chunks"` } - if err := json.Unmarshal(data, &inputFormat); err != nil || inputFormat.Chunks == nil { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "invalid JSON format: expected {\"chunks\": [...]}", - }) + if err = json.Unmarshal(data, &inputFormat); err != nil || inputFormat.Chunks == nil { + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "invalid JSON format: expected {\"chunks\": [...]}") return } if len(inputFormat.Chunks) == 0 { - c.JSON(http.StatusBadRequest, gin.H{ - "code": 400, - "message": "no chunks found in file", - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "no chunks found in file") return } @@ -558,18 +461,11 @@ func (h *TenantHandler) InsertMetadataFromFile(c *gin.Context) { docEngine := engine.Get() result, err := docEngine.InsertMetadata(c.Request.Context(), inputFormat.Chunks, tenantID) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{ - "code": 500, - "message": "failed to insert metadata: " + err.Error(), - }) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "failed to insert metadata: "+err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": 0, - "data": result, - "message": "success", - }) + common.SuccessWithData(c, result, "success") } // ListTenantMembers lists all non-owner members of a tenant. @@ -581,22 +477,22 @@ func (h *TenantHandler) InsertMetadataFromFile(c *gin.Context) { func (h *TenantHandler) ListTenantMembers(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } tenantID := c.Param("tenant_id") if tenantID == "" { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeBadRequest, "data": nil, "message": "tenant_id is required"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "tenant_id is required") return } members, code, err := h.tenantService.ListMembers(user.ID, tenantID) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": code, "data": nil, "message": err.Error()}) + common.ResponseWithCodeData(c, code, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{"code": common.CodeSuccess, "data": members, "message": "success"}) + common.SuccessWithData(c, members, "success") } // AddTenantMember invites a user (by email) to the tenant. @@ -610,28 +506,28 @@ func (h *TenantHandler) ListTenantMembers(c *gin.Context) { func (h *TenantHandler) AddTenantMember(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } tenantID := c.Param("tenant_id") if tenantID == "" { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeBadRequest, "data": nil, "message": "tenant_id is required"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "tenant_id is required") return } var req service.AddMemberRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeBadRequest, "data": nil, "message": "invalid request body: " + err.Error()}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "invalid request body: "+err.Error()) return } resp, code, err := h.tenantService.AddMember(user.ID, tenantID, &req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": code, "data": nil, "message": err.Error()}) + common.ResponseWithCodeData(c, code, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{"code": common.CodeSuccess, "data": resp, "message": "success"}) + common.SuccessWithData(c, resp, "success") } // RemoveTenantMember removes a user from the tenant. @@ -645,13 +541,13 @@ func (h *TenantHandler) AddTenantMember(c *gin.Context) { func (h *TenantHandler) RemoveTenantMember(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } tenantID := c.Param("tenant_id") if tenantID == "" { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeBadRequest, "data": nil, "message": "tenant_id is required"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "tenant_id is required") return } @@ -659,16 +555,16 @@ func (h *TenantHandler) RemoveTenantMember(c *gin.Context) { UserID string `json:"user_id"` } if err := c.ShouldBindJSON(&body); err != nil || body.UserID == "" { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeBadRequest, "data": nil, "message": "user_id is required"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "user_id is required") return } code, err := h.tenantService.RemoveMember(user.ID, tenantID, body.UserID) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": code, "data": nil, "message": err.Error()}) + common.ResponseWithCodeData(c, code, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{"code": common.CodeSuccess, "data": true, "message": "success"}) + common.SuccessWithData(c, true, "success") } // AcceptTenantInvite accepts a pending team invitation, transitioning role invite → normal. @@ -680,20 +576,20 @@ func (h *TenantHandler) RemoveTenantMember(c *gin.Context) { func (h *TenantHandler) AcceptTenantInvite(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } tenantID := c.Param("tenant_id") if tenantID == "" { - c.JSON(http.StatusBadRequest, gin.H{"code": common.CodeBadRequest, "data": nil, "message": "tenant_id is required"}) + common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "tenant_id is required") return } code, err := h.tenantService.AcceptInvite(user.ID, tenantID) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": code, "data": nil, "message": err.Error()}) + common.ResponseWithCodeData(c, code, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{"code": common.CodeSuccess, "data": true, "message": "success"}) + common.SuccessWithData(c, true, "success") } diff --git a/internal/handler/user.go b/internal/handler/user.go index 86a4ffebab..18c52cd80b 100644 --- a/internal/handler/user.go +++ b/internal/handler/user.go @@ -56,11 +56,7 @@ func NewUserHandler(userService *service.UserService) *UserHandler { func (h *UserHandler) Register(c *gin.Context) { var req service.RegisterRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeBadRequest, false, err.Error()) return } @@ -70,30 +66,18 @@ func (h *UserHandler) Register(c *gin.Context) { if code == common.CodeExceptionError { data = nil } - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - "data": data, - }) + common.ResponseWithCodeData(c, code, data, err.Error()) return } secretKey, err := server.GetSecretKey(redis.Get()) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": fmt.Sprintf("Failed to get secret key: %s", err.Error()), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeServerError, false, err.Error()) return } authToken, err := utility.DumpAccessToken(*user.AccessToken, secretKey) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": "Failed to generate auth token", - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeServerError, false, "Failed to generate auth token") return } @@ -105,11 +89,7 @@ func (h *UserHandler) Register(c *gin.Context) { c.Header("Access-Control-Expose-Headers", "Authorization") profile := h.userService.GetUserProfile(user) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": fmt.Sprintf("%s, welcome aboard!", req.Nickname), - "data": profile, - }) + common.SuccessWithData(c, profile, fmt.Sprintf("%s, welcome aboard!", req.Nickname)) } // Login user login @@ -124,41 +104,25 @@ func (h *UserHandler) Register(c *gin.Context) { func (h *UserHandler) Login(c *gin.Context) { var req service.LoginRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeBadRequest, false, err.Error()) return } user, code, err := h.userService.Login(&req) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, code, false, err.Error()) return } // Sign the access_token using itsdangerous (compatible with Python) secretKey, err := server.GetSecretKey(redis.Get()) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": fmt.Sprintf("Failed to get secret key: %s", err.Error()), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeServerError, false, fmt.Sprintf("Failed to get secret key: %s", err.Error())) return } authToken, err := utility.DumpAccessToken(*user.AccessToken, secretKey) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": "Failed to generate auth token", - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeServerError, false, "Failed to generate auth token") return } @@ -172,11 +136,7 @@ func (h *UserHandler) Login(c *gin.Context) { c.Header("Access-Control-Expose-Headers", "Authorization") profile := h.userService.GetUserProfile(user) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "Welcome back!", - "data": profile, - }) + common.SuccessWithData(c, profile, "Welcome back!") } // LoginByEmail user login by email @@ -191,50 +151,30 @@ func (h *UserHandler) Login(c *gin.Context) { func (h *UserHandler) LoginByEmail(c *gin.Context) { var req service.EmailLoginRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeBadRequest, false, err.Error()) return } if !local.IsAdminAvailable() { license := local.GetAdminStatus() - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeAuthenticationError, - "message": license.Reason, - "data": "No", - }) + common.ResponseWithCodeData(c, common.CodeAuthenticationError, "No", license.Reason) return } user, code, err := h.userService.LoginByEmail(&req) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, code, false, err.Error()) return } secretKey, err := server.GetSecretKey(redis.Get()) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": fmt.Sprintf("Failed to get secret key: %s", err.Error()), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeServerError, false, fmt.Sprintf("Failed to get secret key: %s", err.Error())) return } authToken, err := utility.DumpAccessToken(*user.AccessToken, secretKey) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": "Failed to generate auth token", - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeServerError, false, "Failed to generate auth token") return } setOAuthAuthCookie(c, authToken) @@ -245,11 +185,7 @@ func (h *UserHandler) LoginByEmail(c *gin.Context) { c.Header("Access-Control-Expose-Headers", "Authorization") profile := h.userService.GetUserProfile(user) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "Welcome back!", - "data": profile, - }) + common.SuccessWithData(c, profile, "Welcome back!") } // GetUserByID get user by ID @@ -265,29 +201,17 @@ func (h *UserHandler) GetUserByID(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": "invalid user id", - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeBadRequest, false, "invalid user id") return } user, code, err := h.userService.GetUserByID(uint(id)) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, code, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": user, - }) + common.SuccessWithData(c, user, "success") } // ListUsers user list @@ -313,24 +237,16 @@ func (h *UserHandler) ListUsers(c *gin.Context) { users, total, code, err := h.userService.ListUsers(page, pageSize) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, code, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": gin.H{ - "items": users, - "total": total, - "page": page, - "page_size": pageSize, - }, - }) + common.SuccessWithData(c, gin.H{ + "items": users, + "total": total, + "page": page, + "page_size": pageSize, + }, "success") } // Logout user logout @@ -356,10 +272,7 @@ func (h *UserHandler) Logout(c *gin.Context) { // Same as AuthMiddleware@auth.go token := c.GetHeader("Authorization") if token == "" { - c.JSON(http.StatusUnauthorized, gin.H{ - "code": 401, - "message": "Missing Authorization header", - }) + common.ResponseWithHttpCodeData(c, http.StatusUnauthorized, 401, nil, "Missing Authorization header") c.Abort() return } @@ -367,10 +280,7 @@ func (h *UserHandler) Logout(c *gin.Context) { // Get user by access token user, code, err := h.userService.GetUserByToken(token) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{ - "code": code, - "message": "Invalid access token", - }) + common.ResponseWithHttpCodeData(c, http.StatusUnauthorized, code, nil, "Invalid access token") c.Abort() return } @@ -378,19 +288,11 @@ func (h *UserHandler) Logout(c *gin.Context) { // Logout user code, err = h.userService.Logout(user) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, code, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "data": true, - "message": "success", - }) + common.SuccessWithData(c, true, "success") } // Info get user profile information @@ -405,18 +307,14 @@ func (h *UserHandler) Logout(c *gin.Context) { func (h *UserHandler) Info(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } // Get user profile profile := h.userService.GetUserProfile(user) - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": profile, - }) + common.SuccessWithData(c, profile, "success") } // Setting update user settings @@ -432,18 +330,14 @@ func (h *UserHandler) Info(c *gin.Context) { func (h *UserHandler) Setting(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } // Parse request var req service.UpdateSettingsRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeBadRequest, false, err.Error()) return } @@ -451,26 +345,14 @@ func (h *UserHandler) Setting(c *gin.Context) { code, err := h.userService.UpdateUserSettings(user, &req) if err != nil { if code == common.CodeExceptionError { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeExceptionError, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, code, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": true, - }) + common.SuccessWithData(c, true, "success") } // ChangePassword change user password @@ -486,37 +368,25 @@ func (h *UserHandler) Setting(c *gin.Context) { func (h *UserHandler) ChangePassword(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } // Parse request var req service.ChangePasswordRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeBadRequest, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeBadRequest, false, err.Error()) return } // Change password code, err := h.userService.ChangePassword(user, &req) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, code, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "password changed successfully", - "data": true, - }) + common.SuccessWithData(c, true, "password changed successfully") } // GetLoginChannels get all supported authentication channels @@ -530,19 +400,11 @@ func (h *UserHandler) ChangePassword(c *gin.Context) { func (h *UserHandler) GetLoginChannels(c *gin.Context) { channels, code, err := h.userService.GetLoginChannels() if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": "Load channels failure, error: " + err.Error(), - "data": []interface{}{}, - }) + common.ResponseWithCodeData(c, code, []interface{}{}, "Load channels failure, error: "+err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": channels, - }) + common.SuccessWithData(c, channels, "success") } // SetTenantInfo update tenant information @@ -558,7 +420,7 @@ func (h *UserHandler) GetLoginChannels(c *gin.Context) { func (h *UserHandler) SetTenantInfo(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { - jsonError(c, errorCode, errorMessage) + common.ErrorWithCode(c, int(errorCode), errorMessage) return } @@ -567,11 +429,7 @@ func (h *UserHandler) SetTenantInfo(c *gin.Context) { var payload map[string]interface{} if err := c.ShouldBindBodyWith(&payload, binding.JSON); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": missingArgumentMessage, - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, missingArgumentMessage) return } @@ -582,11 +440,7 @@ func (h *UserHandler) SetTenantInfo(c *gin.Context) { } } if len(missing) > 0 { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": fmt.Sprintf("required argument are missing: %s; ", joinStrings(missing)), - "data": nil, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, fmt.Sprintf("required argument are missing: %s; ", joinStrings(missing))) return } @@ -615,19 +469,11 @@ func (h *UserHandler) SetTenantInfo(c *gin.Context) { code, err := h.userService.SetTenantInfo(user.ID, &req) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - "data": nil, - }) + common.ResponseWithCodeData(c, code, nil, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "success", - "data": true, - }) + common.SuccessWithData(c, true, "success") } func joinStrings(values []string) string { @@ -692,21 +538,13 @@ func (h *UserHandler) ForgotCaptcha(c *gin.Context) { captchaID, captchaImage, errCode, err := h.userService.ForgotIssueCaptcha(req.Email) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errCode, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, errCode, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "captcha issued", - "data": gin.H{ - "captcha_id": captchaID, - "captcha_image": captchaImage, - }, - }) + common.SuccessWithData(c, gin.H{ + "captcha_id": captchaID, + "captcha_image": captchaImage, + }, "captcha issued") } type forgotSendOTPRequest struct { @@ -729,27 +567,15 @@ type forgotSendOTPRequest struct { func (h *UserHandler) ForgotSendOTP(c *gin.Context) { var req forgotSendOTPRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, false, err.Error()) return } errCode, err := h.userService.ForgotSendOTP(req.Email, req.CaptchaID, req.Captcha) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errCode, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, errCode, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "verification passed, email sent", - "data": true, - }) + common.SuccessWithData(c, true, "verification passed, email sent") } type forgotVerifyOTPRequest struct { @@ -771,27 +597,15 @@ type forgotVerifyOTPRequest struct { func (h *UserHandler) ForgotVerifyOTP(c *gin.Context) { var req forgotVerifyOTPRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, false, err.Error()) return } errCode, err := h.userService.ForgotVerifyOTP(req.Email, req.OTP) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": errCode, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, errCode, false, err.Error()) return } - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "otp verified", - "data": true, - }) + common.SuccessWithData(c, true, "otp verified") } // ForgotResetPassword POST /api/v1/auth/password/reset @@ -808,40 +622,24 @@ func (h *UserHandler) ForgotVerifyOTP(c *gin.Context) { func (h *UserHandler) ForgotResetPassword(c *gin.Context) { var req service.ForgotResetPasswordRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, false, err.Error()) return } user, code, err := h.userService.ForgotResetPassword(&req) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": code, - "message": err.Error(), - "data": false, - }) + common.ResponseWithCodeData(c, code, false, err.Error()) return } secretKey, err := server.GetSecretKey(redis.Get()) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": fmt.Sprintf("Failed to get secret key: %s", err.Error()), - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeServerError, false, fmt.Sprintf("Failed to get secret key: %s", err.Error())) return } authToken, err := utility.DumpAccessToken(*user.AccessToken, secretKey) if err != nil { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeServerError, - "message": "Failed to generate auth token", - "data": false, - }) + common.ResponseWithCodeData(c, common.CodeServerError, false, "Failed to generate auth token") return } c.Header("Authorization", authToken) @@ -855,9 +653,5 @@ func (h *UserHandler) ForgotResetPassword(c *gin.Context) { profile := h.userService.GetUserProfile(user) delete(profile, "password") delete(profile, "access_token") - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeSuccess, - "message": "Password reset successful. Logged in.", - "data": profile, - }) + common.SuccessWithData(c, profile, "Password reset successful. Logged in.") } diff --git a/internal/service/openai_chat.go b/internal/service/openai_chat.go index 0964bf72a4..78914b5fa6 100644 --- a/internal/service/openai_chat.go +++ b/internal/service/openai_chat.go @@ -829,18 +829,10 @@ func streamChatCompletionSSE( // writeArgError writes a 101 JSON error envelope (malformed request). func (s *OpenAIChatService) writeArgError(c *gin.Context, msg string) { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeArgumentError, - "data": nil, - "message": msg, - }) + common.ResponseWithCodeData(c, common.CodeArgumentError, nil, msg) } // writeDataError writes a 102 JSON error envelope (service failure). func (s *OpenAIChatService) writeDataError(c *gin.Context, msg string) { - c.JSON(http.StatusOK, gin.H{ - "code": common.CodeDataError, - "data": nil, - "message": msg, - }) + common.ResponseWithCodeData(c, common.CodeDataError, nil, msg) }