mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-22 07:31:05 +08:00
Refactor: dataset/document/file service (#17071)
### Summary Refactor dataset.go document.do file.go file2document.go in internal/service.
This commit is contained in:
@@ -36,6 +36,7 @@ import (
|
||||
"ragflow/internal/dao"
|
||||
"ragflow/internal/entity"
|
||||
"ragflow/internal/service"
|
||||
"ragflow/internal/service/file"
|
||||
|
||||
dslpkg "ragflow/internal/agent/dsl"
|
||||
)
|
||||
@@ -104,7 +105,7 @@ func (h *AgentHandler) WithDocumentService(s documentAccessChecker) *AgentHandle
|
||||
|
||||
// NewAgentHandler create agent handler
|
||||
|
||||
func NewAgentHandler(agentService *service.AgentService, fileService *service.FileService) *AgentHandler {
|
||||
func NewAgentHandler(agentService *service.AgentService, fileService *file.FileService) *AgentHandler {
|
||||
return &AgentHandler{
|
||||
agentService: agentService,
|
||||
chatRunner: agentService,
|
||||
|
||||
@@ -30,11 +30,12 @@ import (
|
||||
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/service"
|
||||
dataset "ragflow/internal/service/dataset"
|
||||
)
|
||||
|
||||
// DatasetsHandler handles the RESTful dataset endpoints.
|
||||
type DatasetsHandler struct {
|
||||
datasetsService *service.DatasetService
|
||||
datasetsService *dataset.DatasetService
|
||||
metadataService *service.MetadataService
|
||||
searchDatasetsService searchDatasetsService
|
||||
searchDatasetService searchDatasetService
|
||||
@@ -55,7 +56,7 @@ type listDatasetsExt struct {
|
||||
}
|
||||
|
||||
// NewDatasetsHandler creates a new datasets handler.
|
||||
func NewDatasetsHandler(datasetsService *service.DatasetService, metadataService *service.MetadataService) *DatasetsHandler {
|
||||
func NewDatasetsHandler(datasetsService *dataset.DatasetService, metadataService *service.MetadataService) *DatasetsHandler {
|
||||
h := &DatasetsHandler{
|
||||
datasetsService: datasetsService,
|
||||
metadataService: metadataService,
|
||||
|
||||
@@ -38,25 +38,27 @@ import (
|
||||
|
||||
"ragflow/internal/dao"
|
||||
"ragflow/internal/service"
|
||||
dataset "ragflow/internal/service/dataset"
|
||||
"ragflow/internal/service/document"
|
||||
)
|
||||
|
||||
var IMG_BASE64_PREFIX = "data:image/png;base64,"
|
||||
|
||||
// documentServiceIface defines the DocumentService methods used by DocumentHandler.
|
||||
type documentServiceIface interface {
|
||||
GetDocumentByID(id string) (*service.DocumentResponse, error)
|
||||
UpdateDocument(id string, req *service.UpdateDocumentRequest) error
|
||||
GetDocumentByID(id string) (*document.DocumentResponse, error)
|
||||
UpdateDocument(id string, req *document.UpdateDocumentRequest) error
|
||||
DeleteDocument(id string) error
|
||||
DeleteDocuments(ids []string, deleteAll bool, datasetID, userID string) (int, error)
|
||||
ParseDocuments(datasetID, userID string, docIDs []string) ([]*service.ParseDocumentResponse, error)
|
||||
StopParseDocuments(datasetID string, docIDs []string) (map[string]interface{}, error)
|
||||
ListDocuments(page, pageSize int) ([]*service.DocumentResponse, int64, error)
|
||||
ListDocuments(page, pageSize int) ([]*document.DocumentResponse, int64, error)
|
||||
ListDocumentsByDatasetID(kbID, keywords string, page, pageSize int) ([]*entity.DocumentListItem, int64, error)
|
||||
ListDocumentsByDatasetIDWithOptions(opts dao.DocumentListOptions, page, pageSize int) ([]*entity.DocumentListItem, int64, error)
|
||||
ListDocumentIDsByDatasetIDWithOptions(opts dao.DocumentListOptions) ([]string, error)
|
||||
GetDocumentFiltersByDatasetID(opts dao.DocumentListOptions) (map[string]interface{}, int64, error)
|
||||
GetMetadataByKBs(kbIDs []string) (map[string]interface{}, error)
|
||||
GetDocumentsByAuthorID(authorID, page, pageSize int) ([]*service.DocumentResponse, int64, error)
|
||||
GetDocumentsByAuthorID(authorID, page, pageSize int) ([]*document.DocumentResponse, int64, error)
|
||||
GetThumbnails(userID string, docIDs []string) (map[string]string, error)
|
||||
GetDocumentImage(imageID string) ([]byte, error)
|
||||
GetMetadataSummary(kbID string, docIDs []string) (map[string]interface{}, error)
|
||||
@@ -64,35 +66,41 @@ type documentServiceIface interface {
|
||||
DeleteDocumentMetadata(docID string, keys []string) error
|
||||
DeleteDocumentAllMetadata(docID string) error
|
||||
GetDocumentMetadataByID(docID string) (map[string]interface{}, error)
|
||||
GetDocumentArtifact(filename, userID string) (*service.ArtifactResponse, error)
|
||||
GetDocumentPreview(docID string) (*service.DocumentPreview, error)
|
||||
GetDocumentArtifact(filename, userID string) (*document.ArtifactResponse, error)
|
||||
GetDocumentPreview(docID string) (*document.DocumentPreview, error)
|
||||
UploadLocalDocuments(kb *entity.Knowledgebase, tenantID string, files []*multipart.FileHeader, parentPath string, parserConfigOverride map[string]interface{}) ([]map[string]interface{}, []string)
|
||||
UploadWebDocument(kb *entity.Knowledgebase, tenantID, name, url string) (map[string]interface{}, common.ErrorCode, error)
|
||||
UploadEmptyDocument(kb *entity.Knowledgebase, tenantID, name string) (map[string]interface{}, common.ErrorCode, error)
|
||||
DownloadDocument(datasetID, docID string) (*service.DownloadDocumentResp, error)
|
||||
UpdateDatasetDocument(userID, datasetID, documentID string, req *service.UpdateDatasetDocumentRequest, present map[string]bool) (*service.UpdateDatasetDocumentResponse, common.ErrorCode, error)
|
||||
BatchUpdateDocumentMetadatas(datasetID string, selector *service.DocumentMetadataSelector, updates []service.DocumentMetadataUpdate, deletes []service.DocumentMetadataDelete) (*service.BatchUpdateDocumentMetadatasResponse, common.ErrorCode, error)
|
||||
UploadDocumentInfos(userID string, files []*multipart.FileHeader) ([]map[string]interface{}, common.ErrorCode, error)
|
||||
UploadDocumentInfoByURL(userID, rawURL string) (map[string]interface{}, common.ErrorCode, error)
|
||||
DownloadDocument(datasetID, docID string) (*document.DownloadDocumentResp, error)
|
||||
UpdateDatasetDocument(userID, datasetID, documentID string, req *document.UpdateDatasetDocumentRequest, present map[string]bool) (*document.UpdateDatasetDocumentResponse, common.ErrorCode, error)
|
||||
BatchUpdateDocumentMetadatas(datasetID string, selector *document.DocumentMetadataSelector, updates []document.DocumentMetadataUpdate, deletes []document.DocumentMetadataDelete) (*document.BatchUpdateDocumentMetadatasResponse, common.ErrorCode, error)
|
||||
ListIngestionTasks(userID string, datasetID *string, page, pageSize int) ([]*entity.IngestionTask, error)
|
||||
IngestDocuments(datasetID, userID string, docIDs []string) ([]*service.ParseDocumentResponse, error)
|
||||
StopIngestionTasks(tasks []string, userID string) ([]*entity.IngestionTask, error)
|
||||
Ingest(userID string, req *service.IngestDocumentRequest) (common.ErrorCode, error)
|
||||
Ingest(userID string, req *document.IngestDocumentRequest) (common.ErrorCode, error)
|
||||
RemoveIngestionTasks(tasks []string, userID string) ([]map[string]string, error)
|
||||
BatchUpdateDocumentStatus(userID, datasetID, status string, DocumentIDs []string) (map[string]interface{}, common.ErrorCode, error)
|
||||
}
|
||||
|
||||
// fileUploadIface defines the FileService upload methods used by DocumentHandler.
|
||||
type fileUploadIface interface {
|
||||
UploadDocumentInfos(userID string, files []*multipart.FileHeader) ([]map[string]interface{}, common.ErrorCode, error)
|
||||
UploadDocumentInfoByURL(userID, rawURL string) (map[string]interface{}, common.ErrorCode, error)
|
||||
}
|
||||
|
||||
// DocumentHandler document handler
|
||||
type DocumentHandler struct {
|
||||
documentService documentServiceIface
|
||||
datasetService *service.DatasetService
|
||||
datasetService *dataset.DatasetService
|
||||
fileService fileUploadIface
|
||||
}
|
||||
|
||||
// NewDocumentHandler create document handler
|
||||
func NewDocumentHandler(documentService documentServiceIface, datasetService *service.DatasetService) *DocumentHandler {
|
||||
func NewDocumentHandler(documentService documentServiceIface, datasetService *dataset.DatasetService, fileService fileUploadIface) *DocumentHandler {
|
||||
return &DocumentHandler{
|
||||
documentService: documentService,
|
||||
datasetService: datasetService,
|
||||
fileService: fileService,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,9 +227,9 @@ func (h *DocumentHandler) GetDocumentArtifact(c *gin.Context) {
|
||||
artifact, err := h.documentService.GetDocumentArtifact(filename, user.ID)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, service.ErrArtifactInvalidFilename),
|
||||
errors.Is(err, service.ErrArtifactInvalidFileType),
|
||||
errors.Is(err, service.ErrArtifactNotFound):
|
||||
case errors.Is(err, document.ErrArtifactInvalidFilename),
|
||||
errors.Is(err, document.ErrArtifactInvalidFileType),
|
||||
errors.Is(err, document.ErrArtifactNotFound):
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
|
||||
default:
|
||||
@@ -272,7 +280,7 @@ func (h *DocumentHandler) GetDocumentPreview(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path int true "document ID"
|
||||
// @Param request body service.UpdateDocumentRequest true "update info"
|
||||
// @Param request body document.UpdateDocumentRequest true "update info"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/documents/{id} [put]
|
||||
func (h *DocumentHandler) UpdateDocument(c *gin.Context) {
|
||||
@@ -300,7 +308,7 @@ func (h *DocumentHandler) UpdateDocument(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
var req service.UpdateDocumentRequest
|
||||
var req document.UpdateDocumentRequest
|
||||
if err = c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": err.Error(),
|
||||
@@ -1230,7 +1238,7 @@ func (h *DocumentHandler) SetMeta(c *gin.Context) {
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param request body service.IngestDocumentRequest true "ingestion info"
|
||||
// @Param request body document.IngestDocumentRequest true "ingestion info"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/documents/ingest [post]
|
||||
func (h *DocumentHandler) Ingest(c *gin.Context) {
|
||||
@@ -1246,7 +1254,7 @@ func (h *DocumentHandler) Ingest(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
var req service.IngestDocumentRequest
|
||||
var req document.IngestDocumentRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
common.ErrorWithCode(c, common.CodeBadRequest, err.Error())
|
||||
return
|
||||
@@ -1577,7 +1585,7 @@ func (h *DocumentHandler) UpdateDatasetDocument(c *gin.Context) {
|
||||
for key := range raw {
|
||||
present[key] = true
|
||||
}
|
||||
var req service.UpdateDatasetDocumentRequest
|
||||
var req document.UpdateDatasetDocumentRequest
|
||||
if err = json.Unmarshal(body, &req); err != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error())
|
||||
return
|
||||
@@ -1621,7 +1629,7 @@ func (h *DocumentHandler) UploadInfo(c *gin.Context) {
|
||||
}
|
||||
|
||||
if rawURL != "" {
|
||||
data, code, err := h.documentService.UploadDocumentInfoByURL(user.ID, rawURL)
|
||||
data, code, err := h.fileService.UploadDocumentInfoByURL(user.ID, rawURL)
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, code, err.Error())
|
||||
return
|
||||
@@ -1630,7 +1638,7 @@ func (h *DocumentHandler) UploadInfo(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
data, code, err := h.documentService.UploadDocumentInfos(user.ID, fileHeaders)
|
||||
data, code, err := h.fileService.UploadDocumentInfos(user.ID, fileHeaders)
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, code, err.Error())
|
||||
return
|
||||
@@ -1646,9 +1654,9 @@ func (h *DocumentHandler) UploadInfo(c *gin.Context) {
|
||||
}
|
||||
|
||||
type documentMetadataBatchRequest struct {
|
||||
Selector *service.DocumentMetadataSelector `json:"selector"`
|
||||
Updates []service.DocumentMetadataUpdate `json:"updates"`
|
||||
Deletes []service.DocumentMetadataDelete `json:"deletes"`
|
||||
Selector *document.DocumentMetadataSelector `json:"selector"`
|
||||
Updates []document.DocumentMetadataUpdate `json:"updates"`
|
||||
Deletes []document.DocumentMetadataDelete `json:"deletes"`
|
||||
}
|
||||
|
||||
func (h *DocumentHandler) MetadataBatchUpdate(c *gin.Context) {
|
||||
@@ -1682,13 +1690,13 @@ func (h *DocumentHandler) handleBatchUpdateDocumentMetadatas(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
if req.Selector == nil {
|
||||
req.Selector = &service.DocumentMetadataSelector{}
|
||||
req.Selector = &document.DocumentMetadataSelector{}
|
||||
}
|
||||
if req.Updates == nil {
|
||||
req.Updates = []service.DocumentMetadataUpdate{}
|
||||
req.Updates = []document.DocumentMetadataUpdate{}
|
||||
}
|
||||
if req.Deletes == nil {
|
||||
req.Deletes = []service.DocumentMetadataDelete{}
|
||||
req.Deletes = []document.DocumentMetadataDelete{}
|
||||
}
|
||||
|
||||
resp, code, err := h.documentService.BatchUpdateDocumentMetadatas(datasetID, req.Selector, req.Updates, req.Deletes)
|
||||
|
||||
@@ -34,13 +34,15 @@ import (
|
||||
"ragflow/internal/dao"
|
||||
"ragflow/internal/entity"
|
||||
"ragflow/internal/service"
|
||||
dataset "ragflow/internal/service/dataset"
|
||||
"ragflow/internal/service/document"
|
||||
)
|
||||
|
||||
// fakeDocumentService implements documentServiceIface for handler tests.
|
||||
type fakeDocumentService struct {
|
||||
deleted int
|
||||
err error
|
||||
doc *service.DocumentResponse
|
||||
doc *document.DocumentResponse
|
||||
docErr error
|
||||
updateCalled bool
|
||||
updatedID string
|
||||
@@ -71,7 +73,7 @@ type fakeDocumentService struct {
|
||||
ingestCode common.ErrorCode
|
||||
ingestErr error
|
||||
ingestUserID string
|
||||
ingestReq *service.IngestDocumentRequest
|
||||
ingestReq *document.IngestDocumentRequest
|
||||
listOpts dao.DocumentListOptions
|
||||
filterOpts dao.DocumentListOptions
|
||||
filterResult map[string]interface{}
|
||||
@@ -80,7 +82,7 @@ type fakeDocumentService struct {
|
||||
metadataByKBs map[string]interface{}
|
||||
}
|
||||
|
||||
func (f *fakeDocumentService) Ingest(userID string, req *service.IngestDocumentRequest) (common.ErrorCode, error) {
|
||||
func (f *fakeDocumentService) Ingest(userID string, req *document.IngestDocumentRequest) (common.ErrorCode, error) {
|
||||
f.ingestUserID = userID
|
||||
f.ingestReq = req
|
||||
if f.ingestCode != 0 || f.ingestErr != nil {
|
||||
@@ -91,54 +93,48 @@ func (f *fakeDocumentService) Ingest(userID string, req *service.IngestDocumentR
|
||||
|
||||
const uploadTestDatasetID = "123e4567-e89b-12d3-a456-426614174000"
|
||||
|
||||
func (f *fakeDocumentService) UpdateDatasetDocument(userID, datasetID, documentID string, req *service.UpdateDatasetDocumentRequest, present map[string]bool) (*service.UpdateDatasetDocumentResponse, common.ErrorCode, error) {
|
||||
func (f *fakeDocumentService) UpdateDatasetDocument(userID, datasetID, documentID string, req *document.UpdateDatasetDocumentRequest, present map[string]bool) (*document.UpdateDatasetDocumentResponse, common.ErrorCode, error) {
|
||||
return nil, common.CodeSuccess, nil
|
||||
}
|
||||
func (f *fakeDocumentService) BatchUpdateDocumentMetadatas(datasetID string, selector *service.DocumentMetadataSelector, updates []service.DocumentMetadataUpdate, deletes []service.DocumentMetadataDelete) (*service.BatchUpdateDocumentMetadatasResponse, common.ErrorCode, error) {
|
||||
return nil, common.CodeSuccess, nil
|
||||
}
|
||||
func (f *fakeDocumentService) UploadDocumentInfos(userID string, files []*multipart.FileHeader) ([]map[string]interface{}, common.ErrorCode, error) {
|
||||
return nil, common.CodeSuccess, nil
|
||||
}
|
||||
func (f *fakeDocumentService) UploadDocumentInfoByURL(userID, rawURL string) (map[string]interface{}, common.ErrorCode, error) {
|
||||
func (f *fakeDocumentService) BatchUpdateDocumentMetadatas(datasetID string, selector *document.DocumentMetadataSelector, updates []document.DocumentMetadataUpdate, deletes []document.DocumentMetadataDelete) (*document.BatchUpdateDocumentMetadatasResponse, common.ErrorCode, error) {
|
||||
return nil, common.CodeSuccess, nil
|
||||
}
|
||||
|
||||
func (f *fakeDocumentService) GetDocumentArtifact(filename, _ string) (*service.ArtifactResponse, error) {
|
||||
func (f *fakeDocumentService) GetDocumentArtifact(filename, _ string) (*document.ArtifactResponse, error) {
|
||||
if filename == "error.txt" {
|
||||
return nil, service.ErrArtifactNotFound
|
||||
return nil, document.ErrArtifactNotFound
|
||||
}
|
||||
if filename == "unexpected.txt" {
|
||||
return nil, fmt.Errorf("unexpected error")
|
||||
}
|
||||
return &service.ArtifactResponse{
|
||||
return &document.ArtifactResponse{
|
||||
Data: []byte("artifact content"),
|
||||
ContentType: "text/plain",
|
||||
SafeFilename: "safe.txt",
|
||||
ForceAttachment: false,
|
||||
}, nil
|
||||
}
|
||||
func (f *fakeDocumentService) GetDocumentPreview(docID string) (*service.DocumentPreview, error) {
|
||||
func (f *fakeDocumentService) GetDocumentPreview(docID string) (*document.DocumentPreview, error) {
|
||||
if docID == "not-found" {
|
||||
return nil, fmt.Errorf("not found")
|
||||
}
|
||||
return &service.DocumentPreview{
|
||||
return &document.DocumentPreview{
|
||||
Data: []byte("preview content"),
|
||||
ContentType: "text/plain",
|
||||
FileName: "preview.txt",
|
||||
}, nil
|
||||
}
|
||||
func (f *fakeDocumentService) DownloadDocument(datasetID, docID string) (*service.DownloadDocumentResp, error) {
|
||||
func (f *fakeDocumentService) DownloadDocument(datasetID, docID string) (*document.DownloadDocumentResp, error) {
|
||||
if docID == "not-found" {
|
||||
return nil, fmt.Errorf("not found")
|
||||
}
|
||||
return &service.DownloadDocumentResp{
|
||||
return &document.DownloadDocumentResp{
|
||||
Data: []byte("document data"),
|
||||
ContentType: "application/pdf",
|
||||
FileName: "doc.pdf",
|
||||
}, nil
|
||||
}
|
||||
func (f *fakeDocumentService) GetDocumentByID(id string) (*service.DocumentResponse, error) {
|
||||
func (f *fakeDocumentService) GetDocumentByID(id string) (*document.DocumentResponse, error) {
|
||||
if f.docErr != nil {
|
||||
return nil, f.docErr
|
||||
}
|
||||
@@ -147,7 +143,7 @@ func (f *fakeDocumentService) GetDocumentByID(id string) (*service.DocumentRespo
|
||||
}
|
||||
return nil, fmt.Errorf("document not found")
|
||||
}
|
||||
func (f *fakeDocumentService) UpdateDocument(id string, req *service.UpdateDocumentRequest) error {
|
||||
func (f *fakeDocumentService) UpdateDocument(id string, req *document.UpdateDocumentRequest) error {
|
||||
f.updateCalled = true
|
||||
f.updatedID = id
|
||||
return nil
|
||||
@@ -166,7 +162,7 @@ func (f *fakeDocumentService) ParseDocuments(datasetID, userID string, docIDs []
|
||||
func (f *fakeDocumentService) StopParseDocuments(datasetID string, docIDs []string) (map[string]interface{}, error) {
|
||||
return f.stopResult, f.stopErr
|
||||
}
|
||||
func (f *fakeDocumentService) ListDocuments(page, pageSize int) ([]*service.DocumentResponse, int64, error) {
|
||||
func (f *fakeDocumentService) ListDocuments(page, pageSize int) ([]*document.DocumentResponse, int64, error) {
|
||||
return nil, 0, nil
|
||||
}
|
||||
func (f *fakeDocumentService) ListDocumentsByDatasetID(kbID, keywords string, page, pageSize int) ([]*entity.DocumentListItem, int64, error) {
|
||||
@@ -204,7 +200,7 @@ func (f *fakeDocumentService) GetThumbnails(userID string, docIDs []string) (map
|
||||
func (f *fakeDocumentService) GetDocumentImage(imageID string) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (f *fakeDocumentService) GetDocumentsByAuthorID(authorID, page, pageSize int) ([]*service.DocumentResponse, int64, error) {
|
||||
func (f *fakeDocumentService) GetDocumentsByAuthorID(authorID, page, pageSize int) ([]*document.DocumentResponse, int64, error) {
|
||||
return nil, 0, nil
|
||||
}
|
||||
func (f *fakeDocumentService) GetMetadataSummary(kbID string, docIDs []string) (map[string]interface{}, error) {
|
||||
@@ -312,11 +308,11 @@ func TestSetMetaHandler_NotAccessible(t *testing.T) {
|
||||
setupDocumentPermissionDB(t, false)
|
||||
|
||||
fake := &fakeDocumentService{
|
||||
doc: &service.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
doc: &document.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("POST", "/api/v1/document/set_meta", `{"doc_id":"doc-1","meta":"{\"poc\":\"blocked\"}"}`)
|
||||
@@ -344,11 +340,11 @@ func TestSetMetaHandler_Accessible(t *testing.T) {
|
||||
setupDocumentPermissionDB(t, true)
|
||||
|
||||
fake := &fakeDocumentService{
|
||||
doc: &service.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
doc: &document.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("POST", "/api/v1/document/set_meta", `{"doc_id":"doc-1","meta":"{\"category\":\"tech\",\"year\":2026}"}`)
|
||||
@@ -379,11 +375,11 @@ func TestDeleteDocumentHandler_NotAccessible(t *testing.T) {
|
||||
setupDocumentPermissionDB(t, false)
|
||||
|
||||
fake := &fakeDocumentService{
|
||||
doc: &service.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
doc: &document.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("DELETE", "/api/v1/documents/doc-1", "")
|
||||
@@ -412,11 +408,11 @@ func TestDeleteDocumentHandler_Accessible(t *testing.T) {
|
||||
setupDocumentPermissionDB(t, true)
|
||||
|
||||
fake := &fakeDocumentService{
|
||||
doc: &service.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
doc: &document.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("DELETE", "/api/v1/documents/doc-1", "")
|
||||
@@ -445,11 +441,11 @@ func TestUpdateDocumentHandler_NotAccessible(t *testing.T) {
|
||||
setupDocumentPermissionDB(t, false)
|
||||
|
||||
fake := &fakeDocumentService{
|
||||
doc: &service.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
doc: &document.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("PUT", "/api/v1/documents/doc-1", `{"name":"blocked"}`)
|
||||
@@ -478,11 +474,11 @@ func TestUpdateDocumentHandler_Accessible(t *testing.T) {
|
||||
setupDocumentPermissionDB(t, true)
|
||||
|
||||
fake := &fakeDocumentService{
|
||||
doc: &service.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
doc: &document.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("PUT", "/api/v1/documents/doc-1", `{"name":"allowed"}`)
|
||||
@@ -586,7 +582,7 @@ func setupDocumentIngestRoute(userID string, svc *fakeDocumentService) *gin.Engi
|
||||
gin.SetMode(gin.TestMode)
|
||||
h := &DocumentHandler{
|
||||
documentService: svc,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
r := gin.New()
|
||||
r.Use(func(c *gin.Context) {
|
||||
@@ -603,7 +599,7 @@ func TestDeleteDocumentsHandler_Success(t *testing.T) {
|
||||
fake := &fakeDocumentService{deleted: 3}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("DELETE", "/api/v1/datasets/ds-1/documents", `{"ids": ["doc-1", "doc-2", "doc-3"]}`)
|
||||
@@ -639,7 +635,7 @@ func TestUploadDocumentsHandler_LocalUsesFullKBAndIgnoresBadParserConfig(t *test
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupUploadContext(t, "/api/v1/datasets/ds-1/documents?type=local", map[string]string{
|
||||
@@ -680,7 +676,7 @@ func TestUploadDocumentsHandler_LocalReturnsPartialSuccess(t *testing.T) {
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupUploadContext(t, "/api/v1/datasets/ds-1/documents?type=local", nil, "ok.txt", []byte("abc"))
|
||||
@@ -714,7 +710,7 @@ func TestUploadDocumentsHandler_DeniesNonNormalTeamRole(t *testing.T) {
|
||||
fake := &fakeDocumentService{}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupUploadContext(t, "/api/v1/datasets/ds-1/documents?type=local", nil, "a.txt", []byte("abc"))
|
||||
@@ -741,7 +737,7 @@ func TestDeleteDocumentsHandler_DeleteAll(t *testing.T) {
|
||||
fake := &fakeDocumentService{deleted: 5}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("DELETE", "/api/v1/datasets/ds-1/documents", `{"delete_all": true}`)
|
||||
@@ -760,7 +756,7 @@ func TestDeleteDocumentsHandler_MutuallyExclusive(t *testing.T) {
|
||||
fake := &fakeDocumentService{}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("DELETE", "/api/v1/datasets/ds-1/documents", `{"ids": ["doc-1"], "delete_all": true}`)
|
||||
@@ -785,7 +781,7 @@ func TestDeleteDocumentsHandler_NoIDsNoDeleteAll(t *testing.T) {
|
||||
fake := &fakeDocumentService{}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("DELETE", "/api/v1/datasets/ds-1/documents", `{}`)
|
||||
@@ -810,7 +806,7 @@ func TestDeleteDocumentsHandler_ServiceError(t *testing.T) {
|
||||
fake := &fakeDocumentService{err: fmt.Errorf("permission denied")}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("DELETE", "/api/v1/datasets/ds-1/documents", `{"ids": ["doc-1"]}`)
|
||||
@@ -835,7 +831,7 @@ func TestDeleteDocumentsHandler_MissingDatasetID(t *testing.T) {
|
||||
fake := &fakeDocumentService{}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("DELETE", "/api/v1/datasets//documents", `{"ids": ["doc-1"]}`)
|
||||
@@ -859,7 +855,7 @@ func TestDocumentHandlerIngestMatchesPythonResponseShape(t *testing.T) {
|
||||
fake := &fakeDocumentService{}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("POST", "/api/v1/documents/ingest", `{"doc_ids":["doc-1"],"run":"1"}`)
|
||||
@@ -938,7 +934,7 @@ func TestDocumentHandlerIngestPropagatesServiceErrorCode(t *testing.T) {
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("POST", "/api/v1/documents/ingest", `{"doc_ids":["doc-1"],"run":"1"}`)
|
||||
@@ -969,7 +965,7 @@ func TestStopParseDocumentsHandler_EmptyDocIDs(t *testing.T) {
|
||||
fake := &fakeDocumentService{}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("POST", "/api/v1/datasets/ds-1/documents/stop", `{"document_ids": []}`)
|
||||
@@ -994,7 +990,7 @@ func TestStopParseDocumentsHandler_BadJSON(t *testing.T) {
|
||||
fake := &fakeDocumentService{}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("POST", "/api/v1/datasets/ds-1/documents/stop", `not json`)
|
||||
@@ -1071,7 +1067,7 @@ func TestListDocumentsHandler_FilterRequestUsesQueryFilters(t *testing.T) {
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("GET", "/api/v1/datasets/ds-1/documents?type=filter&keywords=report&suffix=pdf&run=DONE&types=doc&desc=false", "")
|
||||
@@ -1129,7 +1125,7 @@ func TestListDocumentsHandler_MetadataFilterNarrowsDocumentIDs(t *testing.T) {
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("GET", "/api/v1/datasets/ds-1/documents?metadata[author][]=Alice", "")
|
||||
@@ -1161,7 +1157,7 @@ func TestStopParseDocumentsHandler_Success(t *testing.T) {
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("POST", "/api/v1/datasets/ds-1/documents/stop", `{"document_ids": ["doc-1"]}`)
|
||||
@@ -1197,7 +1193,7 @@ func TestStopParseDocumentsHandler_ServiceError(t *testing.T) {
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("POST", "/api/v1/datasets/ds-1/documents/stop", `{"document_ids": ["doc-1"]}`)
|
||||
@@ -1227,7 +1223,7 @@ func TestStopParseDocumentsHandler_NotAccessible(t *testing.T) {
|
||||
fake := &fakeDocumentService{}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("POST", "/api/v1/datasets/ds-1/documents/stop", `{"document_ids": ["doc-1"]}`)
|
||||
@@ -1340,7 +1336,7 @@ func TestMetadataSummaryByDataset_Success(t *testing.T) {
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: service.NewDatasetService(),
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("GET", "/api/v1/datasets/ds-1/metadata/summary?doc_ids=doc-1,doc-2", "")
|
||||
|
||||
@@ -30,21 +30,23 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"ragflow/internal/service"
|
||||
"ragflow/internal/service/document"
|
||||
"ragflow/internal/service/file"
|
||||
)
|
||||
|
||||
// FileHandler file handler
|
||||
type FileHandler struct {
|
||||
fileService *service.FileService
|
||||
fileService *file.FileService
|
||||
userService *service.UserService
|
||||
file2DocumentService *service.File2DocumentService
|
||||
file2DocumentService *document.File2DocumentService
|
||||
}
|
||||
|
||||
// NewFileHandler create file handler
|
||||
func NewFileHandler(fileService *service.FileService, userService *service.UserService) *FileHandler {
|
||||
func NewFileHandler(fileService *file.FileService, userService *service.UserService) *FileHandler {
|
||||
return &FileHandler{
|
||||
fileService: fileService,
|
||||
userService: userService,
|
||||
file2DocumentService: service.NewFile2DocumentService(),
|
||||
file2DocumentService: document.NewFile2DocumentService(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +62,7 @@ func NewFileHandler(fileService *service.FileService, userService *service.UserS
|
||||
// @Param page_size query int false "items per page (default: 15, min: 1, max: 100)"
|
||||
// @Param orderby query string false "order by field (default: create_time)"
|
||||
// @Param desc query bool false "descending order (default: true)"
|
||||
// @Success 200 {object} service.ListFilesResponse
|
||||
// @Success 200 {object} file.ListFilesResponse
|
||||
// @Router /api/v1/files [get]
|
||||
func (h *FileHandler) ListFiles(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
@@ -527,7 +529,7 @@ func (h *FileHandler) Download(c *gin.Context) {
|
||||
// @Tags file
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body service.LinkToDatasetsRequest true "file_ids and kb_ids"
|
||||
// @Param request body document.LinkToDatasetsRequest true "file_ids and kb_ids"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/files/link-to-datasets [post]
|
||||
func (h *FileHandler) LinkToDatasets(c *gin.Context) {
|
||||
@@ -537,7 +539,7 @@ func (h *FileHandler) LinkToDatasets(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
var req service.LinkToDatasetsRequest
|
||||
var req document.LinkToDatasetsRequest
|
||||
// Tolerate bind errors: a malformed or empty body simply leaves the fields
|
||||
// empty, which the validate_request-style check below reports as missing
|
||||
// arguments — matching Python's @validate_request behaviour and code.
|
||||
@@ -571,9 +573,9 @@ func (h *FileHandler) LinkToDatasets(c *gin.Context) {
|
||||
// any other (internal) error is reported as a server error.
|
||||
func linkToDatasetsErrorCode(err error) common.ErrorCode {
|
||||
switch {
|
||||
case errors.Is(err, service.ErrLinkFileNotFound),
|
||||
errors.Is(err, service.ErrLinkDatasetNotFound),
|
||||
errors.Is(err, service.ErrLinkNoAuthorization):
|
||||
case errors.Is(err, document.ErrLinkFileNotFound),
|
||||
errors.Is(err, document.ErrLinkDatasetNotFound),
|
||||
errors.Is(err, document.ErrLinkNoAuthorization):
|
||||
return common.CodeDataError
|
||||
default:
|
||||
return common.CodeServerError
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/mcp"
|
||||
"ragflow/internal/service"
|
||||
dataset "ragflow/internal/service/dataset"
|
||||
)
|
||||
|
||||
// MCPRetrievalService abstracts the dataset retrieval operations needed
|
||||
@@ -112,7 +113,7 @@ func (h *MCPServerHandler) HandleMCP(c *gin.Context) {
|
||||
|
||||
// MCPListDatasets wraps DatasetService.ListDatasets for the MCP tool handler,
|
||||
// filling in default values for parameters that the MCP tool does not expose.
|
||||
func MCPListDatasets(ds *service.DatasetService, userID string, page, pageSize int, orderby string, desc bool) ([]map[string]interface{}, int64, error) {
|
||||
func MCPListDatasets(ds *dataset.DatasetService, userID string, page, pageSize int, orderby string, desc bool) ([]map[string]interface{}, int64, error) {
|
||||
data, total, _, err := ds.ListDatasets(
|
||||
"", "", page, pageSize, orderby, desc,
|
||||
"", nil, "", userID,
|
||||
@@ -141,7 +142,7 @@ func MCPListChats(cs *service.ChatService, userID string, page, pageSize int, or
|
||||
// MCPRetrieval executes a retrieval request on behalf of the MCP tool handler.
|
||||
// It translates the mcp.RetrievalRequest into a service.SearchDatasetsRequest
|
||||
// and calls DatasetService.SearchDatasets. The result is serialized as JSON.
|
||||
func MCPRetrieval(ds *service.DatasetService, userID string, req mcp.RetrievalRequest) (string, error) {
|
||||
func MCPRetrieval(ds *dataset.DatasetService, userID string, req mcp.RetrievalRequest) (string, error) {
|
||||
// Resolve dataset IDs: if none provided, fetch ALL accessible datasets
|
||||
// across all pages (matching Python _fetch_all_datasets behaviour).
|
||||
datasetIDs := req.DatasetIDs
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/engine"
|
||||
"ragflow/internal/service"
|
||||
"ragflow/internal/service/file"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
@@ -35,12 +36,13 @@ type SkillSearchHandler struct {
|
||||
docEngine engine.DocEngine
|
||||
}
|
||||
|
||||
// NewSkillSearchHandler creates a new skill search handler
|
||||
func NewSkillSearchHandler(docEngine engine.DocEngine) *SkillSearchHandler {
|
||||
// NewSkillSearchHandler creates a new skill search handler.
|
||||
// spaceRemover is the document remover used by the skill space service for file deletion.
|
||||
func NewSkillSearchHandler(docEngine engine.DocEngine, spaceRemover file.DocRemover) *SkillSearchHandler {
|
||||
return &SkillSearchHandler{
|
||||
searchService: service.NewSkillSearchService(),
|
||||
indexerService: service.NewSkillIndexerService(),
|
||||
spaceService: service.NewSkillSpaceService(),
|
||||
spaceService: service.NewSkillSpaceService(spaceRemover),
|
||||
docEngine: docEngine,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,17 +26,18 @@ import (
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/engine"
|
||||
"ragflow/internal/service"
|
||||
dataset "ragflow/internal/service/dataset"
|
||||
)
|
||||
|
||||
// TenantHandler tenant handler
|
||||
type TenantHandler struct {
|
||||
tenantService *service.TenantService
|
||||
userService *service.UserService
|
||||
datasetService *service.DatasetService
|
||||
datasetService *dataset.DatasetService
|
||||
}
|
||||
|
||||
// NewTenantHandler create tenant handler
|
||||
func NewTenantHandler(tenantService *service.TenantService, userService *service.UserService, datasetService *service.DatasetService) *TenantHandler {
|
||||
func NewTenantHandler(tenantService *service.TenantService, userService *service.UserService, datasetService *dataset.DatasetService) *TenantHandler {
|
||||
return &TenantHandler{
|
||||
tenantService: tenantService,
|
||||
userService: userService,
|
||||
|
||||
Reference in New Issue
Block a user