Yimaru-BackEnd/internal/repository/notification.go

175 lines
5.2 KiB
Go

package repository
import (
"context"
"encoding/json"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/jackc/pgx/v5/pgtype"
)
type NotificationRepository interface {
CreateNotification(ctx context.Context, notification *domain.Notification) (*domain.Notification, error)
UpdateNotificationStatus(ctx context.Context, id, status string, isRead bool, metadata []byte) (*domain.Notification, error)
ListNotifications(ctx context.Context, recipientID string, limit, offset int) ([]domain.Notification, error)
ListFailedNotifications(ctx context.Context, limit int) ([]domain.Notification, error)
}
type Repository struct {
store *Store
}
func NewNotificationRepository(store *Store) NotificationRepository {
return &Repository{store: store}
}
func (r *Repository) CreateNotification(ctx context.Context, notification *domain.Notification) (*domain.Notification, error) {
var errorSeverity pgtype.Text
if notification.ErrorSeverity != nil {
errorSeverity.String = string(*notification.ErrorSeverity)
errorSeverity.Valid = true
}
var deliveryChannel pgtype.Text
if notification.DeliveryChannel != "" {
deliveryChannel.String = string(notification.DeliveryChannel)
deliveryChannel.Valid = true
}
var priority pgtype.Int4
if notification.Priority != 0 {
priority.Int32 = int32(notification.Priority)
priority.Valid = true
}
params := dbgen.CreateNotificationParams{
ID: notification.ID,
RecipientID: notification.RecipientID,
Type: string(notification.Type),
Level: string(notification.Level),
ErrorSeverity: errorSeverity,
Reciever: string(notification.Reciever),
IsRead: notification.IsRead,
DeliveryStatus: string(notification.DeliveryStatus),
DeliveryChannel: deliveryChannel,
Payload: marshalPayload(notification.Payload),
Priority: priority,
Timestamp: pgtype.Timestamptz{Time: notification.Timestamp, Valid: true},
Metadata: notification.Metadata,
}
dbNotification, err := r.store.queries.CreateNotification(ctx, params)
if err != nil {
return nil, err
}
return r.mapDBToDomain(&dbNotification), nil
}
func (r *Repository) UpdateNotificationStatus(ctx context.Context, id, status string, isRead bool, metadata []byte) (*domain.Notification, error) {
params := dbgen.UpdateNotificationStatusParams{
ID: id,
DeliveryStatus: status,
IsRead: isRead,
Metadata: metadata,
}
dbNotification, err := r.store.queries.UpdateNotificationStatus(ctx, params)
if err != nil {
return nil, err
}
return r.mapDBToDomain(&dbNotification), nil
}
func (r *Repository) ListNotifications(ctx context.Context, recipientID string, limit, offset int) ([]domain.Notification, error) {
params := dbgen.ListNotificationsParams{
RecipientID: recipientID,
Limit: int32(limit),
Offset: int32(offset),
}
dbNotifications, err := r.store.queries.ListNotifications(ctx, params)
if err != nil {
return nil, err
}
var result []domain.Notification
for _, dbNotif := range dbNotifications {
domainNotif := r.mapDBToDomain(&dbNotif)
result = append(result, *domainNotif)
}
return result, nil
}
func (r *Repository) ListFailedNotifications(ctx context.Context, limit int) ([]domain.Notification, error) {
dbNotifications, err := r.store.queries.ListFailedNotifications(ctx, int32(limit))
if err != nil {
return nil, err
}
var result []domain.Notification
for _, dbNotif := range dbNotifications {
domainNotif := r.mapDBToDomain(&dbNotif)
result = append(result, *domainNotif)
}
return result, nil
}
func (r *Repository) mapDBToDomain(dbNotif *dbgen.Notification) *domain.Notification {
var errorSeverity *domain.NotificationErrorSeverity
if dbNotif.ErrorSeverity.Valid {
s := domain.NotificationErrorSeverity(dbNotif.ErrorSeverity.String)
errorSeverity = &s
}
var deliveryChannel domain.DeliveryChannel
if dbNotif.DeliveryChannel.Valid {
deliveryChannel = domain.DeliveryChannel(dbNotif.DeliveryChannel.String)
} else {
deliveryChannel = ""
}
var priority int
if dbNotif.Priority.Valid {
priority = int(dbNotif.Priority.Int32)
}
payload, err := unmarshalPayload(dbNotif.Payload)
if err != nil {
payload = domain.NotificationPayload{}
}
return &domain.Notification{
ID: dbNotif.ID,
RecipientID: dbNotif.RecipientID,
Type: domain.NotificationType(dbNotif.Type),
Level: domain.NotificationLevel(dbNotif.Level),
ErrorSeverity: errorSeverity,
Reciever: domain.NotificationRecieverSide(dbNotif.Reciever),
IsRead: dbNotif.IsRead,
DeliveryStatus: domain.NotificationDeliveryStatus(dbNotif.DeliveryStatus),
DeliveryChannel: deliveryChannel,
Payload: payload,
Priority: priority,
Timestamp: dbNotif.Timestamp.Time,
Metadata: dbNotif.Metadata,
}
}
func marshalPayload(payload domain.NotificationPayload) []byte {
data, _ := json.Marshal(payload)
return data
}
func unmarshalPayload(data []byte) (domain.NotificationPayload, error) {
var payload domain.NotificationPayload
if err := json.Unmarshal(data, &payload); err != nil {
return domain.NotificationPayload{}, err
}
return payload, nil
}