mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-11-10 21:32:43 +08:00
Refactor: Delete not used APIs (#20894)
This commit is contained in:
1 parent
2cfc74f8bd
commit
863fee004c
18 files changed
+139
-688
No files matched your search
@@ -2623,12 +2623,7 @@ func (c *CLI) DevUpdateChunkCommand(commandCount int, cmd *Command) (ResponseIf,
|
||||
return nil, fmt.Errorf("invalid JSON body: %w", err)
|
||||
}
|
||||
|
||||
// Add IDs to payload
|
||||
payload["dataset_id"] = datasetID
|
||||
payload["document_id"] = docID
|
||||
payload["chunk_id"] = chunkID
|
||||
|
||||
resp, err := httpClient.Request(commandCount, "POST", "/chunk/update", httpClient.AuthKind(), nil, payload)
|
||||
resp, err := httpClient.Request(commandCount, "PATCH", utils.APIPath("/datasets", datasetID, "documents", docID, "chunks", chunkID), httpClient.AuthKind(), nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update chunk: %w", err)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// 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 cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDevUpdateChunkCommandUsesChunkResource(t *testing.T) {
|
||||
updated := make(chan struct{}, 1)
|
||||
client := newTestHTTPClient(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
switch r.URL.Path {
|
||||
case "/api/v1/datasets":
|
||||
if r.Method != http.MethodGet {
|
||||
t.Errorf("dataset lookup method = %s, want GET", r.Method)
|
||||
}
|
||||
_, _ = fmt.Fprint(w, `{"code":0,"data":[{"id":"dataset-1","name":"test"}]}`)
|
||||
case "/api/v1/datasets/dataset-1/documents/doc-1/chunks/chunk-1":
|
||||
if r.Method != http.MethodPatch {
|
||||
t.Errorf("update method = %s, want PATCH", r.Method)
|
||||
}
|
||||
var payload map[string]interface{}
|
||||
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
||||
t.Errorf("decode update: %v", err)
|
||||
}
|
||||
if payload["content"] != "updated" || payload["available"] != false {
|
||||
t.Errorf("unexpected update payload: %#v", payload)
|
||||
}
|
||||
updated <- struct{}{}
|
||||
_, _ = fmt.Fprint(w, `{"code":0,"message":"success"}`)
|
||||
default:
|
||||
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}))
|
||||
client.useAPIKey = true
|
||||
c := &CLI{
|
||||
Config: &CommandLineConfig{
|
||||
CLIMode: APIMode,
|
||||
APIClientConfig: APIModeConfig{CurrentAPIServer: "test"},
|
||||
},
|
||||
APIServerClientMap: map[string]*HTTPClient{"test": client},
|
||||
}
|
||||
result, err := c.DevUpdateChunkCommand(1, &Command{Params: map[string]interface{}{
|
||||
"dataset_name": "test",
|
||||
"doc_id": "doc-1",
|
||||
"chunk_id": "chunk-1",
|
||||
"json_body": `{"content":"updated","available":false}`,
|
||||
}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
select {
|
||||
case <-updated:
|
||||
default:
|
||||
t.Fatal("chunk update was not sent")
|
||||
}
|
||||
if response, ok := result.(*SimpleResponse); !ok || response.Code != 0 {
|
||||
t.Fatalf("unexpected response: %#v", result)
|
||||
}
|
||||
}
|
||||
@@ -361,50 +361,6 @@ func (h *ChunkHandler) StopParsing(c *gin.Context) {
|
||||
common.SuccessWithData(c, data, message)
|
||||
}
|
||||
|
||||
// List retrieves chunks for a document.
|
||||
// @Summary List Chunks
|
||||
// @Description Retrieve paginated chunks for a document with optional filtering.
|
||||
// @Tags chunks
|
||||
// @Param request body service.ListChunksRequest true "List chunks parameters"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/chunk/list [post]
|
||||
func (h *ChunkHandler) List(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, errorCode, errorMessage)
|
||||
return
|
||||
}
|
||||
|
||||
// Bind JSON request
|
||||
var req service.ListChunksRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Set default values for optional parameters
|
||||
if req.Page == nil {
|
||||
defaultPage := 1
|
||||
req.Page = &defaultPage
|
||||
}
|
||||
if req.Size == nil {
|
||||
defaultSize := 30
|
||||
req.Size = &defaultSize
|
||||
}
|
||||
|
||||
ctx := c.Request.Context()
|
||||
resp, err := h.chunkService.List(ctx, &req, user.ID)
|
||||
if err != nil {
|
||||
if respondPermissionErrorIf(c, err, false) {
|
||||
return
|
||||
}
|
||||
common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 500, nil, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
common.SuccessWithData(c, resp, "success")
|
||||
}
|
||||
|
||||
// SwitchChunks enable or disable a chunk
|
||||
func (h *ChunkHandler) SwitchChunks(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
@@ -539,7 +495,7 @@ func optionalBodyString(rawBody map[string]interface{}, field, typeMessage strin
|
||||
// @Tags chunks
|
||||
// @Param request body service.UpdateChunkRequest true "update chunk"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/chunk/update [post]
|
||||
// @Router /api/v1/datasets/{dataset_id}/documents/{document_id}/chunks/{chunk_id} [patch]
|
||||
func (h *ChunkHandler) UpdateChunk(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
@@ -547,7 +503,7 @@ func (h *ChunkHandler) UpdateChunk(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Validate allowed update fields and get IDs from body
|
||||
// Decode the update fields.
|
||||
body, err := io.ReadAll(c.Request.Body)
|
||||
var rawBody map[string]interface{}
|
||||
if err == nil {
|
||||
|
||||
@@ -66,9 +66,6 @@ type documentServiceIface interface {
|
||||
GetDocumentImageForDocument(ctx context.Context, userID, docID, imageID string) ([]byte, error)
|
||||
GetDocumentThumbnail(ctx context.Context, userID, docID string) ([]byte, error)
|
||||
GetMetadataSummary(ctx context.Context, kbID string, docIDs []string) (map[string]interface{}, error)
|
||||
SetDocumentMetadata(ctx context.Context, docID string, meta map[string]interface{}) error
|
||||
DeleteDocumentMetadata(ctx context.Context, docID string, keys []string) error
|
||||
DeleteDocumentAllMetadata(ctx context.Context, docID string) error
|
||||
GetDocumentMetadataByID(ctx context.Context, docID string) (map[string]interface{}, error)
|
||||
GetDocumentArtifact(ctx context.Context, filename, userID string) (*document.ArtifactResponse, error)
|
||||
GetDocumentPreview(ctx context.Context, userID, docID string) (*document.DocumentPreview, error)
|
||||
@@ -1311,137 +1308,6 @@ func stringValue(value *string) string {
|
||||
return *value
|
||||
}
|
||||
|
||||
// MetadataSummary handles the metadata summary request
|
||||
func (h *DocumentHandler) MetadataSummary(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, errorCode, errorMessage)
|
||||
return
|
||||
}
|
||||
|
||||
var requestBody struct {
|
||||
KBID string `json:"kb_id" binding:"required"`
|
||||
DocIDs []string `json:"doc_ids"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&requestBody); err != nil {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "kb_id is required")
|
||||
return
|
||||
}
|
||||
|
||||
kbID := requestBody.KBID
|
||||
if kbID == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "kb_id is required")
|
||||
return
|
||||
}
|
||||
|
||||
ctx := c.Request.Context()
|
||||
if err := h.datasetService.CheckAccess(ctx, permission.Subject{UserID: user.ID}, kbID, permission.OperationRead); err != nil {
|
||||
respondHTTPPermissionError(c, err, false)
|
||||
return
|
||||
}
|
||||
|
||||
summary, err := h.documentService.GetMetadataSummary(ctx, kbID, requestBody.DocIDs)
|
||||
if err != nil {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 1, nil, "Failed to get metadata summary: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
common.SuccessWithData(c, gin.H{"summary": summary}, "success")
|
||||
}
|
||||
|
||||
// SetMetaRequest represents the request for setting document metadata
|
||||
type SetMetaRequest struct {
|
||||
DocID string `json:"doc_id" binding:"required"`
|
||||
Meta string `json:"meta" binding:"required"`
|
||||
}
|
||||
|
||||
// SetMeta handles the set metadata request for a document
|
||||
// @Summary Set Document Metadata
|
||||
// @Description Set metadata for a specific document
|
||||
// @Tags documents
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param request body SetMetaRequest true "metadata info"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/document/set_meta [post]
|
||||
func (h *DocumentHandler) SetMeta(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, errorCode, errorMessage)
|
||||
return
|
||||
}
|
||||
|
||||
var req SetMetaRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if req.DocID == "" {
|
||||
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 {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "Json syntax error: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if meta == nil {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "meta is required")
|
||||
return
|
||||
}
|
||||
|
||||
// Validate meta values - must be str, int, float, or list of those
|
||||
for k, v := range meta {
|
||||
switch val := v.(type) {
|
||||
case string, int, float64:
|
||||
// Valid
|
||||
case []interface{}:
|
||||
for _, item := range val {
|
||||
if _, ok := item.(string); !ok {
|
||||
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:
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, fmt.Sprintf("Unsupported type for key %s: %T", k, v))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Authorization: user must be able to access the document's dataset.
|
||||
ctx := c.Request.Context()
|
||||
doc, err := h.documentService.GetDocumentByID(ctx, req.DocID)
|
||||
if err != nil {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "document not found")
|
||||
return
|
||||
}
|
||||
if err := h.datasetService.CheckAccess(ctx, permission.Subject{UserID: user.ID}, doc.KbID, permission.OperationUpdate); err != nil {
|
||||
respondPermissionError(c, err, false)
|
||||
return
|
||||
}
|
||||
|
||||
err = h.documentService.SetDocumentMetadata(ctx, req.DocID, meta)
|
||||
if err != nil {
|
||||
errMsg := err.Error()
|
||||
if strings.Contains(errMsg, "no such document") || strings.Contains(errMsg, "document not found") {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, errMsg)
|
||||
} else {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 1, nil, "Failed to set metadata: "+errMsg)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
common.SuccessWithData(c, true, "success")
|
||||
}
|
||||
|
||||
// Ingest handles document ingestion
|
||||
// @Summary Ingest Document
|
||||
// @Description Ingest a document for processing
|
||||
@@ -1477,93 +1343,6 @@ func (h *DocumentHandler) Ingest(c *gin.Context) {
|
||||
common.SuccessWithData(c, true, "success")
|
||||
}
|
||||
|
||||
// DeleteMetaRequest represents the request for deleting document metadata
|
||||
type DeleteMetaRequest struct {
|
||||
DocID string `json:"doc_id" binding:"required"`
|
||||
Keys string `json:"keys"` // optional - if provided, deletes specific keys; otherwise deletes entire document metadata
|
||||
}
|
||||
|
||||
// DeleteMeta handles the delete metadata request for a document
|
||||
// If Keys is provided, deletes specific metadata keys; otherwise deletes entire document metadata
|
||||
// @Summary Delete Document Metadata
|
||||
// @Description Delete metadata keys or entire document metadata for a specific document
|
||||
// @Tags documents
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param request body DeleteMetaRequest true "metadata keys to delete or empty to delete all"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/document/delete_meta [post]
|
||||
func (h *DocumentHandler) DeleteMeta(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, errorCode, errorMessage)
|
||||
return
|
||||
}
|
||||
|
||||
var req DeleteMetaRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if req.DocID == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "doc_id is required")
|
||||
return
|
||||
}
|
||||
|
||||
ctx := c.Request.Context()
|
||||
doc, err := h.documentService.GetDocumentByID(ctx, req.DocID)
|
||||
if err != nil {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "document not found")
|
||||
return
|
||||
}
|
||||
if err := h.datasetService.CheckAccess(ctx, permission.Subject{UserID: user.ID}, doc.KbID, permission.OperationUpdate); err != nil {
|
||||
respondPermissionError(c, err, false)
|
||||
return
|
||||
}
|
||||
|
||||
// If Keys is provided, parse and delete specific keys; otherwise delete entire document metadata
|
||||
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 {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "Json syntax error: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if keys == nil || len(keys) == 0 {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, "keys list is required")
|
||||
return
|
||||
}
|
||||
|
||||
err = h.documentService.DeleteDocumentMetadata(ctx, req.DocID, keys)
|
||||
if err != nil {
|
||||
errMsg := err.Error()
|
||||
if strings.Contains(errMsg, "no such document") || strings.Contains(errMsg, "document not found") {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, errMsg)
|
||||
} else {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 1, nil, "Failed to delete metadata: "+errMsg)
|
||||
}
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// Delete entire document metadata
|
||||
err = h.documentService.DeleteDocumentAllMetadata(ctx, req.DocID)
|
||||
if err != nil {
|
||||
errMsg := err.Error()
|
||||
if strings.Contains(errMsg, "no such document") || strings.Contains(errMsg, "document not found") {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 1, nil, errMsg)
|
||||
} else {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusInternalServerError, 1, nil, "Failed to delete metadata: "+errMsg)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
common.SuccessWithData(c, true, "success")
|
||||
}
|
||||
|
||||
type ListIngestionsRequest struct {
|
||||
DatasetID *string `json:"dataset_id"`
|
||||
}
|
||||
|
||||
@@ -146,9 +146,6 @@ type fakeDocumentService struct {
|
||||
metadataErr error
|
||||
metadataKBID string
|
||||
metadataDocIDs []string
|
||||
setMetaCalled bool
|
||||
setMetaDocID string
|
||||
setMetaValue map[string]interface{}
|
||||
uploadLocalData []map[string]interface{}
|
||||
uploadLocalErrs []string
|
||||
uploadLocalKB *entity.Knowledgebase
|
||||
@@ -336,18 +333,6 @@ func (f *fakeDocumentService) HasActiveIngestionTasks(ctx context.Context, datas
|
||||
return f.hasActiveTasks, f.hasActiveTasksErr
|
||||
}
|
||||
|
||||
func (f *fakeDocumentService) SetDocumentMetadata(ctx context.Context, docID string, meta map[string]interface{}) error {
|
||||
f.setMetaCalled = true
|
||||
f.setMetaDocID = docID
|
||||
f.setMetaValue = meta
|
||||
return nil
|
||||
}
|
||||
func (f *fakeDocumentService) DeleteDocumentMetadata(ctx context.Context, docID string, keys []string) error {
|
||||
return nil
|
||||
}
|
||||
func (f *fakeDocumentService) DeleteDocumentAllMetadata(ctx context.Context, docID string) error {
|
||||
return nil
|
||||
}
|
||||
func (f *fakeDocumentService) GetDocumentMetadataByID(ctx context.Context, docID string) (map[string]interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -457,17 +442,18 @@ func TestDocumentReadHandlersForbidden(t *testing.T) {
|
||||
body string
|
||||
params gin.Params
|
||||
handler gin.HandlerFunc
|
||||
status int
|
||||
}{
|
||||
{"document detail", http.MethodGet, "/api/v1/documents/doc-1", "", gin.Params{{Key: "id", Value: "doc-1"}}, h.GetDocumentByID},
|
||||
{"metadata summary", http.MethodPost, "/api/v1/document/metadata/summary", `{"kb_id":"kb-owner","doc_ids":["doc-1"]}`, nil, h.MetadataSummary},
|
||||
{"document detail", http.MethodGet, "/api/v1/documents/doc-1", "", gin.Params{{Key: "id", Value: "doc-1"}}, h.GetDocumentByID, http.StatusForbidden},
|
||||
{"metadata summary", http.MethodGet, "/api/v1/datasets/kb-owner/metadata/summary?doc_ids=doc-1", "", gin.Params{{Key: "dataset_id", Value: "kb-owner"}}, h.MetadataSummaryByDataset, http.StatusOK},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
c, w := setupGinContextWithUser(tt.method, tt.path, tt.body)
|
||||
c.Params = tt.params
|
||||
tt.handler(c)
|
||||
if w.Code != http.StatusForbidden {
|
||||
t.Fatalf("status = %d, want 403: %s", w.Code, w.Body.String())
|
||||
if w.Code != tt.status {
|
||||
t.Fatalf("status = %d, want %d: %s", w.Code, tt.status, w.Body.String())
|
||||
}
|
||||
var resp struct {
|
||||
Code common.ErrorCode `json:"code"`
|
||||
@@ -487,73 +473,6 @@ func TestDocumentReadHandlersForbidden(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetMetaHandler_NotAccessible(t *testing.T) {
|
||||
setupDocumentPermissionDB(t, false)
|
||||
|
||||
fake := &fakeDocumentService{
|
||||
doc: &document.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("POST", "/api/v1/document/set_meta", `{"doc_id":"doc-1","meta":"{\"poc\":\"blocked\"}"}`)
|
||||
h.SetMeta(c)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
|
||||
}
|
||||
var resp map[string]interface{}
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if resp["code"] != float64(common.CodeForbidden) {
|
||||
t.Fatalf("expected auth error, got %v", resp)
|
||||
}
|
||||
if resp["message"] != "Permission denied" {
|
||||
t.Fatalf("unexpected message: %v", resp["message"])
|
||||
}
|
||||
if fake.setMetaCalled {
|
||||
t.Fatal("SetDocumentMetadata should not be called without dataset access")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetMetaHandler_Accessible(t *testing.T) {
|
||||
setupDocumentPermissionDB(t, true)
|
||||
|
||||
fake := &fakeDocumentService{
|
||||
doc: &document.DocumentResponse{ID: "doc-1", KbID: "kb-owner"},
|
||||
}
|
||||
h := &DocumentHandler{
|
||||
documentService: fake,
|
||||
datasetService: dataset.NewDatasetService(),
|
||||
}
|
||||
|
||||
c, w := setupGinContextWithUser("POST", "/api/v1/document/set_meta", `{"doc_id":"doc-1","meta":"{\"category\":\"tech\",\"year\":2026}"}`)
|
||||
h.SetMeta(c)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
|
||||
}
|
||||
var resp map[string]interface{}
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if resp["code"] != float64(common.CodeSuccess) || resp["data"] != true {
|
||||
t.Fatalf("unexpected response: %v", resp)
|
||||
}
|
||||
if !fake.setMetaCalled {
|
||||
t.Fatal("SetDocumentMetadata should be called with dataset access")
|
||||
}
|
||||
if fake.setMetaDocID != "doc-1" {
|
||||
t.Fatalf("set meta doc id = %q, want doc-1", fake.setMetaDocID)
|
||||
}
|
||||
if fake.setMetaValue["category"] != "tech" || fake.setMetaValue["year"] != float64(2026) {
|
||||
t.Fatalf("unexpected meta: %#v", fake.setMetaValue)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteDocumentHandler_NotAccessible(t *testing.T) {
|
||||
setupDocumentPermissionDB(t, false)
|
||||
|
||||
|
||||
@@ -133,33 +133,6 @@ func (h *FileHandler) ListFiles(c *gin.Context) {
|
||||
common.SuccessWithData(c, result, "success")
|
||||
}
|
||||
|
||||
// GetRootFolder gets root folder for current user
|
||||
// @Summary Get Root Folder
|
||||
// @Description Get or create root folder for the current user
|
||||
// @Tags file
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/file/root_folder [get]
|
||||
func (h *FileHandler) GetRootFolder(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, errorCode, errorMessage)
|
||||
return
|
||||
}
|
||||
userID := user.ID
|
||||
|
||||
ctx := c.Request.Context()
|
||||
// Get root folder
|
||||
rootFolder, err := h.fileService.GetRootFolder(ctx, userID)
|
||||
if err != nil {
|
||||
respondFileServiceError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
common.SuccessWithData(c, gin.H{"root_folder": rootFolder}, common.CodeSuccess.Message())
|
||||
}
|
||||
|
||||
// GetParentFolder gets parent folder of a file
|
||||
// @Summary Get Parent Folder
|
||||
// @Description Get parent folder of a file by file ID
|
||||
@@ -168,7 +141,7 @@ func (h *FileHandler) GetRootFolder(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Param file_id query string true "file ID"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/file/parent_folder [get]
|
||||
// @Router /api/v1/files/{id}/parent [get]
|
||||
func (h *FileHandler) GetParentFolder(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
@@ -195,41 +168,6 @@ func (h *FileHandler) GetParentFolder(c *gin.Context) {
|
||||
common.SuccessWithData(c, gin.H{"parent_folder": parentFolder}, common.CodeSuccess.Message())
|
||||
}
|
||||
|
||||
// GetAllParentFolders gets all parent folders in path
|
||||
// @Summary Get All Parent Folders
|
||||
// @Description Get all parent folders in path from file to root
|
||||
// @Tags file
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param file_id query string true "file ID"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/file/all_parent_folder [get]
|
||||
func (h *FileHandler) GetAllParentFolders(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, errorCode, errorMessage)
|
||||
return
|
||||
}
|
||||
userID := user.ID
|
||||
|
||||
// Get file_id from query
|
||||
fileID := c.Query("file_id")
|
||||
if fileID == "" {
|
||||
common.ResponseWithCodeData(c, common.CodeBadRequest, nil, "file_id is required")
|
||||
return
|
||||
}
|
||||
|
||||
ctx := c.Request.Context()
|
||||
// Get all parent folders with permission check
|
||||
parentFolders, err := h.fileService.GetAllParentFolders(ctx, userID, fileID)
|
||||
if err != nil {
|
||||
respondFileServiceError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
common.SuccessWithData(c, gin.H{"parent_folders": parentFolders}, common.CodeSuccess.Message())
|
||||
}
|
||||
|
||||
// GetFileAncestors gets all ancestor folders of a file (matches Python /files/<file_id>/ancestors)
|
||||
// @Summary Get File Ancestors
|
||||
// @Description Get all ancestor folders in path from file to root
|
||||
|
||||
@@ -160,7 +160,7 @@ func (h *TenantHandler) TenantInfo(c *gin.Context) {
|
||||
// @Tags tenants
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/tenant/list [get]
|
||||
// @Router /api/v1/tenants [get]
|
||||
func (h *TenantHandler) TenantList(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
|
||||
+12
-33
@@ -281,7 +281,6 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
// Tenant routes (per-tenant resources)
|
||||
tenant := v1.Group("/tenant")
|
||||
{
|
||||
tenant.GET("/list", r.tenantHandler.TenantList)
|
||||
tenant.POST("/chunk_store", r.tenantHandler.CreateChunkStore) // Internal API only for GO
|
||||
tenant.DELETE("/chunk_store", r.tenantHandler.DeleteChunkStore) // Internal API only for GO
|
||||
tenant.POST("/metadata_store", r.tenantHandler.CreateMetadataStore) // Internal API only for GO
|
||||
@@ -420,7 +419,6 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
searches.GET("/:search_id", r.searchHandler.GetSearch)
|
||||
searches.PUT("/:search_id", r.searchHandler.UpdateSearch)
|
||||
searches.DELETE("/:search_id", r.searchHandler.DeleteSearch)
|
||||
searches.POST("/:search_id/completion", r.searchHandler.Completion)
|
||||
searches.POST("/:search_id/completions", r.searchHandler.Completion)
|
||||
}
|
||||
|
||||
@@ -441,14 +439,6 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
workspaceFiles.GET("/:file_id/versions", r.fileCommitHandler.GetFileVersionHistory)
|
||||
}
|
||||
|
||||
// File routes
|
||||
file := authorized.Group("/v1/file")
|
||||
{
|
||||
file.GET("/root_folder", r.fileHandler.GetRootFolder)
|
||||
file.GET("/parent_folder", r.fileHandler.GetParentFolder)
|
||||
file.GET("/all_parent_folder", r.fileHandler.GetAllParentFolders)
|
||||
}
|
||||
|
||||
// File commit routes — /folders/ takes folder_id directly
|
||||
commitFolders := v1.Group("/folders")
|
||||
{
|
||||
@@ -556,13 +546,18 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
provider.PATCH("/:provider_id_or_name/instances/:instance_id_or_name/models/*model_name", r.providerHandler.AlterModel)
|
||||
provider.POST("/:provider_id_or_name/instances/:instance_id_or_name/models", r.providerHandler.AddModel)
|
||||
provider.DELETE("/:provider_id_or_name/instances/:instance_id_or_name/models", r.providerHandler.DropInstanceModels)
|
||||
v1.POST("/chat/to_model", r.providerHandler.ChatToModel)
|
||||
v1.POST("/embeddings", r.providerHandler.EmbedText)
|
||||
v1.POST("/rerank", r.providerHandler.RerankDocument)
|
||||
v1.POST("/audio/transcriptions", r.providerHandler.TranscribeAudio)
|
||||
v1.POST("/audio/speech", r.providerHandler.AudioSpeech)
|
||||
v1.POST("/file/ocr", r.providerHandler.OCRFile)
|
||||
v1.POST("/file/parse", r.providerHandler.ParseFile)
|
||||
}
|
||||
|
||||
// command is for CLI
|
||||
command := v1
|
||||
{
|
||||
command.POST("/chat/to_model", r.providerHandler.ChatToModel)
|
||||
command.POST("/embeddings", r.providerHandler.EmbedText)
|
||||
command.POST("/rerank", r.providerHandler.RerankDocument)
|
||||
command.POST("/audio/transcriptions", r.providerHandler.TranscribeAudio)
|
||||
command.POST("/audio/speech", r.providerHandler.AudioSpeech)
|
||||
command.POST("/file/ocr", r.providerHandler.OCRFile)
|
||||
command.POST("/file/parse", r.providerHandler.ParseFile)
|
||||
}
|
||||
|
||||
model := v1.Group("/models")
|
||||
@@ -692,22 +687,6 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
system.PUT("/concurrency", r.systemHandler.SetConcurrency)
|
||||
}
|
||||
|
||||
// Document routes
|
||||
doc := v1.Group("/document")
|
||||
{
|
||||
doc.POST("/list", r.documentHandler.ListDocuments)
|
||||
doc.POST("/metadata/summary", r.documentHandler.MetadataSummary)
|
||||
doc.POST("/set_meta", r.documentHandler.SetMeta)
|
||||
doc.POST("/delete_meta", r.documentHandler.DeleteMeta) // Internal API only for GO
|
||||
}
|
||||
|
||||
// Chunk routes
|
||||
chunk := v1.Group("/chunk")
|
||||
{
|
||||
chunk.POST("/list", r.chunkHandler.List)
|
||||
chunk.POST("/update", r.chunkHandler.UpdateChunk) // Internal API only for GO
|
||||
}
|
||||
|
||||
// Chat Channel
|
||||
chatChannel := v1.Group("/chat-channels")
|
||||
{
|
||||
|
||||
@@ -7,12 +7,46 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/handler"
|
||||
"ragflow/internal/service"
|
||||
)
|
||||
|
||||
func TestRouterSetupRemovesActionRoutes(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
originalLogger := common.Logger
|
||||
common.Logger = zap.NewNop()
|
||||
t.Cleanup(func() { common.Logger = originalLogger })
|
||||
|
||||
engine := gin.New()
|
||||
r := &Router{authHandler: handler.NewAuthHandler()}
|
||||
r.Setup(engine)
|
||||
|
||||
tests := []struct {
|
||||
method string
|
||||
path string
|
||||
}{
|
||||
{http.MethodGet, "/api/v1/tenant/list"},
|
||||
{http.MethodPost, "/api/v1/document/list"},
|
||||
{http.MethodPost, "/api/v1/document/metadata/summary"},
|
||||
{http.MethodPost, "/api/v1/document/delete_meta"},
|
||||
{http.MethodPost, "/api/v1/document/set_meta"},
|
||||
{http.MethodPost, "/api/v1/chunk/list"},
|
||||
{http.MethodPost, "/api/v1/chunk/update"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.method+" "+tt.path, func(t *testing.T) {
|
||||
resp := httptest.NewRecorder()
|
||||
engine.ServeHTTP(resp, httptest.NewRequest(tt.method, tt.path, nil))
|
||||
if resp.Code != http.StatusNotFound {
|
||||
t.Fatalf("status=%d body=%s; want 404", resp.Code, resp.Body.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConnectorRoutesDoNotConflictWithOAuthCallbacks(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ def test_search_completion_requires_question(rest_client, search_resource):
|
||||
search_id = search_resource
|
||||
expected_message = "question is required"
|
||||
|
||||
completion_res = rest_client.post(f"/searches/{search_id}/completion", json={})
|
||||
completion_res = rest_client.post(f"/searches/{search_id}/completions", json={})
|
||||
assert completion_res.status_code == 200
|
||||
completion_payload = completion_res.json()
|
||||
assert completion_payload["code"] == 101, completion_payload
|
||||
@@ -123,7 +123,7 @@ def test_search_completion_requires_question(rest_client, search_resource):
|
||||
@pytest.mark.p2
|
||||
def test_search_completion_requires_kb_ids(rest_client, search_resource):
|
||||
search_id = search_resource
|
||||
for path in ("completion", "completions"):
|
||||
for path in ["completions"]:
|
||||
res = rest_client.post(
|
||||
f"/searches/{search_id}/{path}",
|
||||
json={"question": "what is coriander?"},
|
||||
@@ -140,7 +140,7 @@ def test_search_completion_sse_shape_when_kb_ids_provided(rest_client, search_re
|
||||
# Even with kb_ids provided, runtime may return an error event in-stream, but
|
||||
# contract remains SSE with JSON data lines and terminal boolean event.
|
||||
res = rest_client.post(
|
||||
f"/searches/{search_id}/completion",
|
||||
f"/searches/{search_id}/completions",
|
||||
json={"question": "what is coriander?", "kb_ids": ["nonexistent_dataset"]},
|
||||
timeout=60,
|
||||
)
|
||||
|
||||
@@ -22,7 +22,6 @@ export const enum DocumentApiAction {
|
||||
RemoveDocument = 'removeDocument',
|
||||
SaveDocumentName = 'saveDocumentName',
|
||||
SetDocumentParser = 'setDocumentParser',
|
||||
SetDocumentMeta = 'setDocumentMeta',
|
||||
FetchDocumentFilter = 'fetchDocumentFilter',
|
||||
CreateDocument = 'createDocument',
|
||||
FetchDocumentThumbnails = 'fetchDocumentThumbnails',
|
||||
|
||||
@@ -29,10 +29,7 @@ import {
|
||||
IClaimsResponse,
|
||||
IStructureGraphResponse,
|
||||
} from '@/interfaces/database/document-structure';
|
||||
import {
|
||||
IChangeParserConfigRequestBody,
|
||||
IDocumentMetaRequestBody,
|
||||
} from '@/interfaces/request/document';
|
||||
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
|
||||
import i18n from '@/locales/config';
|
||||
import { EMPTY_METADATA_FIELD } from '@/pages/dataset/dataset/use-select-filters';
|
||||
import {
|
||||
@@ -702,39 +699,6 @@ export const useSetDocumentPipelineParser = () => {
|
||||
return { setDocumentPipelineParser: mutateAsync, data, loading };
|
||||
};
|
||||
|
||||
export const useSetDocumentMeta = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const {
|
||||
data,
|
||||
isPending: loading,
|
||||
mutateAsync,
|
||||
} = useMutation({
|
||||
mutationKey: [DocumentApiAction.SetDocumentMeta],
|
||||
mutationFn: async (params: IDocumentMetaRequestBody) => {
|
||||
try {
|
||||
const { data } = await kbService.setMeta({
|
||||
meta: params.meta,
|
||||
doc_id: params.documentId,
|
||||
});
|
||||
|
||||
if (data?.code === 0) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: DocumentKeys.all(),
|
||||
});
|
||||
|
||||
message.success(i18n.t('message.modified'));
|
||||
}
|
||||
return data?.code;
|
||||
} catch (error) {
|
||||
message.error('error:' + error);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return { setDocumentMeta: mutateAsync, data, loading };
|
||||
};
|
||||
|
||||
export const useCreateDocument = () => {
|
||||
const { id } = useParams();
|
||||
const { setPaginationParams, page } = useSetPaginationParams();
|
||||
|
||||
@@ -44,8 +44,3 @@ export interface IChangeParserRequestBody {
|
||||
doc_id?: string;
|
||||
parser_config: IChangeParserConfigRequestBody;
|
||||
}
|
||||
|
||||
export interface IDocumentMetaRequestBody {
|
||||
documentId: string;
|
||||
meta: string; // json format string
|
||||
}
|
||||
@@ -307,8 +307,6 @@ export const useManageMetaDataModal = (
|
||||
resetOperations,
|
||||
} = useMetadataOperations();
|
||||
|
||||
// const { setDocumentMeta } = useSetDocumentMeta();
|
||||
|
||||
useEffect(() => {
|
||||
if (fetchTypeList.includes(type)) {
|
||||
if (data) {
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog';
|
||||
import { TagRenameId } from '@/constants/knowledge';
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { ButtonLoading } from '@/components/ui/button';
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from '@/components/ui/form';
|
||||
import { IDocumentInfo } from '@/interfaces/database/document';
|
||||
import Editor, { loader } from '@monaco-editor/react';
|
||||
import DOMPurify from 'dompurify';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
loader.config({ paths: { vs: '/vs' } });
|
||||
|
||||
export function SetMetaDialog({
|
||||
hideModal,
|
||||
onOk,
|
||||
loading,
|
||||
initialMetaData,
|
||||
}: IModalProps<any> & { initialMetaData?: IDocumentInfo['meta_fields'] }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const FormSchema = z.object({
|
||||
meta: z
|
||||
.string()
|
||||
.min(1, {
|
||||
message: t('knowledgeDetails.pleaseInputJson'),
|
||||
})
|
||||
.trim()
|
||||
.refine(
|
||||
(value) => {
|
||||
try {
|
||||
JSON.parse(value);
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{ message: t('knowledgeDetails.pleaseInputJson') },
|
||||
),
|
||||
});
|
||||
|
||||
const form = useForm<z.infer<typeof FormSchema>>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
defaultValues: {},
|
||||
});
|
||||
|
||||
async function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||
const ret = await onOk?.(data.meta);
|
||||
if (ret) {
|
||||
hideModal?.();
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
form.setValue('meta', JSON.stringify(initialMetaData, null, 4));
|
||||
}, [form, initialMetaData]);
|
||||
|
||||
return (
|
||||
<Dialog open onOpenChange={hideModal}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('knowledgeDetails.setMetaData')}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<Form {...form}>
|
||||
<form
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
className="space-y-6"
|
||||
id={TagRenameId}
|
||||
>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="meta"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel
|
||||
tooltip={
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: DOMPurify.sanitize(
|
||||
t('knowledgeDetails.documentMetaTips'),
|
||||
),
|
||||
}}
|
||||
></div>
|
||||
}
|
||||
>
|
||||
{t('knowledgeDetails.metaData')}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Editor
|
||||
height={200}
|
||||
defaultLanguage="json"
|
||||
theme="vs-dark"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</form>
|
||||
</Form>
|
||||
<DialogFooter>
|
||||
<ButtonLoading type="submit" form={TagRenameId} loading={loading}>
|
||||
{t('common.save')}
|
||||
</ButtonLoading>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import { useSetDocumentMeta } from '@/hooks/use-document-request';
|
||||
import { IDocumentInfo } from '@/interfaces/database/document';
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
export const useSaveMeta = () => {
|
||||
const { setDocumentMeta, loading } = useSetDocumentMeta();
|
||||
const [record, setRecord] = useState<IDocumentInfo>({} as IDocumentInfo);
|
||||
|
||||
const {
|
||||
visible: setMetaVisible,
|
||||
hideModal: hideSetMetaModal,
|
||||
showModal: showSetMetaModal,
|
||||
} = useSetModalState();
|
||||
|
||||
const onSetMetaModalOk = useCallback(
|
||||
async (meta: string) => {
|
||||
const ret = await setDocumentMeta({
|
||||
documentId: record?.id,
|
||||
meta,
|
||||
});
|
||||
if (ret === 0) {
|
||||
hideSetMetaModal();
|
||||
}
|
||||
},
|
||||
[setDocumentMeta, record?.id, hideSetMetaModal],
|
||||
);
|
||||
|
||||
const handleShowSetMetaModal = useCallback(
|
||||
(row: IDocumentInfo) => {
|
||||
setRecord(row);
|
||||
showSetMetaModal();
|
||||
},
|
||||
[showSetMetaModal],
|
||||
);
|
||||
|
||||
return {
|
||||
setMetaLoading: loading,
|
||||
onSetMetaModalOk,
|
||||
setMetaVisible,
|
||||
hideSetMetaModal,
|
||||
showSetMetaModal: handleShowSetMetaModal,
|
||||
metaRecord: record,
|
||||
};
|
||||
};
|
||||
|
||||
export type UseSaveMetaShowType = Pick<
|
||||
ReturnType<typeof useSaveMeta>,
|
||||
'showSetMetaModal'
|
||||
>;
|
||||
@@ -37,7 +37,6 @@ const {
|
||||
documentIngest,
|
||||
listTagByKnowledgeIds,
|
||||
listPipelines,
|
||||
setMeta,
|
||||
getMeta,
|
||||
getMetaKeys,
|
||||
retrievalTestShare,
|
||||
@@ -64,10 +63,6 @@ const methods = {
|
||||
url: documentThumbnails,
|
||||
method: 'get',
|
||||
},
|
||||
setMeta: {
|
||||
url: setMeta,
|
||||
method: 'post',
|
||||
},
|
||||
listTagByKnowledgeIds: {
|
||||
url: listTagByKnowledgeIds,
|
||||
method: 'get',
|
||||
|
||||
@@ -289,7 +289,6 @@ export default {
|
||||
webCrawl: (datasetId: string) =>
|
||||
`${restAPIv1}/datasets/${datasetId}/documents?type=web`,
|
||||
documentInfoUpload: `${restAPIv1}/documents/upload`,
|
||||
setMeta: `${webAPI}/document/set_meta`,
|
||||
getDatasetFilter: (datasetId: string) =>
|
||||
`${restAPIv1}/datasets/${datasetId}/documents?type=filter`,
|
||||
|
||||
|
||||
Reference in new issue
Block a user