feat: update ai chat and update user data

This commit is contained in:
hanif salafi 2025-09-20 09:45:59 +07:00
parent cd3ac6d340
commit 974daf4c25
41 changed files with 799 additions and 5831 deletions

View File

@ -6,14 +6,14 @@ import (
)
type AIChatLogs struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
SessionID uint `json:"session_id" gorm:"type:int4;not null;index"`
UserID uint `json:"user_id" gorm:"type:int4;not null;index"`
StartDate time.Time `json:"start_date" gorm:"not null"`
EndDate *time.Time `json:"end_date"`
TotalDuration int64 `json:"total_duration" gorm:"type:bigint;default:0"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
Session *AIChatSessions `json:"session" gorm:"foreignKey:SessionID;references:ID"`
User *users.Users `json:"user" gorm:"foreignKey:UserID;references:ID"`
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
SessionID uint `json:"session_id" gorm:"type:int4;not null;index"`
UserID uint `json:"user_id" gorm:"type:int4;not null;index"`
StartDate time.Time `json:"start_date" gorm:"not null"`
EndDate *time.Time `json:"end_date"`
TotalDuration int64 `json:"total_duration" gorm:"type:bigint;default:0"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
User *users.Users `json:"user" gorm:"foreignKey:UserID;references:ID"`
}

View File

@ -5,10 +5,10 @@ import (
)
type AIChatMessages struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
SessionID uint `json:"session_id" gorm:"type:int4;not null;index"`
MessageType string `json:"message_type" gorm:"type:varchar;not null"`
Content string `json:"content" gorm:"type:text;not null"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
Session *AIChatSessions `json:"session" gorm:"foreignKey:SessionID;references:ID"`
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
SessionID string `json:"session_id" gorm:"type:varchar;not null;index"`
MessageType string `json:"message_type" gorm:"type:varchar;not null"`
Content string `json:"content" gorm:"type:text;not null"`
IsActive bool `json:"is_active" gorm:"type:bool;default:true"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
}

View File

@ -7,12 +7,12 @@ import (
type AIChatSessions struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
AISessionID string `json:"ai_session_id" gorm:"type:varchar;not null;unique"`
SessionID string `json:"session_id" gorm:"type:varchar;not null;unique;index"`
UserID uint `json:"user_id" gorm:"type:int4;not null;index"`
AgentID *string `json:"agent_id" gorm:"type:varchar"`
AgentID string `json:"agent_id" gorm:"type:varchar;not null"`
Title string `json:"title" gorm:"type:varchar;not null"`
MessageCount int `json:"message_count" gorm:"type:int4;default:0"`
Status string `json:"status" gorm:"type:varchar;default:'active'"`
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()"`
User *users.Users `json:"user" gorm:"foreignKey:UserID;references:ID"`

View File

@ -6,16 +6,18 @@ import (
)
type ChatMessages struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
ConversationID uint `json:"conversation_id" gorm:"type:int4;not null;index"`
SenderID uint `json:"sender_id" gorm:"type:int4;not null;index"`
MessageText *string `json:"message_text" gorm:"type:text"`
MessageType string `json:"message_type" gorm:"type:varchar;not null;default:'text'"`
FileURL *string `json:"file_url" gorm:"type:varchar"`
FileName *string `json:"file_name" gorm:"type:varchar"`
FileSize *int64 `json:"file_size" gorm:"type:bigint"`
IsRead bool `json:"is_read" gorm:"default:false"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
Conversation *Conversations `json:"conversation" gorm:"foreignKey:ConversationID;references:ID"`
Sender *users.Users `json:"sender" gorm:"foreignKey:SenderID;references:ID"`
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
ConversationID uint `json:"conversation_id" gorm:"type:int4;not null;index"`
SenderID uint `json:"sender_id" gorm:"type:int4;not null;index"`
MessageText *string `json:"message_text" gorm:"type:text"`
MessageType string `json:"message_type" gorm:"type:varchar;not null;default:'text'"`
FileURL *string `json:"file_url" gorm:"type:varchar"`
FileName *string `json:"file_name" gorm:"type:varchar"`
FileSize *int64 `json:"file_size" gorm:"type:bigint"`
IsRead bool `json:"is_read" gorm:"default:false"`
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()"`
// Conversation *Conversations `json:"conversation" gorm:"foreignKey:ConversationID;references:ID"`
Sender *users.Users `json:"sender" gorm:"foreignKey:SenderID;references:ID"`
}

View File

@ -6,15 +6,14 @@ import (
)
type ChatSessions struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
SessionID string `json:"session_id" gorm:"type:varchar;not null;unique;index"`
UserID uint `json:"user_id" gorm:"type:int4;not null;index"`
AgentID string `json:"agent_id" gorm:"type:varchar;not null"`
Title string `json:"title" gorm:"type:varchar;not null"`
MessageCount int `json:"message_count" gorm:"type:int4;default:0"`
Status string `json:"status" gorm:"type:varchar;default:'active'"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
User *users.Users `json:"user" gorm:"foreignKey:UserID;references:ID"`
Messages []ChatMessages `json:"messages" gorm:"foreignKey:SessionID;references:SessionID"`
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
SessionID string `json:"session_id" gorm:"type:varchar;not null;unique;index"`
UserID uint `json:"user_id" gorm:"type:int4;not null;index"`
AgentID string `json:"agent_id" gorm:"type:varchar;not null"`
Title string `json:"title" gorm:"type:varchar;not null"`
MessageCount int `json:"message_count" gorm:"type:int4;default:0"`
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()"`
User *users.Users `json:"user" gorm:"foreignKey:UserID;references:ID"`
}

View File

@ -1,7 +1,7 @@
package controller
import (
"narasi-ahli-be/app/module/activity_logs/request"
"narasi-ahli-be/app/module/activity_logs/request"
"narasi-ahli-be/app/module/activity_logs/service"
"narasi-ahli-be/utils/paginator"
utilRes "narasi-ahli-be/utils/response"
@ -39,7 +39,6 @@ func NewActivityLogsController(activityLogsService service.ActivityLogsService,
// @Description API for getting all ActivityLogs
// @Tags ActivityLogs
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.ActivityLogsQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -53,7 +52,7 @@ func (_i *activityLogsController) All(c *fiber.Ctx) error {
return err
}
reqContext := request.ActivityLogsQueryRequestContext{
reqContext := request.ActivityLogsQueryRequestContext{
ActivityTypeId: c.Query("activityTypeId"),
Url: c.Query("url"),
ArticleId: c.Query("articleId"),
@ -80,7 +79,6 @@ func (_i *activityLogsController) All(c *fiber.Ctx) error {
// @Description API for getting one ActivityLogs
// @Tags ActivityLogs
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "ActivityLogs ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -93,7 +91,7 @@ func (_i *activityLogsController) Show(c *fiber.Ctx) error {
return err
}
activityLogsData, err := _i.activityLogsService.Show(uint(id))
activityLogsData, err := _i.activityLogsService.Show(uint(id))
if err != nil {
return err
}
@ -110,7 +108,6 @@ func (_i *activityLogsController) Show(c *fiber.Ctx) error {
// @Description API for create ActivityLogs
// @Tags ActivityLogs
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.ActivityLogsCreateRequest true "Required payload"
@ -125,7 +122,7 @@ func (_i *activityLogsController) Save(c *fiber.Ctx) error {
return err
}
var authToken *string
var authToken *string
getTokenFromHeader := c.Get("Authorization")
if getTokenFromHeader == "" {
authToken = nil
@ -151,7 +148,6 @@ func (_i *activityLogsController) Save(c *fiber.Ctx) error {
// @Description API for update ActivityLogs
// @Tags ActivityLogs
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.ActivityLogsUpdateRequest true "Required payload"
// @Param id path int true "ActivityLogs ID"
@ -171,7 +167,7 @@ func (_i *activityLogsController) Update(c *fiber.Ctx) error {
return err
}
err = _i.activityLogsService.Update(uint(id), *req)
err = _i.activityLogsService.Update(uint(id), *req)
if err != nil {
return err
}
@ -187,7 +183,6 @@ func (_i *activityLogsController) Update(c *fiber.Ctx) error {
// @Description API for delete ActivityLogs
// @Tags ActivityLogs
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "ActivityLogs ID"
// @Success 200 {object} response.Response
@ -201,7 +196,7 @@ func (_i *activityLogsController) Delete(c *fiber.Ctx) error {
return err
}
err = _i.activityLogsService.Delete(uint(id))
err = _i.activityLogsService.Delete(uint(id))
if err != nil {
return err
}
@ -217,7 +212,6 @@ func (_i *activityLogsController) Delete(c *fiber.Ctx) error {
// @Description API for get activity stats ActivityLogs
// @Tags ActivityLogs
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
@ -226,7 +220,7 @@ func (_i *activityLogsController) Delete(c *fiber.Ctx) error {
func (_i *activityLogsController) GetActivityStats(c *fiber.Ctx) error {
_i.Log.Info().Interface("GetActivityStats", "checker controller").Msg("")
activityStatsData, err := _i.activityLogsService.GetActivityStats()
activityStatsData, err := _i.activityLogsService.GetActivityStats()
if err != nil {
return err
}

View File

@ -1,7 +1,7 @@
package controller
import (
"narasi-ahli-be/app/module/advertisement/request"
"narasi-ahli-be/app/module/advertisement/request"
"narasi-ahli-be/app/module/advertisement/service"
"narasi-ahli-be/utils/paginator"
"strconv"
@ -41,7 +41,6 @@ func NewAdvertisementController(advertisementService service.AdvertisementServic
// @Description API for getting all Advertisement
// @Tags Advertisement
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.AdvertisementQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -55,7 +54,7 @@ func (_i *advertisementController) All(c *fiber.Ctx) error {
return err
}
reqContext := request.AdvertisementQueryRequestContext{
reqContext := request.AdvertisementQueryRequestContext{
Title: c.Query("title"),
Description: c.Query("description"),
RedirectLink: c.Query("redirectLink"),
@ -83,7 +82,6 @@ func (_i *advertisementController) All(c *fiber.Ctx) error {
// @Description API for getting one Advertisement
// @Tags Advertisement
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "Advertisement ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -96,7 +94,7 @@ func (_i *advertisementController) Show(c *fiber.Ctx) error {
return err
}
advertisementData, err := _i.advertisementService.Show(uint(id))
advertisementData, err := _i.advertisementService.Show(uint(id))
if err != nil {
return err
}
@ -113,7 +111,6 @@ func (_i *advertisementController) Show(c *fiber.Ctx) error {
// @Description API for create Advertisement
// @Tags Advertisement
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.AdvertisementCreateRequest true "Required payload"
@ -128,7 +125,7 @@ func (_i *advertisementController) Save(c *fiber.Ctx) error {
return err
}
dataResult, err := _i.advertisementService.Save(*req)
dataResult, err := _i.advertisementService.Save(*req)
if err != nil {
return err
}
@ -146,7 +143,6 @@ func (_i *advertisementController) Save(c *fiber.Ctx) error {
// @Tags Advertisement
// @Security Bearer
// @Produce json
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param file formData file true "Upload file" multiple false
// @Param id path int true "Advertisement ID"
@ -161,7 +157,7 @@ func (_i *advertisementController) Upload(c *fiber.Ctx) error {
return err
}
err = _i.advertisementService.Upload(c, uint(id))
err = _i.advertisementService.Upload(c, uint(id))
if err != nil {
return err
}
@ -177,7 +173,6 @@ func (_i *advertisementController) Upload(c *fiber.Ctx) error {
// @Description API for update Advertisement
// @Tags Advertisement
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.AdvertisementUpdateRequest true "Required payload"
// @Param id path int true "Advertisement ID"
@ -197,7 +192,7 @@ func (_i *advertisementController) Update(c *fiber.Ctx) error {
return err
}
err = _i.advertisementService.Update(uint(id), *req)
err = _i.advertisementService.Update(uint(id), *req)
if err != nil {
return err
}
@ -213,7 +208,6 @@ func (_i *advertisementController) Update(c *fiber.Ctx) error {
// @Description API for Update Publish Advertisement
// @Tags Advertisement
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param id path int true "Advertisement ID"
@ -234,7 +228,7 @@ func (_i *advertisementController) UpdatePublish(c *fiber.Ctx) error {
return err
}
err = _i.advertisementService.UpdatePublish(uint(id), isPublish)
err = _i.advertisementService.UpdatePublish(uint(id), isPublish)
if err != nil {
return err
}
@ -250,7 +244,6 @@ func (_i *advertisementController) UpdatePublish(c *fiber.Ctx) error {
// @Description API for delete Advertisement
// @Tags Advertisement
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Advertisement ID"
// @Success 200 {object} response.Response
@ -264,7 +257,7 @@ func (_i *advertisementController) Delete(c *fiber.Ctx) error {
return err
}
err = _i.advertisementService.Delete(uint(id))
err = _i.advertisementService.Delete(uint(id))
if err != nil {
return err
}
@ -280,7 +273,6 @@ func (_i *advertisementController) Delete(c *fiber.Ctx) error {
// @Description API for Viewer Advertisement
// @Tags Advertisement
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param filename path string true "Content File Name"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -288,5 +280,5 @@ func (_i *advertisementController) Delete(c *fiber.Ctx) error {
// @Failure 500 {object} response.InternalServerError
// @Router /advertisement/viewer/{filename} [get]
func (_i *advertisementController) Viewer(c *fiber.Ctx) error {
return _i.advertisementService.Viewer(c)
return _i.advertisementService.Viewer(c)
}

View File

@ -53,10 +53,10 @@ func (_i *AIChatRouter) RegisterAIChatRoutes() {
router.Delete("/sessions/:id", aiChatController.DeleteSession)
// Messages routes
router.Get("/sessions/:sessionId/messages", aiChatController.GetSessionMessages)
router.Post("/sessions/:sessionId/messages", aiChatController.SendMessage)
router.Put("/sessions/:sessionId/messages/:messageId", aiChatController.UpdateMessage)
router.Delete("/sessions/:sessionId/messages/:messageId", aiChatController.DeleteMessage)
router.Get("/sessions/messages", aiChatController.GetSessionMessages)
router.Post("/sessions/messages", aiChatController.SendMessage)
router.Put("/sessions/messages/:messageId", aiChatController.UpdateMessage)
router.Delete("/sessions/messages/:messageId", aiChatController.DeleteMessage)
// Logs routes
router.Get("/logs", aiChatController.GetUserLogs)

View File

@ -48,7 +48,7 @@ func NewAIChatController(aiChatService service.AIChatService, log zerolog.Logger
// @Description API for getting all AI chat sessions for authenticated user
// @Tags AI Chat
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param req query request.AIChatSessionsQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -65,7 +65,7 @@ func (_i *aiChatController) GetUserSessions(c *fiber.Ctx) error {
authHeader := c.Get("Authorization")
reqContext := request.AIChatSessionsQueryRequestContext{
Status: c.Query("status"),
IsActive: c.Query("isActive"),
}
req := reqContext.ToParamRequest()
req.Pagination = paginate
@ -88,7 +88,7 @@ func (_i *aiChatController) GetUserSessions(c *fiber.Ctx) error {
// @Description API for getting one AI chat session
// @Tags AI Chat
// @Security Bearer
// @Param X-Client-Key header string false "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 "Session ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -120,7 +120,6 @@ func (_i *aiChatController) GetSession(c *fiber.Ctx) error {
// @Description API for create AI chat session
// @Tags AI Chat
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.AIChatSessionsCreateRequest true "Required payload"
@ -154,7 +153,7 @@ func (_i *aiChatController) CreateSession(c *fiber.Ctx) error {
// @Description API for update AI chat session
// @Tags AI Chat
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Session ID"
// @Param payload body request.AIChatSessionsUpdateRequest true "Required payload"
@ -192,7 +191,7 @@ func (_i *aiChatController) UpdateSession(c *fiber.Ctx) error {
// @Description API for delete AI chat session
// @Tags AI Chat
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Session ID"
// @Success 200 {object} response.Response
@ -224,7 +223,7 @@ func (_i *aiChatController) DeleteSession(c *fiber.Ctx) error {
// @Description API for getting all messages in an AI chat session
// @Tags AI Chat
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param sessionId path int true "Session ID"
// @Param req query request.AIChatMessagesQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
@ -234,10 +233,7 @@ func (_i *aiChatController) DeleteSession(c *fiber.Ctx) error {
// @Failure 500 {object} response.InternalServerError
// @Router /ai-chat/sessions/{sessionId}/messages [get]
func (_i *aiChatController) GetSessionMessages(c *fiber.Ctx) error {
sessionId, err := strconv.ParseUint(c.Params("sessionId"), 10, 0)
if err != nil {
return err
}
sessionId := c.Params("sessionId")
paginate, err := paginator.Paginate(c)
if err != nil {
@ -247,12 +243,12 @@ func (_i *aiChatController) GetSessionMessages(c *fiber.Ctx) error {
authHeader := c.Get("Authorization")
reqContext := request.AIChatMessagesQueryRequestContext{
SessionID: c.Query("sessionId"),
SessionID: sessionId,
}
req := reqContext.ToParamRequest()
req.Pagination = paginate
messagesData, paging, err := _i.aiChatService.GetSessionMessages(authHeader, uint(sessionId), req)
messagesData, paging, err := _i.aiChatService.GetSessionMessages(authHeader, sessionId, req)
if err != nil {
return err
}
@ -270,21 +266,15 @@ func (_i *aiChatController) GetSessionMessages(c *fiber.Ctx) error {
// @Description API for sending a message to an AI chat session
// @Tags AI Chat
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param sessionId path int true "Session ID"
// @Param payload body request.AIChatMessagesCreateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /ai-chat/sessions/{sessionId}/messages [post]
// @Router /ai-chat/sessions/messages [post]
func (_i *aiChatController) SendMessage(c *fiber.Ctx) error {
sessionId, err := strconv.ParseUint(c.Params("sessionId"), 10, 0)
if err != nil {
return err
}
req := new(request.AIChatMessagesCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
@ -292,7 +282,7 @@ func (_i *aiChatController) SendMessage(c *fiber.Ctx) error {
authHeader := c.Get("Authorization")
dataResult, err := _i.aiChatService.SendMessage(authHeader, uint(sessionId), *req)
dataResult, err := _i.aiChatService.SendMessage(authHeader, *req)
if err != nil {
return err
}
@ -309,22 +299,16 @@ func (_i *aiChatController) SendMessage(c *fiber.Ctx) error {
// @Description API for update AI chat message
// @Tags AI Chat
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param sessionId path int true "Session ID"
// @Param messageId path int true "Message ID"
// @Param payload body request.AIChatMessagesUpdateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /ai-chat/sessions/{sessionId}/messages/{messageId} [put]
// @Router /ai-chat/sessions/messages/{messageId} [put]
func (_i *aiChatController) UpdateMessage(c *fiber.Ctx) error {
sessionId, err := strconv.ParseUint(c.Params("sessionId"), 10, 0)
if err != nil {
return err
}
messageId, err := strconv.ParseUint(c.Params("messageId"), 10, 0)
if err != nil {
return err
@ -337,7 +321,7 @@ func (_i *aiChatController) UpdateMessage(c *fiber.Ctx) error {
authHeader := c.Get("Authorization")
err = _i.aiChatService.UpdateMessage(authHeader, uint(sessionId), uint(messageId), *req)
err = _i.aiChatService.UpdateMessage(authHeader, uint(messageId), *req)
if err != nil {
return err
}
@ -353,21 +337,15 @@ func (_i *aiChatController) UpdateMessage(c *fiber.Ctx) error {
// @Description API for delete AI chat message
// @Tags AI Chat
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param sessionId path int true "Session ID"
// @Param messageId path int true "Message ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /ai-chat/sessions/{sessionId}/messages/{messageId} [delete]
// @Router /ai-chat/sessions/messages/{messageId} [delete]
func (_i *aiChatController) DeleteMessage(c *fiber.Ctx) error {
sessionId, err := strconv.ParseUint(c.Params("sessionId"), 10, 0)
if err != nil {
return err
}
messageId, err := strconv.ParseUint(c.Params("messageId"), 10, 0)
if err != nil {
return err
@ -375,7 +353,7 @@ func (_i *aiChatController) DeleteMessage(c *fiber.Ctx) error {
authHeader := c.Get("Authorization")
err = _i.aiChatService.DeleteMessage(authHeader, uint(sessionId), uint(messageId))
err = _i.aiChatService.DeleteMessage(authHeader, uint(messageId))
if err != nil {
return err
}
@ -391,7 +369,7 @@ func (_i *aiChatController) DeleteMessage(c *fiber.Ctx) error {
// @Description API for getting all AI chat logs for authenticated user
// @Tags AI Chat
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param req query request.AIChatLogsQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -431,7 +409,7 @@ func (_i *aiChatController) GetUserLogs(c *fiber.Ctx) error {
// @Description API for getting one AI chat log
// @Tags AI Chat
// @Security Bearer
// @Param X-Client-Key header string false "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 "Log ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError

View File

@ -8,12 +8,12 @@ import (
func AIChatSessionsResponseMapper(session *entity.AIChatSessions) *response.AIChatSessionsResponse {
result := &response.AIChatSessionsResponse{
ID: session.ID,
AISessionID: session.AISessionID,
SessionID: session.SessionID,
UserID: session.UserID,
AgentID: session.AgentID,
Title: session.Title,
MessageCount: session.MessageCount,
Status: session.Status,
IsActive: session.IsActive,
CreatedAt: session.CreatedAt,
UpdatedAt: session.UpdatedAt,
}
@ -36,6 +36,7 @@ func AIChatMessagesResponseMapper(message *entity.AIChatMessages) *response.AICh
SessionID: message.SessionID,
MessageType: message.MessageType,
Content: message.Content,
IsActive: message.IsActive,
CreatedAt: message.CreatedAt,
}
}

View File

@ -15,18 +15,18 @@ type AIChatRepository interface {
// AI Chat Sessions
GetUserSessions(userId uint, req request.AIChatSessionsQueryRequest) (sessions []*entity.AIChatSessions, paging paginator.Pagination, err error)
FindSessionByUserAndId(userId uint, sessionId uint) (session *entity.AIChatSessions, err error)
FindSessionByAISessionId(aiSessionId string) (session *entity.AIChatSessions, err error)
FindSessionBySessionId(sessionId string) (session *entity.AIChatSessions, err error)
CreateSession(session *entity.AIChatSessions) (result *entity.AIChatSessions, err error)
UpdateSession(userId uint, sessionId uint, session *entity.AIChatSessions) (err error)
DeleteSession(userId uint, sessionId uint) (err error)
IncrementMessageCount(sessionId uint) (err error)
// AI Chat Messages
GetSessionMessages(sessionId uint, req request.AIChatMessagesQueryRequest) (messages []*entity.AIChatMessages, paging paginator.Pagination, err error)
GetSessionMessages(sessionId string, req request.AIChatMessagesQueryRequest) (messages []*entity.AIChatMessages, paging paginator.Pagination, err error)
CreateMessage(message *entity.AIChatMessages) (result *entity.AIChatMessages, err error)
UpdateMessage(messageId uint, message *entity.AIChatMessages) (err error)
DeleteMessage(messageId uint) (err error)
GetLastMessage(sessionId uint) (message *entity.AIChatMessages, err error)
GetLastMessage(sessionId string) (message *entity.AIChatMessages, err error)
// AI Chat Logs
GetUserLogs(userId uint, req request.AIChatLogsQueryRequest) (logs []*entity.AIChatLogs, paging paginator.Pagination, err error)
@ -41,15 +41,15 @@ func NewAIChatRepository(db *database.Database) AIChatRepository {
// AI Chat Sessions methods
func (_i *aiChatRepository) GetUserSessions(userId uint, req request.AIChatSessionsQueryRequest) (sessions []*entity.AIChatSessions, paging paginator.Pagination, err error) {
query := _i.DB.DB.Where("user_id = ?", userId)
query := _i.DB.DB.Model(&entity.AIChatSessions{}).Where("user_id = ?", userId)
// Apply filters
if req.Status != nil {
query = query.Where("status = ?", *req.Status)
if req.IsActive != nil {
query = query.Where("is_active = ?", *req.IsActive)
}
// Include user relationship
query = query.Preload("User")
// query = query.Preload("User")
// Order by updated_at desc (most recent first)
query = query.Order("updated_at DESC")
@ -67,12 +67,12 @@ func (_i *aiChatRepository) GetUserSessions(userId uint, req request.AIChatSessi
}
func (_i *aiChatRepository) FindSessionByUserAndId(userId uint, sessionId uint) (session *entity.AIChatSessions, err error) {
err = _i.DB.DB.Where("user_id = ? AND id = ?", userId, sessionId).Preload("User").First(&session).Error
err = _i.DB.DB.Model(&entity.AIChatSessions{}).Where("user_id = ? AND id = ?", userId, sessionId).Preload("User").First(&session).Error
return
}
func (_i *aiChatRepository) FindSessionByAISessionId(aiSessionId string) (session *entity.AIChatSessions, err error) {
err = _i.DB.DB.Where("ai_session_id = ?", aiSessionId).Preload("User").First(&session).Error
func (_i *aiChatRepository) FindSessionBySessionId(sessionId string) (session *entity.AIChatSessions, err error) {
err = _i.DB.DB.Model(&entity.AIChatSessions{}).Where("session_id = ?", sessionId).Preload("User").First(&session).Error
return
}
@ -83,17 +83,17 @@ func (_i *aiChatRepository) CreateSession(session *entity.AIChatSessions) (resul
}
// Reload with relationships
err = _i.DB.DB.Preload("User").First(&result, session.ID).Error
err = _i.DB.DB.Model(&entity.AIChatSessions{}).Preload("User").First(&result, session.ID).Error
return
}
func (_i *aiChatRepository) UpdateSession(userId uint, sessionId uint, session *entity.AIChatSessions) (err error) {
err = _i.DB.DB.Where("user_id = ? AND id = ?", userId, sessionId).Updates(session).Error
err = _i.DB.DB.Model(&entity.AIChatSessions{}).Where("user_id = ? AND id = ?", userId, sessionId).Updates(session).Error
return
}
func (_i *aiChatRepository) DeleteSession(userId uint, sessionId uint) (err error) {
err = _i.DB.DB.Where("user_id = ? AND id = ?", userId, sessionId).Delete(&entity.AIChatSessions{}).Error
err = _i.DB.DB.Model(&entity.AIChatSessions{}).Where("user_id = ? AND id = ?", userId, sessionId).Delete(&entity.AIChatSessions{}).Error
return
}
@ -103,8 +103,8 @@ func (_i *aiChatRepository) IncrementMessageCount(sessionId uint) (err error) {
}
// AI Chat Messages methods
func (_i *aiChatRepository) GetSessionMessages(sessionId uint, req request.AIChatMessagesQueryRequest) (messages []*entity.AIChatMessages, paging paginator.Pagination, err error) {
query := _i.DB.DB.Where("session_id = ?", sessionId)
func (_i *aiChatRepository) GetSessionMessages(sessionId string, req request.AIChatMessagesQueryRequest) (messages []*entity.AIChatMessages, paging paginator.Pagination, err error) {
query := _i.DB.DB.Model(&entity.AIChatMessages{}).Where("session_id = ?", sessionId)
// Order by created_at asc (oldest first for chat)
query = query.Order("created_at ASC")
@ -128,7 +128,7 @@ func (_i *aiChatRepository) CreateMessage(message *entity.AIChatMessages) (resul
}
// Reload
err = _i.DB.DB.First(&result, message.ID).Error
err = _i.DB.DB.Model(&entity.AIChatMessages{}).First(&result, message.ID).Error
return
}
@ -138,7 +138,7 @@ func (_i *aiChatRepository) UpdateMessage(messageId uint, message *entity.AIChat
}
func (_i *aiChatRepository) DeleteMessage(messageId uint) (err error) {
err = _i.DB.DB.Where("id = ?", messageId).Delete(&entity.AIChatMessages{}).Error
err = _i.DB.DB.Model(&entity.AIChatMessages{}).Where("id = ?", messageId).Delete(&entity.AIChatMessages{}).Error
return
}
@ -146,7 +146,7 @@ func (_i *aiChatRepository) DeleteMessage(messageId uint) (err error) {
func (_i *aiChatRepository) GetUserLogs(userId uint, req request.AIChatLogsQueryRequest) (logs []*entity.AIChatLogs, paging paginator.Pagination, err error) {
var count int64
query := _i.DB.DB.Where("user_id = ?", userId)
query := _i.DB.DB.Model(&entity.AIChatLogs{}).Where("user_id = ?", userId)
// Note: AIChatLogs entity doesn't have LogType field, so we skip this filter
// if req.LogType != nil && *req.LogType != "" {
@ -154,7 +154,7 @@ func (_i *aiChatRepository) GetUserLogs(userId uint, req request.AIChatLogsQuery
// }
// Count total records
err = query.Model(&entity.AIChatLogs{}).Count(&count).Error
err = query.Count(&count).Error
if err != nil {
return
}
@ -183,7 +183,7 @@ func (_i *aiChatRepository) GetUserLogs(userId uint, req request.AIChatLogsQuery
}
func (_i *aiChatRepository) FindLogByUserAndId(userId uint, logId uint) (log *entity.AIChatLogs, err error) {
query := _i.DB.DB.Where("user_id = ? AND id = ?", userId, logId)
query := _i.DB.DB.Model(&entity.AIChatLogs{}).Where("user_id = ? AND id = ?", userId, logId)
if err := query.First(&log).Error; err != nil {
return nil, err
@ -192,7 +192,7 @@ func (_i *aiChatRepository) FindLogByUserAndId(userId uint, logId uint) (log *en
return
}
func (_i *aiChatRepository) GetLastMessage(sessionId uint) (message *entity.AIChatMessages, err error) {
err = _i.DB.DB.Where("session_id = ?", sessionId).Order("created_at DESC").First(&message).Error
func (_i *aiChatRepository) GetLastMessage(sessionId string) (message *entity.AIChatMessages, err error) {
err = _i.DB.DB.Model(&entity.AIChatMessages{}).Where("session_id = ?", sessionId).Order("created_at DESC").First(&message).Error
return
}

View File

@ -7,45 +7,46 @@ import (
// AI Chat Sessions Request DTOs
type AIChatSessionsQueryRequest struct {
Status *string `json:"status"`
IsActive *bool `json:"isActive"`
Pagination *paginator.Pagination `json:"pagination"`
}
type AIChatSessionsCreateRequest struct {
Title string `json:"title" validate:"required,min=2,max=255"`
AgentID *string `json:"agentId"`
SessionID string `json:"sessionId" validate:"required"`
Title string `json:"title" validate:"required,min=2,max=255"`
AgentID string `json:"agentId" validate:"required"`
}
func (req AIChatSessionsCreateRequest) ToEntity() *entity.AIChatSessions {
return &entity.AIChatSessions{
AISessionID: "", // Will be generated in service layer
SessionID: req.SessionID,
AgentID: req.AgentID,
Title: req.Title,
MessageCount: 0,
Status: "active",
IsActive: true,
}
}
type AIChatSessionsUpdateRequest struct {
Title string `json:"title" validate:"required,min=2,max=255"`
Status string `json:"status" validate:"required,oneof=active archived deleted"`
Title string `json:"title" validate:"required,min=2,max=255"`
IsActive bool `json:"isActive"`
}
func (req AIChatSessionsUpdateRequest) ToEntity() *entity.AIChatSessions {
return &entity.AIChatSessions{
Title: req.Title,
Status: req.Status,
Title: req.Title,
IsActive: req.IsActive,
}
}
// AI Chat Messages Request DTOs
type AIChatMessagesQueryRequest struct {
SessionID uint `json:"sessionId" validate:"required"`
SessionID string `json:"sessionId" validate:"required"`
Pagination *paginator.Pagination `json:"pagination"`
}
type AIChatMessagesCreateRequest struct {
SessionID uint `json:"sessionId" validate:"required"`
SessionID string `json:"sessionId" validate:"required"`
MessageType string `json:"messageType" validate:"required,oneof=user assistant"`
Content string `json:"content" validate:"required,min=1"`
}
@ -55,6 +56,7 @@ func (req AIChatMessagesCreateRequest) ToEntity() *entity.AIChatMessages {
SessionID: req.SessionID,
MessageType: req.MessageType,
Content: req.Content,
IsActive: true,
}
}
@ -69,14 +71,15 @@ func (req AIChatMessagesUpdateRequest) ToEntity() *entity.AIChatMessages {
}
type AIChatSessionsQueryRequestContext struct {
Status string `json:"status"`
IsActive string `json:"isActive"`
}
func (req AIChatSessionsQueryRequestContext) ToParamRequest() AIChatSessionsQueryRequest {
var request AIChatSessionsQueryRequest
if status := req.Status; status != "" {
request.Status = &status
if isActiveStr := req.IsActive; isActiveStr != "" {
isActive := isActiveStr == "true"
request.IsActive = &isActive
}
return request

View File

@ -7,12 +7,12 @@ import (
// AI Chat Sessions Response DTOs
type AIChatSessionsResponse struct {
ID uint `json:"id"`
AISessionID string `json:"aiSessionId"`
SessionID string `json:"sessionId"`
UserID uint `json:"userId"`
AgentID *string `json:"agentId"`
AgentID string `json:"agentId"`
Title string `json:"title"`
MessageCount int `json:"messageCount"`
Status string `json:"status"`
IsActive bool `json:"isActive"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
@ -26,9 +26,10 @@ type AIChatSessionsResponse struct {
// AI Chat Messages Response DTOs
type AIChatMessagesResponse struct {
ID uint `json:"id"`
SessionID uint `json:"sessionId"`
SessionID string `json:"sessionId"`
MessageType string `json:"messageType"`
Content string `json:"content"`
IsActive bool `json:"isActive"`
CreatedAt time.Time `json:"createdAt"`
}

View File

@ -2,7 +2,6 @@ package service
import (
"errors"
"fmt"
"narasi-ahli-be/app/module/ai_chat/mapper"
"narasi-ahli-be/app/module/ai_chat/repository"
"narasi-ahli-be/app/module/ai_chat/request"
@ -23,17 +22,17 @@ type aiChatService struct {
type AIChatService interface {
// Sessions
GetUserSessions(authToken string, req request.AIChatSessionsQueryRequest) (sessions []*response.AIChatSessionsResponse, paging paginator.Pagination, err error)
GetSession(authToken string, sessionId uint) (session *response.AIChatSessionsResponse, err error)
GetSession(authToken string, id uint) (session *response.AIChatSessionsResponse, err error)
CreateSession(authToken string, req request.AIChatSessionsCreateRequest) (session *response.AIChatSessionsResponse, err error)
UpdateSession(authToken string, sessionId uint, req request.AIChatSessionsUpdateRequest) (err error)
DeleteSession(authToken string, sessionId uint) error
ArchiveSession(authToken string, sessionId uint) error
UpdateSession(authToken string, id uint, req request.AIChatSessionsUpdateRequest) (err error)
DeleteSession(authToken string, id uint) error
ArchiveSession(authToken string, id uint) error
// Messages
GetSessionMessages(authToken string, sessionId uint, req request.AIChatMessagesQueryRequest) (messages []*response.AIChatMessagesResponse, paging paginator.Pagination, err error)
SendMessage(authToken string, sessionId uint, req request.AIChatMessagesCreateRequest) (message *response.AIChatMessagesResponse, err error)
UpdateMessage(authToken string, sessionId uint, messageId uint, req request.AIChatMessagesUpdateRequest) (err error)
DeleteMessage(authToken string, sessionId uint, messageId uint) error
GetSessionMessages(authToken string, sessionId string, req request.AIChatMessagesQueryRequest) (messages []*response.AIChatMessagesResponse, paging paginator.Pagination, err error)
SendMessage(authToken string, req request.AIChatMessagesCreateRequest) (message *response.AIChatMessagesResponse, err error)
UpdateMessage(authToken string, messageId uint, req request.AIChatMessagesUpdateRequest) (err error)
DeleteMessage(authToken string, messageId uint) error
// Logs
GetUserLogs(authToken string, req request.AIChatLogsQueryRequest) (logs []*response.AIChatLogsResponse, paging paginator.Pagination, err error)
@ -64,10 +63,10 @@ func (_i *aiChatService) GetUserSessions(authToken string, req request.AIChatSes
return
}
func (_i *aiChatService) GetSession(authToken string, sessionId uint) (session *response.AIChatSessionsResponse, err error) {
func (_i *aiChatService) GetSession(authToken string, id uint) (session *response.AIChatSessionsResponse, err error) {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
result, err := _i.Repo.FindSessionByUserAndId(userInfo.ID, sessionId)
result, err := _i.Repo.FindSessionByUserAndId(userInfo.ID, id)
if err != nil {
return nil, err
}
@ -81,8 +80,7 @@ func (_i *aiChatService) CreateSession(authToken string, req request.AIChatSessi
entity := req.ToEntity()
entity.UserID = userInfo.ID
// Generate unique AI session ID
entity.AISessionID = fmt.Sprintf("ai_session_%d_%d", userInfo.ID, entity.ID)
_i.Log.Info().Interface("data", entity).Msg("Create AI chat session")
result, err := _i.Repo.CreateSession(entity)
if err != nil {
@ -92,12 +90,12 @@ func (_i *aiChatService) CreateSession(authToken string, req request.AIChatSessi
return mapper.AIChatSessionsResponseMapper(result), nil
}
func (_i *aiChatService) UpdateSession(authToken string, sessionId uint, req request.AIChatSessionsUpdateRequest) (err error) {
func (_i *aiChatService) UpdateSession(authToken string, id uint, req request.AIChatSessionsUpdateRequest) (err error) {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
_i.Log.Info().Interface("data", req).Msg("Updating AI chat session")
// Check if session exists and belongs to user
existing, err := _i.Repo.FindSessionByUserAndId(userInfo.ID, sessionId)
existing, err := _i.Repo.FindSessionByUserAndId(userInfo.ID, id)
if err != nil {
return err
}
@ -106,15 +104,14 @@ func (_i *aiChatService) UpdateSession(authToken string, sessionId uint, req req
}
entity := req.ToEntity()
return _i.Repo.UpdateSession(userInfo.ID, sessionId, entity)
return _i.Repo.UpdateSession(userInfo.ID, id, entity)
}
func (_i *aiChatService) DeleteSession(authToken string, sessionId uint) error {
func (_i *aiChatService) DeleteSession(authToken string, id uint) error {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
_i.Log.Info().Uint("userId", userInfo.ID).Uint("sessionId", sessionId).Msg("Deleting AI chat session")
// Check if session exists and belongs to user
existing, err := _i.Repo.FindSessionByUserAndId(userInfo.ID, sessionId)
existing, err := _i.Repo.FindSessionByUserAndId(userInfo.ID, id)
if err != nil {
return err
}
@ -122,15 +119,14 @@ func (_i *aiChatService) DeleteSession(authToken string, sessionId uint) error {
return errors.New("AI chat session not found")
}
return _i.Repo.DeleteSession(userInfo.ID, sessionId)
return _i.Repo.DeleteSession(userInfo.ID, id)
}
func (_i *aiChatService) ArchiveSession(authToken string, sessionId uint) error {
func (_i *aiChatService) ArchiveSession(authToken string, id uint) error {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
_i.Log.Info().Uint("userId", userInfo.ID).Uint("sessionId", sessionId).Msg("Archiving AI chat session")
// Check if session exists and belongs to user
existing, err := _i.Repo.FindSessionByUserAndId(userInfo.ID, sessionId)
existing, err := _i.Repo.FindSessionByUserAndId(userInfo.ID, id)
if err != nil {
return err
}
@ -139,16 +135,16 @@ func (_i *aiChatService) ArchiveSession(authToken string, sessionId uint) error
}
// Update status to archived
existing.Status = "archived"
return _i.Repo.UpdateSession(userInfo.ID, sessionId, existing)
existing.IsActive = false
return _i.Repo.UpdateSession(userInfo.ID, id, existing)
}
// Messages methods
func (_i *aiChatService) GetSessionMessages(authToken string, sessionId uint, req request.AIChatMessagesQueryRequest) (messages []*response.AIChatMessagesResponse, paging paginator.Pagination, err error) {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
func (_i *aiChatService) GetSessionMessages(authToken string, sessionId string, req request.AIChatMessagesQueryRequest) (messages []*response.AIChatMessagesResponse, paging paginator.Pagination, err error) {
// userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
// Verify session belongs to user
_, err = _i.Repo.FindSessionByUserAndId(userInfo.ID, sessionId)
_, err = _i.Repo.FindSessionBySessionId(sessionId)
if err != nil {
return nil, paginator.Pagination{}, err
}
@ -165,12 +161,11 @@ func (_i *aiChatService) GetSessionMessages(authToken string, sessionId uint, re
return
}
func (_i *aiChatService) SendMessage(authToken string, sessionId uint, req request.AIChatMessagesCreateRequest) (message *response.AIChatMessagesResponse, err error) {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
_i.Log.Info().Interface("data", req).Msg("Sending AI chat message")
func (_i *aiChatService) SendMessage(authToken string, req request.AIChatMessagesCreateRequest) (message *response.AIChatMessagesResponse, err error) {
// userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
// Verify session belongs to user
_, err = _i.Repo.FindSessionByUserAndId(userInfo.ID, req.SessionID)
// Verify session exists
session, err := _i.Repo.FindSessionBySessionId(req.SessionID)
if err != nil {
return nil, err
}
@ -183,7 +178,7 @@ func (_i *aiChatService) SendMessage(authToken string, sessionId uint, req reque
}
// Increment message count in session
err = _i.Repo.IncrementMessageCount(req.SessionID)
err = _i.Repo.IncrementMessageCount(session.ID)
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to increment message count")
}
@ -192,28 +187,16 @@ func (_i *aiChatService) SendMessage(authToken string, sessionId uint, req reque
}
// Update Message
func (_i *aiChatService) UpdateMessage(authToken string, sessionId uint, messageId uint, req request.AIChatMessagesUpdateRequest) (err error) {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
// Verify session belongs to user
_, err = _i.Repo.FindSessionByUserAndId(userInfo.ID, sessionId)
if err != nil {
return err
}
func (_i *aiChatService) UpdateMessage(authToken string, messageId uint, req request.AIChatMessagesUpdateRequest) (err error) {
// userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
entity := req.ToEntity()
return _i.Repo.UpdateMessage(messageId, entity)
}
// Delete Message
func (_i *aiChatService) DeleteMessage(authToken string, sessionId uint, messageId uint) error {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
// Verify session belongs to user
_, err := _i.Repo.FindSessionByUserAndId(userInfo.ID, sessionId)
if err != nil {
return err
}
func (_i *aiChatService) DeleteMessage(authToken string, messageId uint) error {
// userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
return _i.Repo.DeleteMessage(messageId)
}

View File

@ -1,7 +1,7 @@
package controller
import (
"narasi-ahli-be/app/module/article_approvals/request"
"narasi-ahli-be/app/module/article_approvals/request"
"narasi-ahli-be/app/module/article_approvals/service"
"narasi-ahli-be/utils/paginator"
"strconv"
@ -108,7 +108,6 @@ func (_i *articleApprovalsController) Show(c *fiber.Ctx) error {
// @Description API for create ArticleApprovals
// @Tags ArticleApprovals
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.ArticleApprovalsCreateRequest true "Required payload"
@ -126,7 +125,7 @@ func (_i *articleApprovalsController) Save(c *fiber.Ctx) error {
authToken := c.Get("Authorization")
// Get from context
dataResult, err := _i.articleApprovalsService.Save(*req, authToken)
dataResult, err := _i.articleApprovalsService.Save(*req, authToken)
if err != nil {
return err
}

View File

@ -1,7 +1,7 @@
package controller
import (
"narasi-ahli-be/app/module/article_categories/request"
"narasi-ahli-be/app/module/article_categories/request"
"narasi-ahli-be/app/module/article_categories/service"
"narasi-ahli-be/utils/paginator"
"strconv"
@ -39,7 +39,6 @@ func NewArticleCategoriesController(articleCategoriesService service.ArticleCate
// @Description API for getting all ArticleCategories
// @Tags Article Categories
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param req query request.ArticleCategoriesQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
@ -55,7 +54,7 @@ func (_i *articleCategoriesController) All(c *fiber.Ctx) error {
}
authToken := c.Get("Authorization")
reqContext := request.ArticleCategoriesQueryRequestContext{
reqContext := request.ArticleCategoriesQueryRequestContext{
Title: c.Query("title"),
Description: c.Query("description"),
ParentId: c.Query("parentId"),
@ -83,7 +82,6 @@ func (_i *articleCategoriesController) All(c *fiber.Ctx) error {
// @Description API for getting one ArticleCategories
// @Tags Article Categories
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "ArticleCategories ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -96,7 +94,7 @@ func (_i *articleCategoriesController) Show(c *fiber.Ctx) error {
return err
}
articleCategoriesData, err := _i.articleCategoriesService.Show(uint(id))
articleCategoriesData, err := _i.articleCategoriesService.Show(uint(id))
if err != nil {
return err
}
@ -113,7 +111,6 @@ func (_i *articleCategoriesController) Show(c *fiber.Ctx) error {
// @Description API for getting one ArticleCategories
// @Tags Article Categories
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "ArticleCategories Old ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -126,7 +123,7 @@ func (_i *articleCategoriesController) ShowByOldId(c *fiber.Ctx) error {
return err
}
articleCategoriesData, err := _i.articleCategoriesService.ShowByOldId(uint(id))
articleCategoriesData, err := _i.articleCategoriesService.ShowByOldId(uint(id))
if err != nil {
return err
}
@ -143,7 +140,6 @@ func (_i *articleCategoriesController) ShowByOldId(c *fiber.Ctx) error {
// @Description API for getting one ArticleCategories
// @Tags Article Categories
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param slug path string true "ArticleCategories Slug"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -152,7 +148,7 @@ func (_i *articleCategoriesController) ShowByOldId(c *fiber.Ctx) error {
// @Router /article-categories/slug/{slug} [get]
func (_i *articleCategoriesController) ShowBySlug(c *fiber.Ctx) error {
slug := c.Params("slug")
articleCategoriesData, err := _i.articleCategoriesService.ShowBySlug(slug)
articleCategoriesData, err := _i.articleCategoriesService.ShowBySlug(slug)
if err != nil {
return err
}
@ -169,7 +165,6 @@ func (_i *articleCategoriesController) ShowBySlug(c *fiber.Ctx) error {
// @Description API for create ArticleCategories
// @Tags Article Categories
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.ArticleCategoriesCreateRequest true "Required payload"
@ -185,7 +180,7 @@ func (_i *articleCategoriesController) Save(c *fiber.Ctx) error {
}
authToken := c.Get("Authorization")
dataResult, err := _i.articleCategoriesService.Save(*req, authToken)
dataResult, err := _i.articleCategoriesService.Save(*req, authToken)
if err != nil {
return err
}
@ -203,7 +198,6 @@ func (_i *articleCategoriesController) Save(c *fiber.Ctx) error {
// @Tags Article Categories
// @Security Bearer
// @Produce json
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param files formData file true "Upload thumbnail"
// @Param id path int true "ArticleCategories ID"
@ -213,7 +207,7 @@ func (_i *articleCategoriesController) Save(c *fiber.Ctx) error {
// @Failure 500 {object} response.InternalServerError
// @Router /article-categories/thumbnail/{id} [post]
func (_i *articleCategoriesController) SaveThumbnail(c *fiber.Ctx) error {
err := _i.articleCategoriesService.SaveThumbnail(c)
err := _i.articleCategoriesService.SaveThumbnail(c)
if err != nil {
return err
}
@ -229,7 +223,6 @@ func (_i *articleCategoriesController) SaveThumbnail(c *fiber.Ctx) error {
// @Description API for update ArticleCategories
// @Tags Article Categories
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.ArticleCategoriesUpdateRequest true "Required payload"
// @Param id path int true "ArticleCategories ID"
@ -249,7 +242,7 @@ func (_i *articleCategoriesController) Update(c *fiber.Ctx) error {
return err
}
err = _i.articleCategoriesService.Update(uint(id), *req)
err = _i.articleCategoriesService.Update(uint(id), *req)
if err != nil {
return err
}
@ -265,7 +258,6 @@ func (_i *articleCategoriesController) Update(c *fiber.Ctx) error {
// @Description API for delete ArticleCategories
// @Tags Article Categories
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "ArticleCategories ID"
// @Success 200 {object} response.Response
@ -279,7 +271,7 @@ func (_i *articleCategoriesController) Delete(c *fiber.Ctx) error {
return err
}
err = _i.articleCategoriesService.Delete(uint(id))
err = _i.articleCategoriesService.Delete(uint(id))
if err != nil {
return err
}
@ -295,7 +287,6 @@ func (_i *articleCategoriesController) Delete(c *fiber.Ctx) error {
// @Description API for View Thumbnail of ArticleCategories
// @Tags Article Categories
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path string true "ArticleCategories ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError

View File

@ -1,14 +1,15 @@
package controller
import (
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog"
"narasi-ahli-be/app/module/article_comments/request"
"narasi-ahli-be/app/module/article_comments/request"
"narasi-ahli-be/app/module/article_comments/service"
"narasi-ahli-be/utils/paginator"
utilRes "narasi-ahli-be/utils/response"
utilVal "narasi-ahli-be/utils/validator"
"strconv"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog"
)
type articleCommentsController struct {
@ -37,7 +38,6 @@ func NewArticleCommentsController(articleCommentsService service.ArticleComments
// @Description API for getting all ArticleComments
// @Tags ArticleComments
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.ArticleCommentsQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -47,7 +47,7 @@ func NewArticleCommentsController(articleCommentsService service.ArticleComments
// @Router /article-comments [get]
func (_i *articleCommentsController) All(c *fiber.Ctx) error {
// Get from context
paginate, err := paginator.Paginate(c)
paginate, err := paginator.Paginate(c)
if err != nil {
return err
}
@ -80,7 +80,6 @@ func (_i *articleCommentsController) All(c *fiber.Ctx) error {
// @Description API for getting one ArticleComments
// @Tags ArticleComments
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "ArticleComments ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -89,7 +88,7 @@ func (_i *articleCommentsController) All(c *fiber.Ctx) error {
// @Router /article-comments/{id} [get]
func (_i *articleCommentsController) Show(c *fiber.Ctx) error {
// Get from context
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
@ -111,7 +110,6 @@ func (_i *articleCommentsController) Show(c *fiber.Ctx) error {
// @Description API for create ArticleComments
// @Tags ArticleComments
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.ArticleCommentsCreateRequest true "Required payload"
@ -122,7 +120,7 @@ func (_i *articleCommentsController) Show(c *fiber.Ctx) error {
// @Router /article-comments [post]
func (_i *articleCommentsController) Save(c *fiber.Ctx) error {
// Get from context
req := new(request.ArticleCommentsCreateRequest)
req := new(request.ArticleCommentsCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
@ -145,7 +143,6 @@ func (_i *articleCommentsController) Save(c *fiber.Ctx) error {
// @Description API for update ArticleComments
// @Tags ArticleComments
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.ArticleCommentsUpdateRequest true "Required payload"
// @Param id path int true "ArticleComments ID"
@ -156,7 +153,7 @@ func (_i *articleCommentsController) Save(c *fiber.Ctx) error {
// @Router /article-comments/{id} [put]
func (_i *articleCommentsController) Update(c *fiber.Ctx) error {
// Get from context
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
@ -182,7 +179,6 @@ func (_i *articleCommentsController) Update(c *fiber.Ctx) error {
// @Description API for delete ArticleComments
// @Tags ArticleComments
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "ArticleComments ID"
// @Success 200 {object} response.Response
@ -192,7 +188,7 @@ func (_i *articleCommentsController) Update(c *fiber.Ctx) error {
// @Router /article-comments/{id} [delete]
func (_i *articleCommentsController) Delete(c *fiber.Ctx) error {
// Get from context
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
@ -213,7 +209,6 @@ func (_i *articleCommentsController) Delete(c *fiber.Ctx) error {
// @Description API for Approval ArticleComments
// @Tags ArticleComments
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.ArticleCommentsApprovalRequest true "Required payload"
// @Success 200 {object} response.Response
@ -223,7 +218,7 @@ func (_i *articleCommentsController) Delete(c *fiber.Ctx) error {
// @Router /article-comments/approval [post]
func (_i *articleCommentsController) Approval(c *fiber.Ctx) error {
// Get from context
req := new(request.ArticleCommentsApprovalRequest)
req := new(request.ArticleCommentsApprovalRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}

View File

@ -2,7 +2,7 @@ package controller
import (
"fmt"
"narasi-ahli-be/app/module/article_files/request"
"narasi-ahli-be/app/module/article_files/request"
"narasi-ahli-be/app/module/article_files/service"
"narasi-ahli-be/utils/paginator"
utilRes "narasi-ahli-be/utils/response"
@ -37,7 +37,6 @@ func NewArticleFilesController(articleFilesService service.ArticleFilesService)
// @Description API for getting all ArticleFiles
// @Tags Article Files
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.ArticleFilesQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -47,7 +46,7 @@ func NewArticleFilesController(articleFilesService service.ArticleFilesService)
// @Router /article-files [get]
func (_i *articleFilesController) All(c *fiber.Ctx) error {
// Get from context
paginate, err := paginator.Paginate(c)
paginate, err := paginator.Paginate(c)
if err != nil {
return err
}
@ -79,7 +78,6 @@ func (_i *articleFilesController) All(c *fiber.Ctx) error {
// @Description API for getting one ArticleFiles
// @Tags Article Files
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "ArticleFiles ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -88,7 +86,7 @@ func (_i *articleFilesController) All(c *fiber.Ctx) error {
// @Router /article-files/{id} [get]
func (_i *articleFilesController) Show(c *fiber.Ctx) error {
// Get from context
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
@ -111,7 +109,6 @@ func (_i *articleFilesController) Show(c *fiber.Ctx) error {
// @Tags Article Files
// @Security Bearer
// @Produce json
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param files formData file true "Upload file" multiple true
// @Param articleId path int true "Article ID"
@ -122,7 +119,7 @@ func (_i *articleFilesController) Show(c *fiber.Ctx) error {
// @Router /article-files/{articleId} [post]
func (_i *articleFilesController) Save(c *fiber.Ctx) error {
// Get from context
id, err := strconv.ParseUint(c.Params("articleId"), 10, 0)
id, err := strconv.ParseUint(c.Params("articleId"), 10, 0)
if err != nil {
return err
}
@ -143,7 +140,6 @@ func (_i *articleFilesController) Save(c *fiber.Ctx) error {
// @Description API for update ArticleFiles
// @Tags Article Files
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.ArticleFilesUpdateRequest true "Required payload"
// @Param id path int true "ArticleFiles ID"
@ -154,7 +150,7 @@ func (_i *articleFilesController) Save(c *fiber.Ctx) error {
// @Router /article-files/{id} [put]
func (_i *articleFilesController) Update(c *fiber.Ctx) error {
// Get from context
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
@ -180,7 +176,6 @@ func (_i *articleFilesController) Update(c *fiber.Ctx) error {
// @Description API for delete ArticleFiles
// @Tags Article Files
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "ArticleFiles ID"
// @Success 200 {object} response.Response
@ -190,7 +185,7 @@ func (_i *articleFilesController) Update(c *fiber.Ctx) error {
// @Router /article-files/{id} [delete]
func (_i *articleFilesController) Delete(c *fiber.Ctx) error {
// Get from context
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
@ -211,7 +206,6 @@ func (_i *articleFilesController) Delete(c *fiber.Ctx) error {
// @Description API for Viewer ArticleFiles
// @Tags Article Files
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param filename path string true "Article File Name"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -220,7 +214,7 @@ func (_i *articleFilesController) Delete(c *fiber.Ctx) error {
// @Router /article-files/viewer/{filename} [get]
func (_i *articleFilesController) Viewer(c *fiber.Ctx) error {
// Get from context
return _i.articleFilesService.Viewer(c)
return _i.articleFilesService.Viewer(c)
}
// GetUploadStatus ArticleFiles

View File

@ -106,7 +106,7 @@ func (_i *articlesController) Show(c *fiber.Ctx) error {
}
// Get from context
articlesData, err := _i.articlesService.Show(uint(id))
articlesData, err := _i.articlesService.Show(uint(id))
if err != nil {
return err
}
@ -136,7 +136,7 @@ func (_i *articlesController) ShowByOldId(c *fiber.Ctx) error {
}
// Get from context
articlesData, err := _i.articlesService.ShowByOldId(uint(id))
articlesData, err := _i.articlesService.ShowByOldId(uint(id))
if err != nil {
return err
}
@ -153,7 +153,6 @@ func (_i *articlesController) ShowByOldId(c *fiber.Ctx) error {
// @Description API for create Articles
// @Tags Articles
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string false "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.ArticlesCreateRequest true "Required payload"
@ -171,7 +170,7 @@ func (_i *articlesController) Save(c *fiber.Ctx) error {
authToken := c.Get("Authorization")
// Get from context
dataResult, err := _i.articlesService.Save(*req, authToken)
dataResult, err := _i.articlesService.Save(*req, authToken)
if err != nil {
return err
}
@ -189,7 +188,6 @@ func (_i *articlesController) Save(c *fiber.Ctx) error {
// @Tags Articles
// @Security Bearer
// @Produce json
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param files formData file true "Upload thumbnail"
// @Param id path int true "Articles ID"
@ -200,7 +198,7 @@ func (_i *articlesController) Save(c *fiber.Ctx) error {
// @Router /articles/thumbnail/{id} [post]
func (_i *articlesController) SaveThumbnail(c *fiber.Ctx) error {
// Get from context
err := _i.articlesService.SaveThumbnail(c)
err := _i.articlesService.SaveThumbnail(c)
if err != nil {
return err
}
@ -236,7 +234,7 @@ func (_i *articlesController) Update(c *fiber.Ctx) error {
}
// Get from context
err = _i.articlesService.Update(uint(id), *req)
err = _i.articlesService.Update(uint(id), *req)
if err != nil {
return err
}
@ -272,7 +270,7 @@ func (_i *articlesController) UpdateBanner(c *fiber.Ctx) error {
}
// Get from context
err = _i.articlesService.UpdateBanner(uint(id), isBanner)
err = _i.articlesService.UpdateBanner(uint(id), isBanner)
if err != nil {
return err
}
@ -302,7 +300,7 @@ func (_i *articlesController) Delete(c *fiber.Ctx) error {
}
// Get from context
err = _i.articlesService.Delete(uint(id))
err = _i.articlesService.Delete(uint(id))
if err != nil {
return err
}
@ -326,7 +324,7 @@ func (_i *articlesController) Delete(c *fiber.Ctx) error {
// @Router /articles/thumbnail/viewer/{thumbnailName} [get]
func (_i *articlesController) Viewer(c *fiber.Ctx) error {
// Get from context
return _i.articlesService.Viewer(c)
return _i.articlesService.Viewer(c)
}
// SummaryStats Articles
@ -344,7 +342,7 @@ func (_i *articlesController) SummaryStats(c *fiber.Ctx) error {
authToken := c.Get("Authorization")
// Get from context
response, err := _i.articlesService.SummaryStats(authToken)
response, err := _i.articlesService.SummaryStats(authToken)
if err != nil {
return err
}
@ -375,7 +373,7 @@ func (_i *articlesController) ArticlePerUserLevelStats(c *fiber.Ctx) error {
endDate := c.Query("endDate")
// Get from context
response, err := _i.articlesService.ArticlePerUserLevelStats(authToken, &startDate, &endDate)
response, err := _i.articlesService.ArticlePerUserLevelStats(authToken, &startDate, &endDate)
if err != nil {
return err
}
@ -408,7 +406,7 @@ func (_i *articlesController) ArticleMonthlyStats(c *fiber.Ctx) error {
}
// Get from context
response, err := _i.articlesService.ArticleMonthlyStats(authToken, &yearInt)
response, err := _i.articlesService.ArticleMonthlyStats(authToken, &yearInt)
if err != nil {
return err
}
@ -442,7 +440,7 @@ func (_i *articlesController) PublishScheduling(c *fiber.Ctx) error {
date := c.Query("date")
// Get from context
err = _i.articlesService.PublishScheduling(uint(id), date)
err = _i.articlesService.PublishScheduling(uint(id), date)
if err != nil {
return err
}

View File

@ -1,64 +0,0 @@
package chat_history
import (
"narasi-ahli-be/app/module/chat_history/controller"
"narasi-ahli-be/app/module/chat_history/repository"
"narasi-ahli-be/app/module/chat_history/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
// struct of ChatHistoryRouter
type ChatHistoryRouter struct {
App fiber.Router
Controller controller.ChatHistoryController
}
// register bulky of Chat History module
var NewChatHistoryModule = fx.Options(
// register repository of Chat History module
fx.Provide(repository.NewChatHistoryRepository),
// register service of Chat History module
fx.Provide(service.NewChatHistoryService),
// register controller of Chat History module
fx.Provide(controller.NewChatHistoryController),
// register router of Chat History module
fx.Provide(NewChatHistoryRouter),
)
// init ChatHistoryRouter
func NewChatHistoryRouter(fiber *fiber.App, controller controller.ChatHistoryController) *ChatHistoryRouter {
return &ChatHistoryRouter{
App: fiber,
Controller: controller,
}
}
// register routes of Chat History module
func (_i *ChatHistoryRouter) RegisterChatHistoryRoutes() {
// define controllers
chatHistoryController := _i.Controller
// define routes
_i.App.Route("/chat-history", func(router fiber.Router) {
// Sessions routes
router.Get("/sessions", chatHistoryController.GetUserSessions)
router.Get("/sessions/:sessionId", chatHistoryController.GetSession)
router.Post("/sessions", chatHistoryController.CreateSession)
router.Put("/sessions/:sessionId", chatHistoryController.UpdateSession)
router.Delete("/sessions/:sessionId", chatHistoryController.DeleteSession)
// Messages routes
router.Get("/sessions/:sessionId/messages", chatHistoryController.GetSessionMessages)
router.Post("/sessions/:sessionId/messages", chatHistoryController.CreateMessage)
router.Put("/messages/:messageId", chatHistoryController.UpdateMessage)
router.Delete("/messages/:messageId", chatHistoryController.DeleteMessage)
// Combined operations
router.Post("/save", chatHistoryController.SaveChatHistory)
})
}

View File

@ -1,424 +0,0 @@
package controller
import (
"narasi-ahli-be/app/module/chat_history/request"
"narasi-ahli-be/app/module/chat_history/service"
"narasi-ahli-be/utils/paginator"
utilRes "narasi-ahli-be/utils/response"
utilVal "narasi-ahli-be/utils/validator"
"strconv"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog"
)
type chatHistoryController struct {
chatHistoryService service.ChatHistoryService
Log zerolog.Logger
}
type ChatHistoryController interface {
// Chat History Sessions
GetUserSessions(c *fiber.Ctx) error
GetSession(c *fiber.Ctx) error
CreateSession(c *fiber.Ctx) error
UpdateSession(c *fiber.Ctx) error
DeleteSession(c *fiber.Ctx) error
// Chat History Messages
GetSessionMessages(c *fiber.Ctx) error
CreateMessage(c *fiber.Ctx) error
UpdateMessage(c *fiber.Ctx) error
DeleteMessage(c *fiber.Ctx) error
// Combined operations
SaveChatHistory(c *fiber.Ctx) error
}
func NewChatHistoryController(chatHistoryService service.ChatHistoryService, log zerolog.Logger) ChatHistoryController {
return &chatHistoryController{
chatHistoryService: chatHistoryService,
Log: log,
}
}
// Get User Sessions
// @Summary Get user chat history sessions
// @Description API for getting all chat history sessions for authenticated user
// @Tags Chat History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.ChatHistorySessionsQueryRequest 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 /chat-history/sessions [get]
func (_i *chatHistoryController) GetUserSessions(c *fiber.Ctx) error {
paginate, err := paginator.Paginate(c)
if err != nil {
return err
}
authHeader := c.Get("Authorization")
reqContext := request.ChatHistorySessionsQueryRequestContext{
AgentID: c.Query("agent_id"),
SessionID: c.Query("session_id"),
}
req := reqContext.ToParamRequest()
req.Pagination = paginate
sessionsData, paging, err := _i.chatHistoryService.GetUserSessions(authHeader, req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Chat history sessions successfully retrieved"},
Data: sessionsData,
Meta: paging,
})
}
// Get Session
// @Summary Get one chat history session with messages
// @Description API for getting one chat history session with all its messages
// @Tags Chat History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param sessionId path string true "Session ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /chat-history/sessions/{sessionId} [get]
func (_i *chatHistoryController) GetSession(c *fiber.Ctx) error {
sessionID := c.Params("sessionId")
if sessionID == "" {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Session ID is required"},
})
}
authHeader := c.Get("Authorization")
sessionData, err := _i.chatHistoryService.GetSession(authHeader, sessionID)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Chat history session successfully retrieved"},
Data: sessionData,
})
}
// Create Session
// @Summary Create chat history session
// @Description API for create chat history session
// @Tags Chat History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.ChatHistorySessionsCreateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /chat-history/sessions [post]
func (_i *chatHistoryController) CreateSession(c *fiber.Ctx) error {
req := new(request.ChatHistorySessionsCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
authHeader := c.Get("Authorization")
dataResult, err := _i.chatHistoryService.CreateSession(authHeader, *req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Chat history session successfully created"},
Data: dataResult,
})
}
// Update Session
// @Summary Update chat history session
// @Description API for update chat history session
// @Tags Chat History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param sessionId path string true "Session ID"
// @Param payload body request.ChatHistorySessionsUpdateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /chat-history/sessions/{sessionId} [put]
func (_i *chatHistoryController) UpdateSession(c *fiber.Ctx) error {
sessionID := c.Params("sessionId")
if sessionID == "" {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Session ID is required"},
})
}
req := new(request.ChatHistorySessionsUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
authHeader := c.Get("Authorization")
err := _i.chatHistoryService.UpdateSession(authHeader, sessionID, *req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Chat history session successfully updated"},
})
}
// Delete Session
// @Summary Delete chat history session
// @Description API for delete chat history session
// @Tags Chat History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param sessionId path string true "Session ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /chat-history/sessions/{sessionId} [delete]
func (_i *chatHistoryController) DeleteSession(c *fiber.Ctx) error {
sessionID := c.Params("sessionId")
if sessionID == "" {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Session ID is required"},
})
}
authHeader := c.Get("Authorization")
err := _i.chatHistoryService.DeleteSession(authHeader, sessionID)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Chat history session successfully deleted"},
})
}
// Get Session Messages
// @Summary Get chat history session messages
// @Description API for getting all messages in a chat history session
// @Tags Chat History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param sessionId path string true "Session ID"
// @Param req query request.ChatHistoryMessagesQueryRequest 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 /chat-history/sessions/{sessionId}/messages [get]
func (_i *chatHistoryController) GetSessionMessages(c *fiber.Ctx) error {
sessionID := c.Params("sessionId")
if sessionID == "" {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Session ID is required"},
})
}
paginate, err := paginator.Paginate(c)
if err != nil {
return err
}
authHeader := c.Get("Authorization")
req := request.ChatHistoryMessagesQueryRequest{
SessionID: sessionID,
Pagination: paginate,
}
messagesData, paging, err := _i.chatHistoryService.GetSessionMessages(authHeader, sessionID, req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Chat history messages successfully retrieved"},
Data: messagesData,
Meta: paging,
})
}
// Create Message
// @Summary Create chat history message
// @Description API for creating a message in a chat history session
// @Tags Chat History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param sessionId path string true "Session ID"
// @Param payload body request.ChatHistoryMessagesCreateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /chat-history/sessions/{sessionId}/messages [post]
func (_i *chatHistoryController) CreateMessage(c *fiber.Ctx) error {
sessionID := c.Params("sessionId")
if sessionID == "" {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Session ID is required"},
})
}
req := new(request.ChatHistoryMessagesCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
// Set session ID from URL parameter
req.SessionID = sessionID
authHeader := c.Get("Authorization")
dataResult, err := _i.chatHistoryService.CreateMessage(authHeader, *req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Chat history message successfully created"},
Data: dataResult,
})
}
// Update Message
// @Summary Update chat history message
// @Description API for update chat history message
// @Tags Chat History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param messageId path int true "Message ID"
// @Param payload body request.ChatHistoryMessagesUpdateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /chat-history/messages/{messageId} [put]
func (_i *chatHistoryController) UpdateMessage(c *fiber.Ctx) error {
messageId, err := strconv.ParseUint(c.Params("messageId"), 10, 0)
if err != nil {
return err
}
req := new(request.ChatHistoryMessagesUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
authHeader := c.Get("Authorization")
if err := _i.chatHistoryService.UpdateMessage(authHeader, uint(messageId), *req); err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Chat history message successfully updated"},
})
}
// Delete Message
// @Summary Delete chat history message
// @Description API for delete chat history message
// @Tags Chat History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param messageId path int true "Message ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /chat-history/messages/{messageId} [delete]
func (_i *chatHistoryController) DeleteMessage(c *fiber.Ctx) error {
messageId, err := strconv.ParseUint(c.Params("messageId"), 10, 0)
if err != nil {
return err
}
authHeader := c.Get("Authorization")
if err := _i.chatHistoryService.DeleteMessage(authHeader, uint(messageId)); err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Chat history message successfully deleted"},
})
}
// Save Chat History
// @Summary Save chat history (sessions and messages)
// @Description API for saving complete chat history including sessions and messages
// @Tags Chat History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.ChatHistorySessionsCreateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /chat-history/save [post]
func (_i *chatHistoryController) SaveChatHistory(c *fiber.Ctx) error {
req := new(request.ChatHistorySessionsCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
authHeader := c.Get("Authorization")
dataResult, err := _i.chatHistoryService.SaveChatHistory(authHeader, *req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Chat history saved successfully"},
Data: dataResult,
})
}

View File

@ -1,77 +0,0 @@
package mapper
import (
"narasi-ahli-be/app/database/entity"
"narasi-ahli-be/app/module/chat_history/response"
)
// Chat History Sessions Mapper
func ChatHistorySessionsResponseMapper(entity *entity.ChatSessions) *response.ChatHistorySessionsResponse {
if entity == nil {
return nil
}
return &response.ChatHistorySessionsResponse{
ID: entity.ID,
SessionID: entity.SessionID,
UserID: entity.UserID,
AgentID: entity.AgentID,
Title: entity.Title,
MessageCount: entity.MessageCount,
Status: entity.Status,
CreatedAt: entity.CreatedAt,
UpdatedAt: entity.UpdatedAt,
}
}
// Chat History Messages Mapper
func ChatHistoryMessagesResponseMapper(entity *entity.ChatMessagesNew) *response.ChatHistoryMessagesResponse {
if entity == nil {
return nil
}
return &response.ChatHistoryMessagesResponse{
ID: entity.ID,
SessionID: entity.SessionID,
MessageType: entity.MessageType,
Content: entity.Content,
CreatedAt: entity.CreatedAt,
}
}
// Chat History Session with Messages Mapper
func ChatHistorySessionWithMessagesResponseMapper(session *entity.ChatSessions, messages []*entity.ChatMessagesNew) *response.ChatHistorySessionWithMessagesResponse {
if session == nil {
return nil
}
sessionResponse := ChatHistorySessionsResponseMapper(session)
var messagesResponse []response.ChatHistoryMessagesResponse
for _, message := range messages {
if message != nil {
messagesResponse = append(messagesResponse, *ChatHistoryMessagesResponseMapper(message))
}
}
return &response.ChatHistorySessionWithMessagesResponse{
Session: *sessionResponse,
Messages: messagesResponse,
}
}
// Chat History List Mapper
func ChatHistoryListResponseMapper(sessions []*entity.ChatSessions) *response.ChatHistoryListResponse {
var sessionsResponse []response.ChatHistorySessionsResponse
for _, session := range sessions {
if session != nil {
sessionsResponse = append(sessionsResponse, *ChatHistorySessionsResponseMapper(session))
}
}
return &response.ChatHistoryListResponse{
Sessions: sessionsResponse,
Total: len(sessionsResponse),
}
}

View File

@ -1,159 +0,0 @@
package repository
import (
"narasi-ahli-be/app/database"
"narasi-ahli-be/app/database/entity"
"narasi-ahli-be/app/module/chat_history/request"
"narasi-ahli-be/utils/paginator"
)
type chatHistoryRepository struct {
DB *database.Database
}
type ChatHistoryRepository interface {
// Chat Sessions
GetUserSessions(userId uint, req request.ChatHistorySessionsQueryRequest) (sessions []*entity.ChatSessions, paging paginator.Pagination, err error)
FindSessionByID(id uint) (session *entity.ChatSessions, err error)
FindSessionBySessionID(sessionID string) (session *entity.ChatSessions, err error)
FindSessionByUserAndSessionID(userID uint, sessionID string) (session *entity.ChatSessions, err error)
CreateSession(session *entity.ChatSessions) (result *entity.ChatSessions, err error)
UpdateSession(sessionID string, session *entity.ChatSessions) (err error)
DeleteSession(sessionID string) (err error)
IncrementMessageCount(sessionID string) (err error)
// Chat Messages
GetSessionMessages(sessionID string, req request.ChatHistoryMessagesQueryRequest) (messages []*entity.ChatMessagesNew, paging paginator.Pagination, err error)
CreateMessage(message *entity.ChatMessagesNew) (result *entity.ChatMessagesNew, err error)
UpdateMessage(messageID uint, message *entity.ChatMessagesNew) (err error)
DeleteMessage(messageID uint) (err error)
DeleteMessagesBySessionID(sessionID string) (err error)
GetLastMessage(sessionID string) (message *entity.ChatMessagesNew, err error)
}
func NewChatHistoryRepository(db *database.Database) ChatHistoryRepository {
return &chatHistoryRepository{
DB: db,
}
}
// Chat Sessions methods
func (_i *chatHistoryRepository) GetUserSessions(userId uint, req request.ChatHistorySessionsQueryRequest) (sessions []*entity.ChatSessions, paging paginator.Pagination, err error) {
query := _i.DB.DB.Where("user_id = ?", userId)
// Apply filters
if req.AgentID != nil {
query = query.Where("agent_id = ?", *req.AgentID)
}
if req.SessionID != nil {
query = query.Where("session_id = ?", *req.SessionID)
}
// Include user relationship
query = query.Preload("User")
// Order by updated_at desc (most recent first)
query = query.Order("updated_at DESC")
// Apply pagination
var count int64
query.Count(&count)
req.Pagination.Count = count
req.Pagination = paginator.Paging(req.Pagination)
err = query.Offset(req.Pagination.Offset).Limit(req.Pagination.Limit).Find(&sessions).Error
paging = *req.Pagination
return
}
func (_i *chatHistoryRepository) FindSessionByID(id uint) (session *entity.ChatSessions, err error) {
err = _i.DB.DB.Where("id = ?", id).Preload("User").First(&session).Error
return
}
func (_i *chatHistoryRepository) FindSessionBySessionID(sessionID string) (session *entity.ChatSessions, err error) {
err = _i.DB.DB.Where("session_id = ?", sessionID).Preload("User").First(&session).Error
return
}
func (_i *chatHistoryRepository) FindSessionByUserAndSessionID(userID uint, sessionID string) (session *entity.ChatSessions, err error) {
err = _i.DB.DB.Where("user_id = ? AND session_id = ?", userID, sessionID).Preload("User").First(&session).Error
return
}
func (_i *chatHistoryRepository) CreateSession(session *entity.ChatSessions) (result *entity.ChatSessions, err error) {
err = _i.DB.DB.Create(session).Error
if err != nil {
return nil, err
}
// Reload with relationships
err = _i.DB.DB.Preload("User").First(&result, session.ID).Error
return
}
func (_i *chatHistoryRepository) UpdateSession(sessionID string, session *entity.ChatSessions) (err error) {
err = _i.DB.DB.Where("session_id = ?", sessionID).Updates(session).Error
return
}
func (_i *chatHistoryRepository) DeleteSession(sessionID string) (err error) {
err = _i.DB.DB.Where("session_id = ?", sessionID).Delete(&entity.ChatSessions{}).Error
return
}
func (_i *chatHistoryRepository) IncrementMessageCount(sessionID string) (err error) {
err = _i.DB.DB.Exec("UPDATE chat_sessions SET message_count = message_count + 1 WHERE session_id = ?", sessionID).Error
return
}
// Chat Messages methods
func (_i *chatHistoryRepository) GetSessionMessages(sessionID string, req request.ChatHistoryMessagesQueryRequest) (messages []*entity.ChatMessagesNew, paging paginator.Pagination, err error) {
query := _i.DB.DB.Where("session_id = ?", sessionID)
// Order by created_at asc (oldest first for chat)
query = query.Order("created_at ASC")
// Apply pagination
var count int64
query.Count(&count)
req.Pagination.Count = count
req.Pagination = paginator.Paging(req.Pagination)
err = query.Offset(req.Pagination.Offset).Limit(req.Pagination.Limit).Find(&messages).Error
paging = *req.Pagination
return
}
func (_i *chatHistoryRepository) CreateMessage(message *entity.ChatMessagesNew) (result *entity.ChatMessagesNew, err error) {
err = _i.DB.DB.Create(message).Error
if err != nil {
return nil, err
}
// Reload
err = _i.DB.DB.First(&result, message.ID).Error
return
}
func (_i *chatHistoryRepository) UpdateMessage(messageID uint, message *entity.ChatMessagesNew) (err error) {
err = _i.DB.DB.Model(&entity.ChatMessagesNew{}).Where("id = ?", messageID).Updates(message).Error
return
}
func (_i *chatHistoryRepository) DeleteMessage(messageID uint) (err error) {
err = _i.DB.DB.Where("id = ?", messageID).Delete(&entity.ChatMessagesNew{}).Error
return
}
func (_i *chatHistoryRepository) DeleteMessagesBySessionID(sessionID string) (err error) {
err = _i.DB.DB.Where("session_id = ?", sessionID).Delete(&entity.ChatMessagesNew{}).Error
return
}
func (_i *chatHistoryRepository) GetLastMessage(sessionID string) (message *entity.ChatMessagesNew, err error) {
err = _i.DB.DB.Where("session_id = ?", sessionID).Order("created_at DESC").First(&message).Error
return
}

View File

@ -1,131 +0,0 @@
package request
import (
"narasi-ahli-be/app/database/entity"
"narasi-ahli-be/utils/paginator"
)
// Chat History Sessions Request DTOs
type ChatHistorySessionsQueryRequest struct {
UserID *uint `json:"userId"`
AgentID *string `json:"agentId"`
SessionID *string `json:"sessionId"`
Pagination *paginator.Pagination `json:"pagination"`
}
type ChatHistorySessionsCreateRequest struct {
UserID uint `json:"userId" validate:"required"`
AgentID string `json:"agentId" validate:"required"`
SessionID string `json:"sessionId" validate:"required"`
Title *string `json:"title"`
Messages []ChatMessageRequest `json:"messages"`
}
type ChatMessageRequest struct {
Type string `json:"type" validate:"required,oneof=user assistant"`
Content string `json:"content" validate:"required"`
}
func (req ChatHistorySessionsCreateRequest) ToEntity() *entity.ChatSessions {
title := "Chat Session"
if req.Title != nil {
title = *req.Title
}
return &entity.ChatSessions{
SessionID: req.SessionID,
UserID: req.UserID,
AgentID: req.AgentID,
Title: title,
MessageCount: len(req.Messages),
Status: "active",
}
}
type ChatHistorySessionsUpdateRequest struct {
Title *string `json:"title"`
Status *string `json:"status" validate:"omitempty,oneof=active archived deleted"`
}
func (req ChatHistorySessionsUpdateRequest) ToEntity() *entity.ChatSessions {
entity := &entity.ChatSessions{}
if req.Title != nil {
entity.Title = *req.Title
}
if req.Status != nil {
entity.Status = *req.Status
}
return entity
}
// Chat History Messages Request DTOs
type ChatHistoryMessagesQueryRequest struct {
SessionID string `json:"sessionId" validate:"required"`
Pagination *paginator.Pagination `json:"pagination"`
}
type ChatHistoryMessagesCreateRequest struct {
SessionID string `json:"sessionId" validate:"required"`
MessageType string `json:"messageType" validate:"required,oneof=user assistant"`
Content string `json:"content" validate:"required"`
}
func (req ChatHistoryMessagesCreateRequest) ToEntity() *entity.ChatMessagesNew {
return &entity.ChatMessagesNew{
SessionID: req.SessionID,
MessageType: req.MessageType,
Content: req.Content,
}
}
type ChatHistoryMessagesUpdateRequest struct {
Content string `json:"content" validate:"required"`
}
func (req ChatHistoryMessagesUpdateRequest) ToEntity() *entity.ChatMessagesNew {
return &entity.ChatMessagesNew{
Content: req.Content,
}
}
// Context Request DTOs for query parameters
type ChatHistorySessionsQueryRequestContext struct {
UserID string `json:"userId"`
AgentID string `json:"agentId"`
SessionID string `json:"sessionId"`
}
func (req ChatHistorySessionsQueryRequestContext) ToParamRequest() ChatHistorySessionsQueryRequest {
var request ChatHistorySessionsQueryRequest
if userIDStr := req.UserID; userIDStr != "" {
// Parse user ID from string to uint
// This will be handled in the controller
}
if agentID := req.AgentID; agentID != "" {
request.AgentID = &agentID
}
if sessionID := req.SessionID; sessionID != "" {
request.SessionID = &sessionID
}
return request
}
type ChatHistoryMessagesQueryRequestContext struct {
SessionID string `json:"sessionId"`
}
func (req ChatHistoryMessagesQueryRequestContext) ToParamRequest() ChatHistoryMessagesQueryRequest {
var request ChatHistoryMessagesQueryRequest
if sessionID := req.SessionID; sessionID != "" {
request.SessionID = sessionID
}
return request
}

View File

@ -1,39 +0,0 @@
package response
import (
"time"
)
// Chat History Sessions Response DTOs
type ChatHistorySessionsResponse struct {
ID uint `json:"id"`
SessionID string `json:"sessionId"`
UserID uint `json:"userId"`
AgentID string `json:"agentId"`
Title string `json:"title"`
MessageCount int `json:"messageCount"`
Status string `json:"status"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// Chat History Messages Response DTOs
type ChatHistoryMessagesResponse struct {
ID uint `json:"id"`
SessionID string `json:"sessionId"`
MessageType string `json:"messageType"`
Content string `json:"content"`
CreatedAt time.Time `json:"createdAt"`
}
// Combined Response for Session with Messages
type ChatHistorySessionWithMessagesResponse struct {
Session ChatHistorySessionsResponse `json:"session"`
Messages []ChatHistoryMessagesResponse `json:"messages"`
}
// Chat History List Response
type ChatHistoryListResponse struct {
Sessions []ChatHistorySessionsResponse `json:"sessions"`
Total int `json:"total"`
}

View File

@ -1,317 +0,0 @@
package service
import (
"errors"
"narasi-ahli-be/app/database/entity"
"narasi-ahli-be/app/module/chat_history/mapper"
"narasi-ahli-be/app/module/chat_history/repository"
"narasi-ahli-be/app/module/chat_history/request"
"narasi-ahli-be/app/module/chat_history/response"
usersRepository "narasi-ahli-be/app/module/users/repository"
"narasi-ahli-be/utils/paginator"
utilSvc "narasi-ahli-be/utils/service"
"github.com/rs/zerolog"
)
type chatHistoryService struct {
Repo repository.ChatHistoryRepository
UsersRepo usersRepository.UsersRepository
Log zerolog.Logger
}
type ChatHistoryService interface {
// Sessions
GetUserSessions(authToken string, req request.ChatHistorySessionsQueryRequest) (sessions []*response.ChatHistorySessionsResponse, paging paginator.Pagination, err error)
GetSession(authToken string, sessionID string) (session *response.ChatHistorySessionWithMessagesResponse, err error)
CreateSession(authToken string, req request.ChatHistorySessionsCreateRequest) (session *response.ChatHistorySessionsResponse, err error)
UpdateSession(authToken string, sessionID string, req request.ChatHistorySessionsUpdateRequest) (err error)
DeleteSession(authToken string, sessionID string) error
// Messages
GetSessionMessages(authToken string, sessionID string, req request.ChatHistoryMessagesQueryRequest) (messages []*response.ChatHistoryMessagesResponse, paging paginator.Pagination, err error)
CreateMessage(authToken string, req request.ChatHistoryMessagesCreateRequest) (message *response.ChatHistoryMessagesResponse, err error)
UpdateMessage(authToken string, messageID uint, req request.ChatHistoryMessagesUpdateRequest) (err error)
DeleteMessage(authToken string, messageID uint) error
// Combined operations
SaveChatHistory(authToken string, req request.ChatHistorySessionsCreateRequest) (session *response.ChatHistorySessionsResponse, err error)
}
func NewChatHistoryService(repo repository.ChatHistoryRepository, usersRepo usersRepository.UsersRepository, log zerolog.Logger) ChatHistoryService {
return &chatHistoryService{
Repo: repo,
UsersRepo: usersRepo,
Log: log,
}
}
// Sessions methods
func (_i *chatHistoryService) GetUserSessions(authToken string, req request.ChatHistorySessionsQueryRequest) (sessions []*response.ChatHistorySessionsResponse, paging paginator.Pagination, err error) {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
// Set user ID from auth token
req.UserID = &userInfo.ID
results, paging, err := _i.Repo.GetUserSessions(userInfo.ID, req)
if err != nil {
return
}
for _, result := range results {
sessions = append(sessions, mapper.ChatHistorySessionsResponseMapper(result))
}
return
}
func (_i *chatHistoryService) GetSession(authToken string, sessionID string) (session *response.ChatHistorySessionWithMessagesResponse, err error) {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
// Verify session belongs to user
sessionEntity, err := _i.Repo.FindSessionByUserAndSessionID(userInfo.ID, sessionID)
if err != nil {
return nil, err
}
// Get messages for this session
messagesReq := request.ChatHistoryMessagesQueryRequest{
SessionID: sessionID,
Pagination: &paginator.Pagination{
Limit: 1000, // Get all messages for now
},
}
messages, _, err := _i.Repo.GetSessionMessages(sessionID, messagesReq)
if err != nil {
return nil, err
}
return mapper.ChatHistorySessionWithMessagesResponseMapper(sessionEntity, messages), nil
}
func (_i *chatHistoryService) CreateSession(authToken string, req request.ChatHistorySessionsCreateRequest) (session *response.ChatHistorySessionsResponse, err error) {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
// Set user ID from auth token
req.UserID = userInfo.ID
entity := req.ToEntity()
result, err := _i.Repo.CreateSession(entity)
if err != nil {
return nil, err
}
return mapper.ChatHistorySessionsResponseMapper(result), nil
}
func (_i *chatHistoryService) UpdateSession(authToken string, sessionID string, req request.ChatHistorySessionsUpdateRequest) (err error) {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
_i.Log.Info().Interface("data", req).Msg("Updating chat history session")
// Check if session exists and belongs to user
existing, err := _i.Repo.FindSessionByUserAndSessionID(userInfo.ID, sessionID)
if err != nil {
return err
}
if existing == nil {
return errors.New("chat history session not found")
}
entity := req.ToEntity()
return _i.Repo.UpdateSession(sessionID, entity)
}
func (_i *chatHistoryService) DeleteSession(authToken string, sessionID string) error {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
_i.Log.Info().Uint("userId", userInfo.ID).Str("sessionId", sessionID).Msg("Deleting chat history session")
// Check if session exists and belongs to user
existing, err := _i.Repo.FindSessionByUserAndSessionID(userInfo.ID, sessionID)
if err != nil {
return err
}
if existing == nil {
return errors.New("chat history session not found")
}
return _i.Repo.DeleteSession(sessionID)
}
// Messages methods
func (_i *chatHistoryService) GetSessionMessages(authToken string, sessionID string, req request.ChatHistoryMessagesQueryRequest) (messages []*response.ChatHistoryMessagesResponse, paging paginator.Pagination, err error) {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
// Verify session belongs to user
_, err = _i.Repo.FindSessionByUserAndSessionID(userInfo.ID, sessionID)
if err != nil {
return nil, paginator.Pagination{}, err
}
results, paging, err := _i.Repo.GetSessionMessages(sessionID, req)
if err != nil {
return
}
for _, result := range results {
messages = append(messages, mapper.ChatHistoryMessagesResponseMapper(result))
}
return
}
func (_i *chatHistoryService) CreateMessage(authToken string, req request.ChatHistoryMessagesCreateRequest) (message *response.ChatHistoryMessagesResponse, err error) {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
_i.Log.Info().Interface("data", req).Msg("Creating chat history message")
// Verify session belongs to user
_, err = _i.Repo.FindSessionByUserAndSessionID(userInfo.ID, req.SessionID)
if err != nil {
return nil, err
}
entity := req.ToEntity()
result, err := _i.Repo.CreateMessage(entity)
if err != nil {
return nil, err
}
// Increment message count in session
err = _i.Repo.IncrementMessageCount(req.SessionID)
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to increment message count")
}
return mapper.ChatHistoryMessagesResponseMapper(result), nil
}
func (_i *chatHistoryService) UpdateMessage(authToken string, messageID uint, req request.ChatHistoryMessagesUpdateRequest) (err error) {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
// Get message to verify it belongs to user's session
messages, _, err := _i.Repo.GetSessionMessages("", request.ChatHistoryMessagesQueryRequest{})
if err != nil {
return err
}
// Find the specific message
var targetMessage *entity.ChatMessagesNew
for _, msg := range messages {
if msg.ID == messageID {
targetMessage = msg
break
}
}
if targetMessage == nil {
return errors.New("message not found")
}
// Verify session belongs to user
_, err = _i.Repo.FindSessionByUserAndSessionID(userInfo.ID, targetMessage.SessionID)
if err != nil {
return err
}
entity := req.ToEntity()
return _i.Repo.UpdateMessage(messageID, entity)
}
func (_i *chatHistoryService) DeleteMessage(authToken string, messageID uint) error {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
// Get message to verify it belongs to user's session
messages, _, err := _i.Repo.GetSessionMessages("", request.ChatHistoryMessagesQueryRequest{})
if err != nil {
return err
}
// Find the specific message
var targetMessage *entity.ChatMessagesNew
for _, msg := range messages {
if msg.ID == messageID {
targetMessage = msg
break
}
}
if targetMessage == nil {
return errors.New("message not found")
}
// Verify session belongs to user
_, err = _i.Repo.FindSessionByUserAndSessionID(userInfo.ID, targetMessage.SessionID)
if err != nil {
return err
}
return _i.Repo.DeleteMessage(messageID)
}
// Combined operations
func (_i *chatHistoryService) SaveChatHistory(authToken string, req request.ChatHistorySessionsCreateRequest) (session *response.ChatHistorySessionsResponse, err error) {
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
_i.Log.Info().Interface("data", req).Msg("Saving chat history")
// Set user ID from auth token
req.UserID = userInfo.ID
// Check if session already exists
existingSession, err := _i.Repo.FindSessionBySessionID(req.SessionID)
if err == nil && existingSession != nil {
// Update existing session
updateReq := request.ChatHistorySessionsUpdateRequest{
Title: req.Title,
}
err = _i.UpdateSession(authToken, req.SessionID, updateReq)
if err != nil {
return nil, err
}
// Delete existing messages
err = _i.Repo.DeleteMessagesBySessionID(req.SessionID)
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to delete existing messages")
}
} else {
// Create new session
entity := req.ToEntity()
_, err = _i.Repo.CreateSession(entity)
if err != nil {
return nil, err
}
}
// Save messages if provided
if len(req.Messages) > 0 {
for _, msgReq := range req.Messages {
messageEntity := &entity.ChatMessagesNew{
SessionID: req.SessionID,
MessageType: msgReq.Type,
Content: msgReq.Content,
}
_, err = _i.Repo.CreateMessage(messageEntity)
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to create message")
}
}
// Update message count
err = _i.Repo.UpdateSession(req.SessionID, &entity.ChatSessions{
MessageCount: len(req.Messages),
})
if err != nil {
_i.Log.Error().Err(err).Msg("Failed to update message count")
}
}
// Return the session
result, err := _i.Repo.FindSessionBySessionID(req.SessionID)
if err != nil {
return nil, err
}
return mapper.ChatHistorySessionsResponseMapper(result), nil
}

View File

@ -1,7 +1,7 @@
package controller
import (
"narasi-ahli-be/app/module/custom_static_pages/request"
"narasi-ahli-be/app/module/custom_static_pages/request"
"narasi-ahli-be/app/module/custom_static_pages/service"
"narasi-ahli-be/utils/paginator"
"strconv"
@ -39,7 +39,6 @@ func NewCustomStaticPagesController(customStaticPagesService service.CustomStati
// @Description API for getting all CustomStaticPages
// @Tags CustomStaticPages
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.CustomStaticPagesQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -63,7 +62,7 @@ func (_i *customStaticPagesController) All(c *fiber.Ctx) error {
req.Pagination = paginate
// Get from context
customStaticPagesData, paging, err := _i.customStaticPagesService.All(req)
customStaticPagesData, paging, err := _i.customStaticPagesService.All(req)
if err != nil {
return err
}
@ -81,7 +80,6 @@ func (_i *customStaticPagesController) All(c *fiber.Ctx) error {
// @Description API for getting one CustomStaticPages
// @Tags CustomStaticPages
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "CustomStaticPages ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -95,7 +93,7 @@ func (_i *customStaticPagesController) Show(c *fiber.Ctx) error {
}
// Get from context
customStaticPagesData, err := _i.customStaticPagesService.Show(uint(id))
customStaticPagesData, err := _i.customStaticPagesService.Show(uint(id))
if err != nil {
return err
}
@ -112,7 +110,6 @@ func (_i *customStaticPagesController) Show(c *fiber.Ctx) error {
// @Description API for getting one CustomStaticPages
// @Tags CustomStaticPages
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param slug path string true "CustomStaticPages Slug"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -123,7 +120,7 @@ func (_i *customStaticPagesController) ShowBySlug(c *fiber.Ctx) error {
slug := c.Params("slug")
// Get from context
customStaticPagesData, err := _i.customStaticPagesService.ShowBySlug(slug)
customStaticPagesData, err := _i.customStaticPagesService.ShowBySlug(slug)
if err != nil {
return err
}
@ -140,7 +137,6 @@ func (_i *customStaticPagesController) ShowBySlug(c *fiber.Ctx) error {
// @Description API for create CustomStaticPages
// @Tags CustomStaticPages
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.CustomStaticPagesCreateRequest true "Required payload"
// @Success 200 {object} response.Response
@ -155,7 +151,7 @@ func (_i *customStaticPagesController) Save(c *fiber.Ctx) error {
}
// Get from context
authToken := c.Get("Authorization")
authToken := c.Get("Authorization")
dataResult, err := _i.customStaticPagesService.Save(*req, authToken)
if err != nil {
return err
@ -173,7 +169,6 @@ func (_i *customStaticPagesController) Save(c *fiber.Ctx) error {
// @Description API for update CustomStaticPages
// @Tags CustomStaticPages
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.CustomStaticPagesUpdateRequest true "Required payload"
// @Param id path int true "CustomStaticPages ID"
@ -194,7 +189,7 @@ func (_i *customStaticPagesController) Update(c *fiber.Ctx) error {
}
// Get from context
err = _i.customStaticPagesService.Update(uint(id), *req)
err = _i.customStaticPagesService.Update(uint(id), *req)
if err != nil {
return err
}
@ -210,7 +205,6 @@ func (_i *customStaticPagesController) Update(c *fiber.Ctx) error {
// @Description API for delete CustomStaticPages
// @Tags CustomStaticPages
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "CustomStaticPages ID"
// @Success 200 {object} response.Response
@ -225,7 +219,7 @@ func (_i *customStaticPagesController) Delete(c *fiber.Ctx) error {
}
// Get from context
err = _i.customStaticPagesService.Delete(uint(id))
err = _i.customStaticPagesService.Delete(uint(id))
if err != nil {
return err
}

View File

@ -35,7 +35,6 @@ func NewEducationHistoryController(educationHistoryService service.EducationHist
// @Description API for getting all Education History for authenticated user
// @Tags Education History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.EducationHistoryQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -78,7 +77,6 @@ func (_i *educationHistoryController) All(c *fiber.Ctx) error {
// @Description API for getting one Education History
// @Tags Education History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "Education History ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -110,7 +108,6 @@ func (_i *educationHistoryController) Show(c *fiber.Ctx) error {
// @Description API for create Education History
// @Tags Education History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.EducationHistoryCreateRequest true "Required payload"
@ -144,7 +141,6 @@ func (_i *educationHistoryController) Save(c *fiber.Ctx) error {
// @Description API for update Education History
// @Tags Education History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Education History ID"
// @Param payload body request.EducationHistoryUpdateRequest true "Required payload"
@ -182,7 +178,6 @@ func (_i *educationHistoryController) Update(c *fiber.Ctx) error {
// @Description API for delete Education History
// @Tags Education History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Education History ID"
// @Success 200 {object} response.Response
@ -214,7 +209,6 @@ func (_i *educationHistoryController) Delete(c *fiber.Ctx) error {
// @Description API for upload certificate image for Education History
// @Tags Education History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Education History ID"
// @Param certificate formData file true "Certificate image file"

View File

@ -38,7 +38,6 @@ func NewFeedbacksController(feedbacksService service.FeedbacksService, log zerol
// @Description API for getting all Feedbacks
// @Tags Feedbacks
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.FeedbacksQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -79,7 +78,6 @@ func (_i *feedbacksController) All(c *fiber.Ctx) error {
// @Description API for getting one Feedbacks
// @Tags Feedbacks
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "Feedbacks ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -109,7 +107,6 @@ func (_i *feedbacksController) Show(c *fiber.Ctx) error {
// @Description API for create Feedbacks
// @Tags Feedbacks
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.FeedbacksCreateRequest true "Required payload"
@ -143,7 +140,6 @@ func (_i *feedbacksController) Save(c *fiber.Ctx) error {
// @Description API for update Feedbacks
// @Tags Feedbacks
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.FeedbacksUpdateRequest true "Required payload"
// @Param id path int true "Feedbacks ID"
@ -179,7 +175,6 @@ func (_i *feedbacksController) Update(c *fiber.Ctx) error {
// @Description API for delete Feedbacks
// @Tags Feedbacks
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Feedbacks ID"
// @Success 200 {object} response.Response
@ -209,7 +204,6 @@ func (_i *feedbacksController) Delete(c *fiber.Ctx) error {
// @Description API for FeedbackMonthlyStats of Feedbacks
// @Tags Feedbacks
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param year query int false "year"
// @Success 200 {object} response.Response

View File

@ -37,7 +37,6 @@ func NewMagazinesController(magazinesService service.MagazinesService) Magazines
// @Description API for getting all Magazines
// @Tags Magazines
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.MagazinesQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -78,7 +77,6 @@ func (_i *magazinesController) All(c *fiber.Ctx) error {
// @Description API for getting one Magazines
// @Tags Magazines
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "Magazines ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -107,7 +105,6 @@ func (_i *magazinesController) Show(c *fiber.Ctx) error {
// @Description API for create Magazines
// @Tags Magazines
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.MagazinesCreateRequest true "Required payload"
@ -141,7 +138,6 @@ func (_i *magazinesController) Save(c *fiber.Ctx) error {
// @Description API for update Magazines
// @Tags Magazines
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Magazines ID"
// @Param payload body request.MagazinesUpdateRequest true "Required payload"
@ -177,7 +173,6 @@ func (_i *magazinesController) Update(c *fiber.Ctx) error {
// @Tags Magazines
// @Security Bearer
// @Produce json
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Magazine ID"
// @Param files formData file true "Upload thumbnail"
@ -203,7 +198,6 @@ func (_i *magazinesController) SaveThumbnail(c *fiber.Ctx) error {
// @Description API for View Thumbnail of Magazines
// @Tags Magazines
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param thumbnailName path string true "Magazines Thumbnail Name"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -219,7 +213,6 @@ func (_i *magazinesController) Viewer(c *fiber.Ctx) error {
// @Description API for delete Magazines
// @Tags Magazines
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Magazines ID"
// @Success 200 {object} response.Response

View File

@ -34,7 +34,6 @@ func NewResearchJournalsController(researchJournalsService service.ResearchJourn
// @Description API for getting all Research Journals for authenticated user
// @Tags Research Journals
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.ResearchJournalsQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -83,7 +82,6 @@ func (_i *researchJournalsController) All(c *fiber.Ctx) error {
// @Description API for getting one Research Journal
// @Tags Research Journals
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "Research Journal ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -115,7 +113,6 @@ func (_i *researchJournalsController) Show(c *fiber.Ctx) error {
// @Description API for create Research Journal
// @Tags Research Journals
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.ResearchJournalsCreateRequest true "Required payload"
@ -149,7 +146,6 @@ func (_i *researchJournalsController) Save(c *fiber.Ctx) error {
// @Description API for update Research Journal
// @Tags Research Journals
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Research Journal ID"
// @Param payload body request.ResearchJournalsUpdateRequest true "Required payload"
@ -187,7 +183,6 @@ func (_i *researchJournalsController) Update(c *fiber.Ctx) error {
// @Description API for delete Research Journal
// @Tags Research Journals
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Research Journal ID"
// @Success 200 {object} response.Response

View File

@ -37,7 +37,6 @@ func NewSubscriptionController(subscriptionService service.SubscriptionService,
// @Description API for getting all Subscription
// @Tags Subscription
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.SubscriptionQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -75,7 +74,6 @@ func (_i *subscriptionController) All(c *fiber.Ctx) error {
// @Description API for getting one Subscription
// @Tags Subscription
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "Subscription ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -105,7 +103,6 @@ func (_i *subscriptionController) Show(c *fiber.Ctx) error {
// @Description API for create Subscription
// @Tags Subscription
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.SubscriptionCreateRequest true "Required payload"
// @Success 200 {object} response.Response
@ -136,7 +133,6 @@ func (_i *subscriptionController) Save(c *fiber.Ctx) error {
// @Description API for update Subscription
// @Tags Subscription
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.SubscriptionUpdateRequest true "Required payload"
// @Param id path int true "Subscription ID"
@ -172,7 +168,6 @@ func (_i *subscriptionController) Update(c *fiber.Ctx) error {
// @Description API for delete Subscription
// @Tags Subscription
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Subscription ID"
// @Success 200 {object} response.Response

View File

@ -47,7 +47,6 @@ func NewUsersController(usersService service.UsersService) UsersController {
// @Description API for getting all Users
// @Tags Users
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.UsersQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -96,7 +95,6 @@ func (_i *usersController) All(c *fiber.Ctx) error {
// @Description API for getting one Users
// @Tags Users
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "Users ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -126,7 +124,6 @@ func (_i *usersController) Show(c *fiber.Ctx) error {
// @Description API for getting one Users
// @Tags Users
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param username path string true "Username"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -153,7 +150,6 @@ func (_i *usersController) ShowByUsername(c *fiber.Ctx) error {
// @Description API for ShowUserInfo
// @Tags Users
// @Security Bearer
// @Param X-Client-Key header string false "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
@ -180,7 +176,6 @@ func (_i *usersController) ShowInfo(c *fiber.Ctx) error {
// @Description API for create Users
// @Tags Users
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.UsersCreateRequest true "Required payload"
@ -214,7 +209,6 @@ func (_i *usersController) Save(c *fiber.Ctx) error {
// @Description API for update Users
// @Tags Users
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Users ID"
// @Param payload body request.UsersUpdateRequest true "Required payload"
@ -318,7 +312,6 @@ func (_i *usersController) ParetoLogin(c *fiber.Ctx) error {
// @Description API for delete Users
// @Tags Users
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Users ID"
// @Success 200 {object} response.Response
@ -348,7 +341,6 @@ func (_i *usersController) Delete(c *fiber.Ctx) error {
// @Description API for SavePassword Users
// @Tags Users
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.UserSavePassword true "Required payload"
@ -410,7 +402,6 @@ func (_i *usersController) ResetPassword(c *fiber.Ctx) error {
// @Description API for ForgotPassword Users
// @Tags Users
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.UserForgotPassword true "Required payload"
// @Success 200 {object} response.Response
@ -498,7 +489,6 @@ func (_i *usersController) OtpValidation(c *fiber.Ctx) error {
// @Description API for Email Validation Users
// @Tags Users
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.UserEmailValidationRequest true "Required payload"
// @Success 200 {object} response.Response
@ -528,7 +518,6 @@ func (_i *usersController) EmailValidation(c *fiber.Ctx) error {
// @Description API for Setup Email Users
// @Tags Users
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param payload body request.UserEmailValidationRequest true "Required payload"
// @Success 200 {object} response.Response

View File

@ -34,7 +34,6 @@ func NewWorkHistoryController(workHistoryService service.WorkHistoryService) Wor
// @Description API for getting all Work History for authenticated user
// @Tags Work History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.WorkHistoryQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -76,7 +75,6 @@ func (_i *workHistoryController) All(c *fiber.Ctx) error {
// @Description API for getting one Work History
// @Tags Work History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "Work History ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -108,7 +106,6 @@ func (_i *workHistoryController) Show(c *fiber.Ctx) error {
// @Description API for create Work History
// @Tags Work History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.WorkHistoryCreateRequest true "Required payload"
@ -142,7 +139,6 @@ func (_i *workHistoryController) Save(c *fiber.Ctx) error {
// @Description API for update Work History
// @Tags Work History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Work History ID"
// @Param payload body request.WorkHistoryUpdateRequest true "Required payload"
@ -180,7 +176,6 @@ func (_i *workHistoryController) Update(c *fiber.Ctx) error {
// @Description API for delete Work History
// @Tags Work History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param id path int true "Work History ID"
// @Success 200 {object} response.Response

View File

@ -10,7 +10,6 @@ import (
"narasi-ahli-be/app/module/article_comments"
"narasi-ahli-be/app/module/article_files"
"narasi-ahli-be/app/module/articles"
"narasi-ahli-be/app/module/chat_history"
"narasi-ahli-be/app/module/cities"
"narasi-ahli-be/app/module/custom_static_pages"
"narasi-ahli-be/app/module/districts"
@ -48,7 +47,6 @@ type Router struct {
ArticleCommentsRouter *article_comments.ArticleCommentsRouter
ArticleApprovalsRouter *article_approvals.ArticleApprovalsRouter
ArticlesRouter *articles.ArticlesRouter
ChatHistoryRouter *chat_history.ChatHistoryRouter
CitiesRouter *cities.CitiesRouter
CustomStaticPagesRouter *custom_static_pages.CustomStaticPagesRouter
DistrictsRouter *districts.DistrictsRouter
@ -81,7 +79,6 @@ func NewRouter(
articleCommentsRouter *article_comments.ArticleCommentsRouter,
articleApprovalsRouter *article_approvals.ArticleApprovalsRouter,
articlesRouter *articles.ArticlesRouter,
chatHistoryRouter *chat_history.ChatHistoryRouter,
citiesRouter *cities.CitiesRouter,
customStaticPagesRouter *custom_static_pages.CustomStaticPagesRouter,
districtsRouter *districts.DistrictsRouter,
@ -112,7 +109,6 @@ func NewRouter(
ArticleCommentsRouter: articleCommentsRouter,
ArticleApprovalsRouter: articleApprovalsRouter,
ArticlesRouter: articlesRouter,
ChatHistoryRouter: chatHistoryRouter,
CitiesRouter: citiesRouter,
CustomStaticPagesRouter: customStaticPagesRouter,
DistrictsRouter: districtsRouter,
@ -153,7 +149,6 @@ func (r *Router) Register() {
r.ArticleApprovalsRouter.RegisterArticleApprovalsRoutes()
r.ArticlesRouter.RegisterArticlesRoutes()
r.ArticleCommentsRouter.RegisterArticleCommentsRoutes()
r.ChatHistoryRouter.RegisterChatHistoryRoutes()
r.CitiesRouter.RegisterCitiesRoutes()
r.CustomStaticPagesRouter.RegisterCustomStaticPagesRoutes()
r.DistrictsRouter.RegisterDistrictsRoutes()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,6 @@ import (
"narasi-ahli-be/app/module/article_comments"
"narasi-ahli-be/app/module/article_files"
"narasi-ahli-be/app/module/articles"
"narasi-ahli-be/app/module/chat_history"
"narasi-ahli-be/app/module/cities"
"narasi-ahli-be/app/module/custom_static_pages"
"narasi-ahli-be/app/module/districts"
@ -74,7 +73,6 @@ func main() {
article_approvals.NewArticleApprovalsModule,
articles.NewArticlesModule,
article_comments.NewArticleCommentsModule,
chat_history.NewChatHistoryModule,
cities.NewCitiesModule,
custom_static_pages.NewCustomStaticPagesModule,
districts.NewDistrictsModule,

View File

@ -120,7 +120,6 @@ func NewEducationHistoryController(educationHistoryService service.EducationHist
// @Description API for getting all Education History for authenticated user
// @Tags Education History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param req query request.EducationHistoryQueryRequest false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
@ -173,7 +172,6 @@ func (_i *educationHistoryController) All(c *fiber.Ctx) error {
// @Description API for getting one Education History
// @Tags Education History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param id path int true "Education History ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -214,7 +212,6 @@ func (_i *educationHistoryController) Show(c *fiber.Ctx) error {
// @Description API for create Education History
// @Tags Education History
// @Security Bearer
// @Param X-Client-Key header string false "Insert the X-Client-Key"
// @Param X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.EducationHistoryCreateRequest true "Required payload"

View File

@ -1,38 +0,0 @@
package main
import (
"narasi-ahli-be/app/database"
"narasi-ahli-be/app/database/entity"
"narasi-ahli-be/migrations"
"github.com/rs/zerolog"
"go.uber.org/fx"
)
func main() {
fx.New(
fx.Provide(database.NewDatabase),
fx.Provide(func() zerolog.Logger {
return zerolog.Nop()
}),
fx.Invoke(func(db *database.Database) {
// Run migration
err := migrations.CreateChatHistoryTables(db)
if err != nil {
panic(err)
}
// Also auto-migrate existing entities
err = db.DB.AutoMigrate(
&entity.AIChatSessions{},
&entity.AIChatMessages{},
&entity.AIChatLogs{},
)
if err != nil {
panic(err)
}
println("Migration completed successfully!")
}),
).Run()
}