131 lines
5.0 KiB
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
|
|
}
|