133 lines
3.8 KiB
Go
133 lines
3.8 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
|
|
"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 AttendeeService struct {
|
|
queries *repository.Queries
|
|
calendar *CalendarService
|
|
}
|
|
|
|
func NewAttendeeService(queries *repository.Queries, calendar *CalendarService) *AttendeeService {
|
|
return &AttendeeService{queries: queries, calendar: calendar}
|
|
}
|
|
|
|
func (s *AttendeeService) AddAttendees(ctx context.Context, userID uuid.UUID, eventID uuid.UUID, attendees []AddAttendeeRequest) (*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 _, a := range attendees {
|
|
_, err := s.queries.CreateAttendee(ctx, repository.CreateAttendeeParams{
|
|
ID: utils.ToPgUUID(uuid.New()),
|
|
EventID: utils.ToPgUUID(eventID),
|
|
UserID: optionalPgUUID(a.UserID),
|
|
Email: utils.ToPgTextPtr(a.Email),
|
|
})
|
|
if err != nil {
|
|
return nil, models.ErrInternal
|
|
}
|
|
}
|
|
|
|
reminders, _ := loadRemindersHelper(ctx, s.queries, eventID)
|
|
atts, _ := loadAttendeesHelper(ctx, s.queries, eventID)
|
|
attachments, _ := loadAttachmentsHelper(ctx, s.queries, eventID)
|
|
return eventFromDB(ev, reminders, atts, attachments), nil
|
|
}
|
|
|
|
func (s *AttendeeService) UpdateStatus(ctx context.Context, userID uuid.UUID, eventID uuid.UUID, attendeeID uuid.UUID, status string) (*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
|
|
}
|
|
|
|
att, err := s.queries.GetAttendeeByID(ctx, utils.ToPgUUID(attendeeID))
|
|
if err != nil {
|
|
if err == pgx.ErrNoRows {
|
|
return nil, models.ErrNotFound
|
|
}
|
|
return nil, models.ErrInternal
|
|
}
|
|
|
|
isOrganizer := role == "owner" || role == "editor"
|
|
isOwnAttendee := att.UserID.Valid && utils.FromPgUUID(att.UserID) == userID
|
|
if !isOrganizer && !isOwnAttendee {
|
|
return nil, models.ErrForbidden
|
|
}
|
|
|
|
if status != "pending" && status != "accepted" && status != "declined" && status != "tentative" {
|
|
return nil, models.NewValidationError("status must be pending, accepted, declined, or tentative")
|
|
}
|
|
|
|
_, err = s.queries.UpdateAttendeeStatus(ctx, repository.UpdateAttendeeStatusParams{
|
|
ID: utils.ToPgUUID(attendeeID),
|
|
Status: status,
|
|
})
|
|
if err != nil {
|
|
return nil, models.ErrInternal
|
|
}
|
|
|
|
reminders, _ := loadRemindersHelper(ctx, s.queries, eventID)
|
|
atts, _ := loadAttendeesHelper(ctx, s.queries, eventID)
|
|
attachments, _ := loadAttachmentsHelper(ctx, s.queries, eventID)
|
|
return eventFromDB(ev, reminders, atts, attachments), nil
|
|
}
|
|
|
|
func (s *AttendeeService) DeleteAttendee(ctx context.Context, userID uuid.UUID, eventID uuid.UUID, attendeeID 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.DeleteAttendee(ctx, repository.DeleteAttendeeParams{
|
|
ID: utils.ToPgUUID(attendeeID),
|
|
EventID: utils.ToPgUUID(eventID),
|
|
})
|
|
}
|
|
|
|
type AddAttendeeRequest struct {
|
|
UserID *uuid.UUID
|
|
Email *string
|
|
}
|