Skip to content

chore: update prod from main - #1233

Merged
fhennig merged 4 commits into
prodfrom
main
Jun 2, 2026
Merged

chore: update prod from main#1233
fhennig merged 4 commits into
prodfrom
main

Conversation

@github-actions

Copy link
Copy Markdown

This pull request updates the prod branch with the latest changes from the main branch.

Make sure to merge this creating a merge commit.

Do not squash-merge this PR. Do not rebase and merge.

* feat(example-data): add Python pango lineage collection seeder

Adds example-data/lineages/seed.py, a Python script that fetches pango
lineage definitions from the upstream summary JSON and creates one
backend collection per lineage (nucleotide substitutions as variants).

Mirrors the patterns of seed.mjs: idempotent, supports --wait,
--url, --user-id, and --limit (default 10 for testing, 0 for all).

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

* feat(example-data): add requirements.txt and Dockerfile for lineages seeder

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

* refactor(example-data): unified Python seeder with source modules

Replaces the split JS/Python approach with a single Python codebase:

- seed.py: main entry point with argparse subcommands
  (covid-resistance-mutations, covid-pango-lineages)
- backend.py: shared BackendClient (wait, fetch, create)
- sources/resistance_mutations.py: port of seed.mjs resistance data
- sources/pango_lineages.py: pango lineage fetcher
- Dockerfile updated to run python3 seed.py

Running without a subcommand seeds all sources. --limit only applies
to the covid-pango-lineages subcommand (default: 10, 0 = all).

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

* feat(example-data): replace requirements.txt with pixi

- pixi.toml with [workspace] config, python 3.13, requests via PyPI
- pixi.lock committed for reproducibility
- Dockerfile updated to multi-stage: pixi builder copies site-packages
  into python:3.13-slim final image
- Defines tasks: seed, seed-lineages, seed-all-lineages, seed-resistance

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

* feat(example-data): upsert seed user via POST /users/sync before seeding

BackendClient now calls POST /users/sync (githubId=9999999999,
name="GenSpectrum Team") to obtain the internal user id before any
collection API calls. wait_for_backend() uses this call for polling.
Removes the --user-id CLI flag.

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

* chore: add Python and pixi entries to .gitignore

* docs(example-data): update README for Python/pixi seeder

* feat(example-data): upsert collections instead of skipping existing ones

Collections are now always created or updated (matched by name).
Adds BackendClient.update_collection() using PUT /collections/{id}.

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

* test(example-data): add test suite with mock source and mocked HTTP backend

38 tests across 4 files:
- test_backend.py: BackendClient (responses library for HTTP mocking)
- test_resistance_mutations.py: mature_name offset math, collection structure
- test_pango_lineages.py: collection building, variant filtering, HTTP fetch
- test_seed.py: seed_source create/update/mixed upsert logic

Run with: pixi run -e test test

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

* chore: rename example-data to collection-seeding

* fix(ci): update example-data path to collection-seeding, remove unused SEED_USER_ID

* fix(collection-seeding): use genspectrum-bot GitHub ID (218605180) for user sync

* refactor(collection-seeding): add TypedDict types (Collection, Variant, FilterObject, ExistingCollection)

* refactor(collection-seeding): authenticate via API key through website proxy

Replace the /users/sync + userId query param approach with a pre-provisioned
API key sent as Authorization: Bearer. The seeder now talks to the website
proxy (/api/collections) instead of the backend directly, removing the need
for backend access inside docker-compose.

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

* refactor(collection-seeding): rename backend.py to api.py, BackendClient to ApiClient

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

* refactor(collection-seeding): rename test_backend.py to test_api.py, document name-matching caveat

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

* chore(collection-seeding): pin pixi dependencies, fix README default URL

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

* fix(collection-seeding): fix Dockerfile COPY after backend.py→api.py rename, add missing models.py

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

* feat(collection-seeding): add repeat loop via REPEAT_INTERVAL_HOURS env var, run every 8h in compose

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

* docs(collection-seeding): document REPEAT_INTERVAL_HOURS in README

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

* refactor(collection-seeding): convert sources to classes with Source ABC

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

* README

* refactor(collection-seeding): move _build_collection into class, default to no lineage limit, add sample task

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

* docs(collection-seeding): add docstring to Source ABC

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

* refactor(collection-seeding): use None for no limit, move docstrings to classes, reorder resistance_mutations.py

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

* refactor(collection-seeding): move test collections out of MockSource into test_seed.py

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

* refactor(collection-seeding): --source flag, ALL_SOURCES registry, PangoLineagesSampleSource, --list command

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

* refactor(collection-seeding): move ALL_SOURCES to dedicated sources/registry.py

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

* refactor(collection-seeding): reorder seed.py with main first

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

* fix(collection-seeding): don't require --api-key for --list

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

* refactor(collection-seeding): move repeat loop into main(), add --repeat-interval-hours flag

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

* docs(collection-seeding): update README with sample source, SEEDER_API_KEY, and new CLI flags

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

* fix(collection-seeding): crash on error in repeat mode instead of swallowing

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

* feat(collection-seeding): restructure pango lineage variants into 4 fixed types

Each collection now has exactly 4 variants (nucleotide substitutions,
amino acid substitutions, new nucleotide substitutions, new amino acid
substitutions) instead of one variant per individual nucleotide substitution.

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

* fix(collection-seeding): strip organism from PUT body to avoid 400

CollectionUpdate has no organism field and the backend is configured with
fail-on-unknown-properties=true, so including organism caused every update
to fail with a Bad Request.

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

* refactor(collection-seeding): defer REPEAT_INTERVAL_HOURS parsing to argparse, remove seed.mjs

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

* chore(collection-seeding): rename pixi workspace from example-data-seeder to collection-seeding

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

* refactor(collection-seeding): use dict literal instead of Collection() constructor in pango_lineages

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

* refactor(collection-seeding): make Source.name an abstract property to enforce subclass definition

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

* chore(collection-seeding): add .dockerignore to exclude .pixi, tests, and docs from build context

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

* chore(collection-seeding): add ruff for linting and formatting

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

* chore(collection-seeding): use whitelist dockerignore with COPY . .

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

* refactor(collection-seeding): raise RuntimeError instead of sys.exit in api.py

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

* docs(collection-seeding): fix idempotency description in seed.py

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

* fix(collection-seeding): convert REPEAT_INTERVAL_HOURS env var to float

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

* docs: update collection-seeding ADR with Kotlin rationale

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

* feat(collection-seeding): exclude sample source from default run

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

* ci(collection-seeding): run Python tests before building Docker image

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

* fix(docker-compose): hardcode dummy system user API key for both backend and seeder

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

* fix(ci): set manifest-path for setup-pixi in seeder workflow

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

* feat(collection-seeding): add searchable tags to collection descriptions

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

* feat(collection-seeding): detect and delete orphaned pango lineage collections

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

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Update docs/arc42/09-architecture-decisions.md

Co-authored-by: Fabian Engelniederhammer <92720311+fengelniederhammer@users.noreply.github.com>

---------

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: Fabian Engelniederhammer <92720311+fengelniederhammer@users.noreply.github.com>
@vercel

vercel Bot commented May 29, 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 Jun 2, 2026 9:12am

Request Review

* feat(backend): add excludeSystemCollections param to GET /collections

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

* feat(website): exclude system collections from collections overview table

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

* fix(website): update CollectionsOverview test mock to expect excludeSystemCollections param

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

* test(backend): add tests for excludeSystemCollections param on GET /collections

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

* fix

* Change system user ID handling

* refactor(backend): make systemUserId cache thread-safe with @volatile

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

* refactor(test): make excludeSystemCollections optional in mockGetCollectionSummaries

The helper was silently asserting excludeSystemCollections='true' on every
call, making the signature misleading and preventing tests from asserting the
param is absent or false. It now only asserts the param when explicitly
provided, and existing browser-spec callers are updated to pass true explicitly.
Also renames a backend test to follow the GIVEN/WHEN/THEN convention.

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

* docs(backend): document excludeSystemCollections param in CollectionsController @operation

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

* refactor(website): simplify getCollectionSummaries by passing params object directly

Widen EndpointParameters.requestParams to accept string | boolean | undefined
so axios handles serialization natively, eliminating manual param assembly.

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

* refactor(website): remove unused BackendApiRouteMocker.mockGetCollectionSummaries

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

* format

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes the isStaging() gates that were redirecting to 404 and hiding the Collections menu entries outside of staging.

Closes #1108

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@fhennig
fhennig merged commit bbe221b into prod Jun 2, 2026
10 of 11 checks passed
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.

2 participants