Skip to content

Lock Sapio Study in SS#5870

Open
wendyyang wants to merge 52 commits into
developfrom
5824-y26-172---lock-sapio-mastered-studies
Open

Lock Sapio Study in SS#5870
wendyyang wants to merge 52 commits into
developfrom
5824-y26-172---lock-sapio-mastered-studies

Conversation

@wendyyang

@wendyyang wendyyang commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Closes #

Changes proposed in this pull request

  • add a new field in Study table indicate mastered_in_sapio
  • block editing from SS UI
  • add condition in study controller
  • add update control in study model, only integration hub or console can update sapio study
  • feature flag with Flipper.

Instructions for Reviewers

[All PRs] - Confirm PR template filled
[Feature Branches] - Review code
[Production Merges to main]
    - Check story numbers included
    - Check for debug code
    - Check version

@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.84615% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.83%. Comparing base (1724e6a) to head (690cff9).
⚠️ Report is 38 commits behind head on develop.

Files with missing lines Patch % Lines
app/controllers/sdb/sample_manifests_controller.rb 20.00% 3 Missing and 1 partial ⚠️
app/models/study.rb 81.81% 2 Missing and 2 partials ⚠️
app/controllers/admin/studies_controller.rb 83.33% 0 Missing and 2 partials ⚠️
app/models/api_application.rb 66.66% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #5870      +/-   ##
===========================================
- Coverage    84.84%   84.83%   -0.02%     
===========================================
  Files         1494     1494              
  Lines        33954    34004      +50     
  Branches      3615     3630      +15     
===========================================
+ Hits         28809    28847      +38     
- Misses        4297     4302       +5     
- Partials       848      855       +7     
Flag Coverage Δ
javascript 76.31% <ø> (ø)
ruby 84.72% <78.84%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@wendyyang
wendyyang marked this pull request as ready for review June 22, 2026 22:03
@StephenHulme

Copy link
Copy Markdown
Member

I have a few general thoughts and suggestions, rather than comments about individual lines of code:

  1. Remove references to Sapio from the code. If these are required - like in the banner message - put them in the config file instead. This prevents our code from going out of date if Sapio (or Integration Hub) is renamed.

  2. Rename the mastered_in_sapio field to locked (or similar). This is shorter, and more descriptive while avoiding potentially-biased language.
    There is a movement in software to move away from historically problematic and non-inclusive language. Common examples of this are master -> main and black-list -> deny-list.

  3. Focus on preventing users from altering the study in the UI, instead of putting validations in the study model. Preventing API alterations is not in the story requirements. The workarounds for the Rails Console and Integration Hub requests can then also be removed.

I hope that all makes sense, please let me know if you have any questions or would like to chat on Zoom.

@wendyyang

Copy link
Copy Markdown
Contributor Author

I have a few general thoughts and suggestions, rather than comments about individual lines of code:

  1. Remove references to Sapio from the code. If these are required - like in the banner message - put them in the config file instead. This prevents our code from going out of date if Sapio (or Integration Hub) is renamed.

good points!

  1. Rename the mastered_in_sapio field to locked (or similar). This is shorter, and more descriptive while avoiding potentially-biased language.

May ask the team for suggestions.

There is a movement in software to move away from historically problematic and non-inclusive language. Common examples of this are master -> main and black-list -> deny-list.
3. Focus on preventing users from altering the study in the UI, instead of putting validations in the study model. Preventing API alterations is not in the story requirements. The workarounds for the Rails Console and Integration Hub requests can then also be removed.

This worths discussions.

The Acceptance criteria state:
SequenceScape users will not be able to edit ANY fields of Sapio study.
SequenceScape users will not be able to change a Sapio study's state e.g. activate it or deactivate it.
SequenceScape users cannot create a "Sapio study" in SequenceScape.

There are multiple entries to do the above actions. Implementing restrictions on controller/UI level may not be sufficient. It is easy to miss some of them. Future development may add new controllers to update study without realise the need of adding the restrictions. The consequence of that could cause the studies in Sapio and SS are not consistent. I think Implementing validation on model level provide a single point of enforcement and reduces the risk of missing an update path.

Any harm of doing model level validations? One thing I can think of is the validations may only apply for certain fields, not block all fields for update.

I hope that all makes sense, please let me know if you have any questions or would like to chat on Zoom.

@yoldas yoldas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I have added some comments but avoided repeating the same comment everywhere.

  • About "SequenceScape will not send or create Study data to the MLWH database for Sapio studies.": broadcast_with_warren macro will send the study to MLWH independent of how it is updated. Something like this might cover after_commit case: Register a handler instead of using the default:

broadcast_with_warren(handler: SapioAwareStudyHandler.new)

its def <<(message) method then either ignores the message or routes it to Warren.handler << message

where message.record would be a Study.

  • Also to cover after_touch case, override the rebroadcast method of Study.

  • I can't see how the story criteria item "not accession Sapio Study data to the EBI." is prevented by this PR.

Comment thread app/controllers/admin/studies_controller.rb Outdated
Comment thread app/controllers/admin/studies_controller.rb Outdated
def validate_api_key(api_key)
ApiApplication.find_by!(key: api_key)
api_application = ApiApplication.find_by!(key: api_key)
Current.api_application = api_application

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

praise: this is very useful for the request scope.

note: We might have add an ApiApplication.integration_hub? to avoid checking against strings everywhere: Current.api_application.integration_hub?

Comment thread app/models/sample_manifest.rb Outdated
Comment thread app/models/study.rb
Comment thread app/views/studies/information/show.html.erb Outdated
Comment thread db/migrate/20260612120000_add_mastered_in_sapio_to_studies.rb

@StephenHulme StephenHulme left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Lots of work's gone into this and it's looking good overall : )
I've added some suggestions around functions and accessioning.

Comment thread app/models/current.rb Outdated
# so that it can be accessed in models and other places where the controller context is not available.

class Current < ActiveSupport::CurrentAttributes
attribute :api_application

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would very much like to remove the reliance on CurrentAttributes if at all possible. This is because it blurs the line between controller and model making maintenance much harder in the future.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

refactored

Comment thread app/models/study.rb

# This validation prevents any updates to a study that is managed in SAPIO
# unless the request is coming from Integration Hub
def prevent_updates_when_mastered_in_sapio

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could we change this to allow updates from the api? This solves several naming concerns and also removes the need to check against the request coming from the integration hub itself.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will Integration hub be the only user to use SS study API? What about other applications/users trying to call SS API, to update the study? How to prevent those cases if not checking if the request from Integration hub?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Most likely, I think. Although there is a case to be made for principle of least priviledge, but Sequencescape doesn't currently support authorisation, compared to authentication.

<% add :menu, "Study QC Reports" => study_reports_study_path(@study) -%>

<% if permitted_to_accession?(@study) & @study.samples_accessionable? %>
<% if permitted_to_accession?(@study) & @study.samples_accessionable? && !@study.mastered_in_sapio %>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think the feature-flag check could be added to def samples_accessionable?, simplifying the code here and propagating to the rest of the accessioning functionality?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

updated.

Comment thread spec/controllers/admin/studies_controller_spec.rb
@wendyyang
wendyyang requested review from StephenHulme and yoldas July 9, 2026 19:52

@andrewsparkes andrewsparkes left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks really good!

Suggestion: For UAT ask the SSRs to test it, see if they can find any way to update the study or the samples in it that you might have missed!

def new
@study = Study.find_by(id: params[:study_id])

if @study&.ui_locked?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So to be clear, if the Study is now in Sapio the assumption is all Samples will be entered via Sapio too?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

And edited there, instead of via sample manifest re-uploads in SS?

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

Labels

None yet

Projects

None yet

4 participants