diff --git a/api/v1/openapi.yaml b/api/v1/openapi.yaml index b2749fb..d74c83f 100644 --- a/api/v1/openapi.yaml +++ b/api/v1/openapi.yaml @@ -255,13 +255,13 @@ paths: /v1/trainings/upcoming-dates: get: - summary: List all dates of a training + summary: List all upcoming dates of all trainings operationId: listAllUpcomingTrainingDates tags: - Trainings responses: "200": - description: List of training upcoming dates + description: List of all training upcoming dates content: application/json: schema: @@ -400,7 +400,17 @@ components: ListAllUpcomingTrainingDatesResponse: type: array items: - $ref: "#/components/schemas/TrainingDate" + type: object + properties: + trainingID: + $ref: "#/components/schemas/TrainingID" + dates: + type: array + items: + $ref: "#/components/schemas/TrainingDate" + required: + - trainingID + - dates ListTrainingUpcomingDatesResponse: type: array diff --git a/internal/server/api.gen.go b/internal/server/api.gen.go index 02a700c..9139831 100644 --- a/internal/server/api.gen.go +++ b/internal/server/api.gen.go @@ -47,7 +47,10 @@ type GetTrainingDateResponse = TrainingDate type GetTrainingResponse = Training // ListAllUpcomingTrainingDatesResponse defines model for ListAllUpcomingTrainingDatesResponse. -type ListAllUpcomingTrainingDatesResponse = []TrainingDate +type ListAllUpcomingTrainingDatesResponse = []struct { + Dates []TrainingDate `json:"dates"` + TrainingID TrainingID `json:"trainingID"` +} // ListTrainingDatesResponse defines model for ListTrainingDatesResponse. type ListTrainingDatesResponse = []TrainingDate @@ -181,7 +184,7 @@ type ServerInterface interface { // Create a new training // (POST /v1/trainings) CreateTraining(c *fiber.Ctx) error - // List all dates of a training + // List all upcoming dates of all trainings // (GET /v1/trainings/upcoming-dates) ListAllUpcomingTrainingDates(c *fiber.Ctx) error // Delete a training by ID @@ -948,7 +951,7 @@ type StrictServerInterface interface { // Create a new training // (POST /v1/trainings) CreateTraining(ctx context.Context, request CreateTrainingRequestObject) (CreateTrainingResponseObject, error) - // List all dates of a training + // List all upcoming dates of all trainings // (GET /v1/trainings/upcoming-dates) ListAllUpcomingTrainingDates(ctx context.Context, request ListAllUpcomingTrainingDatesRequestObject) (ListAllUpcomingTrainingDatesResponseObject, error) // Delete a training by ID @@ -1341,36 +1344,37 @@ func (sh *strictHandler) ListTrainingUpcomingDates(ctx *fiber.Ctx, trainingID Tr // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", + "yifra3yrL6v/BwAA//8Lqnf6hDQAAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/internal/server/api.go b/internal/server/api.go index 2746d68..7bc021b 100644 --- a/internal/server/api.go +++ b/internal/server/api.go @@ -382,35 +382,49 @@ func (h *APIHandlers) UpdateTrainingDate(ctx context.Context, req UpdateTraining } func (h *APIHandlers) ListAllUpcomingTrainingDates(ctx context.Context, req ListAllUpcomingTrainingDatesRequestObject) (ListAllUpcomingTrainingDatesResponseObject, error) { - trainingDates, err := h.trainingDateRepository.FindAllUpcoming() + trainings, err := h.trainingRepository.FindAll() if err != nil { return ListAllUpcomingTrainingDates500ApplicationProblemPlusJSONResponse{ InternalErrorApplicationProblemPlusJSONResponse: InternalErrorApplicationProblemPlusJSONResponse{ Status: fiber.StatusInternalServerError, - Title: "Internal Server Error: Failed to list upcoming training dates", + Title: "Internal Server Error: Failed to list all upcoming training dates", Detail: err.Error(), }}, nil } - data := make([]TrainingDate, len(trainingDates)) - for idx, td := range trainingDates { - data[idx] = TrainingDate{ - Id: td.ID, - Date: td.Date, - StartTime: td.StartTime.Format(trainingDateStartTimeFormat), - Days: td.Days, - IsOnline: td.IsOnline, - Location: td.Location, - Address: td.Address, - Capacity: td.Capacity, - Price: TrainingDatePrice{ - Amount: td.Price.Amount, - Currency: td.Price.Currency, - }, + response := make(ListAllUpcomingTrainingDatesResponse, len(trainings)) + for i, t := range trainings { + trainingDates, err := h.trainingDateRepository.FindUpcomingByTrainingID(t.ID) + if err != nil { + return ListAllUpcomingTrainingDates500ApplicationProblemPlusJSONResponse{ + InternalErrorApplicationProblemPlusJSONResponse: InternalErrorApplicationProblemPlusJSONResponse{ + Status: fiber.StatusInternalServerError, + Title: "Internal Server Error: Failed to list all upcoming training dates", + Detail: err.Error(), + }}, nil + } + + response[i].Dates = make([]TrainingDate, len(trainingDates)) + response[i].TrainingID = t.ID + for j, td := range trainingDates { + response[i].Dates[j] = TrainingDate{ + Id: td.ID, + Date: td.Date, + StartTime: td.StartTime.Format(trainingDateStartTimeFormat), + Days: td.Days, + IsOnline: td.IsOnline, + Location: td.Location, + Address: td.Address, + Capacity: td.Capacity, + Price: TrainingDatePrice{ + Amount: td.Price.Amount, + Currency: td.Price.Currency, + }, + } } } - return ListAllUpcomingTrainingDates200JSONResponse(data), nil + return ListAllUpcomingTrainingDates200JSONResponse(response), nil } func (h *APIHandlers) ListTrainingUpcomingDates(ctx context.Context, req ListTrainingUpcomingDatesRequestObject) (ListTrainingUpcomingDatesResponseObject, error) {