318 lines
9.9 KiB
Go
318 lines
9.9 KiB
Go
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
|
|
}
|