mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-29 04:08:12 +08:00
feat: migrate POST /api/v1/datasets/<dataset_id>/documents/stop to Go (#15597)
## Summary
Migrate the stop parse documents endpoint from Python to Go.
### Python endpoint
`POST /api/v1/datasets/<dataset_id>/documents/stop` —
`api/apps/restful_apis/document_api.py:1542-1641`
### Changes
| File | Change |
|------|--------|
| `internal/dao/task.go` | Add `GetByDocID` method |
| `internal/dao/task_test.go` | 3 DAO tests (new file) |
| `internal/service/document.go` | Add `StopParseDocuments` + refactor
shared helpers |
| `internal/service/document_test.go` | 8 service tests |
| `internal/handler/document.go` | Add handler + request struct +
interface |
| `internal/handler/document_test.go` | 5 handler tests |
| `internal/router/router.go` | Add `POST /:dataset_id/documents/stop`
route |
### How it works
1. Validates all document IDs belong to the dataset
2. For each document in RUNNING/CANCEL state (or with unfinished tasks):
- Sets Redis cancel signal `{task_id}-cancel` for each associated task
- Updates `document.run` to CANCEL ("2")
3. Returns `{"success_count": N, "errors": [...]}`
### Test strategy
- **DAO/Service**: SQLite in-memory DB, zero mocks. Redis is nil-safe by
design.
- **Handler**: `fakeDocumentService` implementing `documentServiceIface`
interface.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
@@ -44,6 +44,7 @@ type documentServiceIface interface {
|
||||
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)
|
||||
ListDocumentsByDatasetID(kbID string, page, pageSize int) ([]*entity.DocumentListItem, int64, error)
|
||||
GetDocumentsByAuthorID(authorID, page, pageSize int) ([]*service.DocumentResponse, int64, error)
|
||||
@@ -842,3 +843,46 @@ func (h *DocumentHandler) ParseDocuments(c *gin.Context) {
|
||||
"data": parseResult,
|
||||
})
|
||||
}
|
||||
|
||||
type StopParseDocumentRequest struct {
|
||||
DocumentIDs []string `json:"document_ids" binding:"required"`
|
||||
}
|
||||
|
||||
func (h *DocumentHandler) StopParseDocuments(c *gin.Context) {
|
||||
datasetID := c.Param("dataset_id")
|
||||
|
||||
var req StopParseDocumentRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": common.CodeBadRequest,
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if len(req.DocumentIDs) == 0 {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": common.CodeBadRequest,
|
||||
"message": "`document_ids` is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
userID := c.GetString("user_id")
|
||||
|
||||
if !h.datasetService.Accessible(datasetID, userID) {
|
||||
jsonError(c, common.CodeAuthenticationError, "You don't own the dataset.")
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.documentService.StopParseDocuments(datasetID, req.DocumentIDs)
|
||||
if err != nil {
|
||||
jsonError(c, common.CodeExceptionError, err.Error())
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": result,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user