247 lines
8.2 KiB
Go
247 lines
8.2 KiB
Go
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"
|
|
"narasi-ahli-be/app/module/ai_chat/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 aiChatService struct {
|
|
Repo repository.AIChatRepository
|
|
UsersRepo usersRepository.UsersRepository
|
|
Log zerolog.Logger
|
|
}
|
|
|
|
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)
|
|
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
|
|
|
|
// 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
|
|
|
|
// Logs
|
|
GetUserLogs(authToken string, req request.AIChatLogsQueryRequest) (logs []*response.AIChatLogsResponse, paging paginator.Pagination, err error)
|
|
GetLog(authToken string, logId uint) (log *response.AIChatLogsResponse, err error)
|
|
}
|
|
|
|
func NewAIChatService(repo repository.AIChatRepository, usersRepo usersRepository.UsersRepository, log zerolog.Logger) AIChatService {
|
|
return &aiChatService{
|
|
Repo: repo,
|
|
UsersRepo: usersRepo,
|
|
Log: log,
|
|
}
|
|
}
|
|
|
|
// Sessions methods
|
|
func (_i *aiChatService) GetUserSessions(authToken string, req request.AIChatSessionsQueryRequest) (sessions []*response.AIChatSessionsResponse, paging paginator.Pagination, err error) {
|
|
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
|
|
|
results, paging, err := _i.Repo.GetUserSessions(userInfo.ID, req)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
for _, result := range results {
|
|
sessions = append(sessions, mapper.AIChatSessionsResponseMapper(result))
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (_i *aiChatService) GetSession(authToken string, sessionId uint) (session *response.AIChatSessionsResponse, err error) {
|
|
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
|
|
|
result, err := _i.Repo.FindSessionByUserAndId(userInfo.ID, sessionId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return mapper.AIChatSessionsResponseMapper(result), nil
|
|
}
|
|
|
|
func (_i *aiChatService) CreateSession(authToken string, req request.AIChatSessionsCreateRequest) (session *response.AIChatSessionsResponse, err error) {
|
|
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
|
|
|
entity := req.ToEntity()
|
|
entity.UserID = userInfo.ID
|
|
|
|
// Generate unique AI session ID
|
|
entity.AISessionID = fmt.Sprintf("ai_session_%d_%d", userInfo.ID, entity.ID)
|
|
|
|
result, err := _i.Repo.CreateSession(entity)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return mapper.AIChatSessionsResponseMapper(result), nil
|
|
}
|
|
|
|
func (_i *aiChatService) UpdateSession(authToken string, sessionId 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)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if existing == nil {
|
|
return errors.New("AI chat session not found")
|
|
}
|
|
|
|
entity := req.ToEntity()
|
|
return _i.Repo.UpdateSession(userInfo.ID, sessionId, entity)
|
|
}
|
|
|
|
func (_i *aiChatService) DeleteSession(authToken string, sessionId 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)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if existing == nil {
|
|
return errors.New("AI chat session not found")
|
|
}
|
|
|
|
return _i.Repo.DeleteSession(userInfo.ID, sessionId)
|
|
}
|
|
|
|
func (_i *aiChatService) ArchiveSession(authToken string, sessionId 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)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if existing == nil {
|
|
return errors.New("AI chat session not found")
|
|
}
|
|
|
|
// Update status to archived
|
|
existing.Status = "archived"
|
|
return _i.Repo.UpdateSession(userInfo.ID, sessionId, 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)
|
|
|
|
// Verify session belongs to user
|
|
_, err = _i.Repo.FindSessionByUserAndId(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.AIChatMessagesResponseMapper(result))
|
|
}
|
|
|
|
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")
|
|
|
|
// Verify session belongs to user
|
|
_, err = _i.Repo.FindSessionByUserAndId(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.AIChatMessagesResponseMapper(result), nil
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
return _i.Repo.DeleteMessage(messageId)
|
|
}
|
|
|
|
// Logs methods
|
|
func (_i *aiChatService) GetUserLogs(authToken string, req request.AIChatLogsQueryRequest) (logs []*response.AIChatLogsResponse, paging paginator.Pagination, err error) {
|
|
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
|
|
|
results, paging, err := _i.Repo.GetUserLogs(userInfo.ID, req)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
for _, result := range results {
|
|
logs = append(logs, mapper.AIChatLogsResponseMapper(result))
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (_i *aiChatService) GetLog(authToken string, logId uint) (log *response.AIChatLogsResponse, err error) {
|
|
userInfo := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
|
|
|
result, err := _i.Repo.FindLogByUserAndId(userInfo.ID, logId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return mapper.AIChatLogsResponseMapper(result), nil
|
|
}
|