feat: add knowledge management functionality with CRUD operations and database schema
- Implemented KnowledgeHandler for managing knowledge groups and items, including listing, creating, updating, and deleting operations. - Added database migration scripts to create necessary tables for knowledge management, including knowledge_groups, knowledge_items, knowledge_parse_tasks, and knowledge_chunks_meta. - Introduced prompt_rule_knowledge_groups table to associate prompt rules with knowledge groups.
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/geo-platform/tenant-api/internal/bootstrap"
|
||||
"github.com/geo-platform/tenant-api/internal/shared/response"
|
||||
"github.com/geo-platform/tenant-api/internal/tenant/app"
|
||||
)
|
||||
|
||||
type KnowledgeHandler struct {
|
||||
svc *app.KnowledgeService
|
||||
}
|
||||
|
||||
func NewKnowledgeHandler(a *bootstrap.App) *KnowledgeHandler {
|
||||
return &KnowledgeHandler{
|
||||
svc: app.NewKnowledgeService(
|
||||
a.DB,
|
||||
a.RetrievalProvider,
|
||||
a.VectorStore,
|
||||
a.ObjectStorage,
|
||||
a.Logger,
|
||||
a.Config.Retrieval,
|
||||
a.Config.Generation.QueueSize,
|
||||
a.Config.Generation.WorkerConcurrency,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *KnowledgeHandler) ListGroups(c *gin.Context) {
|
||||
data, err := h.svc.ListGroups(c.Request.Context())
|
||||
if err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.Success(c, data)
|
||||
}
|
||||
|
||||
func (h *KnowledgeHandler) CreateGroup(c *gin.Context) {
|
||||
var req app.KnowledgeGroupRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_params", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
data, err := h.svc.CreateGroup(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.SuccessWithStatus(c, http.StatusCreated, data)
|
||||
}
|
||||
|
||||
func (h *KnowledgeHandler) UpdateGroup(c *gin.Context) {
|
||||
groupID, err := strconv.ParseInt(c.Param("gid"), 10, 64)
|
||||
if err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_id", "knowledge group id must be a number"))
|
||||
return
|
||||
}
|
||||
|
||||
var req app.KnowledgeGroupRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_params", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.svc.UpdateGroup(c.Request.Context(), groupID, req); err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.Success(c, nil)
|
||||
}
|
||||
|
||||
func (h *KnowledgeHandler) DeleteGroup(c *gin.Context) {
|
||||
groupID, err := strconv.ParseInt(c.Param("gid"), 10, 64)
|
||||
if err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_id", "knowledge group id must be a number"))
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.svc.DeleteGroup(c.Request.Context(), groupID); err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.Success(c, nil)
|
||||
}
|
||||
|
||||
func (h *KnowledgeHandler) ListItems(c *gin.Context) {
|
||||
var groupID *int64
|
||||
if raw := c.Query("group_id"); raw != "" {
|
||||
parsed, err := strconv.ParseInt(raw, 10, 64)
|
||||
if err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_group_id", "group id must be a number"))
|
||||
return
|
||||
}
|
||||
groupID = &parsed
|
||||
}
|
||||
|
||||
data, err := h.svc.ListItems(c.Request.Context(), groupID)
|
||||
if err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.Success(c, data)
|
||||
}
|
||||
|
||||
func (h *KnowledgeHandler) CreateTextItem(c *gin.Context) {
|
||||
var req app.KnowledgeTextItemRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_params", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
data, err := h.svc.CreateTextItem(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.SuccessWithStatus(c, http.StatusCreated, data)
|
||||
}
|
||||
|
||||
func (h *KnowledgeHandler) CreateURLItem(c *gin.Context) {
|
||||
var req app.KnowledgeURLItemRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_params", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
data, err := h.svc.CreateURLItem(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.SuccessWithStatus(c, http.StatusCreated, data)
|
||||
}
|
||||
|
||||
func (h *KnowledgeHandler) CreateFileItem(c *gin.Context) {
|
||||
groupID, err := strconv.ParseInt(c.PostForm("group_id"), 10, 64)
|
||||
if err != nil || groupID <= 0 {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_group_id", "group id must be a number"))
|
||||
return
|
||||
}
|
||||
|
||||
name := c.PostForm("name")
|
||||
fileHeader, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_file", "file is required"))
|
||||
return
|
||||
}
|
||||
|
||||
file, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_file", "file cannot be opened"))
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
content, err := io.ReadAll(file)
|
||||
if err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_file", "file cannot be read"))
|
||||
return
|
||||
}
|
||||
|
||||
data, err := h.svc.CreateFileItem(c.Request.Context(), groupID, name, fileHeader.Filename, content)
|
||||
if err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.SuccessWithStatus(c, http.StatusCreated, data)
|
||||
}
|
||||
|
||||
func (h *KnowledgeHandler) DeleteItem(c *gin.Context) {
|
||||
itemID, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
||||
if err != nil {
|
||||
response.Error(c, response.ErrBadRequest(40001, "invalid_id", "knowledge item id must be a number"))
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.svc.DeleteItem(c.Request.Context(), itemID); err != nil {
|
||||
response.Error(c, err)
|
||||
return
|
||||
}
|
||||
response.Success(c, nil)
|
||||
}
|
||||
Reference in New Issue
Block a user