Yimaru-BackEnd/internal/repository/scheduled_notification.go

203 lines
4.9 KiB
Go

package repository
import (
"context"
"encoding/json"
dbgen "Yimaru-Backend/gen/db"
"Yimaru-Backend/internal/domain"
"github.com/jackc/pgx/v5/pgtype"
)
/* =========================
Create
========================= */
func (r *Store) CreateScheduledNotification(
ctx context.Context,
sn *domain.ScheduledNotification,
) (*domain.ScheduledNotification, error) {
params := dbgen.CreateScheduledNotificationParams{
Channel: string(sn.Channel),
Title: pgtype.Text{String: sn.Title, Valid: sn.Title != ""},
Message: sn.Message,
Html: pgtype.Text{String: sn.HTML, Valid: sn.HTML != ""},
ScheduledAt: pgtype.Timestamptz{Time: sn.ScheduledAt, Valid: true},
TargetUserIds: sn.TargetUserIDs,
TargetRole: pgtype.Text{String: sn.TargetRole, Valid: sn.TargetRole != ""},
TargetRaw: json.RawMessage(sn.TargetRaw),
CreatedBy: sn.CreatedBy,
}
dbRow, err := r.queries.CreateScheduledNotification(ctx, params)
if err != nil {
return nil, err
}
return mapScheduledDBToDomain(&dbRow), nil
}
/* =========================
Read
========================= */
func (r *Store) GetScheduledNotification(
ctx context.Context,
id int64,
) (*domain.ScheduledNotification, error) {
dbRow, err := r.queries.GetScheduledNotification(ctx, id)
if err != nil {
return nil, err
}
return mapScheduledDBToDomain(&dbRow), nil
}
func (r *Store) ListScheduledNotifications(
ctx context.Context,
filter domain.ScheduledNotificationFilter,
) ([]domain.ScheduledNotification, int64, error) {
filterParams := dbgen.ListScheduledNotificationsParams{
FilterStatus: pgtype.Text{String: filter.Status, Valid: filter.Status != ""},
FilterChannel: pgtype.Text{String: filter.Channel, Valid: filter.Channel != ""},
PageLimit: int32(filter.Limit),
PageOffset: int32(filter.Offset),
}
countParams := dbgen.CountScheduledNotificationsParams{
FilterStatus: filterParams.FilterStatus,
FilterChannel: filterParams.FilterChannel,
}
if filter.After != nil {
v := pgtype.Timestamptz{Time: *filter.After, Valid: true}
filterParams.FilterAfter = v
countParams.FilterAfter = v
}
if filter.Before != nil {
v := pgtype.Timestamptz{Time: *filter.Before, Valid: true}
filterParams.FilterBefore = v
countParams.FilterBefore = v
}
rows, err := r.queries.ListScheduledNotifications(ctx, filterParams)
if err != nil {
return nil, 0, err
}
total, err := r.queries.CountScheduledNotifications(ctx, countParams)
if err != nil {
return nil, 0, err
}
result := make([]domain.ScheduledNotification, 0, len(rows))
for _, row := range rows {
result = append(result, *mapScheduledDBToDomain(&row))
}
return result, total, nil
}
/* =========================
Update
========================= */
func (r *Store) CancelScheduledNotification(
ctx context.Context,
id int64,
) (*domain.ScheduledNotification, error) {
dbRow, err := r.queries.CancelScheduledNotification(ctx, id)
if err != nil {
return nil, err
}
return mapScheduledDBToDomain(&dbRow), nil
}
func (r *Store) ClaimDueScheduledNotifications(
ctx context.Context,
limit int32,
) ([]domain.ScheduledNotification, error) {
rows, err := r.queries.ClaimDueScheduledNotifications(ctx, limit)
if err != nil {
return nil, err
}
result := make([]domain.ScheduledNotification, 0, len(rows))
for _, row := range rows {
result = append(result, *mapScheduledDBToDomain(&row))
}
return result, nil
}
func (r *Store) MarkScheduledNotificationSent(
ctx context.Context,
id int64,
) error {
return r.queries.MarkScheduledNotificationSent(ctx, id)
}
func (r *Store) MarkScheduledNotificationFailed(
ctx context.Context,
id int64,
lastError string,
) error {
return r.queries.MarkScheduledNotificationFailed(ctx, dbgen.MarkScheduledNotificationFailedParams{
ID: id,
LastError: pgtype.Text{String: lastError, Valid: lastError != ""},
})
}
/* =========================
Mapping
========================= */
func mapScheduledDBToDomain(db *dbgen.ScheduledNotification) *domain.ScheduledNotification {
sn := &domain.ScheduledNotification{
ID: db.ID,
Channel: domain.DeliveryChannel(db.Channel),
Message: db.Message,
ScheduledAt: db.ScheduledAt.Time,
Status: domain.ScheduledNotificationStatus(db.Status),
TargetUserIDs: db.TargetUserIds,
TargetRaw: json.RawMessage(db.TargetRaw),
AttemptCount: db.AttemptCount,
CreatedBy: db.CreatedBy,
CreatedAt: db.CreatedAt.Time,
UpdatedAt: db.UpdatedAt.Time,
}
if db.Title.Valid {
sn.Title = db.Title.String
}
if db.Html.Valid {
sn.HTML = db.Html.String
}
if db.TargetRole.Valid {
sn.TargetRole = db.TargetRole.String
}
if db.LastError.Valid {
sn.LastError = db.LastError.String
}
if db.ProcessingStartedAt.Valid {
t := db.ProcessingStartedAt.Time
sn.ProcessingStartedAt = &t
}
if db.SentAt.Valid {
t := db.SentAt.Time
sn.SentAt = &t
}
if db.CancelledAt.Valid {
t := db.CancelledAt.Time
sn.CancelledAt = &t
}
return sn
}