feat: add bookmarks
This commit is contained in:
parent
a4c83f8f0c
commit
faecc65a46
|
|
@ -0,0 +1,21 @@
|
|||
package entity
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type Bookmarks struct {
|
||||
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
|
||||
UserId uint `json:"user_id" gorm:"type:int4;not null"`
|
||||
ArticleId uint `json:"article_id" gorm:"type:int4;not null"`
|
||||
ClientId *uuid.UUID `json:"client_id" gorm:"type:UUID"`
|
||||
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()"`
|
||||
|
||||
// Relations
|
||||
User Users `json:"user" gorm:"foreignKey:UserId;references:ID"`
|
||||
Article Articles `json:"article" gorm:"foreignKey:ArticleId;references:ID"`
|
||||
}
|
||||
|
|
@ -98,6 +98,7 @@ func Models() []interface{} {
|
|||
entity.ArticleComments{},
|
||||
entity.ArticleNulisAI{},
|
||||
entity.AuditTrails{},
|
||||
entity.Bookmarks{},
|
||||
entity.Cities{},
|
||||
entity.Clients{},
|
||||
entity.ClientApprovalSettings{},
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
package activity_logs
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/fx"
|
||||
"web-medols-be/app/module/activity_logs/controller"
|
||||
"web-medols-be/app/module/activity_logs/repository"
|
||||
"web-medols-be/app/module/activity_logs/service"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
// struct of ActivityLogsRouter
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
package bookmarks
|
||||
|
||||
import (
|
||||
"web-medols-be/app/middleware"
|
||||
"web-medols-be/app/module/bookmarks/controller"
|
||||
"web-medols-be/app/module/bookmarks/repository"
|
||||
"web-medols-be/app/module/bookmarks/service"
|
||||
usersRepo "web-medols-be/app/module/users/repository"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
// BookmarksRouter struct of BookmarksRouter
|
||||
type BookmarksRouter struct {
|
||||
App fiber.Router
|
||||
Controller controller.BookmarksController
|
||||
UsersRepo usersRepo.UsersRepository
|
||||
}
|
||||
|
||||
// NewBookmarksModule register bulky of Bookmarks module
|
||||
var NewBookmarksModule = fx.Options(
|
||||
// register repository of Bookmarks module
|
||||
fx.Provide(repository.NewBookmarksRepository),
|
||||
|
||||
// register service of Bookmarks module
|
||||
fx.Provide(service.NewBookmarksService),
|
||||
|
||||
// register controller of Bookmarks module
|
||||
fx.Provide(controller.NewBookmarksController),
|
||||
|
||||
// register router of Bookmarks module
|
||||
fx.Provide(NewBookmarksRouter),
|
||||
)
|
||||
|
||||
// NewBookmarksRouter init BookmarksRouter
|
||||
func NewBookmarksRouter(fiber *fiber.App, controller controller.BookmarksController, usersRepo usersRepo.UsersRepository) *BookmarksRouter {
|
||||
return &BookmarksRouter{
|
||||
App: fiber,
|
||||
Controller: controller,
|
||||
UsersRepo: usersRepo,
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterBookmarksRoutes register routes of Bookmarks module
|
||||
func (_i *BookmarksRouter) RegisterBookmarksRoutes() {
|
||||
// define controllers
|
||||
bookmarksController := _i.Controller
|
||||
|
||||
// define routes
|
||||
_i.App.Route("/bookmarks", func(router fiber.Router) {
|
||||
// Add user middleware to extract user level from JWT token
|
||||
router.Use(middleware.UserMiddleware(_i.UsersRepo))
|
||||
|
||||
// Public routes (require authentication)
|
||||
router.Get("/", bookmarksController.All)
|
||||
router.Get("/:id", bookmarksController.Show)
|
||||
router.Post("/", bookmarksController.Save)
|
||||
router.Delete("/:id", bookmarksController.Delete)
|
||||
|
||||
// User-specific routes
|
||||
router.Get("/user", bookmarksController.GetByUserId)
|
||||
router.Post("/toggle/:articleId", bookmarksController.ToggleBookmark)
|
||||
router.Get("/summary", bookmarksController.GetBookmarkSummary)
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,342 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"web-medols-be/app/middleware"
|
||||
"web-medols-be/app/module/bookmarks/request"
|
||||
"web-medols-be/app/module/bookmarks/service"
|
||||
"web-medols-be/utils/paginator"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/rs/zerolog"
|
||||
|
||||
utilRes "web-medols-be/utils/response"
|
||||
utilVal "web-medols-be/utils/validator"
|
||||
)
|
||||
|
||||
type bookmarksController struct {
|
||||
bookmarksService service.BookmarksService
|
||||
Log zerolog.Logger
|
||||
}
|
||||
|
||||
type BookmarksController interface {
|
||||
All(c *fiber.Ctx) error
|
||||
Show(c *fiber.Ctx) error
|
||||
Save(c *fiber.Ctx) error
|
||||
Delete(c *fiber.Ctx) error
|
||||
GetByUserId(c *fiber.Ctx) error
|
||||
ToggleBookmark(c *fiber.Ctx) error
|
||||
GetBookmarkSummary(c *fiber.Ctx) error
|
||||
}
|
||||
|
||||
func NewBookmarksController(bookmarksService service.BookmarksService, log zerolog.Logger) BookmarksController {
|
||||
return &bookmarksController{
|
||||
bookmarksService: bookmarksService,
|
||||
Log: log,
|
||||
}
|
||||
}
|
||||
|
||||
// All Bookmarks
|
||||
// @Summary Get all Bookmarks
|
||||
// @Description API for getting all Bookmarks
|
||||
// @Tags Bookmarks
|
||||
// @Security Bearer
|
||||
// @Param X-Client-Key header string true "Insert the X-Client-Key"
|
||||
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
|
||||
// @Param req query request.BookmarksQueryRequest false "query parameters"
|
||||
// @Param req query paginator.Pagination false "pagination parameters"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 400 {object} response.BadRequestError
|
||||
// @Failure 401 {object} response.UnauthorizedError
|
||||
// @Failure 500 {object} response.InternalServerError
|
||||
// @Router /bookmarks [get]
|
||||
func (_i *bookmarksController) All(c *fiber.Ctx) error {
|
||||
paginate, err := paginator.Paginate(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
reqContext := request.BookmarksQueryRequestContext{
|
||||
ArticleId: c.Query("articleId"),
|
||||
}
|
||||
req := reqContext.ToParamRequest()
|
||||
req.Pagination = paginate
|
||||
|
||||
// Get ClientId from context
|
||||
clientId := middleware.GetClientID(c)
|
||||
|
||||
_i.Log.Info().Interface("clientId", clientId).Msg("")
|
||||
|
||||
// Get Authorization token from header
|
||||
authToken := c.Get("Authorization")
|
||||
|
||||
bookmarksData, paging, err := _i.bookmarksService.All(clientId, authToken, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{"Successfully retrieved bookmarks"},
|
||||
Data: bookmarksData,
|
||||
Meta: &paging,
|
||||
})
|
||||
}
|
||||
|
||||
// Show Bookmark
|
||||
// @Summary Get Bookmark by ID
|
||||
// @Description API for getting Bookmark by ID
|
||||
// @Tags Bookmarks
|
||||
// @Security Bearer
|
||||
// @Param X-Client-Key header string true "Insert the X-Client-Key"
|
||||
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
|
||||
// @Param id path int true "Bookmark ID"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 400 {object} response.BadRequestError
|
||||
// @Failure 401 {object} response.UnauthorizedError
|
||||
// @Failure 500 {object} response.InternalServerError
|
||||
// @Router /bookmarks/{id} [get]
|
||||
func (_i *bookmarksController) Show(c *fiber.Ctx) error {
|
||||
id, err := strconv.Atoi(c.Params("id"))
|
||||
if err != nil {
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: false,
|
||||
Messages: utilRes.Messages{"Invalid bookmark ID"},
|
||||
})
|
||||
}
|
||||
|
||||
// Get ClientId from context
|
||||
clientId := middleware.GetClientID(c)
|
||||
|
||||
_i.Log.Info().Interface("clientId", clientId).Msg("")
|
||||
|
||||
bookmarkData, err := _i.bookmarksService.Show(clientId, uint(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{"Successfully retrieved bookmark"},
|
||||
Data: bookmarkData,
|
||||
})
|
||||
}
|
||||
|
||||
// Save Bookmark
|
||||
// @Summary Create new Bookmark
|
||||
// @Description API for creating new Bookmark
|
||||
// @Tags Bookmarks
|
||||
// @Security Bearer
|
||||
// @Param X-Client-Key header string true "Insert the X-Client-Key"
|
||||
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
|
||||
// @Param req body request.BookmarksCreateRequest true "Bookmark data"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 400 {object} response.BadRequestError
|
||||
// @Failure 401 {object} response.UnauthorizedError
|
||||
// @Failure 500 {object} response.InternalServerError
|
||||
// @Router /bookmarks [post]
|
||||
func (_i *bookmarksController) Save(c *fiber.Ctx) error {
|
||||
var req request.BookmarksCreateRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: false,
|
||||
Messages: utilRes.Messages{"Invalid request body"},
|
||||
})
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if err := utilVal.ValidateStruct(req); err != nil {
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: false,
|
||||
Messages: utilRes.Messages{"Validation error"},
|
||||
Data: err,
|
||||
})
|
||||
}
|
||||
|
||||
// Get ClientId from context
|
||||
clientId := middleware.GetClientID(c)
|
||||
|
||||
// Get Authorization token from header
|
||||
authToken := c.Get("Authorization")
|
||||
_i.Log.Info().Interface("clientId", clientId).Msg("")
|
||||
_i.Log.Info().Str("authToken", authToken).Msg("")
|
||||
|
||||
bookmarkData, err := _i.bookmarksService.Save(clientId, req, authToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{"Successfully created bookmark"},
|
||||
Data: bookmarkData,
|
||||
})
|
||||
}
|
||||
|
||||
// Delete Bookmark
|
||||
// @Summary Delete Bookmark
|
||||
// @Description API for deleting Bookmark
|
||||
// @Tags Bookmarks
|
||||
// @Security Bearer
|
||||
// @Param X-Client-Key header string true "Insert the X-Client-Key"
|
||||
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
|
||||
// @Param id path int true "Bookmark ID"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 400 {object} response.BadRequestError
|
||||
// @Failure 401 {object} response.UnauthorizedError
|
||||
// @Failure 500 {object} response.InternalServerError
|
||||
// @Router /bookmarks/{id} [delete]
|
||||
func (_i *bookmarksController) Delete(c *fiber.Ctx) error {
|
||||
id, err := strconv.Atoi(c.Params("id"))
|
||||
if err != nil {
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: false,
|
||||
Messages: utilRes.Messages{"Invalid bookmark ID"},
|
||||
})
|
||||
}
|
||||
|
||||
// Get ClientId from context
|
||||
clientId := middleware.GetClientID(c)
|
||||
|
||||
_i.Log.Info().Interface("clientId", clientId).Msg("")
|
||||
|
||||
err = _i.bookmarksService.Delete(clientId, uint(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{"Successfully deleted bookmark"},
|
||||
})
|
||||
}
|
||||
|
||||
// Get Bookmarks by User ID
|
||||
// @Summary Get Bookmarks by User ID
|
||||
// @Description API for getting Bookmarks by User ID
|
||||
// @Tags Bookmarks
|
||||
// @Security Bearer
|
||||
// @Param X-Client-Key header string true "Insert the X-Client-Key"
|
||||
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
|
||||
// @Param req query request.BookmarksQueryRequest false "query parameters"
|
||||
// @Param req query paginator.Pagination false "pagination parameters"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 400 {object} response.BadRequestError
|
||||
// @Failure 401 {object} response.UnauthorizedError
|
||||
// @Failure 500 {object} response.InternalServerError
|
||||
// @Router /bookmarks/user [get]
|
||||
func (_i *bookmarksController) GetByUserId(c *fiber.Ctx) error {
|
||||
paginate, err := paginator.Paginate(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
reqContext := request.BookmarksQueryRequestContext{
|
||||
ArticleId: c.Query("articleId"),
|
||||
}
|
||||
req := reqContext.ToParamRequest()
|
||||
req.Pagination = paginate
|
||||
|
||||
// Get ClientId from context
|
||||
clientId := middleware.GetClientID(c)
|
||||
|
||||
// Get Authorization token from header
|
||||
authToken := c.Get("Authorization")
|
||||
_i.Log.Info().Interface("clientId", clientId).Msg("")
|
||||
_i.Log.Info().Str("authToken", authToken).Msg("")
|
||||
|
||||
bookmarksData, paging, err := _i.bookmarksService.GetByUserId(clientId, authToken, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{"Successfully retrieved user bookmarks"},
|
||||
Data: bookmarksData,
|
||||
Meta: &paging,
|
||||
})
|
||||
}
|
||||
|
||||
// Toggle Bookmark
|
||||
// @Summary Toggle Bookmark (Add/Remove)
|
||||
// @Description API for toggling bookmark status for an article
|
||||
// @Tags Bookmarks
|
||||
// @Security Bearer
|
||||
// @Param X-Client-Key header string true "Insert the X-Client-Key"
|
||||
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
|
||||
// @Param articleId path int true "Article ID"
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 400 {object} response.BadRequestError
|
||||
// @Failure 401 {object} response.UnauthorizedError
|
||||
// @Failure 500 {object} response.InternalServerError
|
||||
// @Router /bookmarks/toggle/{articleId} [post]
|
||||
func (_i *bookmarksController) ToggleBookmark(c *fiber.Ctx) error {
|
||||
articleId, err := strconv.Atoi(c.Params("articleId"))
|
||||
if err != nil {
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: false,
|
||||
Messages: utilRes.Messages{"Invalid article ID"},
|
||||
})
|
||||
}
|
||||
|
||||
// Get ClientId from context
|
||||
clientId := middleware.GetClientID(c)
|
||||
|
||||
// Get Authorization token from header
|
||||
authToken := c.Get("Authorization")
|
||||
_i.Log.Info().Interface("clientId", clientId).Msg("")
|
||||
_i.Log.Info().Str("authToken", authToken).Msg("")
|
||||
|
||||
isBookmarked, err := _i.bookmarksService.ToggleBookmark(clientId, authToken, uint(articleId))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
message := "Bookmark removed"
|
||||
if isBookmarked {
|
||||
message = "Bookmark added"
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{message},
|
||||
Data: map[string]interface{}{
|
||||
"isBookmarked": isBookmarked,
|
||||
"articleId": articleId,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Get Bookmark Summary
|
||||
// @Summary Get Bookmark Summary for User
|
||||
// @Description API for getting bookmark summary including total count and recent bookmarks
|
||||
// @Tags Bookmarks
|
||||
// @Security Bearer
|
||||
// @Param X-Client-Key header string true "Insert the X-Client-Key"
|
||||
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
|
||||
// @Success 200 {object} response.Response
|
||||
// @Failure 400 {object} response.BadRequestError
|
||||
// @Failure 401 {object} response.UnauthorizedError
|
||||
// @Failure 500 {object} response.InternalServerError
|
||||
// @Router /bookmarks/summary [get]
|
||||
func (_i *bookmarksController) GetBookmarkSummary(c *fiber.Ctx) error {
|
||||
// Get ClientId from context
|
||||
clientId := middleware.GetClientID(c)
|
||||
|
||||
// Get Authorization token from header
|
||||
authToken := c.Get("Authorization")
|
||||
_i.Log.Info().Interface("clientId", clientId).Msg("")
|
||||
_i.Log.Info().Str("authToken", authToken).Msg("")
|
||||
|
||||
summaryData, err := _i.bookmarksService.GetBookmarkSummary(clientId, authToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utilRes.Resp(c, utilRes.Response{
|
||||
Success: true,
|
||||
Messages: utilRes.Messages{"Successfully retrieved bookmark summary"},
|
||||
Data: summaryData,
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package mapper
|
||||
|
||||
import (
|
||||
"web-medols-be/app/database/entity"
|
||||
"web-medols-be/app/module/bookmarks/response"
|
||||
)
|
||||
|
||||
func ToBookmarksResponse(bookmark *entity.Bookmarks) *response.BookmarksResponse {
|
||||
return &response.BookmarksResponse{
|
||||
ID: bookmark.ID,
|
||||
UserId: bookmark.UserId,
|
||||
ArticleId: bookmark.ArticleId,
|
||||
IsActive: bookmark.IsActive,
|
||||
CreatedAt: bookmark.CreatedAt,
|
||||
UpdatedAt: bookmark.UpdatedAt,
|
||||
Article: response.ArticleDetails{
|
||||
ID: bookmark.Article.ID,
|
||||
Title: bookmark.Article.Title,
|
||||
Slug: bookmark.Article.Slug,
|
||||
Description: bookmark.Article.Description,
|
||||
HtmlDescription: bookmark.Article.HtmlDescription,
|
||||
CategoryId: bookmark.Article.CategoryId,
|
||||
TypeId: bookmark.Article.TypeId,
|
||||
Tags: bookmark.Article.Tags,
|
||||
ThumbnailUrl: getThumbnailUrl(bookmark.Article.ThumbnailPath),
|
||||
PageUrl: bookmark.Article.PageUrl,
|
||||
CreatedById: bookmark.Article.CreatedById,
|
||||
ShareCount: bookmark.Article.ShareCount,
|
||||
ViewCount: bookmark.Article.ViewCount,
|
||||
CommentCount: bookmark.Article.CommentCount,
|
||||
StatusId: bookmark.Article.StatusId,
|
||||
IsBanner: bookmark.Article.IsBanner,
|
||||
IsPublish: bookmark.Article.IsPublish,
|
||||
PublishedAt: bookmark.Article.PublishedAt,
|
||||
IsActive: bookmark.Article.IsActive,
|
||||
CreatedAt: bookmark.Article.CreatedAt,
|
||||
UpdatedAt: bookmark.Article.UpdatedAt,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func ToBookmarksResponseList(bookmarks []entity.Bookmarks) []*response.BookmarksResponse {
|
||||
var responses []*response.BookmarksResponse
|
||||
for _, bookmark := range bookmarks {
|
||||
responses = append(responses, ToBookmarksResponse(&bookmark))
|
||||
}
|
||||
return responses
|
||||
}
|
||||
|
||||
func getThumbnailUrl(thumbnailPath *string) string {
|
||||
if thumbnailPath != nil && *thumbnailPath != "" {
|
||||
return *thumbnailPath
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"web-medols-be/app/database"
|
||||
"web-medols-be/app/database/entity"
|
||||
"web-medols-be/app/module/bookmarks/request"
|
||||
"web-medols-be/utils/paginator"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type bookmarksRepository struct {
|
||||
DB *database.Database
|
||||
Log zerolog.Logger
|
||||
}
|
||||
|
||||
// BookmarksRepository define interface of IBookmarksRepository
|
||||
type BookmarksRepository interface {
|
||||
GetAll(clientId *uuid.UUID, req request.BookmarksQueryRequest) (bookmarks []*entity.Bookmarks, paging paginator.Pagination, err error)
|
||||
FindOne(clientId *uuid.UUID, id uint) (bookmark *entity.Bookmarks, err error)
|
||||
FindByUserAndArticle(clientId *uuid.UUID, userId uint, articleId uint) (bookmark *entity.Bookmarks, err error)
|
||||
Create(clientId *uuid.UUID, bookmark *entity.Bookmarks) (bookmarkReturn *entity.Bookmarks, err error)
|
||||
Update(clientId *uuid.UUID, id uint, bookmark *entity.Bookmarks) (err error)
|
||||
Delete(clientId *uuid.UUID, id uint) (err error)
|
||||
GetByUserId(clientId *uuid.UUID, userId uint, req request.BookmarksQueryRequest) (bookmarks []*entity.Bookmarks, paging paginator.Pagination, err error)
|
||||
CountByUserId(clientId *uuid.UUID, userId uint) (count int64, err error)
|
||||
}
|
||||
|
||||
func NewBookmarksRepository(db *database.Database, log zerolog.Logger) BookmarksRepository {
|
||||
return &bookmarksRepository{
|
||||
DB: db,
|
||||
Log: log,
|
||||
}
|
||||
}
|
||||
|
||||
// implement interface of IBookmarksRepository
|
||||
func (_i *bookmarksRepository) GetAll(clientId *uuid.UUID, req request.BookmarksQueryRequest) (bookmarks []*entity.Bookmarks, paging paginator.Pagination, err error) {
|
||||
var count int64
|
||||
|
||||
query := _i.DB.DB.Model(&entity.Bookmarks{}).Preload("User").Preload("Article")
|
||||
|
||||
// Apply client filter
|
||||
if clientId != nil {
|
||||
query = query.Where("client_id = ?", clientId)
|
||||
}
|
||||
|
||||
// Apply filters
|
||||
if req.UserId != nil {
|
||||
query = query.Where("user_id = ?", *req.UserId)
|
||||
}
|
||||
|
||||
if req.ArticleId != nil {
|
||||
query = query.Where("article_id = ?", *req.ArticleId)
|
||||
}
|
||||
|
||||
// Count total records
|
||||
if err = query.Count(&count).Error; err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to count bookmarks")
|
||||
return nil, paging, err
|
||||
}
|
||||
|
||||
// Apply pagination
|
||||
if req.Pagination != nil {
|
||||
offset := (req.Pagination.Page - 1) * req.Pagination.Limit
|
||||
query = query.Offset(offset).Limit(req.Pagination.Limit)
|
||||
paging = *req.Pagination
|
||||
}
|
||||
|
||||
// Execute query
|
||||
if err = query.Find(&bookmarks).Error; err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to get bookmarks")
|
||||
return nil, paging, err
|
||||
}
|
||||
|
||||
paging.Count = count
|
||||
paging = *paginator.Paging(&paging)
|
||||
|
||||
return bookmarks, paging, nil
|
||||
}
|
||||
|
||||
func (_i *bookmarksRepository) FindOne(clientId *uuid.UUID, id uint) (bookmark *entity.Bookmarks, err error) {
|
||||
query := _i.DB.DB.Model(&entity.Bookmarks{}).Preload("User").Preload("Article")
|
||||
|
||||
// Apply client filter
|
||||
if clientId != nil {
|
||||
query = query.Where("client_id = ?", clientId)
|
||||
}
|
||||
|
||||
if err = query.Where("id = ?", id).First(&bookmark).Error; err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to find bookmark")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bookmark, nil
|
||||
}
|
||||
|
||||
func (_i *bookmarksRepository) FindByUserAndArticle(clientId *uuid.UUID, userId uint, articleId uint) (bookmark *entity.Bookmarks, err error) {
|
||||
query := _i.DB.DB.Model(&entity.Bookmarks{})
|
||||
|
||||
// Apply client filter
|
||||
if clientId != nil {
|
||||
query = query.Where("client_id = ?", clientId)
|
||||
}
|
||||
|
||||
if err = query.Where("user_id = ? AND article_id = ?", userId, articleId).First(&bookmark).Error; err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to find bookmark by user and article")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bookmark, nil
|
||||
}
|
||||
|
||||
func (_i *bookmarksRepository) Create(clientId *uuid.UUID, bookmark *entity.Bookmarks) (bookmarkReturn *entity.Bookmarks, err error) {
|
||||
bookmark.ClientId = clientId
|
||||
|
||||
if err = _i.DB.DB.Create(bookmark).Error; err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to create bookmark")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bookmark, nil
|
||||
}
|
||||
|
||||
func (_i *bookmarksRepository) Update(clientId *uuid.UUID, id uint, bookmark *entity.Bookmarks) (err error) {
|
||||
query := _i.DB.DB.Model(&entity.Bookmarks{})
|
||||
|
||||
// Apply client filter
|
||||
if clientId != nil {
|
||||
query = query.Where("client_id = ?", clientId)
|
||||
}
|
||||
|
||||
if err = query.Where("id = ?", id).Updates(bookmark).Error; err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to update bookmark")
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_i *bookmarksRepository) Delete(clientId *uuid.UUID, id uint) (err error) {
|
||||
query := _i.DB.DB.Model(&entity.Bookmarks{})
|
||||
|
||||
// Apply client filter
|
||||
if clientId != nil {
|
||||
query = query.Where("client_id = ?", clientId)
|
||||
}
|
||||
|
||||
if err = query.Where("id = ?", id).Delete(&entity.Bookmarks{}).Error; err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to delete bookmark")
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_i *bookmarksRepository) GetByUserId(clientId *uuid.UUID, userId uint, req request.BookmarksQueryRequest) (bookmarks []*entity.Bookmarks, paging paginator.Pagination, err error) {
|
||||
var count int64
|
||||
|
||||
query := _i.DB.DB.Model(&entity.Bookmarks{}).Preload("User").Preload("Article")
|
||||
|
||||
// Apply client filter
|
||||
if clientId != nil {
|
||||
query = query.Where("client_id = ?", clientId)
|
||||
}
|
||||
|
||||
// Apply user filter
|
||||
query = query.Where("user_id = ?", userId)
|
||||
|
||||
// Apply additional filters
|
||||
if req.ArticleId != nil {
|
||||
query = query.Where("article_id = ?", *req.ArticleId)
|
||||
}
|
||||
|
||||
// Count total records
|
||||
if err = query.Count(&count).Error; err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to count user bookmarks")
|
||||
return nil, paging, err
|
||||
}
|
||||
|
||||
// Apply pagination
|
||||
if req.Pagination != nil {
|
||||
offset := (req.Pagination.Page - 1) * req.Pagination.Limit
|
||||
query = query.Offset(offset).Limit(req.Pagination.Limit)
|
||||
paging = *req.Pagination
|
||||
}
|
||||
|
||||
// Execute query
|
||||
if err = query.Find(&bookmarks).Error; err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to get user bookmarks")
|
||||
return nil, paging, err
|
||||
}
|
||||
|
||||
paging.Count = count
|
||||
paging = *paginator.Paging(&paging)
|
||||
|
||||
return bookmarks, paging, nil
|
||||
}
|
||||
|
||||
func (_i *bookmarksRepository) CountByUserId(clientId *uuid.UUID, userId uint) (count int64, err error) {
|
||||
query := _i.DB.DB.Model(&entity.Bookmarks{})
|
||||
|
||||
// Apply client filter
|
||||
if clientId != nil {
|
||||
query = query.Where("client_id = ?", clientId)
|
||||
}
|
||||
|
||||
// Apply user filter
|
||||
query = query.Where("user_id = ?", userId)
|
||||
|
||||
if err = query.Count(&count).Error; err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to count user bookmarks")
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package request
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
"web-medols-be/app/database/entity"
|
||||
"web-medols-be/utils/paginator"
|
||||
)
|
||||
|
||||
type BookmarksGeneric interface {
|
||||
ToEntity()
|
||||
}
|
||||
|
||||
type BookmarksQueryRequest struct {
|
||||
UserId *uint `json:"userId"`
|
||||
ArticleId *uint `json:"articleId"`
|
||||
Pagination *paginator.Pagination `json:"pagination"`
|
||||
}
|
||||
|
||||
type BookmarksCreateRequest struct {
|
||||
ArticleId uint `json:"articleId" validate:"required"`
|
||||
}
|
||||
|
||||
func (req BookmarksCreateRequest) ToEntity(userId uint) *entity.Bookmarks {
|
||||
return &entity.Bookmarks{
|
||||
UserId: userId,
|
||||
ArticleId: req.ArticleId,
|
||||
IsActive: boolPtr(true),
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
type BookmarksQueryRequestContext struct {
|
||||
UserId string `json:"userId"`
|
||||
ArticleId string `json:"articleId"`
|
||||
}
|
||||
|
||||
func (req BookmarksQueryRequestContext) ToParamRequest() BookmarksQueryRequest {
|
||||
var request BookmarksQueryRequest
|
||||
|
||||
if userIdStr := req.UserId; userIdStr != "" {
|
||||
userId, err := strconv.Atoi(userIdStr)
|
||||
if err == nil {
|
||||
userIdUint := uint(userId)
|
||||
request.UserId = &userIdUint
|
||||
}
|
||||
}
|
||||
if articleIdStr := req.ArticleId; articleIdStr != "" {
|
||||
articleId, err := strconv.Atoi(articleIdStr)
|
||||
if err == nil {
|
||||
articleIdUint := uint(articleId)
|
||||
request.ArticleId = &articleIdUint
|
||||
}
|
||||
}
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
// Helper function to create bool pointer
|
||||
func boolPtr(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package response
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type BookmarksResponse struct {
|
||||
ID uint `json:"id"`
|
||||
UserId uint `json:"userId"`
|
||||
ArticleId uint `json:"articleId"`
|
||||
IsActive *bool `json:"isActive"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
|
||||
// Article details
|
||||
Article ArticleDetails `json:"article"`
|
||||
}
|
||||
|
||||
type ArticleDetails struct {
|
||||
ID uint `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Slug string `json:"slug"`
|
||||
Description string `json:"description"`
|
||||
HtmlDescription string `json:"htmlDescription"`
|
||||
CategoryId int `json:"categoryId"`
|
||||
TypeId int `json:"typeId"`
|
||||
Tags string `json:"tags"`
|
||||
ThumbnailUrl string `json:"thumbnailUrl"`
|
||||
PageUrl *string `json:"pageUrl"`
|
||||
CreatedById *uint `json:"createdById"`
|
||||
ShareCount *int `json:"shareCount"`
|
||||
ViewCount *int `json:"viewCount"`
|
||||
CommentCount *int `json:"commentCount"`
|
||||
StatusId *int `json:"statusId"`
|
||||
IsBanner *bool `json:"isBanner"`
|
||||
IsPublish *bool `json:"isPublish"`
|
||||
PublishedAt *time.Time `json:"publishedAt"`
|
||||
IsActive *bool `json:"isActive"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type BookmarksSummaryResponse struct {
|
||||
TotalBookmarks int `json:"totalBookmarks"`
|
||||
RecentBookmarks []*BookmarksResponse `json:"recentBookmarks"`
|
||||
}
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"web-medols-be/app/database/entity"
|
||||
articlesRepository "web-medols-be/app/module/articles/repository"
|
||||
"web-medols-be/app/module/bookmarks/mapper"
|
||||
"web-medols-be/app/module/bookmarks/repository"
|
||||
"web-medols-be/app/module/bookmarks/request"
|
||||
"web-medols-be/app/module/bookmarks/response"
|
||||
usersRepository "web-medols-be/app/module/users/repository"
|
||||
"web-medols-be/utils/paginator"
|
||||
utilSvc "web-medols-be/utils/service"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// BookmarksService
|
||||
type bookmarksService struct {
|
||||
Repo repository.BookmarksRepository
|
||||
ArticlesRepo articlesRepository.ArticlesRepository
|
||||
UsersRepo usersRepository.UsersRepository
|
||||
Log zerolog.Logger
|
||||
}
|
||||
|
||||
// BookmarksService define interface of IBookmarksService
|
||||
type BookmarksService interface {
|
||||
All(clientId *uuid.UUID, authToken string, req request.BookmarksQueryRequest) (bookmarks []*response.BookmarksResponse, paging paginator.Pagination, err error)
|
||||
Show(clientId *uuid.UUID, id uint) (bookmark *response.BookmarksResponse, err error)
|
||||
Save(clientId *uuid.UUID, req request.BookmarksCreateRequest, authToken string) (bookmark *entity.Bookmarks, err error)
|
||||
Delete(clientId *uuid.UUID, id uint) error
|
||||
GetByUserId(clientId *uuid.UUID, authToken string, req request.BookmarksQueryRequest) (bookmarks []*response.BookmarksResponse, paging paginator.Pagination, err error)
|
||||
ToggleBookmark(clientId *uuid.UUID, authToken string, articleId uint) (isBookmarked bool, err error)
|
||||
GetBookmarkSummary(clientId *uuid.UUID, authToken string) (summary *response.BookmarksSummaryResponse, err error)
|
||||
}
|
||||
|
||||
// NewBookmarksService init BookmarksService
|
||||
func NewBookmarksService(
|
||||
repo repository.BookmarksRepository,
|
||||
articlesRepo articlesRepository.ArticlesRepository,
|
||||
usersRepo usersRepository.UsersRepository,
|
||||
log zerolog.Logger,
|
||||
) BookmarksService {
|
||||
return &bookmarksService{
|
||||
Repo: repo,
|
||||
ArticlesRepo: articlesRepo,
|
||||
UsersRepo: usersRepo,
|
||||
Log: log,
|
||||
}
|
||||
}
|
||||
|
||||
// implement interface of IBookmarksService
|
||||
func (_i *bookmarksService) All(clientId *uuid.UUID, authToken string, req request.BookmarksQueryRequest) (bookmarks []*response.BookmarksResponse, paging paginator.Pagination, err error) {
|
||||
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
||||
if user == nil {
|
||||
_i.Log.Error().Msg("User not found from auth token")
|
||||
return nil, paging, errors.New("user not found")
|
||||
}
|
||||
req.UserId = &user.ID
|
||||
|
||||
bookmarksEntity, paging, err := _i.Repo.GetAll(clientId, req)
|
||||
if err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to get all bookmarks")
|
||||
return nil, paging, err
|
||||
}
|
||||
|
||||
// Convert []*entity.Bookmarks to []entity.Bookmarks
|
||||
var bookmarksSlice []entity.Bookmarks
|
||||
for _, b := range bookmarksEntity {
|
||||
bookmarksSlice = append(bookmarksSlice, *b)
|
||||
}
|
||||
bookmarks = mapper.ToBookmarksResponseList(bookmarksSlice)
|
||||
return bookmarks, paging, nil
|
||||
}
|
||||
|
||||
func (_i *bookmarksService) Show(clientId *uuid.UUID, id uint) (bookmark *response.BookmarksResponse, err error) {
|
||||
bookmarkEntity, err := _i.Repo.FindOne(clientId, id)
|
||||
if err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to show bookmark")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bookmark = mapper.ToBookmarksResponse(bookmarkEntity)
|
||||
return bookmark, nil
|
||||
}
|
||||
|
||||
func (_i *bookmarksService) Save(clientId *uuid.UUID, req request.BookmarksCreateRequest, authToken string) (bookmark *entity.Bookmarks, err error) {
|
||||
// Extract user info from auth token
|
||||
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
||||
if user == nil {
|
||||
_i.Log.Error().Msg("User not found from auth token")
|
||||
return nil, errors.New("user not found")
|
||||
}
|
||||
|
||||
// Check if article exists
|
||||
_, err = _i.ArticlesRepo.FindOne(clientId, req.ArticleId)
|
||||
if err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Article not found")
|
||||
return nil, errors.New("article not found")
|
||||
}
|
||||
|
||||
// Check if bookmark already exists
|
||||
existingBookmark, err := _i.Repo.FindByUserAndArticle(clientId, user.ID, req.ArticleId)
|
||||
if err == nil && existingBookmark != nil {
|
||||
_i.Log.Error().Msg("Bookmark already exists")
|
||||
return nil, errors.New("article already bookmarked")
|
||||
}
|
||||
|
||||
// Create new bookmark
|
||||
bookmarkEntity := req.ToEntity(user.ID)
|
||||
bookmark, err = _i.Repo.Create(clientId, bookmarkEntity)
|
||||
if err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to create bookmark")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bookmark, nil
|
||||
}
|
||||
|
||||
func (_i *bookmarksService) Delete(clientId *uuid.UUID, id uint) error {
|
||||
err := _i.Repo.Delete(clientId, id)
|
||||
if err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to delete bookmark")
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_i *bookmarksService) GetByUserId(clientId *uuid.UUID, authToken string, req request.BookmarksQueryRequest) (bookmarks []*response.BookmarksResponse, paging paginator.Pagination, err error) {
|
||||
// Extract user info from auth token
|
||||
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
||||
if user == nil {
|
||||
_i.Log.Error().Msg("User not found from auth token")
|
||||
return nil, paging, errors.New("user not found")
|
||||
}
|
||||
|
||||
bookmarksEntity, paging, err := _i.Repo.GetByUserId(clientId, user.ID, req)
|
||||
if err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to get bookmarks by user ID")
|
||||
return nil, paging, err
|
||||
}
|
||||
|
||||
// Convert []*entity.Bookmarks to []entity.Bookmarks
|
||||
var bookmarksSlice []entity.Bookmarks
|
||||
for _, b := range bookmarksEntity {
|
||||
bookmarksSlice = append(bookmarksSlice, *b)
|
||||
}
|
||||
bookmarks = mapper.ToBookmarksResponseList(bookmarksSlice)
|
||||
return bookmarks, paging, nil
|
||||
}
|
||||
|
||||
func (_i *bookmarksService) ToggleBookmark(clientId *uuid.UUID, authToken string, articleId uint) (isBookmarked bool, err error) {
|
||||
// Extract user info from auth token
|
||||
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
||||
if user == nil {
|
||||
_i.Log.Error().Msg("User not found from auth token")
|
||||
return false, errors.New("user not found")
|
||||
}
|
||||
|
||||
// Check if article exists
|
||||
_, err = _i.ArticlesRepo.FindOne(clientId, articleId)
|
||||
if err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Article not found")
|
||||
return false, errors.New("article not found")
|
||||
}
|
||||
|
||||
// Check if bookmark already exists
|
||||
existingBookmark, err := _i.Repo.FindByUserAndArticle(clientId, user.ID, articleId)
|
||||
if err == nil && existingBookmark != nil {
|
||||
// Bookmark exists, delete it
|
||||
err = _i.Repo.Delete(clientId, existingBookmark.ID)
|
||||
if err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to delete existing bookmark")
|
||||
return false, err
|
||||
}
|
||||
return false, nil // Bookmark removed
|
||||
}
|
||||
|
||||
// Bookmark doesn't exist, create it
|
||||
bookmarkEntity := &entity.Bookmarks{
|
||||
UserId: user.ID,
|
||||
ArticleId: articleId,
|
||||
IsActive: boolPtr(true),
|
||||
}
|
||||
|
||||
_, err = _i.Repo.Create(clientId, bookmarkEntity)
|
||||
if err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to create bookmark")
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil // Bookmark added
|
||||
}
|
||||
|
||||
func (_i *bookmarksService) GetBookmarkSummary(clientId *uuid.UUID, authToken string) (summary *response.BookmarksSummaryResponse, err error) {
|
||||
// Extract user info from auth token
|
||||
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
||||
if user == nil {
|
||||
_i.Log.Error().Msg("User not found from auth token")
|
||||
return nil, errors.New("user not found")
|
||||
}
|
||||
|
||||
// Get total count
|
||||
totalCount, err := _i.Repo.CountByUserId(clientId, user.ID)
|
||||
if err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to count user bookmarks")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get recent bookmarks (last 5)
|
||||
req := request.BookmarksQueryRequest{
|
||||
Pagination: &paginator.Pagination{
|
||||
Page: 1,
|
||||
Limit: 5,
|
||||
},
|
||||
}
|
||||
|
||||
recentBookmarksEntity, _, err := _i.Repo.GetByUserId(clientId, user.ID, req)
|
||||
if err != nil {
|
||||
_i.Log.Error().Err(err).Msg("Failed to get recent bookmarks")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert []*entity.Bookmarks to []entity.Bookmarks
|
||||
var bookmarksSlice []entity.Bookmarks
|
||||
for _, b := range recentBookmarksEntity {
|
||||
bookmarksSlice = append(bookmarksSlice, *b)
|
||||
}
|
||||
recentBookmarks := mapper.ToBookmarksResponseList(bookmarksSlice)
|
||||
|
||||
summary = &response.BookmarksSummaryResponse{
|
||||
TotalBookmarks: int(totalCount),
|
||||
RecentBookmarks: recentBookmarks,
|
||||
}
|
||||
|
||||
return summary, nil
|
||||
}
|
||||
|
||||
// Helper function to create bool pointer
|
||||
func boolPtr(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
|
@ -14,6 +14,7 @@ import (
|
|||
"web-medols-be/app/module/article_files"
|
||||
"web-medols-be/app/module/article_nulis_ai"
|
||||
"web-medols-be/app/module/articles"
|
||||
"web-medols-be/app/module/bookmarks"
|
||||
"web-medols-be/app/module/cities"
|
||||
"web-medols-be/app/module/client_approval_settings"
|
||||
"web-medols-be/app/module/clients"
|
||||
|
|
@ -54,6 +55,7 @@ type Router struct {
|
|||
ArticleApprovalsRouter *article_approvals.ArticleApprovalsRouter
|
||||
ArticlesRouter *articles.ArticlesRouter
|
||||
ArticleNulisAIRouter *article_nulis_ai.ArticleNulisAIRouter
|
||||
BookmarksRouter *bookmarks.BookmarksRouter
|
||||
CitiesRouter *cities.CitiesRouter
|
||||
ClientApprovalSettingsRouter *client_approval_settings.ClientApprovalSettingsRouter
|
||||
ClientsRouter *clients.ClientsRouter
|
||||
|
|
@ -89,6 +91,7 @@ func NewRouter(
|
|||
articleApprovalsRouter *article_approvals.ArticleApprovalsRouter,
|
||||
articlesRouter *articles.ArticlesRouter,
|
||||
articleNulisRouter *article_nulis_ai.ArticleNulisAIRouter,
|
||||
bookmarksRouter *bookmarks.BookmarksRouter,
|
||||
citiesRouter *cities.CitiesRouter,
|
||||
clientApprovalSettingsRouter *client_approval_settings.ClientApprovalSettingsRouter,
|
||||
clientsRouter *clients.ClientsRouter,
|
||||
|
|
@ -122,6 +125,7 @@ func NewRouter(
|
|||
ArticleApprovalsRouter: articleApprovalsRouter,
|
||||
ArticlesRouter: articlesRouter,
|
||||
ArticleNulisAIRouter: articleNulisRouter,
|
||||
BookmarksRouter: bookmarksRouter,
|
||||
CitiesRouter: citiesRouter,
|
||||
ClientApprovalSettingsRouter: clientApprovalSettingsRouter,
|
||||
ClientsRouter: clientsRouter,
|
||||
|
|
@ -165,6 +169,7 @@ func (r *Router) Register() {
|
|||
r.ArticlesRouter.RegisterArticlesRoutes()
|
||||
r.ArticleCommentsRouter.RegisterArticleCommentsRoutes()
|
||||
r.ArticleNulisAIRouter.RegisterArticleNulisAIRoutes()
|
||||
r.BookmarksRouter.RegisterBookmarksRoutes()
|
||||
r.CitiesRouter.RegisterCitiesRoutes()
|
||||
r.ClientApprovalSettingsRouter.RegisterClientApprovalSettingsRoutes()
|
||||
r.ClientsRouter.RegisterClientsRoutes()
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ body-limit = 1048576000 # "100 * 1024 * 1024"
|
|||
[db.postgres]
|
||||
dsn = "postgresql://medols_user:MedolsDB@2025@38.47.180.165:5432/medols_db" # <driver>://<username>:<password>@<host>:<port>/<database>
|
||||
log-mode = "ERROR"
|
||||
migrate = false
|
||||
migrate = true
|
||||
seed = false
|
||||
|
||||
[logger]
|
||||
|
|
|
|||
|
|
@ -7943,6 +7943,524 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/bookmarks": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for getting all Bookmarks",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Get all Bookmarks",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "articleId",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "userId",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "count",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "nextPage",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "previousPage",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "sort",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "sortBy",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "totalPage",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for creating new Bookmark",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Create new Bookmark",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"description": "Bookmark data",
|
||||
"name": "req",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.BookmarksCreateRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bookmarks/summary": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for getting bookmark summary including total count and recent bookmarks",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Get Bookmark Summary for User",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
}
|
||||
],
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bookmarks/toggle/{articleId}": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for toggling bookmark status for an article",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Toggle Bookmark (Add/Remove)",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Article ID",
|
||||
"name": "articleId",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bookmarks/user": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for getting Bookmarks by User ID",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Get Bookmarks by User ID",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "articleId",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "userId",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "count",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "nextPage",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "previousPage",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "sort",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "sortBy",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "totalPage",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bookmarks/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for getting Bookmark by ID",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Get Bookmark by ID",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Bookmark ID",
|
||||
"name": "id",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for deleting Bookmark",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Delete Bookmark",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Bookmark ID",
|
||||
"name": "id",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/cities": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
|
@ -15738,6 +16256,17 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"request.BookmarksCreateRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"articleId"
|
||||
],
|
||||
"properties": {
|
||||
"articleId": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.BulkCreateApprovalWorkflowStepsRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
|
|
|||
|
|
@ -7932,6 +7932,524 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/bookmarks": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for getting all Bookmarks",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Get all Bookmarks",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "articleId",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "userId",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "count",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "nextPage",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "previousPage",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "sort",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "sortBy",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "totalPage",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for creating new Bookmark",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Create new Bookmark",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"description": "Bookmark data",
|
||||
"name": "req",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.BookmarksCreateRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bookmarks/summary": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for getting bookmark summary including total count and recent bookmarks",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Get Bookmark Summary for User",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
}
|
||||
],
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bookmarks/toggle/{articleId}": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for toggling bookmark status for an article",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Toggle Bookmark (Add/Remove)",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Article ID",
|
||||
"name": "articleId",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bookmarks/user": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for getting Bookmarks by User ID",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Get Bookmarks by User ID",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "articleId",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "userId",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "count",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "nextPage",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "previousPage",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "sort",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "sortBy",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "totalPage",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/bookmarks/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for getting Bookmark by ID",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Get Bookmark by ID",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Bookmark ID",
|
||||
"name": "id",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "API for deleting Bookmark",
|
||||
"tags": [
|
||||
"Bookmarks"
|
||||
],
|
||||
"summary": "Delete Bookmark",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Insert the X-Client-Key",
|
||||
"name": "X-Client-Key",
|
||||
"in": "header",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default": "Bearer \u003cAdd access token here\u003e",
|
||||
"description": "Insert your access token",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "Bookmark ID",
|
||||
"name": "id",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/cities": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
|
@ -15727,6 +16245,17 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"request.BookmarksCreateRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"articleId"
|
||||
],
|
||||
"properties": {
|
||||
"articleId": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.BulkCreateApprovalWorkflowStepsRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
|
|
|||
|
|
@ -529,6 +529,13 @@ definitions:
|
|||
- title
|
||||
- typeId
|
||||
type: object
|
||||
request.BookmarksCreateRequest:
|
||||
properties:
|
||||
articleId:
|
||||
type: integer
|
||||
required:
|
||||
- articleId
|
||||
type: object
|
||||
request.BulkCreateApprovalWorkflowStepsRequest:
|
||||
properties:
|
||||
steps:
|
||||
|
|
@ -6452,6 +6459,338 @@ paths:
|
|||
summary: Get articles waiting for approval by current user level
|
||||
tags:
|
||||
- Articles
|
||||
/bookmarks:
|
||||
get:
|
||||
description: API for getting all Bookmarks
|
||||
parameters:
|
||||
- description: Insert the X-Client-Key
|
||||
in: header
|
||||
name: X-Client-Key
|
||||
required: true
|
||||
type: string
|
||||
- default: Bearer <Add access token here>
|
||||
description: Insert your access token
|
||||
in: header
|
||||
name: Authorization
|
||||
type: string
|
||||
- in: query
|
||||
name: articleId
|
||||
type: integer
|
||||
- in: query
|
||||
name: userId
|
||||
type: integer
|
||||
- in: query
|
||||
name: count
|
||||
type: integer
|
||||
- in: query
|
||||
name: limit
|
||||
type: integer
|
||||
- in: query
|
||||
name: nextPage
|
||||
type: integer
|
||||
- in: query
|
||||
name: page
|
||||
type: integer
|
||||
- in: query
|
||||
name: previousPage
|
||||
type: integer
|
||||
- in: query
|
||||
name: sort
|
||||
type: string
|
||||
- in: query
|
||||
name: sortBy
|
||||
type: string
|
||||
- in: query
|
||||
name: totalPage
|
||||
type: integer
|
||||
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: Get all Bookmarks
|
||||
tags:
|
||||
- Bookmarks
|
||||
post:
|
||||
description: API for creating new Bookmark
|
||||
parameters:
|
||||
- description: Insert the X-Client-Key
|
||||
in: header
|
||||
name: X-Client-Key
|
||||
required: true
|
||||
type: string
|
||||
- default: Bearer <Add access token here>
|
||||
description: Insert your access token
|
||||
in: header
|
||||
name: Authorization
|
||||
type: string
|
||||
- description: Bookmark data
|
||||
in: body
|
||||
name: req
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/request.BookmarksCreateRequest'
|
||||
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 new Bookmark
|
||||
tags:
|
||||
- Bookmarks
|
||||
/bookmarks/{id}:
|
||||
delete:
|
||||
description: API for deleting Bookmark
|
||||
parameters:
|
||||
- description: Insert the X-Client-Key
|
||||
in: header
|
||||
name: X-Client-Key
|
||||
required: true
|
||||
type: string
|
||||
- default: Bearer <Add access token here>
|
||||
description: Insert your access token
|
||||
in: header
|
||||
name: Authorization
|
||||
type: string
|
||||
- description: Bookmark ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
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: Delete Bookmark
|
||||
tags:
|
||||
- Bookmarks
|
||||
get:
|
||||
description: API for getting Bookmark by ID
|
||||
parameters:
|
||||
- description: Insert the X-Client-Key
|
||||
in: header
|
||||
name: X-Client-Key
|
||||
required: true
|
||||
type: string
|
||||
- default: Bearer <Add access token here>
|
||||
description: Insert your access token
|
||||
in: header
|
||||
name: Authorization
|
||||
type: string
|
||||
- description: Bookmark ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
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: Get Bookmark by ID
|
||||
tags:
|
||||
- Bookmarks
|
||||
/bookmarks/summary:
|
||||
get:
|
||||
description: API for getting bookmark summary including total count and recent
|
||||
bookmarks
|
||||
parameters:
|
||||
- description: Insert the X-Client-Key
|
||||
in: header
|
||||
name: X-Client-Key
|
||||
required: true
|
||||
type: string
|
||||
- default: Bearer <Add access token here>
|
||||
description: Insert your access token
|
||||
in: header
|
||||
name: Authorization
|
||||
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: Get Bookmark Summary for User
|
||||
tags:
|
||||
- Bookmarks
|
||||
/bookmarks/toggle/{articleId}:
|
||||
post:
|
||||
description: API for toggling bookmark status for an article
|
||||
parameters:
|
||||
- description: Insert the X-Client-Key
|
||||
in: header
|
||||
name: X-Client-Key
|
||||
required: true
|
||||
type: string
|
||||
- default: Bearer <Add access token here>
|
||||
description: Insert your access token
|
||||
in: header
|
||||
name: Authorization
|
||||
type: string
|
||||
- description: Article ID
|
||||
in: path
|
||||
name: articleId
|
||||
required: true
|
||||
type: integer
|
||||
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: Toggle Bookmark (Add/Remove)
|
||||
tags:
|
||||
- Bookmarks
|
||||
/bookmarks/user:
|
||||
get:
|
||||
description: API for getting Bookmarks by User ID
|
||||
parameters:
|
||||
- description: Insert the X-Client-Key
|
||||
in: header
|
||||
name: X-Client-Key
|
||||
required: true
|
||||
type: string
|
||||
- default: Bearer <Add access token here>
|
||||
description: Insert your access token
|
||||
in: header
|
||||
name: Authorization
|
||||
type: string
|
||||
- in: query
|
||||
name: articleId
|
||||
type: integer
|
||||
- in: query
|
||||
name: userId
|
||||
type: integer
|
||||
- in: query
|
||||
name: count
|
||||
type: integer
|
||||
- in: query
|
||||
name: limit
|
||||
type: integer
|
||||
- in: query
|
||||
name: nextPage
|
||||
type: integer
|
||||
- in: query
|
||||
name: page
|
||||
type: integer
|
||||
- in: query
|
||||
name: previousPage
|
||||
type: integer
|
||||
- in: query
|
||||
name: sort
|
||||
type: string
|
||||
- in: query
|
||||
name: sortBy
|
||||
type: string
|
||||
- in: query
|
||||
name: totalPage
|
||||
type: integer
|
||||
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: Get Bookmarks by User ID
|
||||
tags:
|
||||
- Bookmarks
|
||||
/cities:
|
||||
get:
|
||||
description: API for getting all Cities
|
||||
|
|
|
|||
2
main.go
2
main.go
|
|
@ -17,6 +17,7 @@ import (
|
|||
"web-medols-be/app/module/article_files"
|
||||
"web-medols-be/app/module/article_nulis_ai"
|
||||
"web-medols-be/app/module/articles"
|
||||
"web-medols-be/app/module/bookmarks"
|
||||
"web-medols-be/app/module/cities"
|
||||
"web-medols-be/app/module/client_approval_settings"
|
||||
"web-medols-be/app/module/clients"
|
||||
|
|
@ -80,6 +81,7 @@ func main() {
|
|||
articles.NewArticlesModule,
|
||||
article_comments.NewArticleCommentsModule,
|
||||
article_nulis_ai.NewArticleNulisAIModule,
|
||||
bookmarks.NewBookmarksModule,
|
||||
cities.NewCitiesModule,
|
||||
client_approval_settings.NewClientApprovalSettingsModule,
|
||||
clients.NewClientsModule,
|
||||
|
|
|
|||
Loading…
Reference in New Issue