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

131 lines
5.0 KiB
Go

package repository
import (
"narasi-ahli-be/app/database/entity"
"narasi-ahli-be/app/module/communications/request"
"narasi-ahli-be/utils/paginator"
"time"
"gorm.io/gorm"
)
type communicationsRepository struct {
DB *gorm.DB
}
type CommunicationsRepository interface {
// Conversations
GetUserConversations(userId uint, req request.ConversationsQueryRequest) (conversations []*entity.Conversations, paging paginator.Pagination, err error)
FindConversationByParticipants(participant1ID, participant2ID uint) (conversation *entity.Conversations, err error)
FindConversationByUserAndId(userId uint, conversationId uint) (conversation *entity.Conversations, err error)
CreateConversation(conversation *entity.Conversations) (result *entity.Conversations, err error)
UpdateConversationLastMessage(conversationId uint, lastMessageAt *time.Time) (err error)
// Chat Messages
GetConversationMessages(conversationId uint, req request.ChatMessagesQueryRequest) (messages []*entity.ChatMessages, paging paginator.Pagination, err error)
CreateChatMessage(message *entity.ChatMessages) (result *entity.ChatMessages, err error)
MarkMessageAsRead(messageId uint, userId uint) (err error)
GetUnreadCount(conversationId uint, userId uint) (count int64, err error)
}
func NewCommunicationsRepository(db *gorm.DB) CommunicationsRepository {
return &communicationsRepository{
DB: db,
}
}
// Conversations methods
func (_i *communicationsRepository) GetUserConversations(userId uint, req request.ConversationsQueryRequest) (conversations []*entity.Conversations, paging paginator.Pagination, err error) {
query := _i.DB.Where("participant1_id = ? OR participant2_id = ?", userId, userId)
// Include relationships
query = query.Preload("Participant1").Preload("Participant2")
// Order by last message time desc, then by created_at desc
query = query.Order("last_message_at DESC NULLS LAST, 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(&conversations).Error
paging = *req.Pagination
return
}
func (_i *communicationsRepository) FindConversationByParticipants(participant1ID, participant2ID uint) (conversation *entity.Conversations, err error) {
err = _i.DB.Where(
"(participant1_id = ? AND participant2_id = ?) OR (participant1_id = ? AND participant2_id = ?)",
participant1ID, participant2ID, participant2ID, participant1ID).Preload("Participant1").Preload("Participant2").First(&conversation).Error
return
}
func (_i *communicationsRepository) FindConversationByUserAndId(userId uint, conversationId uint) (conversation *entity.Conversations, err error) {
err = _i.DB.Where(
"id = ? AND (participant1_id = ? OR participant2_id = ?)",
conversationId, userId, userId).Preload("Participant1").Preload("Participant2").First(&conversation).Error
return
}
func (_i *communicationsRepository) CreateConversation(conversation *entity.Conversations) (result *entity.Conversations, err error) {
err = _i.DB.Create(conversation).Error
if err != nil {
return nil, err
}
// Reload with relationships
err = _i.DB.Preload("Participant1").Preload("Participant2").First(&result, conversation.ID).Error
return
}
func (_i *communicationsRepository) UpdateConversationLastMessage(conversationId uint, lastMessageAt *time.Time) (err error) {
err = _i.DB.Model(&entity.Conversations{}).Where("id = ?", conversationId).Update("last_message_at", lastMessageAt).Error
return
}
// Chat Messages methods
func (_i *communicationsRepository) GetConversationMessages(conversationId uint, req request.ChatMessagesQueryRequest) (messages []*entity.ChatMessages, paging paginator.Pagination, err error) {
query := _i.DB.Where("conversation_id = ?", conversationId)
// Include sender relationship
query = query.Preload("Sender")
// 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 *communicationsRepository) CreateChatMessage(message *entity.ChatMessages) (result *entity.ChatMessages, err error) {
err = _i.DB.Create(message).Error
if err != nil {
return nil, err
}
// Reload with relationships
err = _i.DB.Preload("Sender").First(&result, message.ID).Error
return
}
func (_i *communicationsRepository) MarkMessageAsRead(messageId uint, userId uint) (err error) {
err = _i.DB.Model(&entity.ChatMessages{}).Where("id = ? AND sender_id != ?", messageId, userId).Update("is_read", true).Error
return
}
func (_i *communicationsRepository) GetUnreadCount(conversationId uint, userId uint) (count int64, err error) {
err = _i.DB.Model(&entity.ChatMessages{}).Where("conversation_id = ? AND sender_id != ? AND is_read = false", conversationId, userId).Count(&count).Error
return
}