feat(backend): add variantCount and includeVariants param to collections endpoint#1224
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
601ef37 to
6156432
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a lightweight “collection summary” shape to the collections list endpoint by introducing variantCount and an includeVariants query param, and updates the frontend to use counts instead of loading full variant lists for overview pages.
Changes:
- Backend: add
variantCounttoCollectionand addincludeVariantstoGET /collectionsto optionally omitvariants. - Frontend: split collection Zod schema into summary vs full collection, add
getCollectionSummaries, and update overview UI/tests to usevariantCount. - Tests/mocking: adapt backend and frontend tests + route mockers for the new list-response shape.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| website/src/types/Collection.ts | Introduces variantCount and a CollectionSummary schema/type split from full Collection. |
| website/src/components/collections/overview/CollectionsOverview.tsx | Switches overview list to fetch summaries and display variantCount. |
| website/src/components/collections/overview/CollectionsOverview.browser.spec.tsx | Updates UI tests to mock summaries and assert variantCount. |
| website/src/backendApi/backendService.ts | Adds getCollectionSummaries and makes getCollections force includeVariants=true. |
| website/src/backendApi/backendService.spec.ts | Updates service tests to validate summary-fetching behavior. |
| website/routeMocker.ts | Renames mocked backend/astro collections list route to summary variant. |
| backend/src/test/kotlin/org/genspectrum/dashboardsbackend/controller/CollectionsPutTest.kt | Adjusts PUT tests for nullable variants in the shared API model. |
| backend/src/test/kotlin/org/genspectrum/dashboardsbackend/controller/CollectionsPostTest.kt | Adjusts POST tests for nullable variants in the shared API model. |
| backend/src/test/kotlin/org/genspectrum/dashboardsbackend/controller/CollectionsGetTest.kt | Adds coverage for includeVariants behavior and variantCount. |
| backend/src/test/kotlin/org/genspectrum/dashboardsbackend/controller/CollectionsClient.kt | Extends test client with includeVariants query param support. |
| backend/src/main/kotlin/org/genspectrum/dashboardsbackend/model/collection/CollectionTable.kt | Adds variantCount population when mapping entities to API models. |
| backend/src/main/kotlin/org/genspectrum/dashboardsbackend/model/collection/CollectionModel.kt | Implements conditional variant loading vs counting for list endpoint. |
| backend/src/main/kotlin/org/genspectrum/dashboardsbackend/controller/CollectionsController.kt | Adds includeVariants request param to GET /collections. |
| backend/src/main/kotlin/org/genspectrum/dashboardsbackend/api/Collection.kt | Makes variants nullable/omittable and adds variantCount to API model. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…llections endpoint
GET /collections now includes variantCount on every response, and accepts
includeVariants=false (default) to omit the full variant list for lighter
list-view requests. GET /collections/{id} always returns variants.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lectionSummary type - Split collection schema into CollectionSummary (list, no variants) and Collection (single/create/update, with variants) - Rename getCollections -> getCollectionSummaries for the lightweight endpoint; add getCollections with includeVariants=true returning full Collection[] - CollectionsOverview uses getCollectionSummaries and reads variantCount directly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…udeVariants=false When variants are not requested, replace the batch fetch of all variant rows with a single COUNT(*) GROUP BY collection_id query. This avoids loading variant data (including large JSONB filter_object columns) for every collection, which was causing >7s response times at scale. 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>
f3ea85d to
afff678
Compare
| "organism": "covid", | ||
| "description": "A collection of interesting variants", | ||
| "variants": [], | ||
| "variantCount": 1, |
Comment on lines
+184
to
196
| test('should GET collection summaries without organism filter', async () => { | ||
| backendRouteMocker.mockGetCollectionSummaries([aCollection]); | ||
|
|
||
| await expect(backendService.getCollections()).resolves.to.deep.equal([aCollection]); | ||
| await expect(backendService.getCollectionSummaries()).resolves.to.deep.equal([aCollection]); | ||
| }); | ||
|
|
||
| test('should GET collections filtered by organism', async () => { | ||
| backendRouteMocker.mockGetCollections([aCollection], 'covid'); | ||
| test('should GET collection summaries filtered by organism', async () => { | ||
| backendRouteMocker.mockGetCollectionSummaries([aCollection], 'covid'); | ||
|
|
||
| await expect(backendService.getCollections({ organism: 'covid' })).resolves.to.deep.equal([aCollection]); | ||
| await expect(backendService.getCollectionSummaries({ organism: 'covid' })).resolves.to.deep.equal([ | ||
| aCollection, | ||
| ]); | ||
| }); |
| assertThat(createdCollection.updatedAt, notNullValue()) | ||
| assertThat(createdCollection.createdAt, equalTo(createdCollection.updatedAt)) | ||
| createdCollection.variants.forEach { variant -> | ||
| createdCollection.variants!!.forEach { variant -> |
Comment on lines
56
to
+60
| assertThat(updated.name, equalTo("Updated Name")) | ||
| assertThat(updated.description, equalTo("Updated Description")) | ||
| assertThat(updated.variants.size, equalTo(1)) | ||
| val firstVariant = updated.variants[0] as Variant.QueryVariant | ||
| val resultVariants = updated.variants!! | ||
| assertThat(resultVariants.size, equalTo(1)) | ||
| val firstVariant = resultVariants[0] as Variant.QueryVariant |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
resolves #1107
Summary
Backend
variantCount: Intfield to theCollectionresponse — always present on all collection endpointsincludeVariantsquery parameter (defaultfalse) toGET /collections: when false, thevariantskey is omitted from the response, giving callers a lighter payload for list viewsGET /collections/{id}is unchanged — always returns the full variant list (plus the newvariantCount)variantCountAPI Example
GET /collections(default,includeVariants=false):{ "id": 1, "name": "...", "variantCount": 3, "createdAt": "..." }GET /collections?includeVariants=true:{ "id": 1, "name": "...", "variantCount": 3, "variants": [...], "createdAt": "..." }Frontend
collectionSchemaZod schema intocollectionSummarySchema(novariants, for the list endpoint) andcollectionSchema(with requiredvariants, for single-collection/create/update endpoints), withvariantCounton bothbackendService.getCollections→getCollectionSummaries(returnsCollectionSummary[]); addedgetCollectionsthat passesincludeVariants=trueand returnsCollection[]CollectionsOverviewnow usesgetCollectionSummariesand readsvariantCountdirectly instead ofvariants.lengthPR Checklist