first commit
Made-with: Cursor
This commit is contained in:
132
internal/service/reminder.go
Normal file
132
internal/service/reminder.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/calendarapi/internal/models"
|
||||
"github.com/calendarapi/internal/repository"
|
||||
"github.com/calendarapi/internal/utils"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
type ReminderService struct {
|
||||
queries *repository.Queries
|
||||
calendar *CalendarService
|
||||
scheduler ReminderScheduler
|
||||
}
|
||||
|
||||
func NewReminderService(queries *repository.Queries, calendar *CalendarService, scheduler ReminderScheduler) *ReminderService {
|
||||
return &ReminderService{queries: queries, calendar: calendar, scheduler: scheduler}
|
||||
}
|
||||
|
||||
func (s *ReminderService) AddReminders(ctx context.Context, userID uuid.UUID, eventID uuid.UUID, minutesBefore []int32) (*models.Event, error) {
|
||||
ev, err := s.queries.GetEventByID(ctx, utils.ToPgUUID(eventID))
|
||||
if err != nil {
|
||||
if err == pgx.ErrNoRows {
|
||||
return nil, models.ErrNotFound
|
||||
}
|
||||
return nil, models.ErrInternal
|
||||
}
|
||||
|
||||
calID := utils.FromPgUUID(ev.CalendarID)
|
||||
role, err := s.calendar.GetRole(ctx, calID, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if role != "owner" && role != "editor" {
|
||||
return nil, models.ErrForbidden
|
||||
}
|
||||
|
||||
for _, mins := range minutesBefore {
|
||||
if err := utils.ValidateReminderMinutes(mins); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rID := uuid.New()
|
||||
_, err := s.queries.CreateReminder(ctx, repository.CreateReminderParams{
|
||||
ID: utils.ToPgUUID(rID),
|
||||
EventID: utils.ToPgUUID(eventID),
|
||||
MinutesBefore: mins,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, models.ErrInternal
|
||||
}
|
||||
|
||||
startTime := utils.FromPgTimestamptz(ev.StartTime)
|
||||
triggerAt := startTime.Add(-time.Duration(mins) * time.Minute)
|
||||
if triggerAt.After(time.Now()) && s.scheduler != nil {
|
||||
_ = s.scheduler.ScheduleReminder(ctx, eventID, rID, userID, triggerAt)
|
||||
}
|
||||
}
|
||||
|
||||
reminders, _ := loadRemindersHelper(ctx, s.queries, eventID)
|
||||
attendees, _ := loadAttendeesHelper(ctx, s.queries, eventID)
|
||||
attachments, _ := loadAttachmentsHelper(ctx, s.queries, eventID)
|
||||
return eventFromDB(ev, reminders, attendees, attachments), nil
|
||||
}
|
||||
|
||||
func (s *ReminderService) DeleteReminder(ctx context.Context, userID uuid.UUID, eventID uuid.UUID, reminderID uuid.UUID) error {
|
||||
ev, err := s.queries.GetEventByID(ctx, utils.ToPgUUID(eventID))
|
||||
if err != nil {
|
||||
if err == pgx.ErrNoRows {
|
||||
return models.ErrNotFound
|
||||
}
|
||||
return models.ErrInternal
|
||||
}
|
||||
|
||||
calID := utils.FromPgUUID(ev.CalendarID)
|
||||
role, err := s.calendar.GetRole(ctx, calID, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if role != "owner" && role != "editor" {
|
||||
return models.ErrForbidden
|
||||
}
|
||||
|
||||
return s.queries.DeleteReminder(ctx, repository.DeleteReminderParams{
|
||||
ID: utils.ToPgUUID(reminderID),
|
||||
EventID: utils.ToPgUUID(eventID),
|
||||
})
|
||||
}
|
||||
|
||||
func loadRemindersHelper(ctx context.Context, q *repository.Queries, eventID uuid.UUID) ([]models.Reminder, error) {
|
||||
rows, err := q.ListRemindersByEvent(ctx, utils.ToPgUUID(eventID))
|
||||
if err != nil {
|
||||
return []models.Reminder{}, err
|
||||
}
|
||||
result := make([]models.Reminder, len(rows))
|
||||
for i, r := range rows {
|
||||
result[i] = models.Reminder{ID: utils.FromPgUUID(r.ID), MinutesBefore: r.MinutesBefore}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func loadAttendeesHelper(ctx context.Context, q *repository.Queries, eventID uuid.UUID) ([]models.Attendee, error) {
|
||||
rows, err := q.ListAttendeesByEvent(ctx, utils.ToPgUUID(eventID))
|
||||
if err != nil {
|
||||
return []models.Attendee{}, err
|
||||
}
|
||||
result := make([]models.Attendee, len(rows))
|
||||
for i, a := range rows {
|
||||
var uid *uuid.UUID
|
||||
if a.UserID.Valid {
|
||||
u := utils.FromPgUUID(a.UserID)
|
||||
uid = &u
|
||||
}
|
||||
result[i] = models.Attendee{ID: utils.FromPgUUID(a.ID), UserID: uid, Email: utils.FromPgText(a.Email), Status: a.Status}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func loadAttachmentsHelper(ctx context.Context, q *repository.Queries, eventID uuid.UUID) ([]models.Attachment, error) {
|
||||
rows, err := q.ListAttachmentsByEvent(ctx, utils.ToPgUUID(eventID))
|
||||
if err != nil {
|
||||
return []models.Attachment{}, err
|
||||
}
|
||||
result := make([]models.Attachment, len(rows))
|
||||
for i, a := range rows {
|
||||
result[i] = models.Attachment{ID: utils.FromPgUUID(a.ID), FileURL: a.FileUrl}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
Reference in New Issue
Block a user