Skip to content

CheckinsController#index loads a user's entire check-in history to render one day #874

Description

@suttondemlong

Summary

Api::V1::CheckinsController#index filters check-ins in Ruby instead of in MongoDB. When the date param is present, the endpoint loads every check-in the user has ever created into memory and then discards all but one day's worth.

Details

https://github.com/rubyforgood/Flaredown/blob/master/backend/app/controllers/api/v1/checkins_controller.rb#L10-L12

render json: current_user.checkins.includes([:harvey_bradshaw_index, :promotion_rate, :conditions, :symptoms, :treatments]).select { |x|
  x.date.to_date == Date.parse(date)
}

.select here takes a block, so it is Enumerable#select, not Mongoid::Criteria#select. Calling it forces the criteria to load. The includes(...) call makes it worse by eager-loading the associated documents for the whole history, not just the matching day.

Impact

This is the endpoint the web and native clients hit to render a single day's check-in, so it is one of the hottest paths in the app. Cost scales linearly with account age: a user who has checked in daily for three years pulls ~1,100 documents plus their embedded conditions, symptoms and treatments on every day-view request, to render one. Since Flaredown is aimed at people tracking chronic conditions over long periods, the users hurt most are the most engaged ones.

Proposed fix

Checkin already has both pieces needed, and neither is being used here:

  • scope :by_date, ->(startkey, endkey) { where(:date.gte => startkey, :date.lte => endkey) }backend/app/models/checkin.rb#L50
  • index(date: 1, encrypted_user_id: 1)backend/app/models/checkin.rb#L39

Replace the in-Ruby filter with the existing scope over the parsed day's bounds so the query is served by the existing compound index.

Behaviour should be unchanged: the existing specs in spec/controllers/api/v1/checkins_controller_spec.rb cover multiple check-ins on the same calendar day and check-ins on neighbouring days, and must keep passing.

Note on indexes

Worth confirming separately that rake db:mongoid:create_indexes has actually been run against production. I could not find anything in the repo that invokes it — no Procfile release phase, and Rakefile deploy runs only rake db:migrate — so the declared indexes may not exist on the deployed cluster. That is a separate issue, but it affects how much this fix buys in practice.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions