209 lines
6.5 KiB
Go
209 lines
6.5 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"
|
|
"golang.org/x/net/websocket"
|
|
)
|
|
|
|
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 int64, limit, offset int) ([]domain.Notification, error)
|
|
ListFailedNotifications(ctx context.Context, limit int) ([]domain.Notification, error)
|
|
ListRecipientIDs(ctx context.Context, receiver domain.NotificationRecieverSide) ([]int64, error)
|
|
CountUnreadNotifications(ctx context.Context, recipient_id int64) (int64, error)
|
|
GetAllNotifications(ctx context.Context, limit, offset int) ([]domain.Notification, error)
|
|
}
|
|
|
|
type Repository struct {
|
|
store *Store
|
|
}
|
|
|
|
func NewNotificationRepository(store *Store) NotificationRepository {
|
|
return &Repository{store: store}
|
|
}
|
|
|
|
func (r *Repository) ConnectWebSocket(ctx context.Context, recipientID int64, c *websocket.Conn) error {
|
|
return nil
|
|
}
|
|
|
|
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 int64, 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) GetAllNotifications(ctx context.Context, limit, offset int) ([]domain.Notification, error) {
|
|
|
|
dbNotifications, err := r.store.queries.GetAllNotifications(ctx, dbgen.GetAllNotificationsParams{
|
|
Limit: int32(limit),
|
|
Offset: int32(offset),
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var result []domain.Notification = make([]domain.Notification, 0, len(dbNotifications))
|
|
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) ListRecipientIDs(ctx context.Context, receiver domain.NotificationRecieverSide) ([]int64, error) {
|
|
return r.store.queries.ListRecipientIDsByReceiver(ctx, string(receiver))
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
func (r *Repository) CountUnreadNotifications(ctx context.Context, recipient_id int64) (int64, error) {
|
|
return r.store.queries.CountUnreadNotifications(ctx, recipient_id)
|
|
}
|