mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-08-01 21:37:33 +08:00
feat(go): port knowledge compilation template/group + wiki artifact/nav/skill REST APIs from Python (#17656)
This commit is contained in:
78
internal/handler/compilation_template.go
Normal file
78
internal/handler/compilation_template.go
Normal file
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// 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 (
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// CompilationTemplateHandler serves the knowledge-compilation template REST
|
||||
// APIs. It mirrors the Python compilation_template_api blueprint.
|
||||
type CompilationTemplateHandler struct {
|
||||
compilationTemplateService *service.CompilationTemplateService
|
||||
}
|
||||
|
||||
// NewCompilationTemplateHandler creates a CompilationTemplateHandler.
|
||||
func NewCompilationTemplateHandler(svc *service.CompilationTemplateService) *CompilationTemplateHandler {
|
||||
return &CompilationTemplateHandler{compilationTemplateService: svc}
|
||||
}
|
||||
|
||||
// ListBuiltins returns the built-in template palette used by the frontend
|
||||
// "Add template group" panel.
|
||||
//
|
||||
// @Summary List built-in compilation templates
|
||||
// @Tags compilation template
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/compilation-templates/builtins [get]
|
||||
func (h *CompilationTemplateHandler) ListBuiltins(c *gin.Context) {
|
||||
user, code, msg := GetUser(c)
|
||||
if code != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, code, msg)
|
||||
return
|
||||
}
|
||||
templates, err := h.compilationTemplateService.ListBuiltins(c.Request.Context(), user.ID)
|
||||
if err != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, templates, "success")
|
||||
}
|
||||
|
||||
// ListWikiPresets returns the wiki page-structure presets loaded from YAML.
|
||||
//
|
||||
// @Summary List wiki presets
|
||||
// @Tags compilation template
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/compilation-templates/wiki-presets [get]
|
||||
func (h *CompilationTemplateHandler) ListWikiPresets(c *gin.Context) {
|
||||
_, code, msg := GetUser(c)
|
||||
if code != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, code, msg)
|
||||
return
|
||||
}
|
||||
presets, err := h.compilationTemplateService.LoadWikiPresets()
|
||||
if err != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, presets, "success")
|
||||
}
|
||||
233
internal/handler/compilation_template_group.go
Normal file
233
internal/handler/compilation_template_group.go
Normal file
@@ -0,0 +1,233 @@
|
||||
//
|
||||
// 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 (
|
||||
"strconv"
|
||||
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// CompilationTemplateGroupHandler serves the knowledge-compilation template
|
||||
// group REST APIs. It mirrors the Python compilation_template_group_api blueprint.
|
||||
type CompilationTemplateGroupHandler struct {
|
||||
compilationTemplateGroupService *service.CompilationTemplateGroupService
|
||||
}
|
||||
|
||||
// NewCompilationTemplateGroupHandler creates a CompilationTemplateGroupHandler.
|
||||
func NewCompilationTemplateGroupHandler(svc *service.CompilationTemplateGroupService) *CompilationTemplateGroupHandler {
|
||||
return &CompilationTemplateGroupHandler{compilationTemplateGroupService: svc}
|
||||
}
|
||||
|
||||
// List returns the tenant's compilation template groups with their nested
|
||||
// templates and pagination.
|
||||
//
|
||||
// @Summary List compilation template groups
|
||||
// @Tags compilation template group
|
||||
// @Security ApiKeyAuth
|
||||
// @Param keywords query string false "name keyword filter"
|
||||
// @Param scope query string false "scope filter (file|dataset)"
|
||||
// @Param page query int false "page number" default(1)
|
||||
// @Param page_size query int false "items per page" default(30)
|
||||
// @Param orderby query string false "order field" default(create_time)
|
||||
// @Param desc query bool false "descending" default(true)
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/compilation-template-groups [get]
|
||||
func (h *CompilationTemplateGroupHandler) List(c *gin.Context) {
|
||||
user, code, msg := GetUser(c)
|
||||
if code != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, code, msg)
|
||||
return
|
||||
}
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "30"))
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize < 1 {
|
||||
pageSize = 30
|
||||
}
|
||||
keywords := c.Query("keywords")
|
||||
scope := c.Query("scope")
|
||||
orderby := c.DefaultQuery("orderby", "create_time")
|
||||
desc := c.DefaultQuery("desc", "true") != "false"
|
||||
|
||||
groups, err := h.compilationTemplateGroupService.ListSaved(c.Request.Context(), user.ID, keywords, scope, orderby, desc)
|
||||
if err != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error())
|
||||
return
|
||||
}
|
||||
total := len(groups)
|
||||
if page > 0 && pageSize > 0 {
|
||||
start := (page - 1) * pageSize
|
||||
if start >= total {
|
||||
groups = []*service.GroupListItem{}
|
||||
} else {
|
||||
end := start + pageSize
|
||||
if end > total {
|
||||
end = total
|
||||
}
|
||||
groups = groups[start:end]
|
||||
}
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"groups": groups, "total": total}, "success")
|
||||
}
|
||||
|
||||
// Get returns a single compilation template group.
|
||||
//
|
||||
// @Summary Get compilation template group
|
||||
// @Tags compilation template group
|
||||
// @Security ApiKeyAuth
|
||||
// @Param group_id path string true "group id"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/compilation-template-groups/{group_id} [get]
|
||||
func (h *CompilationTemplateGroupHandler) Get(c *gin.Context) {
|
||||
user, code, msg := GetUser(c)
|
||||
if code != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, code, msg)
|
||||
return
|
||||
}
|
||||
id := c.Param("group_id")
|
||||
group, err := h.compilationTemplateGroupService.GetSaved(c.Request.Context(), user.ID, id)
|
||||
if err != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error())
|
||||
return
|
||||
}
|
||||
if group == nil {
|
||||
common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Cannot find compilation template group "+id+".")
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, group, "success")
|
||||
}
|
||||
|
||||
// Save creates a new compilation template group with its child templates.
|
||||
//
|
||||
// @Summary Save compilation template group
|
||||
// @Tags compilation template group
|
||||
// @Security ApiKeyAuth
|
||||
// @Param request body service.GroupRequest true "group payload"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/compilation-template-groups [post]
|
||||
func (h *CompilationTemplateGroupHandler) Save(c *gin.Context) {
|
||||
user, code, msg := GetUser(c)
|
||||
if code != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, code, msg)
|
||||
return
|
||||
}
|
||||
var req service.GroupRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request: "+err.Error())
|
||||
return
|
||||
}
|
||||
if err := service.ValidateGroupRequest(&req); err != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error())
|
||||
return
|
||||
}
|
||||
nameExists, err := h.compilationTemplateGroupService.NameExists(c.Request.Context(), user.ID, req.Name)
|
||||
if err != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error())
|
||||
return
|
||||
}
|
||||
if nameExists {
|
||||
common.ResponseWithCodeData(c, common.CodeDataError, nil, "Duplicated compilation template group name.")
|
||||
return
|
||||
}
|
||||
group, err := h.compilationTemplateGroupService.CreateGroup(c.Request.Context(), user.ID, &req)
|
||||
if err != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, group, "success")
|
||||
}
|
||||
|
||||
// Update applies a partial update to a compilation template group.
|
||||
//
|
||||
// @Summary Update compilation template group
|
||||
// @Tags compilation template group
|
||||
// @Security ApiKeyAuth
|
||||
// @Param group_id path string true "group id"
|
||||
// @Param request body service.GroupRequest true "group payload"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/compilation-template-groups/{group_id} [put]
|
||||
func (h *CompilationTemplateGroupHandler) Update(c *gin.Context) {
|
||||
user, code, msg := GetUser(c)
|
||||
if code != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, code, msg)
|
||||
return
|
||||
}
|
||||
id := c.Param("group_id")
|
||||
var req service.GroupRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeArgumentError, nil, "Invalid request: "+err.Error())
|
||||
return
|
||||
}
|
||||
if err := service.ValidateGroupRequest(&req); err != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error())
|
||||
return
|
||||
}
|
||||
if req.Name != "" {
|
||||
nameExists, nerr := h.compilationTemplateGroupService.NameExists(c.Request.Context(), user.ID, req.Name, id)
|
||||
if nerr != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeExceptionError, nil, nerr.Error())
|
||||
return
|
||||
}
|
||||
if nameExists {
|
||||
common.ResponseWithCodeData(c, common.CodeDataError, nil, "Duplicated compilation template group name.")
|
||||
return
|
||||
}
|
||||
}
|
||||
group, err := h.compilationTemplateGroupService.UpdateGroup(c.Request.Context(), user.ID, id, &req)
|
||||
if err != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeDataError, nil, err.Error())
|
||||
return
|
||||
}
|
||||
if group == nil {
|
||||
common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Cannot find compilation template group "+id+".")
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, group, "success")
|
||||
}
|
||||
|
||||
// Delete soft-deletes a compilation template group and its children.
|
||||
//
|
||||
// @Summary Delete compilation template group
|
||||
// @Tags compilation template group
|
||||
// @Security ApiKeyAuth
|
||||
// @Param group_id path string true "group id"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/compilation-template-groups/{group_id} [delete]
|
||||
func (h *CompilationTemplateGroupHandler) Delete(c *gin.Context) {
|
||||
user, code, msg := GetUser(c)
|
||||
if code != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, code, msg)
|
||||
return
|
||||
}
|
||||
id := c.Param("group_id")
|
||||
ok, err := h.compilationTemplateGroupService.DeleteGroup(c.Request.Context(), user.ID, id)
|
||||
if err != nil {
|
||||
common.ResponseWithCodeData(c, common.CodeExceptionError, nil, err.Error())
|
||||
return
|
||||
}
|
||||
if !ok {
|
||||
common.ResponseWithCodeData(c, common.CodeNotFound, nil, "Cannot find compilation template group "+id+".")
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, true, "success")
|
||||
}
|
||||
475
internal/handler/dataset_artifact.go
Normal file
475
internal/handler/dataset_artifact.go
Normal file
@@ -0,0 +1,475 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// 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"
|
||||
"strconv"
|
||||
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/dao"
|
||||
"ragflow/internal/entity"
|
||||
"ragflow/internal/service"
|
||||
dataset "ragflow/internal/service/dataset"
|
||||
"ragflow/internal/service/file"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// maxArtifactPageSize caps the page_size query parameter for artifact list
|
||||
// endpoints so a client cannot force an unbounded document-engine search.
|
||||
const maxArtifactPageSize = 100
|
||||
|
||||
// DatasetArtifactHandler exposes the knowledge-compilation artifact REST APIs
|
||||
// backed by DatasetArtifactService.
|
||||
type DatasetArtifactHandler struct {
|
||||
svc *service.DatasetArtifactService
|
||||
datasetSvc *dataset.DatasetService
|
||||
fileCommitSvc *file.FileCommitService
|
||||
}
|
||||
|
||||
// NewDatasetArtifactHandler creates a DatasetArtifactHandler.
|
||||
func NewDatasetArtifactHandler(svc *service.DatasetArtifactService, datasetSvc *dataset.DatasetService, fileCommitSvc *file.FileCommitService) *DatasetArtifactHandler {
|
||||
return &DatasetArtifactHandler{svc: svc, datasetSvc: datasetSvc, fileCommitSvc: fileCommitSvc}
|
||||
}
|
||||
|
||||
// datasetOwner resolves the dataset and returns its tenant id. It also enforces
|
||||
// dataset access permission for the requesting user. When the request is
|
||||
// unauthenticated, the dataset is missing, or the user is not allowed to access
|
||||
// it, an error response is written and (nil, "", "") is returned so callers can
|
||||
// abort without sending a second response.
|
||||
func (h *DatasetArtifactHandler) datasetOwner(c *gin.Context, datasetID string) (*entity.User, string, string) {
|
||||
user, code, msg := GetUser(c)
|
||||
if code != common.CodeSuccess {
|
||||
common.ErrorWithCode(c, code, msg)
|
||||
return nil, "", ""
|
||||
}
|
||||
kb, err := h.datasetSvc.GetKnowledgebaseByID(c.Request.Context(), datasetID)
|
||||
if err != nil {
|
||||
if dao.IsNotFoundErr(err) {
|
||||
common.ErrorWithCode(c, common.CodeNotFound, "dataset not found")
|
||||
} else {
|
||||
common.ErrorWithCode(c, common.CodeServerError, "failed to resolve dataset")
|
||||
}
|
||||
return nil, "", ""
|
||||
}
|
||||
if kb == nil {
|
||||
common.ErrorWithCode(c, common.CodeNotFound, "dataset not found")
|
||||
return nil, "", ""
|
||||
}
|
||||
if !h.datasetSvc.Accessible(c.Request.Context(), datasetID, user.ID) {
|
||||
common.ErrorWithCode(c, common.CodeForbidden, "no permission to access this dataset")
|
||||
return nil, "", ""
|
||||
}
|
||||
return user, kb.TenantID, msg
|
||||
}
|
||||
|
||||
// HEAD /artifacts — any wiki artifact present?
|
||||
func (h *DatasetArtifactHandler) AnyArtifact(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
has, err := h.svc.HasWiki(c.Request.Context(), tenantID, c.Param("dataset_id"))
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
if has {
|
||||
c.Status(http.StatusOK)
|
||||
} else {
|
||||
c.Status(http.StatusNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
// GET /artifacts — list wiki pages.
|
||||
func (h *DatasetArtifactHandler) ListArtifacts(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
datasetID := c.Param("dataset_id")
|
||||
pageType := c.Query("page_type")
|
||||
topic := c.Query("topic")
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "30"))
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if pageSize < 1 {
|
||||
pageSize = 30
|
||||
}
|
||||
if pageSize > maxArtifactPageSize {
|
||||
pageSize = maxArtifactPageSize
|
||||
}
|
||||
items, total, err := h.svc.ListWikiPages(c.Request.Context(), tenantID, datasetID, pageType, topic, page, pageSize)
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"total": total, "pages": items}, "success")
|
||||
}
|
||||
|
||||
// PUT /artifacts/<page_type>/<slug> — edit a wiki page.
|
||||
func (h *DatasetArtifactHandler) UpdateArtifact(c *gin.Context) {
|
||||
user, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
datasetID := c.Param("dataset_id")
|
||||
pageType := c.Param("page_type")
|
||||
slug := c.Param("slug")
|
||||
var req struct {
|
||||
ContentMd string `json:"content_md"`
|
||||
Title string `json:"title"`
|
||||
Outlinks []string `json:"outlinks"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
common.ErrorWithCode(c, common.CodeArgumentError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Read the current page before mutating so an audit commit can record an
|
||||
// accurate old-to-new diff. Only record when the prior state was read
|
||||
// successfully; a failed read must not produce a diff against an unknown
|
||||
// old value.
|
||||
var oldContent string
|
||||
canRecordAudit := false
|
||||
if req.ContentMd != "" {
|
||||
before, gerr := h.svc.GetWikiPage(c.Request.Context(), tenantID, datasetID, pageType, slug)
|
||||
if gerr != nil {
|
||||
common.Warn("failed to read wiki page before recording edit commit", zap.Error(gerr))
|
||||
} else if before != nil {
|
||||
oldContent = before.ContentMd
|
||||
canRecordAudit = true
|
||||
}
|
||||
}
|
||||
|
||||
detail, err := h.svc.UpdateWikiPage(c.Request.Context(), tenantID, datasetID, pageType, slug, req.ContentMd, req.Title, req.Outlinks)
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
if detail == nil {
|
||||
common.ErrorWithCode(c, common.CodeNotFound, "page not found")
|
||||
return
|
||||
}
|
||||
|
||||
// Record a wiki-page edit audit commit (git-style parent chain) when the
|
||||
// content actually changed. Best-effort: a commit write failure must not
|
||||
// roll back the page edit already persisted above.
|
||||
if canRecordAudit && req.ContentMd != oldContent && h.fileCommitSvc != nil {
|
||||
title := req.Title
|
||||
if title == "" {
|
||||
title = detail.Title
|
||||
}
|
||||
if _, cerr := h.fileCommitSvc.RecordPageEdit(c.Request.Context(), file.PageEditCommitInput{
|
||||
DatasetID: datasetID,
|
||||
DocID: pageType + "/" + slug,
|
||||
Slug: slug,
|
||||
PageType: pageType,
|
||||
Title: title,
|
||||
AuthorID: user.ID,
|
||||
OldContent: oldContent,
|
||||
NewContent: req.ContentMd,
|
||||
}); cerr != nil {
|
||||
common.Warn("failed to record wiki page edit commit", zap.Error(cerr))
|
||||
}
|
||||
}
|
||||
|
||||
common.SuccessWithData(c, detail, "success")
|
||||
}
|
||||
|
||||
// GET /artifacts/<page_type>/<slug> — single wiki page.
|
||||
func (h *DatasetArtifactHandler) GetArtifact(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
datasetID := c.Param("dataset_id")
|
||||
pageType := c.Param("page_type")
|
||||
slug := c.Param("slug")
|
||||
detail, err := h.svc.GetWikiPage(c.Request.Context(), tenantID, datasetID, pageType, slug)
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
if detail == nil {
|
||||
common.ErrorWithCode(c, common.CodeNotFound, "page not found")
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, detail, "success")
|
||||
}
|
||||
|
||||
// DELETE /artifacts — clear all wiki artifacts.
|
||||
func (h *DatasetArtifactHandler) DeleteArtifacts(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
deleted, err := h.svc.ClearWiki(c.Request.Context(), tenantID, c.Param("dataset_id"))
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, deleted, "success")
|
||||
}
|
||||
|
||||
// GET /artifacts/topics — list wiki topics.
|
||||
func (h *DatasetArtifactHandler) ListArtifactTopics(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
datasetID := c.Param("dataset_id")
|
||||
items, total, err := h.svc.ListWikiTopics(c.Request.Context(), tenantID, datasetID)
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"total": total, "topics": items}, "success")
|
||||
}
|
||||
|
||||
// GET /artifacts/alteration — wiki alteration summary.
|
||||
func (h *DatasetArtifactHandler) GetArtifactAlteration(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
datasetID := c.Param("dataset_id")
|
||||
alt, err := h.svc.GetWikiAlteration(c.Request.Context(), tenantID, datasetID)
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, alt, "success")
|
||||
}
|
||||
|
||||
// GET /artifacts/graph — wiki entity/relation graph.
|
||||
func (h *DatasetArtifactHandler) GetArtifactGraph(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
datasetID := c.Param("dataset_id")
|
||||
graph, err := h.svc.GetWikiGraph(c.Request.Context(), tenantID, datasetID)
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, graph, "success")
|
||||
}
|
||||
|
||||
// GET /artifacts/structure — list compiled structures of a dataset.
|
||||
func (h *DatasetArtifactHandler) ListStructures(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
datasetID := c.Param("dataset_id")
|
||||
structureKind := c.Query("structure_kind")
|
||||
structureIndexType := c.Query("structure_index_type")
|
||||
items, total, err := h.svc.ListStructures(c.Request.Context(), tenantID, datasetID, structureKind, structureIndexType)
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"total": total, "structures": items}, "success")
|
||||
}
|
||||
|
||||
// DELETE /artifacts/structure — delete compiled structures of a dataset.
|
||||
func (h *DatasetArtifactHandler) DeleteStructures(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
datasetID := c.Param("dataset_id")
|
||||
structureKind := c.Query("structure_kind")
|
||||
structureIndexType := c.Query("structure_index_type")
|
||||
n, err := h.svc.DeleteStructures(c.Request.Context(), tenantID, datasetID, structureKind, structureIndexType)
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"deleted": n}, "success")
|
||||
}
|
||||
|
||||
// HEAD /skills — any skill artifact present?
|
||||
func (h *DatasetArtifactHandler) AnySkill(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
has, err := h.svc.HasSkill(c.Request.Context(), tenantID, c.Param("dataset_id"))
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
if has {
|
||||
c.Status(http.StatusOK)
|
||||
} else {
|
||||
c.Status(http.StatusNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
// GET /navigation — list navigation clusters.
|
||||
func (h *DatasetArtifactHandler) ListNavigation(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
items, total, err := h.svc.ListNavClusters(c.Request.Context(), tenantID, c.Param("dataset_id"))
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"total": total, "nav": items}, "success")
|
||||
}
|
||||
|
||||
// DELETE /navigation — delete all navigation clusters.
|
||||
func (h *DatasetArtifactHandler) DeleteNavigation(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
n, err := h.svc.DeleteNav(c.Request.Context(), tenantID, c.Param("dataset_id"))
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"deleted": n}, "success")
|
||||
}
|
||||
|
||||
// DELETE /navigation/<name> — delete a single navigation cluster.
|
||||
func (h *DatasetArtifactHandler) DeleteNavigationNode(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
n, err := h.svc.DeleteNavNode(c.Request.Context(), tenantID, c.Param("dataset_id"), c.Param("name"))
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"deleted": n}, "success")
|
||||
}
|
||||
|
||||
// GET /navigation/<name>/children — list children of a navigation cluster.
|
||||
func (h *DatasetArtifactHandler) ListNavigationChildren(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
items, total, err := h.svc.ListNavChildren(c.Request.Context(), tenantID, c.Param("dataset_id"), c.Param("name"))
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"total": total, "children": items}, "success")
|
||||
}
|
||||
|
||||
// GET /skills — skill tree.
|
||||
func (h *DatasetArtifactHandler) GetSkillTree(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
kwd := c.Query("kwd")
|
||||
items, total, err := h.svc.GetSkillTree(c.Request.Context(), tenantID, c.Param("dataset_id"), kwd)
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"total": total, "tree": items}, "success")
|
||||
}
|
||||
|
||||
// DELETE /skills — delete all skills.
|
||||
func (h *DatasetArtifactHandler) DeleteSkills(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
n, err := h.svc.DeleteSkills(c.Request.Context(), tenantID, c.Param("dataset_id"), "")
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"deleted": n}, "success")
|
||||
}
|
||||
|
||||
// GET /skills/<skill_kwd> — single skill page.
|
||||
func (h *DatasetArtifactHandler) GetSkillPage(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
detail, err := h.svc.GetSkillPage(c.Request.Context(), tenantID, c.Param("dataset_id"), c.Param("skill_kwd"))
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
if detail == nil {
|
||||
common.ErrorWithCode(c, common.CodeNotFound, "skill not found")
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, detail, "success")
|
||||
}
|
||||
|
||||
// DELETE /skills/<skill_kwd> — delete a single skill.
|
||||
func (h *DatasetArtifactHandler) DeleteSkill(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
n, err := h.svc.DeleteSkills(c.Request.Context(), tenantID, c.Param("dataset_id"), c.Param("skill_kwd"))
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"deleted": n}, "success")
|
||||
}
|
||||
|
||||
// GET /documents/<document_id>/structure/graph — document structure graph.
|
||||
func (h *DatasetArtifactHandler) GetDocumentGraph(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
datasetID := c.Param("dataset_id")
|
||||
documentID := c.Param("document_id")
|
||||
graphType := c.Query("graph_type")
|
||||
items, total, err := h.svc.GetDocumentGraph(c.Request.Context(), tenantID, datasetID, documentID, graphType)
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"total": total, "graph": items}, "success")
|
||||
}
|
||||
|
||||
// DELETE /documents/<document_id>/structure/graph — delete document structure graph.
|
||||
func (h *DatasetArtifactHandler) DeleteDocumentGraph(c *gin.Context) {
|
||||
_, tenantID, _ := h.datasetOwner(c, c.Param("dataset_id"))
|
||||
if tenantID == "" {
|
||||
return
|
||||
}
|
||||
datasetID := c.Param("dataset_id")
|
||||
documentID := c.Param("document_id")
|
||||
n, err := h.svc.DeleteDocumentGraph(c.Request.Context(), tenantID, datasetID, documentID)
|
||||
if err != nil {
|
||||
common.ErrorWithCode(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{"deleted": n}, "success")
|
||||
}
|
||||
@@ -38,6 +38,7 @@ type fileCommitService interface {
|
||||
GetCommitTree(ctx context.Context, commitID string) (map[string]interface{}, error)
|
||||
GetCommitFileContent(ctx context.Context, folderID, commitID, fileID string) ([]byte, error)
|
||||
GetFileVersionHistory(ctx context.Context, fileID string) ([]entity.VersionEntry, error)
|
||||
ListPageCommits(ctx context.Context, datasetID, pageType, slug string, page, pageSize int) ([]*entity.FileCommit, int64, error)
|
||||
}
|
||||
|
||||
// FileCommitHandler file commit handler
|
||||
@@ -217,6 +218,49 @@ func (h *FileCommitHandler) ListCommits(c *gin.Context) {
|
||||
}
|
||||
|
||||
ctx := c.Request.Context()
|
||||
|
||||
// Python's list_commits supports ?slug=<page_slug> to filter audit commits
|
||||
// for a specific wiki/skill page (written by record_page_edit). These page
|
||||
// commits are scoped to the dataset and page file key, so route them through
|
||||
// the page-commit path instead of the folder-based ListCommits. This only
|
||||
// applies to the /datasets/{dataset_id}/commits route.
|
||||
if slug := c.Query("slug"); slug != "" {
|
||||
datasetID := c.Param("dataset_id")
|
||||
if datasetID == "" {
|
||||
common.ErrorWithCode(c, common.CodeArgumentError, "slug requires a dataset scope")
|
||||
return
|
||||
}
|
||||
pageType := c.Query("page_type")
|
||||
commits, total, err := h.commitService.ListPageCommits(ctx, datasetID, pageType, slug, page, pageSize)
|
||||
if err != nil {
|
||||
jsonInternalError(c, err)
|
||||
return
|
||||
}
|
||||
var commitList []entity.CommitResponse
|
||||
for _, commit := range commits {
|
||||
var ct int64
|
||||
if commit.CreateTime != nil {
|
||||
ct = *commit.CreateTime
|
||||
}
|
||||
commitList = append(commitList, entity.CommitResponse{
|
||||
ID: commit.ID,
|
||||
FolderID: commit.FolderID,
|
||||
ParentID: commit.ParentID,
|
||||
Message: commit.Message,
|
||||
AuthorID: commit.AuthorID,
|
||||
FileCount: commit.FileCount,
|
||||
CreateTime: &ct,
|
||||
})
|
||||
}
|
||||
common.SuccessWithData(c, gin.H{
|
||||
"total": total,
|
||||
"page": page,
|
||||
"page_size": pageSize,
|
||||
"commits": commitList,
|
||||
}, common.CodeSuccess.Message())
|
||||
return
|
||||
}
|
||||
|
||||
commits, total, err := h.commitService.ListCommits(ctx, folderID, page, pageSize, orderBy, desc)
|
||||
if err != nil {
|
||||
jsonInternalError(c, err)
|
||||
|
||||
@@ -41,6 +41,7 @@ type mockFileCommitSvc struct {
|
||||
getCommitTreeFn func(ctx context.Context, commitID string) (map[string]interface{}, error)
|
||||
getCommitFileContentFn func(ctx context.Context, folderID, commitID, fileID string) ([]byte, error)
|
||||
getFileVersionHistoryFn func(ctx context.Context, fileID string) ([]entity.VersionEntry, error)
|
||||
listPageCommitsFn func(ctx context.Context, datasetID, pageType, slug string, page, pageSize int) ([]*entity.FileCommit, int64, error)
|
||||
}
|
||||
|
||||
func (m *mockFileCommitSvc) CreateCommit(ctx context.Context, folderID, authorID, message string, changes []entity.FileChange) (*entity.FileCommit, error) {
|
||||
@@ -128,6 +129,13 @@ func (m *mockFileCommitSvc) GetFileVersionHistory(ctx context.Context, fileID st
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *mockFileCommitSvc) ListPageCommits(ctx context.Context, datasetID, pageType, slug string, page, pageSize int) ([]*entity.FileCommit, int64, error) {
|
||||
if m.listPageCommitsFn != nil {
|
||||
return m.listPageCommitsFn(ctx, datasetID, pageType, slug, page, pageSize)
|
||||
}
|
||||
return []*entity.FileCommit{}, 0, nil
|
||||
}
|
||||
|
||||
func setupFileCommitTest(userID string) (*gin.Engine, *mockFileCommitSvc) {
|
||||
mock := &mockFileCommitSvc{}
|
||||
h := &FileCommitHandler{commitService: mock}
|
||||
|
||||
@@ -112,7 +112,7 @@ func (h *ProviderHandler) AddProvider(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *ProviderHandler) DeleteProvider(c *gin.Context) {
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
@@ -131,7 +131,7 @@ func (h *ProviderHandler) DeleteProvider(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *ProviderHandler) ShowProvider(c *gin.Context) {
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
@@ -146,7 +146,7 @@ func (h *ProviderHandler) ShowProvider(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *ProviderHandler) ListModels(c *gin.Context) {
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
@@ -221,7 +221,7 @@ func (h *ProviderHandler) ListModels(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *ProviderHandler) ShowModel(c *gin.Context) {
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
@@ -249,7 +249,7 @@ type CreateProviderInstanceRequest struct {
|
||||
}
|
||||
|
||||
func (h *ProviderHandler) CreateProviderInstance(c *gin.Context) {
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
@@ -287,7 +287,7 @@ func (h *ProviderHandler) CreateProviderInstance(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *ProviderHandler) ListProviderInstances(c *gin.Context) {
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
@@ -306,13 +306,13 @@ func (h *ProviderHandler) ListProviderInstances(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *ProviderHandler) ShowProviderInstance(c *gin.Context) {
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
}
|
||||
|
||||
instanceIDOrName := c.Param("instance_name")
|
||||
instanceIDOrName := c.Param("instance_id_or_name")
|
||||
if instanceIDOrName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required")
|
||||
return
|
||||
@@ -331,13 +331,13 @@ func (h *ProviderHandler) ShowProviderInstance(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *ProviderHandler) ShowInstanceBalance(c *gin.Context) {
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
}
|
||||
|
||||
instanceName := c.Param("instance_name")
|
||||
instanceName := c.Param("instance_id_or_name")
|
||||
if instanceName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required")
|
||||
return
|
||||
@@ -357,7 +357,7 @@ func (h *ProviderHandler) ShowInstanceBalance(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *ProviderHandler) CheckConnection(c *gin.Context) {
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
@@ -382,13 +382,13 @@ func (h *ProviderHandler) CheckConnection(c *gin.Context) {
|
||||
|
||||
func (h *ProviderHandler) CheckInstanceConnection(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
}
|
||||
|
||||
instanceName := c.Param("instance_name")
|
||||
instanceName := c.Param("instance_id_or_name")
|
||||
if instanceName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required")
|
||||
return
|
||||
@@ -417,13 +417,13 @@ func (h *ProviderHandler) CheckInstanceConnection(c *gin.Context) {
|
||||
|
||||
func (h *ProviderHandler) ListTasks(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
}
|
||||
|
||||
instanceName := c.Param("instance_name")
|
||||
instanceName := c.Param("instance_id_or_name")
|
||||
if instanceName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required")
|
||||
return
|
||||
@@ -443,13 +443,13 @@ func (h *ProviderHandler) ListTasks(c *gin.Context) {
|
||||
|
||||
func (h *ProviderHandler) ShowTask(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
}
|
||||
|
||||
instanceName := c.Param("instance_name")
|
||||
instanceName := c.Param("instance_id_or_name")
|
||||
if instanceName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required")
|
||||
return
|
||||
@@ -484,13 +484,13 @@ type AlterProviderInstanceRequest struct {
|
||||
|
||||
func (h *ProviderHandler) AlterProviderInstance(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
}
|
||||
|
||||
instanceName := c.Param("instance_name")
|
||||
instanceName := c.Param("instance_id_or_name")
|
||||
if instanceName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required")
|
||||
return
|
||||
@@ -527,7 +527,7 @@ type DropProviderInstanceRequest struct {
|
||||
}
|
||||
|
||||
func (h *ProviderHandler) DropProviderInstance(c *gin.Context) {
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
@@ -552,12 +552,12 @@ func (h *ProviderHandler) DropProviderInstance(c *gin.Context) {
|
||||
|
||||
func (h *ProviderHandler) ListInstanceModels(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
}
|
||||
instanceName := c.Param("instance_name")
|
||||
instanceName := c.Param("instance_id_or_name")
|
||||
if instanceName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required")
|
||||
return
|
||||
@@ -600,13 +600,13 @@ type AlterModelRequest struct {
|
||||
}
|
||||
|
||||
func (h *ProviderHandler) AlterModel(c *gin.Context) {
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
}
|
||||
|
||||
instanceName := c.Param("instance_name")
|
||||
instanceName := c.Param("instance_id_or_name")
|
||||
if instanceName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required")
|
||||
return
|
||||
@@ -691,8 +691,8 @@ func (h *ProviderHandler) AddModel(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
req.ProviderName = c.Param("provider_name")
|
||||
req.InstanceName = c.Param("instance_name")
|
||||
req.ProviderName = c.Param("provider_id_or_name")
|
||||
req.InstanceName = c.Param("instance_id_or_name")
|
||||
|
||||
if req.ProviderName == "" || req.InstanceName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, common.CodeBadRequest, nil, "provider_name and instance_name are required")
|
||||
@@ -726,12 +726,12 @@ type DropInstanceModelRequest struct {
|
||||
}
|
||||
|
||||
func (h *ProviderHandler) DropInstanceModels(c *gin.Context) {
|
||||
providerName := c.Param("provider_name")
|
||||
providerName := c.Param("provider_id_or_name")
|
||||
if providerName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Provider name is required")
|
||||
return
|
||||
}
|
||||
instanceName := c.Param("instance_name")
|
||||
instanceName := c.Param("instance_id_or_name")
|
||||
if instanceName == "" {
|
||||
common.ResponseWithHttpCodeData(c, http.StatusBadRequest, 400, nil, "Instance name is required")
|
||||
return
|
||||
|
||||
@@ -88,8 +88,8 @@ func TestProviderHandlerAlterModelRejectsMissingModelSelector(t *testing.T) {
|
||||
ctx, recorder := newProviderHandlerRequest(
|
||||
t,
|
||||
map[string]interface{}{"status": "active"},
|
||||
gin.Param{Key: "provider_name", Value: "OpenAI"},
|
||||
gin.Param{Key: "instance_name", Value: "default"},
|
||||
gin.Param{Key: "provider_id_or_name", Value: "OpenAI"},
|
||||
gin.Param{Key: "instance_id_or_name", Value: "default"},
|
||||
)
|
||||
|
||||
NewProviderHandler(nil, service.NewModelProviderService()).AlterModel(ctx)
|
||||
@@ -107,8 +107,8 @@ func TestProviderHandlerAlterModelRejectsInvalidStatus(t *testing.T) {
|
||||
ctx, recorder := newProviderHandlerRequest(
|
||||
t,
|
||||
map[string]interface{}{"status": "disabled"},
|
||||
gin.Param{Key: "provider_name", Value: "OpenAI"},
|
||||
gin.Param{Key: "instance_name", Value: "default"},
|
||||
gin.Param{Key: "provider_id_or_name", Value: "OpenAI"},
|
||||
gin.Param{Key: "instance_id_or_name", Value: "default"},
|
||||
gin.Param{Key: "model_name", Value: "gpt-test"},
|
||||
)
|
||||
|
||||
@@ -131,8 +131,8 @@ func TestProviderHandlerAlterModelUpdatesStatus(t *testing.T) {
|
||||
ctx, recorder := newProviderHandlerRequest(
|
||||
t,
|
||||
map[string]interface{}{"status": "inactive"},
|
||||
gin.Param{Key: "provider_name", Value: "OpenAI"},
|
||||
gin.Param{Key: "instance_name", Value: "default"},
|
||||
gin.Param{Key: "provider_id_or_name", Value: "OpenAI"},
|
||||
gin.Param{Key: "instance_id_or_name", Value: "default"},
|
||||
gin.Param{Key: "model_name", Value: "gpt-test"},
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user