diff --git a/docs/spec/components/schemas/DailyQuestionDetails.yaml b/docs/spec/components/schemas/DailyQuestionDetails.yaml index 628b8ed..baf7ca5 100644 --- a/docs/spec/components/schemas/DailyQuestionDetails.yaml +++ b/docs/spec/components/schemas/DailyQuestionDetails.yaml @@ -13,7 +13,6 @@ allOf: - correct_answer - time_for_answer - starts_at - - created_at - num_correct_answers - num_incorrect_answers - num_all_participants @@ -57,10 +56,6 @@ allOf: type: string description: Start date when this question is available, hours and minutes are always 0 example: "2024-08-26T00:00:00Z" - created_at: - type: string - description: Start date when this question was create - example: "2024-08-26T00:00:00Z" num_correct_answers: type: integer format: int64 diff --git a/internal/data/daily_questions.go b/internal/data/daily_questions.go index b9e32d5..0872f56 100644 --- a/internal/data/daily_questions.go +++ b/internal/data/daily_questions.go @@ -50,7 +50,7 @@ type DailyQuestionsQ interface { FilterByCreatedAtAfter(date time.Time) DailyQuestionsQ FilterByStartsAtAfter(date time.Time) DailyQuestionsQ FilterByID(ID int64) DailyQuestionsQ - FilterDayQuestions(location *time.Location, day time.Time) DailyQuestionsQ + FilterDayQuestions(day time.Time) DailyQuestionsQ IncrementCorrectAnswer() error IncrementIncorrectAnswer() error diff --git a/internal/data/pg/daily_questions.go b/internal/data/pg/daily_questions.go index 8a76bd4..61b3407 100644 --- a/internal/data/pg/daily_questions.go +++ b/internal/data/pg/daily_questions.go @@ -140,13 +140,11 @@ func (q *dailyQuestionsQ) FilterTodayQuestions(offset int) data.DailyQuestionsQ }) } -func (q *dailyQuestionsQ) FilterDayQuestions(location *time.Location, day time.Time) data.DailyQuestionsQ { - dayInLocation := day.In(location) - dayStart := time.Date(dayInLocation.Year(), dayInLocation.Month(), dayInLocation.Day(), 0, 0, 0, 0, location) - dayEnd := dayStart.Add(24 * time.Hour) +func (q *dailyQuestionsQ) FilterDayQuestions(day time.Time) data.DailyQuestionsQ { + dayEnd := day.Add(24 * time.Hour) return q.applyCondition(squirrel.And{ - squirrel.GtOrEq{"starts_at": dayStart}, + squirrel.GtOrEq{"starts_at": day}, squirrel.Lt{"starts_at": dayEnd}, }) } diff --git a/internal/service/handlers/daily_question_create.go b/internal/service/handlers/daily_question_create.go index 3fd5d1b..c6646b2 100644 --- a/internal/service/handlers/daily_question_create.go +++ b/internal/service/handlers/daily_question_create.go @@ -24,21 +24,11 @@ func CreateDailyQuestion(w http.ResponseWriter, r *http.Request) { req, err := requests.NewDailyQuestion(r) if err != nil { - Log(r).WithError(err).Error("Error get request NewDailyQuestion") ape.RenderErr(w, problems.BadRequest(err)...) return } attributes := req.Data.Attributes - if req.Data.Type != resources.DAILY_QUESTIONS { - err := fmt.Errorf("invalid request data type %s", req.Data.Type) - Log(r).WithError(err).Error("Invalid data type") - ape.RenderErr(w, problems.BadRequest(validation.Errors{ - "type": fmt.Errorf("%v not allowed for this endpoint, must be %v err: %s", req.Data.Type, resources.DAILY_QUESTIONS, err), - })...) - return - } - err = ValidateOptions(attributes.Options) if err != nil { Log(r).WithError(err).Error("Error Answer Options") @@ -49,7 +39,7 @@ func CreateDailyQuestion(w http.ResponseWriter, r *http.Request) { } location := DailyQuestions(r).Location - timeReq, err := time.Parse("2006-01-02", attributes.StartsAt) + timeReq, err := time.ParseInLocation("2006-01-02", attributes.StartsAt, location) if err != nil { Log(r).WithError(err).Error("Failed to parse start time") ape.RenderErr(w, problems.BadRequest(validation.Errors{ @@ -66,7 +56,7 @@ func CreateDailyQuestion(w http.ResponseWriter, r *http.Request) { return } - question, err := DailyQuestionsQ(r).FilterDayQuestions(location, timeReq).Get() + question, err := DailyQuestionsQ(r).FilterDayQuestions(timeReq).Get() if err != nil { Log(r).WithError(err).Error("Error on this day") ape.RenderErr(w, problems.InternalError()) @@ -110,23 +100,23 @@ func CreateDailyQuestion(w http.ResponseWriter, r *http.Request) { return } - stmt := data.DailyQuestion{ + dailyQuestion := data.DailyQuestion{ Title: attributes.Title, TimeForAnswer: attributes.TimeForAnswer, Reward: attributes.Reward, AnswerOptions: answerOptions, CorrectAnswer: attributes.CorrectAnswer, - StartsAt: timeReq, + StartsAt: timeReq.UTC(), } - err = DailyQuestionsQ(r).Insert(stmt) + err = DailyQuestionsQ(r).Insert(dailyQuestion) if err != nil { Log(r).WithError(err).Error("Error ger request NewDailyQuestion") ape.RenderErr(w, problems.InternalError()) return } - question, err = DailyQuestionsQ(r).FilterDayQuestions(location, timeReq).Get() + question, err = DailyQuestionsQ(r).FilterDayQuestions(timeReq.UTC()).Get() if err != nil { Log(r).WithError(err).Error("Error on this day") ape.RenderErr(w, problems.InternalError()) @@ -138,7 +128,7 @@ func CreateDailyQuestion(w http.ResponseWriter, r *http.Request) { return } - ape.Render(w, NewDailyQuestionCreate(&stmt, attributes.Options, question.ID)) + ape.Render(w, NewDailyQuestionCreate(&dailyQuestion, attributes.Options, question.ID)) } func ValidateOptions(options []resources.DailyQuestionOptions) error { @@ -182,7 +172,6 @@ func NewDailyQuestionCreate(q *data.DailyQuestion, options []resources.DailyQues Reward: q.Reward, TimeForAnswer: q.TimeForAnswer, StartsAt: q.StartsAt.String(), - CreatedAt: time.Now().UTC().String(), }, }, } diff --git a/internal/service/handlers/daily_question_delete.go b/internal/service/handlers/daily_question_delete.go index 8c0ad09..fbc308c 100644 --- a/internal/service/handlers/daily_question_delete.go +++ b/internal/service/handlers/daily_question_delete.go @@ -58,8 +58,8 @@ func DeleteDailyQuestion(w http.ResponseWriter, r *http.Request) { ape.RenderErr(w, problems.InternalError()) return } - - response, err := NewDailyQuestionDelete(ID, deletedQuestion) + loc := DailyQuestions(r).Location + response, err := NewDailyQuestionDelete(ID, deletedQuestion, loc) if err != nil { Log(r).WithError(err).Error("Error deleting daily question") ape.RenderErr(w, problems.InternalError()) @@ -68,7 +68,7 @@ func DeleteDailyQuestion(w http.ResponseWriter, r *http.Request) { ape.Render(w, response) } -func NewDailyQuestionDelete(ID int64, q data.DailyQuestion) (resources.DailyQuestionDetailsResponse, error) { +func NewDailyQuestionDelete(ID int64, q data.DailyQuestion, loc *time.Location) (resources.DailyQuestionDetailsResponse, error) { var options []resources.DailyQuestionOptions err := json.Unmarshal(q.AnswerOptions, &options) if err != nil { @@ -85,8 +85,7 @@ func NewDailyQuestionDelete(ID int64, q data.DailyQuestion) (resources.DailyQues CorrectAnswer: q.CorrectAnswer, Reward: q.Reward, TimeForAnswer: q.TimeForAnswer, - StartsAt: q.StartsAt.String(), - CreatedAt: q.CreatedAt.String(), + StartsAt: q.StartsAt.In(loc).String(), }, }, }, nil diff --git a/internal/service/handlers/daily_question_edit.go b/internal/service/handlers/daily_question_edit.go index 19380b6..819cf11 100644 --- a/internal/service/handlers/daily_question_edit.go +++ b/internal/service/handlers/daily_question_edit.go @@ -36,19 +36,10 @@ func EditDailyQuestion(w http.ResponseWriter, r *http.Request) { req, err := requests.NewDailyQuestionEdit(r) if err != nil { - Log(r).WithError(err).Error("Error creating daily question edit request") ape.RenderErr(w, problems.BadRequest(err)...) return } attributes := req.Data.Attributes - if req.Data.Type != resources.DAILY_QUESTIONS { - err := fmt.Errorf("invalid request data type %s", req.Data.Type) - Log(r).WithError(err).Error("Invalid data type") - ape.RenderErr(w, problems.BadRequest(validation.Errors{ - "type": fmt.Errorf("%v not allowed for this endpoint, must be %v err: %s", req.Data.Type, resources.DAILY_QUESTIONS, err), - })...) - return - } question, err := DailyQuestionsQ(r).FilterByID(ID).Get() if err != nil { @@ -78,7 +69,8 @@ func EditDailyQuestion(w http.ResponseWriter, r *http.Request) { } if attributes.StartsAt != nil { - timeReq, err := time.Parse("2006-01-02", *attributes.StartsAt) + location := DailyQuestions(r).Location + timeReq, err := time.ParseInLocation("2006-01-02", *attributes.StartsAt, location) if err != nil { Log(r).WithError(err).Error("Failed to parse start time") ape.RenderErr(w, problems.BadRequest(validation.Errors{ @@ -95,8 +87,7 @@ func EditDailyQuestion(w http.ResponseWriter, r *http.Request) { return } - location := DailyQuestions(r).Location - question, err := DailyQuestionsQ(r).FilterDayQuestions(location, timeReq).Get() + question, err := DailyQuestionsQ(r).FilterDayQuestions(timeReq).Get() if err != nil { Log(r).WithError(err).Error("Error on this day") ape.RenderErr(w, problems.InternalError()) @@ -107,7 +98,7 @@ func EditDailyQuestion(w http.ResponseWriter, r *http.Request) { ape.RenderErr(w, problems.Conflict()) return } - requestBody[data.ColStartAt] = attributes.StartsAt + requestBody[data.ColStartAt] = timeReq.UTC() } if attributes.CorrectAnswer != nil { diff --git a/internal/service/handlers/daily_questions_select.go b/internal/service/handlers/daily_questions_select.go index f11a009..cada47e 100644 --- a/internal/service/handlers/daily_questions_select.go +++ b/internal/service/handlers/daily_questions_select.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "time" "github.com/rarimo/geo-auth-svc/pkg/auth" "github.com/rarimo/geo-points-svc/internal/data" @@ -33,7 +34,8 @@ func FilterStartAtDailyQuestions(w http.ResponseWriter, r *http.Request) { return } - resp, err := NewDailyQuestionsFilterDate(res) + loc := DailyQuestions(r).Location + resp, err := NewDailyQuestionsFilterDate(res, loc) if err != nil { Log(r).WithError(err).Error("Error filtering questions") ape.RenderErr(w, problems.InternalError()) @@ -54,7 +56,7 @@ func FilterStartAtDailyQuestions(w http.ResponseWriter, r *http.Request) { ape.Render(w, resp) } -func NewDailyQuestionModel(question data.DailyQuestion) (resources.DailyQuestionDetails, error) { +func NewDailyQuestionModel(question data.DailyQuestion, loc *time.Location) (resources.DailyQuestionDetails, error) { var options []resources.DailyQuestionOptions err := json.Unmarshal(question.AnswerOptions, &options) @@ -67,23 +69,22 @@ func NewDailyQuestionModel(question data.DailyQuestion) (resources.DailyQuestion Key: resources.NewKeyInt64(question.ID, resources.DAILY_QUESTIONS), Attributes: resources.DailyQuestionDetailsAttributes{ CorrectAnswer: question.CorrectAnswer, - CreatedAt: question.CreatedAt.String(), NumAllParticipants: question.NumAllParticipants, NumCorrectAnswers: question.NumCorrectAnswers, NumIncorrectAnswers: question.NumIncorrectAnswers, Options: options, Reward: question.Reward, - StartsAt: question.StartsAt.String(), + StartsAt: question.StartsAt.In(loc).String(), TimeForAnswer: question.TimeForAnswer, Title: question.Title, }, }, nil } -func NewDailyQuestionsFilterDate(questions []data.DailyQuestion) (resources.DailyQuestionDetailsListResponse, error) { +func NewDailyQuestionsFilterDate(questions []data.DailyQuestion, loc *time.Location) (resources.DailyQuestionDetailsListResponse, error) { list := make([]resources.DailyQuestionDetails, len(questions)) for i, q := range questions { - qModel, err := NewDailyQuestionModel(q) + qModel, err := NewDailyQuestionModel(q, loc) if err != nil { return resources.DailyQuestionDetailsListResponse{}, fmt.Errorf("error make %s daily question model, %s", q, err) } diff --git a/internal/service/requests/daily_question_create.go b/internal/service/requests/daily_question_create.go index 7ddf96d..e42e161 100644 --- a/internal/service/requests/daily_question_create.go +++ b/internal/service/requests/daily_question_create.go @@ -16,7 +16,7 @@ func NewDailyQuestion(r *http.Request) (req resources.DailyQuestionCreateRespons return req, validation.Errors{ "data/id": validation.Validate(&req.Data.ID), - "data/type": validation.Validate(&req.Data.Type, validation.Required), + "data/type": validation.Validate(&req.Data.Type, validation.Required, validation.In(resources.DAILY_QUESTIONS)), "data/attributes": validation.Validate(&req.Data.Attributes, validation.Required), }.Filter() } diff --git a/internal/service/requests/daily_question_edit.go b/internal/service/requests/daily_question_edit.go index 9017b4d..4434931 100644 --- a/internal/service/requests/daily_question_edit.go +++ b/internal/service/requests/daily_question_edit.go @@ -16,7 +16,7 @@ func NewDailyQuestionEdit(r *http.Request) (req resources.DailyQuestionEditRespo return req, validation.Errors{ "data/id": validation.Validate(&req.Data.ID), - "data/type": validation.Validate(&req.Data.Type, validation.Required), + "data/type": validation.Validate(&req.Data.Type, validation.Required, validation.In(resources.DAILY_QUESTIONS)), "data/attributes": validation.Validate(&req.Data.Attributes, validation.Required), }.Filter() } diff --git a/resources/model_daily_question_details_attributes.go b/resources/model_daily_question_details_attributes.go index 52b635a..a4ddda4 100644 --- a/resources/model_daily_question_details_attributes.go +++ b/resources/model_daily_question_details_attributes.go @@ -7,8 +7,6 @@ package resources type DailyQuestionDetailsAttributes struct { // Correct answer ID CorrectAnswer int64 `json:"correct_answer"` - // Start date when this question was create - CreatedAt string `json:"created_at"` // Users who received the question, those who answered and those who did not answer in the time given to them NumAllParticipants int64 `json:"num_all_participants"` // Number of correct answers