narasiahli-be/app/module/chat/repository/chat.repository.go

273 lines
9.4 KiB
Go

package repository
import (
"narasi-ahli-be/app/database"
"narasi-ahli-be/app/database/entity"
"narasi-ahli-be/app/module/chat/request"
"narasi-ahli-be/utils/paginator"
)
type chatRepository struct {
DB *database.Database
}
type ChatRepository interface {
// Chat Session methods
GetAllChatSessions(userId uint, req request.ChatSessionQueryRequest) (chatSessions []*entity.ChatSessions, paging paginator.Pagination, err error)
FindChatSessionByID(id uint) (chatSession *entity.ChatSessions, err error)
FindChatSessionByUserAndID(userId uint, id uint) (chatSession *entity.ChatSessions, err error)
CreateChatSession(chatSession *entity.ChatSessions) (result *entity.ChatSessions, err error)
UpdateChatSession(id uint, chatSession *entity.ChatSessions) (err error)
DeleteChatSession(id uint) (err error)
// Chat Message methods
GetAllChatMessages(req request.ChatMessageQueryRequest) (chatMessages []*entity.ChatMessages, paging paginator.Pagination, err error)
FindChatMessageByID(id uint) (chatMessage *entity.ChatMessages, err error)
FindChatMessageByUserAndID(userId uint, id uint) (chatMessage *entity.ChatMessages, err error)
CreateChatMessage(chatMessage *entity.ChatMessages) (result *entity.ChatMessages, err error)
UpdateChatMessage(id uint, chatMessage *entity.ChatMessages) (err error)
DeleteChatMessage(id uint) (err error)
// Chat Participant methods
CreateChatParticipant(chatParticipant *entity.ChatParticipants) (result *entity.ChatParticipants, err error)
FindChatParticipantsBySessionID(chatSessionID uint) (participants []*entity.ChatParticipants, err error)
UpdateChatParticipant(id uint, chatParticipant *entity.ChatParticipants) (err error)
DeleteChatParticipant(id uint) (err error)
// Utility methods
FindPersonalChatSession(userId1 uint, userId2 uint) (chatSession *entity.ChatSessions, err error)
CheckUserInChatSession(userId uint, chatSessionID uint) (isParticipant bool, err error)
}
func NewChatRepository(db *database.Database) ChatRepository {
return &chatRepository{
DB: db,
}
}
// Chat Session Repository Methods
func (_i *chatRepository) GetAllChatSessions(userId uint, req request.ChatSessionQueryRequest) (chatSessions []*entity.ChatSessions, paging paginator.Pagination, err error) {
// Get chat sessions where user is a participant
query := _i.DB.DB.Model(&entity.ChatSessions{}).
Joins("INNER JOIN chat_participants cp ON chat_sessions.id = cp.chat_session_id").
Where("cp.user_id = ? AND cp.is_active = true", userId)
// Apply filters
if req.Type != nil {
query = query.Where("chat_sessions.type = ?", *req.Type)
}
// Include relationships
query = query.Preload("Creator").
Preload("Participants", "is_active = true").
Preload("Participants.User").
Preload("Messages", "is_deleted = false").
Preload("Messages.Sender")
// Order by updated_at desc (most recent first)
query = query.Order("chat_sessions.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(&chatSessions).Error
paging = *req.Pagination
return
}
func (_i *chatRepository) FindChatSessionByID(id uint) (chatSession *entity.ChatSessions, err error) {
err = _i.DB.DB.Preload("Creator").
Preload("Participants", "is_active = true").
Preload("Participants.User").
Preload("Messages", "is_deleted = false").
Preload("Messages.Sender").
First(&chatSession, id).Error
return
}
func (_i *chatRepository) FindChatSessionByUserAndID(userId uint, id uint) (chatSession *entity.ChatSessions, err error) {
// Check if user is participant in this chat session
var isParticipant bool
err = _i.DB.DB.Table("chat_participants").
Select("COUNT(*) > 0").
Where("chat_session_id = ? AND user_id = ? AND is_active = true", id, userId).
Scan(&isParticipant).Error
if err != nil {
return nil, err
}
if !isParticipant {
return nil, nil
}
err = _i.DB.DB.Preload("Creator").
Preload("Participants", "is_active = true").
Preload("Participants.User").
Preload("Messages", "is_deleted = false").
Preload("Messages.Sender").
First(&chatSession, id).Error
return
}
func (_i *chatRepository) CreateChatSession(chatSession *entity.ChatSessions) (result *entity.ChatSessions, err error) {
err = _i.DB.DB.Create(chatSession).Error
if err != nil {
return nil, err
}
// Reload with relationships
err = _i.DB.DB.Preload("Creator").
Preload("Participants", "is_active = true").
Preload("Participants.User").
First(&result, chatSession.ID).Error
return
}
func (_i *chatRepository) UpdateChatSession(id uint, chatSession *entity.ChatSessions) (err error) {
err = _i.DB.DB.Model(&entity.ChatSessions{}).Where("id = ?", id).Updates(chatSession).Error
return
}
func (_i *chatRepository) DeleteChatSession(id uint) (err error) {
err = _i.DB.DB.Delete(&entity.ChatSessions{}, id).Error
return
}
// Chat Message Repository Methods
func (_i *chatRepository) GetAllChatMessages(req request.ChatMessageQueryRequest) (chatMessages []*entity.ChatMessages, paging paginator.Pagination, err error) {
// Check if user is participant in this chat session
var isParticipant bool
err = _i.DB.DB.Table("chat_participants").
Select("COUNT(*) > 0").
Where("chat_session_id = ? AND user_id = ? AND is_active = true", req.ChatSessionID, req.UserID).
Scan(&isParticipant).Error
if err != nil {
return nil, paginator.Pagination{}, err
}
if !isParticipant {
return nil, paginator.Pagination{}, nil
}
query := _i.DB.DB.Model(&entity.ChatMessages{}).Where("chat_session_id = ? AND is_deleted = false", req.ChatSessionID)
// Include relationships
query = query.Preload("Sender")
// Order by created_at desc (most recent first)
query = query.Order("created_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(&chatMessages).Error
paging = *req.Pagination
return
}
func (_i *chatRepository) FindChatMessageByID(id uint) (chatMessage *entity.ChatMessages, err error) {
err = _i.DB.DB.Preload("Sender").First(&chatMessage, id).Error
return
}
func (_i *chatRepository) FindChatMessageByUserAndID(userId uint, id uint) (chatMessage *entity.ChatMessages, err error) {
// Check if user is participant in the chat session of this message
var isParticipant bool
err = _i.DB.DB.Table("chat_messages cm").
Joins("INNER JOIN chat_participants cp ON cm.chat_session_id = cp.chat_session_id").
Select("COUNT(*) > 0").
Where("cm.id = ? AND cp.user_id = ? AND cp.is_active = true", id, userId).
Scan(&isParticipant).Error
if err != nil {
return nil, err
}
if !isParticipant {
return nil, nil
}
err = _i.DB.DB.Preload("Sender").First(&chatMessage, id).Error
return
}
func (_i *chatRepository) CreateChatMessage(chatMessage *entity.ChatMessages) (result *entity.ChatMessages, err error) {
err = _i.DB.DB.Create(chatMessage).Error
if err != nil {
return nil, err
}
// Reload with relationships
err = _i.DB.DB.Preload("Sender").First(&result, chatMessage.ID).Error
return
}
func (_i *chatRepository) UpdateChatMessage(id uint, chatMessage *entity.ChatMessages) (err error) {
err = _i.DB.DB.Model(&entity.ChatMessages{}).Where("id = ?", id).Updates(chatMessage).Error
return
}
func (_i *chatRepository) DeleteChatMessage(id uint) (err error) {
err = _i.DB.DB.Delete(&entity.ChatMessages{}, id).Error
return
}
// Chat Participant Repository Methods
func (_i *chatRepository) CreateChatParticipant(chatParticipant *entity.ChatParticipants) (result *entity.ChatParticipants, err error) {
err = _i.DB.DB.Create(chatParticipant).Error
if err != nil {
return nil, err
}
// Reload with relationships
err = _i.DB.DB.Preload("User").First(&result, chatParticipant.ID).Error
return
}
func (_i *chatRepository) FindChatParticipantsBySessionID(chatSessionID uint) (participants []*entity.ChatParticipants, err error) {
err = _i.DB.DB.Model(&entity.ChatParticipants{}).Where("chat_session_id = ? AND is_active = true", chatSessionID).
Preload("User").Find(&participants).Error
return
}
func (_i *chatRepository) UpdateChatParticipant(id uint, chatParticipant *entity.ChatParticipants) (err error) {
err = _i.DB.DB.Model(&entity.ChatParticipants{}).Where("id = ?", id).Updates(chatParticipant).Error
return
}
func (_i *chatRepository) DeleteChatParticipant(id uint) (err error) {
err = _i.DB.DB.Delete(&entity.ChatParticipants{}, id).Error
return
}
// Utility Methods
func (_i *chatRepository) FindPersonalChatSession(userId1 uint, userId2 uint) (chatSession *entity.ChatSessions, err error) {
err = _i.DB.DB.Model(&entity.ChatSessions{}).
Joins("INNER JOIN chat_participants cp1 ON chat_sessions.id = cp1.chat_session_id").
Joins("INNER JOIN chat_participants cp2 ON chat_sessions.id = cp2.chat_session_id").
Where("chat_sessions.type = 'personal' AND cp1.user_id = ? AND cp2.user_id = ? AND cp1.is_active = true AND cp2.is_active = true", userId1, userId2).
Preload("Creator").
Preload("Participants", "is_active = true").
Preload("Participants.User").
First(&chatSession).Error
return
}
func (_i *chatRepository) CheckUserInChatSession(userId uint, chatSessionID uint) (isParticipant bool, err error) {
err = _i.DB.DB.Table("chat_participants").
Select("COUNT(*) > 0").
Where("chat_session_id = ? AND user_id = ? AND is_active = true", chatSessionID, userId).
Scan(&isParticipant).Error
return
}