Go: refactor (#16602)

### Summary

1. update doc
2. refactor route code

---------

Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
Jin Hai
2026-07-03 17:00:43 +08:00
committed by GitHub
parent 79518973e5
commit 1880e65e99
169 changed files with 373 additions and 1304 deletions

View File

@@ -40,6 +40,24 @@ 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)
}

View File

@@ -31,7 +31,7 @@ import (
"ragflow/internal/entity"
modelModule "ragflow/internal/entity/models"
"ragflow/internal/service"
"ragflow/internal/service/kg"
"ragflow/internal/service/graph"
"ragflow/internal/service/nlp"
"github.com/gin-gonic/gin"
@@ -291,7 +291,7 @@ func (h *DifyRetrievalHandler) Retrieval(c *gin.Context) {
if kgErr != nil {
common.Warn("KG retrieval: failed to get chat model", zap.String("kbID", req.KnowledgeID), zap.Error(kgErr))
} else if chatModel != nil {
kgPipeline := kg.NewPipeline(
kgPipeline := graph.NewPipeline(
h.docEngine,
[]string{req.KnowledgeID},
[]string{kb.TenantID},

View File

@@ -1189,61 +1189,6 @@ func stringValue(value *string) string {
return *value
}
// GetDocumentsByAuthorID get documents by author ID
// @Summary Get Author Documents
// @Description Get paginated document list by author ID
// @Tags documents
// @Accept json
// @Produce json
// @Param author_id path int true "author ID"
// @Param page query int false "page number" default(1)
// @Param page_size query int false "items per page" default(10)
// @Success 200 {object} map[string]interface{}
// @Router /api/v1/authors/{author_id}/documents [get]
func (h *DocumentHandler) GetDocumentsByAuthorID(c *gin.Context) {
_, errorCode, errorMessage := GetUser(c)
if errorCode != common.CodeSuccess {
jsonError(c, errorCode, errorMessage)
return
}
authorIDStr := c.Param("author_id")
authorID, err := strconv.Atoi(authorIDStr)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "invalid author id",
})
return
}
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 {
pageSize = 10
}
documents, total, err := h.documentService.GetDocumentsByAuthorID(authorID, page, pageSize)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "failed to get documents",
})
return
}
c.JSON(http.StatusOK, gin.H{
"data": gin.H{
"items": documents,
"total": total,
"page": page,
"page_size": pageSize,
},
})
}
// MetadataSummary handles the metadata summary request
func (h *DocumentHandler) MetadataSummary(c *gin.Context) {
_, errorCode, errorMessage := GetUser(c)

View File

@@ -1,435 +0,0 @@
//
// 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 handler
import (
"net/http"
"ragflow/internal/common"
"ragflow/internal/service"
"strings"
"github.com/gin-gonic/gin"
)
// KnowledgebaseHandler handles knowledge base HTTP requests
type KnowledgebaseHandler struct {
kbService *service.KnowledgebaseService
userService *service.UserService
documentService *service.DocumentService
}
// NewKnowledgebaseHandler creates a new knowledge base handler
func NewKnowledgebaseHandler(kbService *service.KnowledgebaseService, userService *service.UserService, documentService *service.DocumentService) *KnowledgebaseHandler {
return &KnowledgebaseHandler{
kbService: kbService,
userService: userService,
documentService: documentService,
}
}
// 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,
})
}
// HTTPError represents an HTTP error
type HTTPError struct {
Code common.ErrorCode
Message string
}
// Error implements the error interface
func (e *HTTPError) Error() string {
return e.Message
}
var (
// ErrMissingAuth indicates missing authorization header
ErrMissingAuth = &HTTPError{Code: common.CodeUnauthorized, Message: "Missing Authorization header"}
// ErrInvalidToken indicates invalid access token
ErrInvalidToken = &HTTPError{Code: common.CodeUnauthorized, Message: "Invalid access token"}
ErrForbidden = &HTTPError{Code: common.CodeForbidden, Message: "Forbidden user"}
)
// @Summary Update Knowledge Base
// @Description Update an existing knowledge base
// @Tags knowledgebase
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body service.UpdateKBRequest true "knowledge base update info"
// @Success 200 {object} map[string]interface{}
// @Router /v1/kb/update [post]
func (h *KnowledgebaseHandler) UpdateKB(c *gin.Context) {
user, errorCode, errorMessage := GetUser(c)
if errorCode != common.CodeSuccess {
jsonError(c, errorCode, errorMessage)
return
}
var req service.UpdateKBRequest
if err := c.ShouldBindJSON(&req); err != nil {
jsonError(c, common.CodeDataError, err.Error())
return
}
result, code, err := h.kbService.UpdateKB(&req, user.ID)
if err != nil {
if strings.Contains(err.Error(), "authorization") {
jsonError(c, common.CodeAuthenticationError, err.Error())
return
}
jsonError(c, code, err.Error())
return
}
jsonResponse(c, common.CodeSuccess, result, "success")
}
// UpdateMetadataSetting handles the update metadata setting request
// @Summary Update Metadata Setting
// @Description Update metadata settings for a knowledge base
// @Tags knowledgebase
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body service.UpdateMetadataSettingRequest true "metadata setting info"
// @Success 200 {object} map[string]interface{}
// @Router /v1/kb/update_metadata_setting [post]
func (h *KnowledgebaseHandler) UpdateMetadataSetting(c *gin.Context) {
user, errorCode, errorMessage := GetUser(c)
if errorCode != common.CodeSuccess {
jsonError(c, errorCode, errorMessage)
return
}
var req service.UpdateMetadataSettingRequest
if err := c.ShouldBindJSON(&req); err != nil {
jsonError(c, common.CodeDataError, err.Error())
return
}
if !h.kbService.Accessible(req.KBID, user.ID) {
jsonError(c, common.CodeAuthenticationError, "No authorization.")
return
}
result, code, err := h.kbService.UpdateMetadataSetting(&req, user.ID)
if err != nil {
if strings.Contains(err.Error(), "authorized") {
jsonError(c, common.CodeAuthenticationError, err.Error())
return
}
jsonError(c, code, err.Error())
return
}
jsonResponse(c, common.CodeSuccess, result, "success")
}
// GetDetail handles the get knowledge base detail request
// @Summary Get Knowledge Base Detail
// @Description Get detailed information about a knowledge base
// @Tags knowledgebase
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param kb_id query string true "Knowledge Base ID"
// @Success 200 {object} map[string]interface{}
// @Router /v1/kb/detail [get]
func (h *KnowledgebaseHandler) GetDetail(c *gin.Context) {
user, errorCode, errorMessage := GetUser(c)
if errorCode != common.CodeSuccess {
jsonError(c, errorCode, errorMessage)
return
}
kbID := c.Query("kb_id")
if kbID == "" {
jsonError(c, common.CodeDataError, "kb_id is required")
return
}
result, code, err := h.kbService.GetDetail(kbID, user.ID)
if err != nil {
if strings.Contains(err.Error(), "authorized") {
jsonError(c, common.CodeOperatingError, err.Error())
return
}
jsonError(c, code, err.Error())
return
}
jsonResponse(c, common.CodeSuccess, result, "success")
}
// ListTags handles the list tags request for a knowledge base
// @Summary List Tags
// @Description List tags for a knowledge base
// @Tags knowledgebase
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param kb_id path string true "Knowledge Base ID"
// @Success 200 {object} map[string]interface{}
// @Router /v1/kb/{kb_id}/tags [get]
func (h *KnowledgebaseHandler) ListTags(c *gin.Context) {
user, errorCode, errorMessage := GetUser(c)
if errorCode != common.CodeSuccess {
jsonError(c, errorCode, errorMessage)
return
}
kbID := c.Param("kb_id")
if kbID == "" {
jsonError(c, common.CodeDataError, "kb_id is required")
return
}
if !h.kbService.Accessible(kbID, user.ID) {
jsonError(c, common.CodeAuthenticationError, "No authorization.")
return
}
jsonResponse(c, common.CodeSuccess, []string{}, "success")
}
// ListTagsFromKbs handles the list tags from multiple knowledge bases request
// @Summary List Tags from Knowledge Bases
// @Description List tags from multiple knowledge bases
// @Tags knowledgebase
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param kb_ids query string true "Comma-separated Knowledge Base IDs"
// @Success 200 {object} map[string]interface{}
// @Router /v1/kb/tags [get]
func (h *KnowledgebaseHandler) ListTagsFromKbs(c *gin.Context) {
user, errorCode, errorMessage := GetUser(c)
if errorCode != common.CodeSuccess {
jsonError(c, errorCode, errorMessage)
return
}
kbIDsStr := c.Query("kb_ids")
if kbIDsStr == "" {
jsonError(c, common.CodeDataError, "kb_ids is required")
return
}
kbIDs := strings.Split(kbIDsStr, ",")
for _, kbID := range kbIDs {
if !h.kbService.Accessible(kbID, user.ID) {
jsonError(c, common.CodeAuthenticationError, "No authorization.")
return
}
}
jsonResponse(c, common.CodeSuccess, []string{}, "success")
}
// RenameTag handles the rename tag request
// @Summary Rename Tag
// @Description Rename a tag in a knowledge base
// @Tags knowledgebase
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param kb_id path string true "Knowledge Base ID"
// @Param request body object{from_tag string, to_tag string} true "tag rename info"
// @Success 200 {object} map[string]interface{}
// @Router /v1/kb/{kb_id}/rename_tag [post]
func (h *KnowledgebaseHandler) RenameTag(c *gin.Context) {
user, errorCode, errorMessage := GetUser(c)
if errorCode != common.CodeSuccess {
jsonError(c, errorCode, errorMessage)
return
}
kbID := c.Param("kb_id")
if kbID == "" {
jsonError(c, common.CodeDataError, "kb_id is required")
return
}
if !h.kbService.Accessible(kbID, user.ID) {
jsonError(c, common.CodeAuthenticationError, "No authorization.")
return
}
var req struct {
FromTag string `json:"from_tag" binding:"required"`
ToTag string `json:"to_tag" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
jsonError(c, common.CodeDataError, err.Error())
return
}
jsonResponse(c, common.CodeSuccess, true, "success")
}
// KnowledgeGraph handles the get knowledge graph request
// @Summary Get Knowledge Graph
// @Description Get knowledge graph for a knowledge base
// @Tags knowledgebase
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param kb_id path string true "Knowledge Base ID"
// @Success 200 {object} map[string]interface{}
// @Router /v1/kb/{kb_id}/knowledge_graph [get]
func (h *KnowledgebaseHandler) KnowledgeGraph(c *gin.Context) {
user, errorCode, errorMessage := GetUser(c)
if errorCode != common.CodeSuccess {
jsonError(c, errorCode, errorMessage)
return
}
kbID := c.Param("kb_id")
if kbID == "" {
jsonError(c, common.CodeDataError, "kb_id is required")
return
}
if !h.kbService.Accessible(kbID, user.ID) {
jsonError(c, common.CodeAuthenticationError, "No authorization.")
return
}
result := map[string]interface{}{
"graph": map[string]interface{}{},
"mind_map": map[string]interface{}{},
}
jsonResponse(c, common.CodeSuccess, result, "success")
}
// DeleteKnowledgeGraph handles the delete knowledge graph request
// @Summary Delete Knowledge Graph
// @Description Delete knowledge graph for a knowledge base
// @Tags knowledgebase
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param kb_id path string true "Knowledge Base ID"
// @Success 200 {object} map[string]interface{}
// @Router /v1/kb/{kb_id}/knowledge_graph [delete]
func (h *KnowledgebaseHandler) DeleteKnowledgeGraph(c *gin.Context) {
user, errorCode, errorMessage := GetUser(c)
if errorCode != common.CodeSuccess {
jsonError(c, errorCode, errorMessage)
return
}
kbID := c.Param("kb_id")
if kbID == "" {
jsonError(c, common.CodeDataError, "kb_id is required")
return
}
if !h.kbService.Accessible(kbID, user.ID) {
jsonError(c, common.CodeAuthenticationError, "No authorization.")
return
}
jsonResponse(c, common.CodeSuccess, true, "success")
}
// GetMeta handles the get metadata request
// @Summary Get Metadata
// @Description Get metadata for knowledge bases
// @Tags knowledgebase
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param kb_ids query string true "Comma-separated Knowledge Base IDs"
// @Success 200 {object} map[string]interface{}
// @Router /v1/kb/get_meta [get]
func (h *KnowledgebaseHandler) GetMeta(c *gin.Context) {
user, errorCode, errorMessage := GetUser(c)
if errorCode != common.CodeSuccess {
jsonError(c, errorCode, errorMessage)
return
}
kbIDsStr := c.Query("kb_ids")
if kbIDsStr == "" {
jsonError(c, common.CodeDataError, "kb_ids is required")
return
}
kbIDs := strings.Split(kbIDsStr, ",")
for _, kbID := range kbIDs {
if !h.kbService.Accessible(kbID, user.ID) {
jsonError(c, common.CodeAuthenticationError, "No authorization.")
return
}
}
meta, err := h.documentService.GetMetadataByKBs(kbIDs)
if err != nil {
jsonError(c, common.CodeExceptionError, err.Error())
return
}
jsonResponse(c, common.CodeSuccess, meta, "success")
}
// GetBasicInfo handles the get basic info request
// @Summary Get Basic Info
// @Description Get basic information for a knowledge base
// @Tags knowledgebase
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param kb_id query string true "Knowledge Base ID"
// @Success 200 {object} map[string]interface{}
// @Router /v1/kb/basic_info [get]
func (h *KnowledgebaseHandler) GetBasicInfo(c *gin.Context) {
user, errorCode, errorMessage := GetUser(c)
if errorCode != common.CodeSuccess {
jsonError(c, errorCode, errorMessage)
return
}
kbID := c.Query("kb_id")
if kbID == "" {
jsonError(c, common.CodeDataError, "kb_id is required")
return
}
if !h.kbService.Accessible(kbID, user.ID) {
jsonError(c, common.CodeAuthenticationError, "No authorization.")
return
}
jsonResponse(c, common.CodeSuccess, map[string]interface{}{}, "success")
}

View File

@@ -30,63 +30,20 @@ import (
// TenantHandler tenant handler
type TenantHandler struct {
tenantService *service.TenantService
userService *service.UserService
kbService *service.KnowledgebaseService
tenantService *service.TenantService
userService *service.UserService
datasetService *service.DatasetService
}
// NewTenantHandler create tenant handler
func NewTenantHandler(tenantService *service.TenantService, userService *service.UserService, kbService *service.KnowledgebaseService) *TenantHandler {
func NewTenantHandler(tenantService *service.TenantService, userService *service.UserService, datasetService *service.DatasetService) *TenantHandler {
return &TenantHandler{
tenantService: tenantService,
userService: userService,
kbService: kbService,
tenantService: tenantService,
userService: userService,
datasetService: datasetService,
}
}
func (h *TenantHandler) GetModels(c *gin.Context) {
user, errorCode, errorMessage := GetUser(c)
if errorCode != common.CodeSuccess {
jsonError(c, 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,
})
return
}
// Always return success with an array. The previous contract returned
// code=102 "No default models" for an empty list, which (a) tripped the
// global error toast in web/src/utils/next-request.ts:141 and (b) was
// inconsistent with the Python counterpart in
// api/apps/restful_apis/models_api.py:30 which returns
// get_result(data=[]) on the no-rows path. Frontend hooks (e.g.
// useFetchAllAddedModels) coerce `null` to `[]` already, so `[]` is
// strictly safer.
if defaultModels == nil {
defaultModels = []service.ModelItem{}
}
c.JSON(http.StatusOK, gin.H{
"code": common.CodeSuccess,
"message": "success",
"data": defaultModels,
})
}
type SetModelRequest struct {
ModelProvider string `json:"model_provider"`
ModelInstance string `json:"model_instance"`
ModelName string `json:"model_name"`
ModelID string `json:"model_id"`
ModelType string `json:"model_type" binding:"required"`
}
func (h *TenantHandler) SetModels(c *gin.Context) {
h.setDefaultModels(c, false)
}
@@ -95,6 +52,14 @@ func (h *TenantHandler) SetDefaultModels(c *gin.Context) {
h.setDefaultModels(c, true)
}
type SetModelRequest struct {
ModelProvider string `json:"model_provider"`
ModelInstance string `json:"model_instance"`
ModelName string `json:"model_name"`
ModelID string `json:"model_id"`
ModelType string `json:"model_type" binding:"required"`
}
func (h *TenantHandler) setDefaultModels(c *gin.Context, wrapModels bool) {
user, errorCode, errorMessage := GetUser(c)
if errorCode != common.CodeSuccess {
@@ -344,7 +309,7 @@ func (h *TenantHandler) CreateChunkStore(c *gin.Context) {
}
// Check authorization - user must have access to this kb
if !h.kbService.Accessible(req.KBID, user.ID) {
if !h.datasetService.Accessible(req.KBID, user.ID) {
jsonError(c, common.CodeAuthenticationError, "No authorization.")
return
}
@@ -395,7 +360,7 @@ func (h *TenantHandler) DeleteChunkStore(c *gin.Context) {
}
// Check authorization
if !h.kbService.Accessible(req.KBID, user.ID) {
if !h.datasetService.Accessible(req.KBID, user.ID) {
jsonError(c, common.CodeAuthenticationError, "No authorization.")
return
}