Skip to content

feat(website): resistance mutation sets as collections - #1181

Merged
fhennig merged 22 commits into
mainfrom
resistance-collections
May 21, 2026
Merged

feat(website): resistance mutation sets as collections#1181
fhennig merged 22 commits into
mainfrom
resistance-collections

Conversation

@fhennig

@fhennig fhennig commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Resistance mutation sets are now sourced from backend collections (IDs 1/2/3) rather than hard-coded arrays in TypeScript
  • Collections are fetched server-side in Wasap.astro (SSR) and passed as a prop to WasapPage, so no client-side fetch or loading state is needed for resistance data
  • The config is resolved server-side in Wasap.astro, picking prod vs staging collection IDs — staging overrides live in wastewaterOrganismStagingConfigs
  • resistanceData.ts contains the plain async fetch logic; useResistanceMutationSets hook deleted
  • Prod collections visible at: https://genspectrum.org/api/collections - I already created them so we don't break prod!

Screenshot

n/a

PR Checklist

  • All necessary documentation has been adapted.
  • The implemented feature is covered by an appropriate test.

@vercel

vercel Bot commented Apr 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
dashboards Ready Ready Preview, Comment May 18, 2026 10:36am

Request Review

@fhennig

fhennig commented Apr 29, 2026

Copy link
Copy Markdown
Contributor Author

Hey Fabian, the resistance stuff is fetched in the astro frontmatter, I think that's better because it's a simple Docker internal call. But I had it before with a React hook, the change is all in this commit: 2b50741 - Both approaches have pros and cons I'd say, we can also revert this commit if the hook approach is better.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Moves W-ASAP resistance mutation sets from hard-coded TypeScript arrays to backend collections, fetching them server-side in Wasap.astro and passing the resolved config + resistance data into the React page to avoid client-side loading.

Changes:

  • Replace resistanceMutationSets with resistanceMutationCollections (collection IDs + metadata) across config/types/tests.
  • Add server-side resistance collection fetching/building (resistanceData.ts) and plumb it through Wasap.astroWasapPage.
  • Remove the old hard-coded resistance mutations module and update the resistance filter UI to use set names derived from fetched data.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
website/src/views/pageStateHandlers/WasapPageStateHandler.spec.ts Updates test config to use resistanceMutationCollections.
website/src/types/wastewaterConfig.ts Switches COVID resistance config to collection-based IDs; adds staging config override export.
website/src/types/wastewaterConfig.spec.ts Adjusts config validation test to new property name.
website/src/components/views/wasap/wasapPageConfig.ts Updates WasapPageConfig to use ResistanceMutationCollectionConfig.
website/src/components/views/wasap/useWasapPageData.ts Threads displayMutationsBySet into the query path for resistance mode.
website/src/components/views/wasap/resistanceMutations.ts Deletes hard-coded resistance mutation sets + conversion helper.
website/src/components/views/wasap/resistanceData.ts Adds SSR fetch + transformation from collections to mutation annotations + display mutations.
website/src/components/views/wasap/WasapPage.tsx Accepts SSR-provided config + resistanceData, wiring them into gs-app + filters.
website/src/components/views/wasap/Wasap.astro Resolves prod vs staging config and fetches resistance collections server-side.
website/src/components/pageStateSelectors/wasap/filters/ResistanceMutationsFilter.tsx Switches selector inputs from full sets to set-name list.
website/src/components/pageStateSelectors/wasap/filters/ResistanceMutationsFilter.browser.spec.tsx Updates browser test to pass set names instead of mutation sets.
website/src/components/pageStateSelectors/wasap/WasapPageStateSelector.tsx Wires resistanceSetNames through to the resistance filter.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread website/src/components/views/wasap/useWasapPageData.ts Outdated
Comment thread website/src/components/views/wasap/useWasapPageData.ts
Comment thread website/src/components/views/wasap/Wasap.astro Outdated
Comment thread website/src/types/wastewaterConfig.ts
fhennig and others added 17 commits May 18, 2026 08:27
…cript

When SESSION_TOKEN is set, the script hits the website proxy at /api/collections
(which injects the user ID from the session) and passes the auth cookie.
Automatically uses the __Secure- cookie prefix for HTTPS targets.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Instead of hard-coding mutation lists in the codebase, fetch them at
runtime from the backend collections API (one collection per set:
3CLpro, RdRp, Spike). The seed script now uses mature protein names
(offset-adjusted) as variant names, so the name calculation is no
longer needed in client code. Offset and matureName are removed from
the frontend entirely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
useResistanceMutationSets now returns ResistanceData directly
(mutationAnnotations + displayMutationsBySet), removing the intermediate
ResistanceMutationSet type and resistanceMutations.ts entirely.
The selector/filter chain now takes plain string[] for set names.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The example data seeder on feat/example-data-seeder handles this now.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…errides

Add wastewaterOrganismStagingConfigs with staging resistance collection IDs
(1/2/3 for 3CLpro/RdRp/Spike). Wasap.astro now selects prod vs staging config
and passes it directly to WasapPage, removing the env dependency from React.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tance collections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
IDs confirmed at https://genspectrum.org/api/collections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…2, 3)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moves resistance collection fetching from a React Query hook to the Astro
SSR layer, so data is available before the page reaches the browser.
WasapPage now receives resistanceData as a prop instead of fetching it
client-side. Removes useResistanceMutationSets hook; logic lives in
resistanceData.ts as a plain async function.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Comment on lines +41 to +54
expect(result.mutationAnnotations).toEqual([
{
name: 'Nirmatrelvir resistant',
symbol: 'R',
description: 'Main protease inhibitors',
aminoAcidMutations: ['S:E484K'],
},
{
name: 'Nirmatrelvir resistant',
symbol: 'R',
description: 'Main protease inhibitors',
aminoAcidMutations: ['S:N501Y'],
},
]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Isn't this wrong? I would expect a single annotation with multiple mutations.

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.

No, we are already doing multiple annotations:

image

Maybe the example should be improved.

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.

done.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

When I log the annotations in the WasapPage, then I see a lot of annotations, each with a single mutation:
grafik

Wouldn't it make more sense to group them? Conceptually, each collection should yield a single annotation set with all its mutations.

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.

Yes we did that so we can get the "index shift" on them. for A432T this can be 3CLpro:A44T for example (432 -> 44). We wanted to have this (name of the mutation in context of the resistance mutation) individually for each mutation.

I can see your point though. We had it before in the way you describe it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As discussed: It makes sense and we'll leave it as it is for now. The filter inside the mutations over time component isn't nice, because it shows a long list of all those mutation annotations, but that's secondary.

@fhennig
fhennig merged commit 5c919a8 into main May 21, 2026
10 checks passed
@fhennig
fhennig deleted the resistance-collections branch May 21, 2026 08:08
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.

3 participants