Skip to content

Conversation

@VishakhaSainani-Josh
Copy link
Collaborator

Allow user to view monthly overview, where in each contribution type it's monthly total count and coins is shown

Comment on lines +66 to +67
ContributionType string `db:"contribution_type"`
ContributionCount int `db:"contribution_count"`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to Type and Count

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also why this struct as db tags?

response.WriteJson(w, http.StatusOK, "user contributions fetched successfully", userContributions)
}

func (h *handler) GetContributionTypeSummaryForMonth(w http.ResponseWriter, r *http.Request) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name like ListMonlyContributionSummary would be more preferable

UpdatedAt time.Time `db:"updated_at"`
}

type ContributionTypeSummary struct {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update name

Comment on lines +43 to +44
month := r.URL.Query().Get("month")

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validate month before passing it to service layer


contributionTypeSummaryForMonth, err := h.contributionService.GetContributionTypeSummaryForMonth(ctx, month)
if err != nil {
slog.Error("error fetching contribution type summary for month")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also print error in the message

func (s *service) GetContributionTypeSummaryForMonth(ctx context.Context, monthParam string) ([]ContributionTypeSummary, error) {
month, err := time.Parse("2006-01", monthParam)
if err != nil {
slog.Error("error parsing month query parameter", "error", err)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Go programs, printing an error typically indicates that we've handled it. Therefore, it's best practice to either print the error or return it, but not both.
(same for all other)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to add more detail you can always wrap errors

return nil, err
}

contributionTypes, err := s.contributionRepository.GetAllContributionTypes(ctx, nil)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a practice in go, Use List as prefix and not get whenever fetching an array.

Comment on lines +307 to +321
var contributionTypeSummaryForMonth []ContributionTypeSummary

for _, contributionType := range contributionTypes {
contributionTypeSummary, err := s.contributionRepository.GetContributionTypeSummaryForMonth(ctx, nil, contributionType.ContributionType, month)
if err != nil {
if errors.Is(err, apperrors.ErrNoContributionForContributionType) {
contributionTypeSummaryForMonth = append(contributionTypeSummaryForMonth, ContributionTypeSummary{ContributionType: contributionType.ContributionType})
continue
}
slog.Error("error fetching contribution type summary", "error", err)
return nil, err
}

contributionTypeSummaryForMonth = append(contributionTypeSummaryForMonth, ContributionTypeSummary(contributionTypeSummary))
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could fetch all the Contribution summary for this month in a single db call then categorise them. This would save a lot of db calls.
(This problem is generally known as n + 1 query problem)

router.HandleFunc("PATCH /api/v1/user/email", middleware.Authentication(deps.UserHandler.UpdateUserEmail, deps.AppCfg))

router.HandleFunc("GET /api/v1/user/contributions/all", middleware.Authentication(deps.ContributionHandler.FetchUserContributions, deps.AppCfg))
router.HandleFunc("GET /api/v1/user/monthlyoverview", middleware.Authentication(deps.ContributionHandler.GetContributionTypeSummaryForMonth, deps.AppCfg))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With standard naming convention it should be /api/v1/user/overview/monthly or monthly can be query param, like /api/v1/user/overview?type=monthly

}

func (cr *contributionRepository) GetContributionTypeSummaryForMonth(ctx context.Context, tx *sqlx.Tx, contributionType string, month time.Time) (ContributionTypeSummary, error) {
userIdValue := ctx.Value(middleware.UserIdKey)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

userId should be passed by the service layer, and ctx values are generally accessed in the handler layer itself.
It Makes the function independent of the caller state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants