Skip to content

Conversation

thomasleese
Copy link
Contributor

@thomasleese thomasleese commented Mar 21, 2025

This introduces a new model, Patient::ConsentStatus, which stores the status of a patient-programme pair in the database so it can queried and rendered quickly. Locally, I'm seeing the consent tab on sessions with 50,000 patients load almost instantly even when filtering on statuses. The session overview page has a slight improvement, but that will only load quickly once the other statuses are cached.

I've decided not to implement a state machine as had been previously discussed, but this could be built on top of this change to enhancement the functionality. For now, this effectively caches the existing logic that runs on the fly to the database.

I've also decided not to implement this using Rails callbacks and instead be explicit where the status is refreshed. This allows us to optimise for bulk refreshes, as is necessary when adding new programmes to sessions, running the seeds, or generally updating the status of an entire session.

This is proposed as an alternative to #3262 for consent statuses, we'd need to apply the same functionality to triage, programmes, sessions and next actions. If we're happy with this approach, we can migrate the statuses one by one to avoid a big bang approach unlike #3262.

@thomasleese thomasleese added refactor Improving maintainability performance Improving performance labels Mar 21, 2025
@thomasleese thomasleese force-pushed the cache-consent-status branch from 7876ee5 to 30019bc Compare March 22, 2025 07:11
@thomasleese thomasleese force-pushed the cache-consent-status branch from 30019bc to 07badab Compare March 23, 2025 08:23
@thomasleese thomasleese force-pushed the cache-consent-status branch from 07badab to 74eb8a1 Compare March 23, 2025 08:34
@thomasleese thomasleese force-pushed the cache-consent-status branch from 74eb8a1 to e626ccb Compare March 23, 2025 17:37
@thomasleese thomasleese force-pushed the cache-consent-status branch from e626ccb to 39a18f0 Compare March 23, 2025 20:45
@thomasleese thomasleese force-pushed the cache-consent-status branch from 39a18f0 to af0cd29 Compare March 23, 2025 20:53
@thomasleese thomasleese marked this pull request as ready for review March 23, 2025 21:02
@thomasleese thomasleese force-pushed the cache-consent-status branch from af0cd29 to 7caf3d6 Compare March 24, 2025 06:24
@thomasleese thomasleese force-pushed the cache-consent-status branch from 7caf3d6 to ee5b2fe Compare March 24, 2025 07:13
@thomasleese thomasleese removed the refactor Improving maintainability label Mar 24, 2025
@thomasleese thomasleese force-pushed the cache-consent-status branch from ee5b2fe to 66c5a13 Compare March 24, 2025 10:05
@thomasleese thomasleese added this to the v2.1.2 milestone Mar 24, 2025
@thomasleese thomasleese force-pushed the cache-consent-status branch from 66c5a13 to 1995557 Compare March 24, 2025 11:59
@thomasleese thomasleese force-pushed the cache-consent-status branch from 1995557 to 378c788 Compare March 24, 2025 16:33
@thomasleese thomasleese force-pushed the cache-consent-status branch from 1491f41 to edb77b1 Compare March 28, 2025 16:00
@thomasleese thomasleese force-pushed the cache-consent-status branch from edb77b1 to ebb2e85 Compare March 28, 2025 16:16
@thomasleese thomasleese changed the base branch from main to v2.1.2-wip March 28, 2025 16:20
@thomasleese thomasleese force-pushed the cache-consent-status branch from ebb2e85 to 55b5484 Compare March 28, 2025 16:22
@thomasleese thomasleese force-pushed the cache-consent-status branch from 55b5484 to 921f83b Compare March 28, 2025 16:29
This removes any usage of the `all` method on the `ConsentOutcome` class
in preparation for the removal of the `ConsentOutcome` class. I think it
also simplifies the code by avoiding the need to go through another
class to fetch all the consent records.
This removes usage of the `latest` method on the `ConsentOutcome` class
in preparation for the removal of this class. The logic has been moved
to a method on the `Patient` model.
This refactors the logic related to grouping consent responses in to a
class so it can be used in multiple places.
This creates a new model that will represent the consent status of a
patient/programme pair so the value can be queried in the database
directly rather than needing to generate the status on the fly each
time.
This adds a method which refreshes the status of a patient-programme
pair to be used in various other parts of the service. This is the main
logic that replaces the `ConsentOutcome` class, although the logic
itself should be the same.
This is a class which handles the process of updating the status of a
list of patient sessions, filtering either on the session or the
patient.
This ensures that at each point where a consent record is created or
updated, we update the consent status of the patient record.

I've decided to avoid using callbacks as I find they can lead to
suprising behaviour and this helps to keep the code explicit, however
I'm not against using callbacks if that's preferred.

This ensures that patients always have the necessary status models when
a programme is added to a session or a patient is added to a session.
This adds a couple of new Rake tasks that can be used to manually update
the status of a patient or a list of patients in a session.
This updates the factories to create instances of the new
`Patient::ConsentStatus` model to ensure the tests are running in
representative database.
This updates the various parts of the code that relied on the
`ConsentOutcome` class to determine the consent status of a patient to
instead use the new `Patient::ConsentStatus` model with the status
cached.
This can be safely removed as it's no longer being used and has been
replaced with the `Patient::ConsentStatus` model.
@thomasleese thomasleese force-pushed the cache-consent-status branch from 921f83b to c497667 Compare March 28, 2025 17:03
@tvararu tvararu temporarily deployed to mavis-pr-3263 March 28, 2025 17:03 Inactive
Copy link

Copy link
Contributor

@misaka misaka left a comment

Choose a reason for hiding this comment

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

🚀 Lots of edge cases, I wonder if we need to beef up our testing.

@thomasleese thomasleese merged commit b5bf568 into v2.1.2-wip Mar 28, 2025
11 checks passed
@thomasleese thomasleese deleted the cache-consent-status branch March 28, 2025 17:11
thomasleese added a commit that referenced this pull request Mar 31, 2025
This introduces a new model, `Patient::TriageStatus`, which stores the
triage status of a patient-programme pair in the database so it can
queried and rendered quickly. Locally, I'm seeing the triage tab on
sessions with 50,000 patients load almost instantly even when filtering
on statuses. The session overview page has a slight improvement, but
that will only load quickly once the other statuses are cached.

I've decided not to implement a state machine as had been previously
discussed, but this could be built on top of this change to enhancement
the functionality. For now, this effectively caches the existing logic
that runs on the fly to the database.

I've also decided not to implement this using Rails callbacks and
instead be explicit where the status is refreshed. This allows us to
optimise for bulk refreshes, as is necessary when adding new programmes
to sessions, running the seeds, or generally updating the status of an
entire session.

This follows up from #3263 which applies the same to the consents.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Improving performance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants