194 lines
4.0 KiB
Go
194 lines
4.0 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"strconv"
|
|
|
|
dbgen "Yimaru-Backend/gen/db"
|
|
"Yimaru-Backend/internal/domain"
|
|
"Yimaru-Backend/internal/ports"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
func NewNotificationStore(s *Store) ports.NotificationStore {
|
|
return s
|
|
}
|
|
|
|
/* =========================
|
|
Create
|
|
========================= */
|
|
|
|
func (r *Store) CreateNotification(
|
|
ctx context.Context,
|
|
n *domain.Notification,
|
|
) (*domain.Notification, error) {
|
|
|
|
params := dbgen.CreateNotificationParams{
|
|
UserID: n.RecipientID,
|
|
Type: string(n.Type),
|
|
Level: string(n.Level),
|
|
Channel: pgtype.Text{String: string(n.DeliveryChannel)},
|
|
Title: n.Payload.Headline,
|
|
Message: n.Payload.Message,
|
|
Payload: marshalPayload(n.Payload),
|
|
}
|
|
|
|
dbNotif, err := r.queries.CreateNotification(ctx, params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return mapDBToDomain(&dbNotif), nil
|
|
}
|
|
|
|
/* =========================
|
|
Read
|
|
========================= */
|
|
|
|
func (r *Store) GetUserNotifications(
|
|
ctx context.Context,
|
|
userID int64,
|
|
limit, offset int,
|
|
) ([]domain.Notification, int64, error) {
|
|
|
|
params := dbgen.GetUserNotificationsParams{
|
|
UserID: userID,
|
|
Limit: int32(limit),
|
|
Offset: int32(offset),
|
|
}
|
|
|
|
rows, err := r.queries.GetUserNotifications(ctx, params)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
total, err := r.queries.GetUserNotificationCount(ctx, userID)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
result := make([]domain.Notification, 0, len(rows))
|
|
for _, row := range rows {
|
|
result = append(result, *mapDBToDomain(&row))
|
|
}
|
|
|
|
return result, total, nil
|
|
}
|
|
|
|
func (r *Store) GetAllNotifications(
|
|
ctx context.Context,
|
|
limit, offset int,
|
|
) ([]domain.Notification, error) {
|
|
|
|
rows, err := r.queries.GetAllNotifications(ctx, dbgen.GetAllNotificationsParams{
|
|
Limit: int32(limit),
|
|
Offset: int32(offset),
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
result := make([]domain.Notification, 0, len(rows))
|
|
for _, row := range rows {
|
|
result = append(result, *mapDBToDomain(&row))
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func (r *Store) CountUnreadNotifications(
|
|
ctx context.Context,
|
|
userID int64,
|
|
) (int64, error) {
|
|
return r.queries.CountUnreadNotifications(ctx, userID)
|
|
}
|
|
|
|
/* =========================
|
|
Update
|
|
========================= */
|
|
|
|
func (r *Store) MarkNotificationAsRead(
|
|
ctx context.Context,
|
|
id int64,
|
|
) (*domain.Notification, error) {
|
|
|
|
dbNotif, err := r.queries.MarkNotificationAsRead(ctx, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return mapDBToDomain(&dbNotif), nil
|
|
}
|
|
|
|
func (r *Store) MarkAllUserNotificationsAsRead(
|
|
ctx context.Context,
|
|
userID int64,
|
|
) error {
|
|
return r.queries.MarkAllUserNotificationsAsRead(ctx, userID)
|
|
}
|
|
|
|
/* =========================
|
|
Delete
|
|
========================= */
|
|
|
|
func (r *Store) DeleteUserNotifications(
|
|
ctx context.Context,
|
|
userID int64,
|
|
) error {
|
|
return r.queries.DeleteUserNotifications(ctx, userID)
|
|
}
|
|
|
|
/* =========================
|
|
Mapping
|
|
========================= */
|
|
|
|
func mapDBToDomain(db *dbgen.Notification) *domain.Notification {
|
|
payload, err := unmarshalPayload(db.Payload)
|
|
if err != nil {
|
|
payload = domain.NotificationPayload{}
|
|
}
|
|
|
|
var channel domain.DeliveryChannel
|
|
if db.Channel.Valid {
|
|
channel = domain.DeliveryChannel(db.Channel.String)
|
|
}
|
|
|
|
return &domain.Notification{
|
|
ID: strconv.FormatInt(db.ID, 10),
|
|
RecipientID: db.UserID,
|
|
Type: domain.NotificationType(db.Type),
|
|
Level: domain.NotificationLevel(db.Level),
|
|
DeliveryChannel: channel,
|
|
DeliveryStatus: "PENDING",
|
|
Payload: domain.NotificationPayload{
|
|
Headline: payload.Headline,
|
|
Message: payload.Message,
|
|
},
|
|
IsRead: db.IsRead,
|
|
Timestamp: db.CreatedAt.Time,
|
|
// ReadAt: db.ReadAt.Time,
|
|
}
|
|
}
|
|
|
|
/* =========================
|
|
JSON Helpers
|
|
========================= */
|
|
|
|
func marshalPayload(p domain.NotificationPayload) []byte {
|
|
b, _ := json.Marshal(p)
|
|
return b
|
|
}
|
|
|
|
func unmarshalPayload(b []byte) (domain.NotificationPayload, error) {
|
|
var p domain.NotificationPayload
|
|
if len(b) == 0 {
|
|
return p, nil
|
|
}
|
|
if err := json.Unmarshal(b, &p); err != nil {
|
|
return p, err
|
|
}
|
|
return p, nil
|
|
}
|