From 4a58dc3a81a0b3d299f398a6cd3facb5f26aec20 Mon Sep 17 00:00:00 2001 From: Vojtech Mares Date: Tue, 7 May 2024 22:07:30 +0200 Subject: [PATCH] feat(server): implement new api handlers for TrainingDateAttendees --- cmd/yggdrasil/main.go | 3 +- internal/server/api.go | 145 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 138 insertions(+), 10 deletions(-) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 1ee7646..0b349ff 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -24,13 +24,14 @@ func main() { trainingRepository := training.NewInMemoryTrainingRepository() trainingDateRepository := training.NewInMemoryTrainingDateRepository() + trainingDateAttendeeRepository := training.NewInMemoryTrainingDateAttendeeRepository() f := faker.NewFaker(trainingRepository, trainingDateRepository) if err := f.GenerateFakeData(); err != nil { logger.Fatal("Error generating fake data", zap.Error(err)) } - apiHandlers := server.NewAPIHandlers(trainingRepository, trainingDateRepository) + apiHandlers := server.NewAPIHandlers(trainingRepository, trainingDateRepository, trainingDateAttendeeRepository) srv := server.NewServer(apiHandlers, port, logger) srv.Run(shutdownCtx) } diff --git a/internal/server/api.go b/internal/server/api.go index de279af..f8dd951 100644 --- a/internal/server/api.go +++ b/internal/server/api.go @@ -2,6 +2,7 @@ package server import ( "context" + "errors" "time" "github.com/gofiber/fiber/v2" @@ -10,14 +11,16 @@ import ( ) type APIHandlers struct { - trainingRepository training.TrainingRepository - trainingDateRepository training.TrainingDateRepository + trainingRepository training.TrainingRepository + trainingDateRepository training.TrainingDateRepository + trainingDateAttendeeRepository training.TrainingDateAttendeeRepository } -func NewAPIHandlers(trainingRepository training.TrainingRepository, trainingDateRepository training.TrainingDateRepository) *APIHandlers { +func NewAPIHandlers(trainingRepository training.TrainingRepository, trainingDateRepository training.TrainingDateRepository, trainingDateAttendeeRepository training.TrainingDateAttendeeRepository) *APIHandlers { return &APIHandlers{ - trainingRepository: trainingRepository, - trainingDateRepository: trainingDateRepository, + trainingRepository: trainingRepository, + trainingDateRepository: trainingDateRepository, + trainingDateAttendeeRepository: trainingDateAttendeeRepository, } } @@ -101,7 +104,7 @@ func (h *APIHandlers) CreateTraining(ctx context.Context, req CreateTrainingRequ func (h *APIHandlers) DeleteTraining(ctx context.Context, req DeleteTrainingRequestObject) (DeleteTrainingResponseObject, error) { err := h.trainingRepository.Delete(req.TrainingID) - if err == training.ErrTrainingNotFound { + if errors.Is(err, training.ErrTrainingNotFound) { return DeleteTraining404ApplicationProblemPlusJSONResponse{ NotFoundErrorApplicationProblemPlusJSONResponse: NotFoundErrorApplicationProblemPlusJSONResponse{ Status: fiber.StatusNotFound, @@ -121,7 +124,7 @@ func (h *APIHandlers) DeleteTraining(ctx context.Context, req DeleteTrainingRequ func (h *APIHandlers) GetTraining(ctx context.Context, req GetTrainingRequestObject) (GetTrainingResponseObject, error) { t, err := h.trainingRepository.FindByID(req.TrainingID) - if err == training.ErrTrainingNotFound { + if errors.Is(err, training.ErrTrainingNotFound) { return GetTraining404ApplicationProblemPlusJSONResponse{ NotFoundErrorApplicationProblemPlusJSONResponse: NotFoundErrorApplicationProblemPlusJSONResponse{ Status: fiber.StatusNotFound, @@ -277,7 +280,7 @@ func (h *APIHandlers) CreateTrainingDate(ctx context.Context, req CreateTraining func (h *APIHandlers) DeleteTrainingDate(ctx context.Context, req DeleteTrainingDateRequestObject) (DeleteTrainingDateResponseObject, error) { err := h.trainingDateRepository.Delete(req.TrainingDateID) - if err == training.ErrTrainingDateNotFound { + if errors.Is(err, training.ErrTrainingDateNotFound) { return DeleteTrainingDate404ApplicationProblemPlusJSONResponse{ NotFoundErrorApplicationProblemPlusJSONResponse: NotFoundErrorApplicationProblemPlusJSONResponse{ Status: fiber.StatusNotFound, @@ -297,7 +300,7 @@ func (h *APIHandlers) DeleteTrainingDate(ctx context.Context, req DeleteTraining func (h *APIHandlers) GetTrainingDate(ctx context.Context, req GetTrainingDateRequestObject) (GetTrainingDateResponseObject, error) { td, err := h.trainingDateRepository.FindByID(req.TrainingDateID) - if err == training.ErrTrainingDateNotFound { + if errors.Is(err, training.ErrTrainingDateNotFound) { return GetTrainingDate404ApplicationProblemPlusJSONResponse{ NotFoundErrorApplicationProblemPlusJSONResponse: NotFoundErrorApplicationProblemPlusJSONResponse{ Status: fiber.StatusNotFound, @@ -459,3 +462,127 @@ func (h *APIHandlers) ListTrainingUpcomingDates(ctx context.Context, req ListTra return ListTrainingUpcomingDates200JSONResponse(data), nil } + +func (h *APIHandlers) ListTrainingDateAttendees(ctx context.Context, req ListTrainingDateAttendeesRequestObject) (ListTrainingDateAttendeesResponseObject, error) { + attendees, err := h.trainingDateAttendeeRepository.FindAllByTrainingDateID(req.TrainingDateID) + if err != nil { + return ListTrainingDateAttendees500ApplicationProblemPlusJSONResponse{ + InternalErrorApplicationProblemPlusJSONResponse: InternalErrorApplicationProblemPlusJSONResponse{ + Status: fiber.StatusInternalServerError, + Title: "Internal Server Error: Failed to list training date attendees", + Detail: err.Error(), + }}, nil + } + + data := make([]TrainingDateAttendee, len(attendees)) + for idx, a := range attendees { + data[idx] = TrainingDateAttendee{ + Id: a.ID, + Name: a.Name, + } + } + + return ListTrainingDateAttendees200JSONResponse(data), nil +} + +func (h *APIHandlers) CreateTrainingDateAttendee(ctx context.Context, req CreateTrainingDateAttendeeRequestObject) (CreateTrainingDateAttendeeResponseObject, error) { + ta := training.TrainingDateAttendee{ + Name: req.Body.Name, + } + + err := h.trainingDateAttendeeRepository.Create(req.TrainingDateID, &ta) + if err != nil { + return CreateTrainingDateAttendee500ApplicationProblemPlusJSONResponse{ + InternalErrorApplicationProblemPlusJSONResponse: InternalErrorApplicationProblemPlusJSONResponse{ + Status: fiber.StatusInternalServerError, + Title: "Internal Server Error: Failed to create training date attendee", + Detail: err.Error(), + }}, nil + } + + return CreateTrainingDateAttendee201JSONResponse{ + Id: ta.ID, + Name: ta.Name, + }, nil +} + +func (h *APIHandlers) GetTrainingDateAttendeeCount(ctx context.Context, req GetTrainingDateAttendeeCountRequestObject) (GetTrainingDateAttendeeCountResponseObject, error) { + attendees, err := h.trainingDateAttendeeRepository.FindAllByTrainingDateID(req.TrainingDateID) + if err != nil { + return GetTrainingDateAttendeeCount500ApplicationProblemPlusJSONResponse{ + InternalErrorApplicationProblemPlusJSONResponse: InternalErrorApplicationProblemPlusJSONResponse{ + Status: fiber.StatusInternalServerError, + Title: "Internal Server Error: Failed to get training date attendee count", + Detail: err.Error(), + }}, nil + } + + return GetTrainingDateAttendeeCount200JSONResponse{ + Count: int8(len(attendees)), + }, nil +} + +func (h *APIHandlers) DeleteTrainingDateAttendee(ctx context.Context, req DeleteTrainingDateAttendeeRequestObject) (DeleteTrainingDateAttendeeResponseObject, error) { + err := h.trainingDateAttendeeRepository.Delete(req.TrainingDateAttendeeID) + if err == training.ErrTrainingDateAttendeeNotFound { + return DeleteTrainingDateAttendee404ApplicationProblemPlusJSONResponse{ + NotFoundErrorApplicationProblemPlusJSONResponse: NotFoundErrorApplicationProblemPlusJSONResponse{ + Status: fiber.StatusNotFound, + Title: "Not Found: Training date attendee not found", + }}, nil + } else if err != nil { + return DeleteTrainingDateAttendee500ApplicationProblemPlusJSONResponse{ + InternalErrorApplicationProblemPlusJSONResponse: InternalErrorApplicationProblemPlusJSONResponse{ + Status: fiber.StatusInternalServerError, + Title: "Internal Server Error: Failed to delete training date attendee", + Detail: err.Error(), + }}, nil + } + + return DeleteTrainingDateAttendee204Response{}, nil +} + +func (h *APIHandlers) GetTrainingDateAttendee(ctx context.Context, req GetTrainingDateAttendeeRequestObject) (GetTrainingDateAttendeeResponseObject, error) { + ta, err := h.trainingDateAttendeeRepository.FindByID(req.TrainingDateAttendeeID) + if errors.Is(err, training.ErrTrainingDateAttendeeNotFound) { + return GetTrainingDateAttendee404ApplicationProblemPlusJSONResponse{ + NotFoundErrorApplicationProblemPlusJSONResponse: NotFoundErrorApplicationProblemPlusJSONResponse{ + Status: fiber.StatusNotFound, + Title: "Not Found: Training date attendee not found", + }}, nil + } else if err != nil { + return GetTrainingDateAttendee500ApplicationProblemPlusJSONResponse{ + InternalErrorApplicationProblemPlusJSONResponse: InternalErrorApplicationProblemPlusJSONResponse{ + Status: fiber.StatusInternalServerError, + Title: "Internal Server Error: Failed to get training date attendee", + Detail: err.Error(), + }}, nil + } + + return GetTrainingDateAttendee200JSONResponse{ + Id: ta.ID, + Name: ta.Name, + }, nil +} + +func (h *APIHandlers) UpdateTrainingDateAttendee(ctx context.Context, req UpdateTrainingDateAttendeeRequestObject) (UpdateTrainingDateAttendeeResponseObject, error) { + ta := training.TrainingDateAttendee{ + ID: req.TrainingDateAttendeeID, + Name: req.Body.Name, + } + + err := h.trainingDateAttendeeRepository.Update(&ta) + if err != nil { + return UpdateTrainingDateAttendee500ApplicationProblemPlusJSONResponse{ + InternalErrorApplicationProblemPlusJSONResponse: InternalErrorApplicationProblemPlusJSONResponse{ + Status: fiber.StatusInternalServerError, + Title: "Internal Server Error: Failed to update training date attendee", + Detail: err.Error(), + }}, nil + } + + return UpdateTrainingDateAttendee200JSONResponse{ + Id: ta.ID, + Name: ta.Name, + }, nil +}