feat:knowlegde base api
This commit is contained in:
parent
c8ed293819
commit
00e3502c2d
|
|
@ -0,0 +1,25 @@
|
|||
package entity
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type KnowledgeBase struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
|
||||
|
||||
AgentId *string `json:"agent_id" gorm:"type:varchar"`
|
||||
AgentName *string `json:"agent_name" gorm:"type:varchar"`
|
||||
CreatedById uint `json:"created_by_id" gorm:"type:int4;not null"`
|
||||
Status int `json:"status" gorm:"type:int4;default:0"` // 0=wating,1=approved,2=reject
|
||||
|
||||
Title *string `json:"title" gorm:"type:varchar"`
|
||||
|
||||
FileJournalUrl *string `json:"file_journal_url" gorm:"type:varchar"`
|
||||
FileAudioUrl *string `json:"file_audio_url" gorm:"type:varchar"`
|
||||
FileVideoUrl *string `json:"file_video_url" gorm:"type:varchar"`
|
||||
|
||||
IsActive bool `json:"is_active" gorm:"type:bool;default:true"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
|
||||
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
knowledgeBaseSvc "narasi-ahli-be/app/module/knowledge_base/service"
|
||||
)
|
||||
|
||||
type Controller struct {
|
||||
KnowledgeBase KnowledgeBaseControllerInterface
|
||||
}
|
||||
|
||||
func NewController(
|
||||
knowledgeBaseService knowledgeBaseSvc.KnowledgeBaseServiceInterface,
|
||||
) *Controller {
|
||||
return &Controller{
|
||||
KnowledgeBase: NewKnowledgeBaseController(knowledgeBaseService),
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,241 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"narasi-ahli-be/app/module/knowledge_base/request"
|
||||
"narasi-ahli-be/app/module/knowledge_base/service"
|
||||
"narasi-ahli-be/utils/paginator"
|
||||
utilRes "narasi-ahli-be/utils/response"
|
||||
utilVal "narasi-ahli-be/utils/validator"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type KnowledgeBaseController struct {
|
||||
KnowledgeBaseService service.KnowledgeBaseServiceInterface
|
||||
}
|
||||
|
||||
type KnowledgeBaseControllerInterface interface {
|
||||
All(c *fiber.Ctx) error
|
||||
Show(c *fiber.Ctx) error
|
||||
Create(c *fiber.Ctx) error
|
||||
Update(c *fiber.Ctx) error
|
||||
Delete(c *fiber.Ctx) error
|
||||
Viewer(c *fiber.Ctx) error
|
||||
UpdateStatus(c *fiber.Ctx) error
|
||||
|
||||
|
||||
}
|
||||
|
||||
func NewKnowledgeBaseController(svc service.KnowledgeBaseServiceInterface) KnowledgeBaseControllerInterface {
|
||||
return &KnowledgeBaseController{
|
||||
KnowledgeBaseService: svc,
|
||||
}
|
||||
}
|
||||
|
||||
// @Summary Get all KnowledgeBase
|
||||
// @Description API for getting all KnowledgeBase
|
||||
// @Tags Knowledge Base
|
||||
// @Security Bearer
|
||||
// @Param agentId query string false "Agent ID"
|
||||
// @Param title query string false "Search title"
|
||||
// @Param status query int false "Status (0=draft,1=published,2=archived)"
|
||||
// @Param createdById query int false "Created By ID"
|
||||
// @Param isActive query bool false "Is active"
|
||||
// @Param page query int false "Page"
|
||||
// @Param limit query int false "Limit"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Router /knowledge-base [get]
|
||||
func (ctl *KnowledgeBaseController) All(c *fiber.Ctx) error {
|
||||
paginate, err := paginator.Paginate(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
reqContext := request.KnowledgeBaseQueryRequestContext{
|
||||
AgentId: c.Query("agentId"),
|
||||
Title: c.Query("title"),
|
||||
Status: c.Query("status"),
|
||||
IsActive: c.Query("isActive"),
|
||||
CreatedById: c.Query("createdById"),
|
||||
}
|
||||
|
||||
req := reqContext.ToParamRequest()
|
||||
req.Pagination = paginate
|
||||
|
||||
data, paging, err := ctl.KnowledgeBaseService.All(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{"KnowledgeBase list successfully retrieved"},
|
||||
Data: data,
|
||||
Meta: paging,
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary Get one KnowledgeBase
|
||||
// @Description API for getting one KnowledgeBase
|
||||
// @Tags Knowledge Base
|
||||
// @Security Bearer
|
||||
// @Param id path int true "KnowledgeBase ID"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Router /knowledge-base/{id} [get]
|
||||
func (ctl *KnowledgeBaseController) Show(c *fiber.Ctx) error {
|
||||
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := ctl.KnowledgeBaseService.Show(uint(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{"KnowledgeBase successfully retrieved"},
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary Create KnowledgeBase
|
||||
// @Description API for creating KnowledgeBase with upload file
|
||||
// @Tags Knowledge Base
|
||||
// @Security Bearer
|
||||
// @Accept multipart/form-data
|
||||
// @Produce json
|
||||
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
|
||||
//
|
||||
// @Param agentId formData string true "Agent ID"
|
||||
// @Param agentName formData string true "Agent Name"
|
||||
// @Param createdById formData int true "Created By ID"
|
||||
// @Param status formData int true "Status (integer)"
|
||||
// @Param title formData string true "Title"
|
||||
//
|
||||
// @Param fileJournal formData file false "Upload Journal File"
|
||||
// @Param fileAudio formData file false "Upload Audio File"
|
||||
// @Param fileVideo formData file false "Upload Video File"
|
||||
//
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 400 {object} response.BadRequestError
|
||||
// @Failure 401 {object} response.UnauthorizedError
|
||||
// @Failure 500 {object} response.InternalServerError
|
||||
// @Router /knowledge-base [post]
|
||||
func (ctl *KnowledgeBaseController) Create(c *fiber.Ctx) error {
|
||||
data, err := ctl.KnowledgeBaseService.Create(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{"KnowledgeBase successfully created"},
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
// Viewer KnowledgeBase
|
||||
// @Summary Viewer KnowledgeBase
|
||||
// @Description API for Viewer KnowledgeBase
|
||||
// @Tags Knowledge Base
|
||||
// @Security Bearer
|
||||
// @Param filename path string true "KnowledgeBase File Name"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 400 {object} response.BadRequestError
|
||||
// @Failure 401 {object} response.UnauthorizedError
|
||||
// @Failure 500 {object} response.InternalServerError
|
||||
// @Router /knowledge-base/viewer/{filename} [get]
|
||||
func (ctl *KnowledgeBaseController) Viewer(c *fiber.Ctx) error {
|
||||
return ctl.KnowledgeBaseService.Viewer(c)
|
||||
}
|
||||
|
||||
// @Summary Update KnowledgeBase
|
||||
// @Description API for updating KnowledgeBase
|
||||
// @Tags Knowledge Base
|
||||
// @Security Bearer
|
||||
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
|
||||
// @Param payload body request.KnowledgeBaseUpdateRequest true "Required payload"
|
||||
// @Param id path int true "KnowledgeBase ID"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Router /knowledge-base/{id} [put]
|
||||
func (ctl *KnowledgeBaseController) Update(c *fiber.Ctx) error {
|
||||
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req := new(request.KnowledgeBaseUpdateRequest)
|
||||
if err := utilVal.ParseAndValidate(c, req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := ctl.KnowledgeBaseService.Update(uint(id), *req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{"KnowledgeBase successfully updated"},
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary Delete KnowledgeBase
|
||||
// @Description API for deleting KnowledgeBase (soft delete)
|
||||
// @Tags Knowledge Base
|
||||
// @Security Bearer
|
||||
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
|
||||
// @Param id path int true "KnowledgeBase ID"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Router /knowledge-base/{id} [delete]
|
||||
func (ctl *KnowledgeBaseController) Delete(c *fiber.Ctx) error {
|
||||
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ctl.KnowledgeBaseService.Delete(uint(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{"KnowledgeBase successfully deleted"},
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary Update KnowledgeBase Status
|
||||
// @Description API untuk update status KnowledgeBase
|
||||
// @Tags Knowledge Base
|
||||
// @Security Bearer
|
||||
// @Param id path int true "KnowledgeBase ID"
|
||||
// @Param payload body request.KnowledgeBaseUpdateStatusRequest true "Required payload"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Router /knowledge-base/{id}/status [patch]
|
||||
func (ctl *KnowledgeBaseController) UpdateStatus(c *fiber.Ctx) error {
|
||||
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req := new(request.KnowledgeBaseUpdateStatusRequest)
|
||||
if err := utilVal.ParseAndValidate(c, req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := ctl.KnowledgeBaseService.UpdateStatus(uint(id), req.Status)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{"KnowledgeBase status successfully updated"},
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package knowledge_base
|
||||
|
||||
import (
|
||||
"narasi-ahli-be/app/module/knowledge_base/controller"
|
||||
"narasi-ahli-be/app/module/knowledge_base/repository"
|
||||
"narasi-ahli-be/app/module/knowledge_base/service"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
// struct of KnowledgeBaseRouter
|
||||
type KnowledgeBaseRouter struct {
|
||||
App fiber.Router
|
||||
Controller *controller.Controller
|
||||
}
|
||||
|
||||
// register bulky of KnowledgeBase module
|
||||
var NewKnowledgeBaseModule = fx.Options(
|
||||
// register repository of KnowledgeBase module
|
||||
fx.Provide(repository.NewKnowledgeBaseRepository),
|
||||
|
||||
// register service of KnowledgeBase module
|
||||
fx.Provide(service.NewKnowledgeBaseService),
|
||||
|
||||
// register controller of KnowledgeBase module
|
||||
fx.Provide(controller.NewController),
|
||||
|
||||
// register router of KnowledgeBase module
|
||||
fx.Provide(NewKnowledgeBaseRouter),
|
||||
)
|
||||
|
||||
// init KnowledgeBaseRouter
|
||||
func NewKnowledgeBaseRouter(fiber *fiber.App, controller *controller.Controller) *KnowledgeBaseRouter {
|
||||
return &KnowledgeBaseRouter{
|
||||
App: fiber,
|
||||
Controller: controller,
|
||||
}
|
||||
}
|
||||
|
||||
// register routes of KnowledgeBase module
|
||||
func (r *KnowledgeBaseRouter) RegisterKnowledgeBaseRoutes() {
|
||||
kbController := r.Controller.KnowledgeBase
|
||||
|
||||
r.App.Route("/knowledge-base", func(router fiber.Router) {
|
||||
router.Get("/", kbController.All)
|
||||
router.Get("/:id", kbController.Show)
|
||||
router.Post("/", kbController.Create)
|
||||
router.Put("/:id", kbController.Update)
|
||||
router.Delete("/:id", kbController.Delete)
|
||||
router.Get("/viewer/:filename", kbController.Viewer)
|
||||
router.Patch("/:id/status", kbController.UpdateStatus)
|
||||
|
||||
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package mapper
|
||||
|
||||
import (
|
||||
"narasi-ahli-be/app/database/entity"
|
||||
res "narasi-ahli-be/app/module/knowledge_base/response"
|
||||
)
|
||||
|
||||
func KnowledgeBaseResponseMapper(kb *entity.KnowledgeBase, host string) (out *res.KnowledgeBaseResponse) {
|
||||
if kb == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
out = &res.KnowledgeBaseResponse{
|
||||
ID: kb.ID,
|
||||
AgentId: kb.AgentId,
|
||||
AgentName: kb.AgentName,
|
||||
CreatedById: kb.CreatedById,
|
||||
Title: kb.Title,
|
||||
Status: kb.Status,
|
||||
|
||||
FileJournalUrl: kb.FileJournalUrl,
|
||||
FileAudioUrl: kb.FileAudioUrl,
|
||||
FileVideoUrl: kb.FileVideoUrl,
|
||||
|
||||
IsActive: kb.IsActive,
|
||||
CreatedAt: kb.CreatedAt,
|
||||
UpdatedAt: kb.UpdatedAt,
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"narasi-ahli-be/app/database"
|
||||
"narasi-ahli-be/app/database/entity"
|
||||
"narasi-ahli-be/app/module/knowledge_base/request"
|
||||
"narasi-ahli-be/utils/paginator"
|
||||
utilSvc "narasi-ahli-be/utils/service"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type KnowledgeBaseRepository struct {
|
||||
DB *database.Database
|
||||
}
|
||||
|
||||
// interface
|
||||
type KnowledgeBaseRepositoryInterface interface {
|
||||
GetAll(req request.KnowledgeBaseQueryRequest) (data []*entity.KnowledgeBase, paging paginator.Pagination, err error)
|
||||
FindOne(id uint) (data *entity.KnowledgeBase, err error)
|
||||
FindByFilename(filename string) (data *entity.KnowledgeBase, fileType string, err error)
|
||||
|
||||
Create(data *entity.KnowledgeBase) (err error)
|
||||
Update(id uint, data *entity.KnowledgeBase) (err error)
|
||||
Delete(id uint) (err error)
|
||||
}
|
||||
|
||||
func NewKnowledgeBaseRepository(db *database.Database) KnowledgeBaseRepositoryInterface {
|
||||
return &KnowledgeBaseRepository{
|
||||
DB: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *KnowledgeBaseRepository) GetAll(req request.KnowledgeBaseQueryRequest) (data []*entity.KnowledgeBase, paging paginator.Pagination, err error) {
|
||||
var count int64
|
||||
|
||||
query := r.DB.DB.Model(&entity.KnowledgeBase{})
|
||||
|
||||
query = query.Where("is_active = ?", true)
|
||||
|
||||
if req.AgentId != nil && *req.AgentId != "" {
|
||||
query = query.Where("agent_id = ?", *req.AgentId)
|
||||
}
|
||||
|
||||
if req.CreatedById != nil && *req.CreatedById > 0 {
|
||||
query = query.Where("created_by_id = ?", *req.CreatedById)
|
||||
}
|
||||
|
||||
if req.Title != nil && strings.TrimSpace(*req.Title) != "" {
|
||||
title := strings.ToLower(strings.TrimSpace(*req.Title))
|
||||
query = query.Where("LOWER(title) LIKE ?", "%"+title+"%")
|
||||
}
|
||||
|
||||
if req.Status != nil {
|
||||
query = query.Where("status = ?", *req.Status)
|
||||
}
|
||||
|
||||
if req.IsActive != nil {
|
||||
query = query.Where("is_active = ?", *req.IsActive)
|
||||
}
|
||||
|
||||
query.Count(&count)
|
||||
|
||||
if req.Pagination != nil && req.Pagination.SortBy != "" {
|
||||
direction := "ASC"
|
||||
if strings.ToLower(req.Pagination.Sort) == "desc" {
|
||||
direction = "DESC"
|
||||
}
|
||||
query = query.Order(fmt.Sprintf("%s %s", req.Pagination.SortBy, direction))
|
||||
} else {
|
||||
query = query.Order("created_at DESC")
|
||||
}
|
||||
|
||||
if req.Pagination == nil {
|
||||
req.Pagination = &paginator.Pagination{}
|
||||
}
|
||||
req.Pagination.Count = count
|
||||
req.Pagination = paginator.Paging(req.Pagination)
|
||||
|
||||
err = query.
|
||||
Offset(req.Pagination.Offset).
|
||||
Limit(req.Pagination.Limit).
|
||||
Find(&data).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, paging, err
|
||||
}
|
||||
|
||||
paging = *req.Pagination
|
||||
return data, paging, nil
|
||||
}
|
||||
|
||||
func (r *KnowledgeBaseRepository) FindOne(id uint) (data *entity.KnowledgeBase, err error) {
|
||||
query := r.DB.DB.Model(&entity.KnowledgeBase{})
|
||||
|
||||
if err := query.Where("id = ? AND is_active = ?", id, true).First(&data).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (r *KnowledgeBaseRepository) Create(data *entity.KnowledgeBase) (err error) {
|
||||
return r.DB.DB.Create(data).Error
|
||||
}
|
||||
|
||||
func (r *KnowledgeBaseRepository) Update(id uint, data *entity.KnowledgeBase) (err error) {
|
||||
updateMap, err := utilSvc.StructToMap(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return r.DB.DB.Model(&entity.KnowledgeBase{}).
|
||||
Where("id = ?", id).
|
||||
Updates(updateMap).
|
||||
Error
|
||||
}
|
||||
|
||||
func (r *KnowledgeBaseRepository) Delete(id uint) (err error) {
|
||||
return r.DB.DB.Delete(&entity.KnowledgeBase{}, id).Error
|
||||
}
|
||||
|
||||
func (r *KnowledgeBaseRepository) FindByFilename(filename string) (data *entity.KnowledgeBase, fileType string, err error) {
|
||||
query := r.DB.DB.Model(&entity.KnowledgeBase{}).Where("is_active = ?", true)
|
||||
|
||||
// cari berdasarkan url yang mengandung filename
|
||||
like := "%" + filename
|
||||
|
||||
// journal
|
||||
var kb entity.KnowledgeBase
|
||||
if err := query.Where("file_journal_url LIKE ?", like).First(&kb).Error; err == nil {
|
||||
return &kb, "journal", nil
|
||||
}
|
||||
|
||||
// audio
|
||||
if err := query.Where("file_audio_url LIKE ?", like).First(&kb).Error; err == nil {
|
||||
return &kb, "audio", nil
|
||||
}
|
||||
|
||||
// video
|
||||
if err := query.Where("file_video_url LIKE ?", like).First(&kb).Error; err == nil {
|
||||
return &kb, "video", nil
|
||||
}
|
||||
|
||||
return nil, "", fmt.Errorf("file not found")
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
package request
|
||||
|
||||
import (
|
||||
"narasi-ahli-be/app/database/entity"
|
||||
"narasi-ahli-be/utils/paginator"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type KnowledgeBaseGeneric interface {
|
||||
ToEntity() *entity.KnowledgeBase
|
||||
}
|
||||
|
||||
type KnowledgeBaseQueryRequest struct {
|
||||
AgentId *string `json:"agentId"`
|
||||
Title *string `json:"title"`
|
||||
Status *int `json:"status"`
|
||||
IsActive *bool `json:"isActive"`
|
||||
CreatedById *uint `json:"createdById"`
|
||||
Pagination *paginator.Pagination `json:"pagination"`
|
||||
}
|
||||
|
||||
type KnowledgeBaseUpdateStatusRequest struct {
|
||||
Status int `json:"status" validate:"required"`
|
||||
}
|
||||
|
||||
type KnowledgeBaseCreateRequest struct {
|
||||
AgentId *string `form:"agentId" validate:"required"`
|
||||
AgentName *string `form:"agentName" validate:"required"`
|
||||
CreatedById uint `form:"createdById" validate:"required"`
|
||||
Title *string `form:"title" validate:"required"`
|
||||
Status int `form:"status" validate:"required"`
|
||||
}
|
||||
|
||||
func (req KnowledgeBaseCreateRequest) ToEntity() *entity.KnowledgeBase {
|
||||
kb := &entity.KnowledgeBase{
|
||||
AgentId: req.AgentId,
|
||||
AgentName: req.AgentName,
|
||||
CreatedById: req.CreatedById,
|
||||
Title: req.Title,
|
||||
Status: req.Status,
|
||||
|
||||
}
|
||||
|
||||
return kb
|
||||
}
|
||||
|
||||
type KnowledgeBaseUpdateRequest struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
|
||||
AgentId *string `json:"agentId" validate:"required"`
|
||||
AgentName *string `json:"agentName" validate:"required"`
|
||||
Title *string `json:"title" validate:"required"`
|
||||
Status int `json:"status" validate:"required"`
|
||||
|
||||
FileJournalUrl *string `json:"fileJournalUrl"`
|
||||
FileAudioUrl *string `json:"fileAudioUrl"`
|
||||
FileVideoUrl *string `json:"fileVideoUrl"`
|
||||
|
||||
IsActive *bool `json:"isActive"`
|
||||
}
|
||||
|
||||
func (req KnowledgeBaseUpdateRequest) ToEntity() *entity.KnowledgeBase {
|
||||
kb := &entity.KnowledgeBase{
|
||||
ID: req.ID,
|
||||
AgentId: req.AgentId,
|
||||
AgentName: req.AgentName,
|
||||
Title: req.Title,
|
||||
Status: req.Status,
|
||||
FileJournalUrl: req.FileJournalUrl,
|
||||
FileAudioUrl: req.FileAudioUrl,
|
||||
FileVideoUrl: req.FileVideoUrl,
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
|
||||
if req.IsActive != nil {
|
||||
kb.IsActive = *req.IsActive
|
||||
}
|
||||
|
||||
return kb
|
||||
}
|
||||
|
||||
type KnowledgeBaseQueryRequestContext struct {
|
||||
AgentId string `json:"agentId"`
|
||||
Title string `json:"title"`
|
||||
Status string `json:"status"`
|
||||
IsActive string `json:"isActive"`
|
||||
CreatedById string `json:"createdById"`
|
||||
}
|
||||
|
||||
func (req KnowledgeBaseQueryRequestContext) ToParamRequest() KnowledgeBaseQueryRequest {
|
||||
var request KnowledgeBaseQueryRequest
|
||||
|
||||
if agentId := req.AgentId; agentId != "" {
|
||||
request.AgentId = &agentId
|
||||
}
|
||||
|
||||
if title := req.Title; title != "" {
|
||||
request.Title = &title
|
||||
}
|
||||
|
||||
if statusStr := req.Status; statusStr != "" {
|
||||
status, err := strconv.Atoi(statusStr)
|
||||
if err == nil {
|
||||
request.Status = &status
|
||||
}
|
||||
}
|
||||
|
||||
if isActiveStr := req.IsActive; isActiveStr != "" {
|
||||
isActive, err := strconv.ParseBool(isActiveStr)
|
||||
if err == nil {
|
||||
request.IsActive = &isActive
|
||||
}
|
||||
}
|
||||
|
||||
if createdByIdStr := req.CreatedById; createdByIdStr != "" {
|
||||
id64, err := strconv.ParseUint(createdByIdStr, 10, 32)
|
||||
if err == nil {
|
||||
uid := uint(id64)
|
||||
request.CreatedById = &uid
|
||||
}
|
||||
}
|
||||
|
||||
return request
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package response
|
||||
|
||||
import "time"
|
||||
|
||||
type KnowledgeBaseResponse struct {
|
||||
ID uint `json:"id"`
|
||||
|
||||
AgentId *string `json:"agentId"`
|
||||
AgentName *string `json:"agentName"`
|
||||
CreatedById uint `json:"createdById"`
|
||||
|
||||
Title *string `json:"title"`
|
||||
Status int `json:"status"`
|
||||
|
||||
FileJournalUrl *string `json:"fileJournalUrl"`
|
||||
FileAudioUrl *string `json:"fileAudioUrl"`
|
||||
FileVideoUrl *string `json:"fileVideoUrl"`
|
||||
|
||||
IsActive bool `json:"isActive"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio-go/v7"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// AsyncUploader menangani proses upload secara asynchronous
|
||||
type UploadService interface {
|
||||
UploadFile(ctx context.Context, minioClient *minio.Client, uploadID string, reader io.Reader, bucketName string, objectName string, size int64, contentType string) error
|
||||
}
|
||||
|
||||
type uploadService struct {
|
||||
uploadManager UploadManager
|
||||
Log zerolog.Logger
|
||||
}
|
||||
|
||||
func NewUploadService(uploadManager UploadManager, log zerolog.Logger) UploadService {
|
||||
return &uploadService{
|
||||
uploadManager: uploadManager,
|
||||
Log: log,
|
||||
}
|
||||
}
|
||||
|
||||
func (u *uploadService) UploadFile(ctx context.Context, minioClient *minio.Client, uploadID string, reader io.Reader, bucketName string, objectName string, size int64, contentType string) error {
|
||||
status := &UploadStatus{
|
||||
FileName: objectName,
|
||||
Size: size,
|
||||
Progress: 0,
|
||||
Status: "uploading",
|
||||
ObjectName: objectName,
|
||||
BucketName: bucketName,
|
||||
StartTime: time.Now(),
|
||||
}
|
||||
|
||||
u.uploadManager.Add(uploadID, status)
|
||||
|
||||
u.Log.Info().Str("timestamp", time.Now().
|
||||
Format(time.RFC3339)).Str("Service:Resource", "UploadService::UploadFile").
|
||||
Interface("add status", status).Msg("")
|
||||
|
||||
// Upload ke Minio
|
||||
_, err := minioClient.PutObject(
|
||||
ctx,
|
||||
bucketName,
|
||||
objectName,
|
||||
reader,
|
||||
size,
|
||||
minio.PutObjectOptions{
|
||||
ContentType: contentType,
|
||||
PartSize: 10 * 1024 * 1024, // 10MB part size
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
u.uploadManager.UpdateStatus(uploadID, "error", err)
|
||||
|
||||
u.Log.Info().Str("timestamp", time.Now().
|
||||
Format(time.RFC3339)).Str("Service:Resource", "UploadService::UploadFile").
|
||||
Interface("error when upload", err).Msg("")
|
||||
}
|
||||
|
||||
u.uploadManager.UpdateStatus(uploadID, "completed", nil)
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,337 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"mime/multipart"
|
||||
"narasi-ahli-be/app/module/knowledge_base/mapper"
|
||||
"narasi-ahli-be/app/module/knowledge_base/repository"
|
||||
"narasi-ahli-be/app/module/knowledge_base/request"
|
||||
"narasi-ahli-be/app/module/knowledge_base/response"
|
||||
config "narasi-ahli-be/config/config"
|
||||
minioStorage "narasi-ahli-be/config/config"
|
||||
"narasi-ahli-be/utils/paginator"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/minio/minio-go/v7"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type KnowledgeBaseService struct {
|
||||
Repo repository.KnowledgeBaseRepositoryInterface
|
||||
Log zerolog.Logger
|
||||
Cfg *config.Config
|
||||
MinioStorage *minioStorage.MinioStorage
|
||||
}
|
||||
|
||||
type KnowledgeBaseServiceInterface interface {
|
||||
All(req request.KnowledgeBaseQueryRequest) (data []*response.KnowledgeBaseResponse, paging paginator.Pagination, err error)
|
||||
Show(id uint) (data *response.KnowledgeBaseResponse, err error)
|
||||
|
||||
Create(c *fiber.Ctx) (data *response.KnowledgeBaseResponse, err error)
|
||||
|
||||
Update(id uint, req request.KnowledgeBaseUpdateRequest) (data *response.KnowledgeBaseResponse, err error)
|
||||
Delete(id uint) error
|
||||
Viewer(c *fiber.Ctx) error
|
||||
UpdateStatus(id uint, status int) (data *response.KnowledgeBaseResponse, err error)
|
||||
|
||||
|
||||
}
|
||||
|
||||
func NewKnowledgeBaseService(
|
||||
repo repository.KnowledgeBaseRepositoryInterface,
|
||||
log zerolog.Logger,
|
||||
cfg *config.Config,
|
||||
minioStorage *minioStorage.MinioStorage,
|
||||
) KnowledgeBaseServiceInterface {
|
||||
return &KnowledgeBaseService{
|
||||
Repo: repo,
|
||||
Log: log,
|
||||
Cfg: cfg,
|
||||
MinioStorage: minioStorage,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *KnowledgeBaseService) uploadFileToMinio(
|
||||
ctx context.Context,
|
||||
minioClient *minio.Client,
|
||||
bucketName string,
|
||||
agentId string,
|
||||
folder string,
|
||||
fileHeader *multipart.FileHeader,
|
||||
) (*string, error) {
|
||||
|
||||
if fileHeader == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
src, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
filename := filepath.Base(fileHeader.Filename)
|
||||
filename = strings.ReplaceAll(filename, " ", "")
|
||||
|
||||
ext := filepath.Ext(filename)
|
||||
filenameWithoutExt := strings.TrimSuffix(filename, ext)
|
||||
|
||||
now := time.Now()
|
||||
newFilename := fmt.Sprintf("%s_%d%s", filenameWithoutExt, now.UnixNano(), ext)
|
||||
|
||||
objectName := fmt.Sprintf(
|
||||
"knowledge-base/%s/%s/%s",
|
||||
agentId,
|
||||
folder,
|
||||
newFilename,
|
||||
)
|
||||
|
||||
_, err = minioClient.PutObject(
|
||||
ctx,
|
||||
bucketName,
|
||||
objectName,
|
||||
src,
|
||||
fileHeader.Size,
|
||||
minio.PutObjectOptions{},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &newFilename, nil
|
||||
}
|
||||
|
||||
func (s *KnowledgeBaseService) All(req request.KnowledgeBaseQueryRequest) (data []*response.KnowledgeBaseResponse, paging paginator.Pagination, err error) {
|
||||
|
||||
results, paging, err := s.Repo.GetAll(req)
|
||||
if err != nil {
|
||||
return nil, paging, err
|
||||
}
|
||||
|
||||
host := s.Cfg.App.Domain
|
||||
for _, item := range results {
|
||||
data = append(data, mapper.KnowledgeBaseResponseMapper(item, host))
|
||||
}
|
||||
|
||||
return data, paging, nil
|
||||
}
|
||||
|
||||
func getFileExtension(filename string) string {
|
||||
parts := strings.Split(filename, ".")
|
||||
|
||||
if len(parts) == 1 || (len(parts) == 2 && parts[0] == "") {
|
||||
return ""
|
||||
}
|
||||
|
||||
return parts[len(parts)-1]
|
||||
}
|
||||
|
||||
func (s *KnowledgeBaseService) Viewer(c *fiber.Ctx) (err error) {
|
||||
filename := c.Params("filename")
|
||||
|
||||
result, folder, err := s.Repo.FindByFilename(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
bucketName := s.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName
|
||||
|
||||
objectName := fmt.Sprintf("knowledge-base/%s/%s/%s", *result.AgentId, folder, filename)
|
||||
|
||||
s.Log.Info().
|
||||
Str("timestamp", time.Now().Format(time.RFC3339)).
|
||||
Str("Service:Resource", "KnowledgeBase:Viewer").
|
||||
Interface("objectName", objectName).
|
||||
Msg("")
|
||||
|
||||
minioClient, err := s.MinioStorage.ConnectMinio()
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": true,
|
||||
"msg": err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
fileContent, err := minioClient.GetObject(ctx, bucketName, objectName, minio.GetObjectOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fileContent.Close()
|
||||
|
||||
contentType := mime.TypeByExtension("." + getFileExtension(objectName))
|
||||
if contentType == "" {
|
||||
contentType = "application/octet-stream"
|
||||
}
|
||||
c.Set("Content-Type", contentType)
|
||||
|
||||
if _, err := io.Copy(c.Response().BodyWriter(), fileContent); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *KnowledgeBaseService) Show(id uint) (data *response.KnowledgeBaseResponse, err error) {
|
||||
result, err := s.Repo.FindOne(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
host := s.Cfg.App.Domain
|
||||
return mapper.KnowledgeBaseResponseMapper(result, host), nil
|
||||
}
|
||||
|
||||
func (s *KnowledgeBaseService) Create(c *fiber.Ctx) (data *response.KnowledgeBaseResponse, err error) {
|
||||
req := new(request.KnowledgeBaseCreateRequest)
|
||||
if err := c.BodyParser(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.AgentId == nil || *req.AgentId == "" {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "agentId is required")
|
||||
}
|
||||
if req.AgentName == nil || *req.AgentName == "" {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "agentName is required")
|
||||
}
|
||||
if req.Title == nil || *req.Title == "" {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "title is required")
|
||||
}
|
||||
|
||||
fileJournal, _ := c.FormFile("fileJournal")
|
||||
fileAudio, _ := c.FormFile("fileAudio")
|
||||
fileVideo, _ := c.FormFile("fileVideo")
|
||||
|
||||
minioClient, err := s.MinioStorage.ConnectMinio()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
bucketName := s.MinioStorage.Cfg.ObjectStorage.MinioStorage.BucketName
|
||||
|
||||
journalFilename, err := s.uploadFileToMinio(ctx, minioClient, bucketName, *req.AgentId, "journal", fileJournal)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
audioFilename, err := s.uploadFileToMinio(ctx, minioClient, bucketName, *req.AgentId, "audio", fileAudio)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
videoFilename, err := s.uploadFileToMinio(ctx, minioClient, bucketName, *req.AgentId, "video", fileVideo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entity := req.ToEntity()
|
||||
|
||||
viewerBase := s.Cfg.App.Domain + "/knowledge-base/viewer/"
|
||||
|
||||
if journalFilename != nil {
|
||||
journalUrl := viewerBase + *journalFilename
|
||||
entity.FileJournalUrl = &journalUrl
|
||||
}
|
||||
if audioFilename != nil {
|
||||
audioUrl := viewerBase + *audioFilename
|
||||
entity.FileAudioUrl = &audioUrl
|
||||
}
|
||||
if videoFilename != nil {
|
||||
videoUrl := viewerBase + *videoFilename
|
||||
entity.FileVideoUrl = &videoUrl
|
||||
}
|
||||
|
||||
if req.Status < 0 {
|
||||
entity.Status = 0
|
||||
}
|
||||
|
||||
err = s.Repo.Create(entity)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err := s.Repo.FindOne(entity.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
host := s.Cfg.App.Domain
|
||||
return mapper.KnowledgeBaseResponseMapper(result, host), nil
|
||||
}
|
||||
|
||||
|
||||
func (s *KnowledgeBaseService) Update(id uint, req request.KnowledgeBaseUpdateRequest) (data *response.KnowledgeBaseResponse, err error) {
|
||||
|
||||
old, err := s.Repo.FindOne(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
old.AgentId = req.AgentId
|
||||
old.AgentName = req.AgentName
|
||||
old.Title = req.Title
|
||||
old.Status = req.Status
|
||||
|
||||
old.FileJournalUrl = req.FileJournalUrl
|
||||
old.FileAudioUrl = req.FileAudioUrl
|
||||
old.FileVideoUrl = req.FileVideoUrl
|
||||
|
||||
if req.IsActive != nil {
|
||||
old.IsActive = *req.IsActive
|
||||
}
|
||||
|
||||
old.UpdatedAt = time.Now()
|
||||
|
||||
err = s.Repo.Update(id, old)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updated, err := s.Repo.FindOne(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
host := s.Cfg.App.Domain
|
||||
return mapper.KnowledgeBaseResponseMapper(updated, host), nil
|
||||
}
|
||||
|
||||
func (s *KnowledgeBaseService) Delete(id uint) error {
|
||||
result, err := s.Repo.FindOne(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result.IsActive = false
|
||||
result.UpdatedAt = time.Now()
|
||||
|
||||
return s.Repo.Update(id, result)
|
||||
}
|
||||
|
||||
func (s *KnowledgeBaseService) UpdateStatus(id uint, status int) (data *response.KnowledgeBaseResponse, err error) {
|
||||
old, err := s.Repo.FindOne(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
old.Status = status
|
||||
old.UpdatedAt = time.Now()
|
||||
|
||||
err = s.Repo.Update(id, old)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updated, err := s.Repo.FindOne(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
host := s.Cfg.App.Domain
|
||||
return mapper.KnowledgeBaseResponseMapper(updated, host), nil
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UploadStatus struct {
|
||||
FileName string `json:"fileName"`
|
||||
Size int64 `json:"size"`
|
||||
Progress int `json:"progress"`
|
||||
Status string `json:"status"`
|
||||
ObjectName string `json:"objectName"`
|
||||
BucketName string `json:"bucketName"`
|
||||
StartTime time.Time `json:"startTime"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
type UploadManager interface {
|
||||
Add(uploadID string, status *UploadStatus)
|
||||
UpdateProgress(uploadID string, progress int)
|
||||
UpdateStatus(uploadID string, status string, err error)
|
||||
Get(uploadID string) (*UploadStatus, bool)
|
||||
}
|
||||
|
||||
type uploadManager struct {
|
||||
uploads map[string]*UploadStatus
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
func NewUploadManager() UploadManager {
|
||||
return &uploadManager{
|
||||
uploads: make(map[string]*UploadStatus),
|
||||
}
|
||||
}
|
||||
|
||||
// Add menambahkan status upload baru
|
||||
func (um *uploadManager) Add(uploadID string, status *UploadStatus) {
|
||||
um.mutex.Lock()
|
||||
defer um.mutex.Unlock()
|
||||
um.uploads[uploadID] = status
|
||||
}
|
||||
|
||||
// UpdateProgress memperbarui progress upload
|
||||
func (um *uploadManager) UpdateProgress(uploadID string, progress int) {
|
||||
um.mutex.Lock()
|
||||
defer um.mutex.Unlock()
|
||||
if status, exists := um.uploads[uploadID]; exists {
|
||||
status.Progress = progress
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateStatus memperbarui status upload
|
||||
func (um *uploadManager) UpdateStatus(uploadID string, status string, err error) {
|
||||
um.mutex.Lock()
|
||||
defer um.mutex.Unlock()
|
||||
if upload, exists := um.uploads[uploadID]; exists {
|
||||
upload.Status = status
|
||||
if err != nil {
|
||||
upload.Error = err.Error()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get mendapatkan status upload berdasarkan ID
|
||||
func (um *uploadManager) Get(uploadID string) (*UploadStatus, bool) {
|
||||
um.mutex.RLock()
|
||||
defer um.mutex.RUnlock()
|
||||
status, exists := um.uploads[uploadID]
|
||||
return status, exists
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ import (
|
|||
"narasi-ahli-be/app/module/ebooks"
|
||||
"narasi-ahli-be/app/module/education_history"
|
||||
"narasi-ahli-be/app/module/feedbacks"
|
||||
"narasi-ahli-be/app/module/knowledge_base"
|
||||
"narasi-ahli-be/app/module/magazine_files"
|
||||
"narasi-ahli-be/app/module/magazines"
|
||||
"narasi-ahli-be/app/module/master_menus"
|
||||
|
|
@ -44,6 +45,7 @@ type Router struct {
|
|||
ActivityLogsRouter *activity_logs.ActivityLogsRouter
|
||||
AdvertisementRouter *advertisement.AdvertisementRouter
|
||||
AIChatRouter *ai_chat.AIChatRouter
|
||||
KnowledgeBaseRouter *knowledge_base.KnowledgeBaseRouter
|
||||
ArticleCategoriesRouter *article_categories.ArticleCategoriesRouter
|
||||
ArticleCategoryDetailsRouter *article_category_details.ArticleCategoryDetailsRouter
|
||||
ArticleFilesRouter *article_files.ArticleFilesRouter
|
||||
|
|
@ -80,6 +82,7 @@ func NewRouter(
|
|||
activityLogsRouter *activity_logs.ActivityLogsRouter,
|
||||
advertisementRouter *advertisement.AdvertisementRouter,
|
||||
aiChatRouter *ai_chat.AIChatRouter,
|
||||
knowledgeBaseRouter *knowledge_base.KnowledgeBaseRouter,
|
||||
articleCategoriesRouter *article_categories.ArticleCategoriesRouter,
|
||||
articleCategoryDetailsRouter *article_category_details.ArticleCategoryDetailsRouter,
|
||||
articleFilesRouter *article_files.ArticleFilesRouter,
|
||||
|
|
@ -119,6 +122,7 @@ func NewRouter(
|
|||
ArticleCommentsRouter: articleCommentsRouter,
|
||||
ArticleApprovalsRouter: articleApprovalsRouter,
|
||||
ArticlesRouter: articlesRouter,
|
||||
KnowledgeBaseRouter: knowledgeBaseRouter,
|
||||
ChatRouter: chatRouter,
|
||||
CitiesRouter: citiesRouter,
|
||||
CustomStaticPagesRouter: customStaticPagesRouter,
|
||||
|
|
@ -162,6 +166,7 @@ func (r *Router) Register() {
|
|||
r.ArticleApprovalsRouter.RegisterArticleApprovalsRoutes()
|
||||
r.ArticlesRouter.RegisterArticlesRoutes()
|
||||
r.ArticleCommentsRouter.RegisterArticleCommentsRoutes()
|
||||
r.KnowledgeBaseRouter.RegisterKnowledgeBaseRoutes()
|
||||
r.ChatRouter.RegisterChatRoutes()
|
||||
r.CitiesRouter.RegisterCitiesRoutes()
|
||||
r.CustomStaticPagesRouter.RegisterCustomStaticPagesRoutes()
|
||||
|
|
|
|||
|
|
@ -10256,6 +10256,379 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/knowledge-base": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for getting all KnowledgeBase",
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Get all KnowledgeBase",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Agent ID",
|
||||
"name": "agentId",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Search title",
|
||||
"name": "title",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Status (0=draft,1=published,2=archived)",
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Created By ID",
|
||||
"name": "createdById",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "Is active",
|
||||
"name": "isActive",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Page",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Limit",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for creating KnowledgeBase with upload file",
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Create KnowledgeBase",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Csrf-Token",
|
||||
"name": "X-Csrf-Token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Agent ID",
|
||||
"name": "agentId",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Agent Name",
|
||||
"name": "agentName",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Created By ID",
|
||||
"name": "createdById",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Status (integer)",
|
||||
"name": "status",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Title",
|
||||
"name": "title",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"description": "Upload Journal File",
|
||||
"name": "fileJournal",
|
||||
"in": "formData"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"description": "Upload Audio File",
|
||||
"name": "fileAudio",
|
||||
"in": "formData"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"description": "Upload Video File",
|
||||
"name": "fileVideo",
|
||||
"in": "formData"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.BadRequestError"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.UnauthorizedError"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.InternalServerError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/knowledge-base/viewer/{filename}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for Viewer KnowledgeBase",
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Viewer KnowledgeBase",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "KnowledgeBase File Name",
|
||||
"name": "filename",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.BadRequestError"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.UnauthorizedError"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.InternalServerError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/knowledge-base/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for getting one KnowledgeBase",
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Get one KnowledgeBase",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "KnowledgeBase ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for updating KnowledgeBase",
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Update KnowledgeBase",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Csrf-Token",
|
||||
"name": "X-Csrf-Token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "Required payload",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.KnowledgeBaseUpdateRequest"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "KnowledgeBase ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for deleting KnowledgeBase (soft delete)",
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Delete KnowledgeBase",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Csrf-Token",
|
||||
"name": "X-Csrf-Token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "KnowledgeBase ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/knowledge-base/{id}/status": {
|
||||
"patch": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API untuk update status KnowledgeBase",
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Update KnowledgeBase Status",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "KnowledgeBase ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "Required payload",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.KnowledgeBaseUpdateStatusRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/magazine-files": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
|
@ -16630,6 +17003,56 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"request.KnowledgeBaseUpdateRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"agentId",
|
||||
"agentName",
|
||||
"id",
|
||||
"status",
|
||||
"title"
|
||||
],
|
||||
"properties": {
|
||||
"agentId": {
|
||||
"type": "string"
|
||||
},
|
||||
"agentName": {
|
||||
"type": "string"
|
||||
},
|
||||
"fileAudioUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"fileJournalUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"fileVideoUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"isActive": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"status": {
|
||||
"type": "integer"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.KnowledgeBaseUpdateStatusRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"status"
|
||||
],
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.MagazinesCreateRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
|
|
|||
|
|
@ -10245,6 +10245,379 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/knowledge-base": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for getting all KnowledgeBase",
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Get all KnowledgeBase",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Agent ID",
|
||||
"name": "agentId",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Search title",
|
||||
"name": "title",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Status (0=draft,1=published,2=archived)",
|
||||
"name": "status",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Created By ID",
|
||||
"name": "createdById",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "Is active",
|
||||
"name": "isActive",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Page",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Limit",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for creating KnowledgeBase with upload file",
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Create KnowledgeBase",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Csrf-Token",
|
||||
"name": "X-Csrf-Token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Agent ID",
|
||||
"name": "agentId",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Agent Name",
|
||||
"name": "agentName",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Created By ID",
|
||||
"name": "createdById",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Status (integer)",
|
||||
"name": "status",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Title",
|
||||
"name": "title",
|
||||
"in": "formData",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"description": "Upload Journal File",
|
||||
"name": "fileJournal",
|
||||
"in": "formData"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"description": "Upload Audio File",
|
||||
"name": "fileAudio",
|
||||
"in": "formData"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"description": "Upload Video File",
|
||||
"name": "fileVideo",
|
||||
"in": "formData"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.BadRequestError"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.UnauthorizedError"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.InternalServerError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/knowledge-base/viewer/{filename}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for Viewer KnowledgeBase",
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Viewer KnowledgeBase",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "KnowledgeBase File Name",
|
||||
"name": "filename",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.BadRequestError"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.UnauthorizedError"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.InternalServerError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/knowledge-base/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for getting one KnowledgeBase",
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Get one KnowledgeBase",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "KnowledgeBase ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for updating KnowledgeBase",
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Update KnowledgeBase",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Csrf-Token",
|
||||
"name": "X-Csrf-Token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "Required payload",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.KnowledgeBaseUpdateRequest"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "KnowledgeBase ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for deleting KnowledgeBase (soft delete)",
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Delete KnowledgeBase",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Csrf-Token",
|
||||
"name": "X-Csrf-Token",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "KnowledgeBase ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/knowledge-base/{id}/status": {
|
||||
"patch": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API untuk update status KnowledgeBase",
|
||||
"tags": [
|
||||
"Knowledge Base"
|
||||
],
|
||||
"summary": "Update KnowledgeBase Status",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "KnowledgeBase ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "Required payload",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.KnowledgeBaseUpdateStatusRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/response.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/magazine-files": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
|
@ -16619,6 +16992,56 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"request.KnowledgeBaseUpdateRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"agentId",
|
||||
"agentName",
|
||||
"id",
|
||||
"status",
|
||||
"title"
|
||||
],
|
||||
"properties": {
|
||||
"agentId": {
|
||||
"type": "string"
|
||||
},
|
||||
"agentName": {
|
||||
"type": "string"
|
||||
},
|
||||
"fileAudioUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"fileJournalUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"fileVideoUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"isActive": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"status": {
|
||||
"type": "integer"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.KnowledgeBaseUpdateStatusRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"status"
|
||||
],
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.MagazinesCreateRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
|
|
|||
|
|
@ -812,6 +812,40 @@ definitions:
|
|||
- id
|
||||
- message
|
||||
type: object
|
||||
request.KnowledgeBaseUpdateRequest:
|
||||
properties:
|
||||
agentId:
|
||||
type: string
|
||||
agentName:
|
||||
type: string
|
||||
fileAudioUrl:
|
||||
type: string
|
||||
fileJournalUrl:
|
||||
type: string
|
||||
fileVideoUrl:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
isActive:
|
||||
type: boolean
|
||||
status:
|
||||
type: integer
|
||||
title:
|
||||
type: string
|
||||
required:
|
||||
- agentId
|
||||
- agentName
|
||||
- id
|
||||
- status
|
||||
- title
|
||||
type: object
|
||||
request.KnowledgeBaseUpdateStatusRequest:
|
||||
properties:
|
||||
status:
|
||||
type: integer
|
||||
required:
|
||||
- status
|
||||
type: object
|
||||
request.MagazinesCreateRequest:
|
||||
properties:
|
||||
createdById:
|
||||
|
|
@ -7930,6 +7964,246 @@ paths:
|
|||
summary: FeedbackMonthlyStats Feedbacks
|
||||
tags:
|
||||
- Feedbacks
|
||||
/knowledge-base:
|
||||
get:
|
||||
description: API for getting all KnowledgeBase
|
||||
parameters:
|
||||
- description: Agent ID
|
||||
in: query
|
||||
name: agentId
|
||||
type: string
|
||||
- description: Search title
|
||||
in: query
|
||||
name: title
|
||||
type: string
|
||||
- description: Status (0=draft,1=published,2=archived)
|
||||
in: query
|
||||
name: status
|
||||
type: integer
|
||||
- description: Created By ID
|
||||
in: query
|
||||
name: createdById
|
||||
type: integer
|
||||
- description: Is active
|
||||
in: query
|
||||
name: isActive
|
||||
type: boolean
|
||||
- description: Page
|
||||
in: query
|
||||
name: page
|
||||
type: integer
|
||||
- description: Limit
|
||||
in: query
|
||||
name: limit
|
||||
type: integer
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get all KnowledgeBase
|
||||
tags:
|
||||
- Knowledge Base
|
||||
post:
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
description: API for creating KnowledgeBase with upload file
|
||||
parameters:
|
||||
- description: Insert the X-Csrf-Token
|
||||
in: header
|
||||
name: X-Csrf-Token
|
||||
required: true
|
||||
type: string
|
||||
- description: Agent ID
|
||||
in: formData
|
||||
name: agentId
|
||||
required: true
|
||||
type: string
|
||||
- description: Agent Name
|
||||
in: formData
|
||||
name: agentName
|
||||
required: true
|
||||
type: string
|
||||
- description: Created By ID
|
||||
in: formData
|
||||
name: createdById
|
||||
required: true
|
||||
type: integer
|
||||
- description: Status (integer)
|
||||
in: formData
|
||||
name: status
|
||||
required: true
|
||||
type: integer
|
||||
- description: Title
|
||||
in: formData
|
||||
name: title
|
||||
required: true
|
||||
type: string
|
||||
- description: Upload Journal File
|
||||
in: formData
|
||||
name: fileJournal
|
||||
type: file
|
||||
- description: Upload Audio File
|
||||
in: formData
|
||||
name: fileAudio
|
||||
type: file
|
||||
- description: Upload Video File
|
||||
in: formData
|
||||
name: fileVideo
|
||||
type: file
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/response.BadRequestError'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/response.UnauthorizedError'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.InternalServerError'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Create KnowledgeBase
|
||||
tags:
|
||||
- Knowledge Base
|
||||
/knowledge-base/{id}:
|
||||
delete:
|
||||
description: API for deleting KnowledgeBase (soft delete)
|
||||
parameters:
|
||||
- description: Insert the X-Csrf-Token
|
||||
in: header
|
||||
name: X-Csrf-Token
|
||||
required: true
|
||||
type: string
|
||||
- description: KnowledgeBase ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Delete KnowledgeBase
|
||||
tags:
|
||||
- Knowledge Base
|
||||
get:
|
||||
description: API for getting one KnowledgeBase
|
||||
parameters:
|
||||
- description: KnowledgeBase ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get one KnowledgeBase
|
||||
tags:
|
||||
- Knowledge Base
|
||||
put:
|
||||
description: API for updating KnowledgeBase
|
||||
parameters:
|
||||
- description: Insert the X-Csrf-Token
|
||||
in: header
|
||||
name: X-Csrf-Token
|
||||
required: true
|
||||
type: string
|
||||
- description: Required payload
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/request.KnowledgeBaseUpdateRequest'
|
||||
- description: KnowledgeBase ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Update KnowledgeBase
|
||||
tags:
|
||||
- Knowledge Base
|
||||
/knowledge-base/{id}/status:
|
||||
patch:
|
||||
description: API untuk update status KnowledgeBase
|
||||
parameters:
|
||||
- description: KnowledgeBase ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
- description: Required payload
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/request.KnowledgeBaseUpdateStatusRequest'
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Update KnowledgeBase Status
|
||||
tags:
|
||||
- Knowledge Base
|
||||
/knowledge-base/viewer/{filename}:
|
||||
get:
|
||||
description: API for Viewer KnowledgeBase
|
||||
parameters:
|
||||
- description: KnowledgeBase File Name
|
||||
in: path
|
||||
name: filename
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/response.Response'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/response.BadRequestError'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/response.UnauthorizedError'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/response.InternalServerError'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Viewer KnowledgeBase
|
||||
tags:
|
||||
- Knowledge Base
|
||||
/magazine-files:
|
||||
get:
|
||||
description: API for getting all MagazineFiles
|
||||
|
|
|
|||
2
main.go
2
main.go
|
|
@ -20,6 +20,7 @@ import (
|
|||
"narasi-ahli-be/app/module/ebooks"
|
||||
"narasi-ahli-be/app/module/education_history"
|
||||
"narasi-ahli-be/app/module/feedbacks"
|
||||
"narasi-ahli-be/app/module/knowledge_base"
|
||||
"narasi-ahli-be/app/module/magazine_files"
|
||||
"narasi-ahli-be/app/module/magazines"
|
||||
"narasi-ahli-be/app/module/master_menus"
|
||||
|
|
@ -70,6 +71,7 @@ func main() {
|
|||
activity_logs.NewActivityLogsModule,
|
||||
advertisement.NewAdvertisementModule,
|
||||
ai_chat.NewAIChatModule,
|
||||
knowledge_base.NewKnowledgeBaseModule,
|
||||
article_categories.NewArticleCategoriesModule,
|
||||
article_category_details.NewArticleCategoryDetailsModule,
|
||||
article_files.NewArticleFilesModule,
|
||||
|
|
|
|||
Loading…
Reference in New Issue