feat!(website, backend): Update bulk file submission/revision format to use metadata file - #6922
feat!(website, backend): Update bulk file submission/revision format to use metadata file#6922tombch wants to merge 77 commits into
Conversation
…file category json if they exist, and centralised file validation after creation in aux table
…xisting tests working
…ly, with file paths for linking to metadata columns
…pplying of file maps to metadata tsv
…dividual submissions, and updated website tests
…culus into bulk-file-submissions
… different failed file linkages (missing from upload, metadata etc) and reflected the results of this in the UI for bulk submissions. removed submissionFileMapping linked/unlinked status as no longer needed
…ed/restructured FolderUploadComponent tests
| const rows = parsed.data.slice(1); | ||
|
|
||
| // Ensure a column exists for every category present in the resolved mapping | ||
| const categories = new Set( |
There was a problem hiding this comment.
hmm... I dont think we need to look at the values of each submissionId at this point as we already ensured that each submissionId will have each category in its fileMapping in resolveFileMappings, we could just look at the first entry to save computation. Alternatively, this information should be in the config submissionDataTypes.files?.categories?.map((c) => c.name)- I wonder if generally the list of categories should always come from the config to reduce needing to get the categories in each mapping.
There was a problem hiding this comment.
ah yeah good point, I will update to use the submissionDataTypes categories
There was a problem hiding this comment.
I updated the EditableMetadata.getMetadataTsv to add empty file categories to its tsv so we don't need this function to add them anymore. I have kept the check for file categories being present, as i think its useful as a stopgap - its not expensive to check and if we ever somehow had file mapping categories not present in the metadata it would mean those mappings weren't included, which would be really bad
| expect(await linesOf(result._unsafeUnwrap())).toEqual(['id\tcountry\tfiles.raw', 'e1\tCH\ta.txt:id-a']); | ||
| }); | ||
|
|
||
| it('leaves rows with no files for the category untouched', async () => { |
There was a problem hiding this comment.
hmm... do we actually want this behavior? this should never happen right? either the metadata referenced a reused file or parseSubmissionFileMapping should have failed?
| const existingFileCollisions = existingFiles.filter((file) => uniqueSelectedNames.has(file.name)); | ||
| // Check for collisions with existing files | ||
| const filePaths = new Set(awaiting.map((file) => file.path)); | ||
| const collisions = fileUploadState.files.filter((file) => filePaths.has(file.path)); |
There was a problem hiding this comment.
hmm shouldnt we be checking for collisions before we set the state to awaitingUrls?
There was a problem hiding this comment.
side thought: all the steps after the state awaitingUrls are handled in the useEffect for the folder component, it seems a bit odd to do this separately for the files - this can be done in a follow up PR
There was a problem hiding this comment.
We do in this case? For the handleFileSelect, the file upload state only gets set to awaitingUrls if it was undefined, so no collisions can occur. If the file upload state wasn't undefined we check for collisions, and if its > 0, display confirmation dialog, only then does the inline addFiles function run that requests the file urls and then sets the state to uploadInProgress. I guess what this does mean is that when hitting add additional files there is no visual state currently for those files awaiting urls - i think this could be updated in the future
…validate in applyFileMappings for categories
…nent.spec.tsx Co-authored-by: Anna (Anya) Parker <50943381+anna-parker@users.noreply.github.com>
…les, or folder with single level of subfolders
…culus into bulk-file-submissions
resolves #6883 and #5820
Breaking changes
Loculus deployments that carry out bulk submissions with extra files enabled will require users to update their bulk submission metadata file to include files.{category} column(s) that list the files for each submission. Details for how to do this for the current subfolder structure are described below in the 'Examples' section under 'Bulk uploads with subfolders'.
Summary
This PR restructures how files are linked to submissions by the website, as well as how file mappings are sent from the website to the backend, in both bulk and form submissions/revisions. Previously, bulk and form website submission/revisions attached a separate file mapping object. Now, users add a list of files to the submitted metadata tsv and the website adds file mappings for each submission before sending the files to the backend for submission/revision.
New
files.{category}columns are introduced within the metadata, and uploaded files must be linked to within here - this can be done simply by adding a space separated list of: the file names (name1 name2 name3, if uploading a flat folder of files) or the file names with the file paths (name1::path1 name2::path2 name3::path3, if uploading a folder containing subfolders - allowing for different submissions to use the same file names within a bulk upload).Examples
Bulk uploads with a flat folder of files
Bulk uploads of files can be carried out with a single flat folder of uniquely named files - the user just needs to link these files to the correct submission in the
metadata.tsv. For example, with this folder ofrawReads:The user must add the following
files.rawReadscolumn to theirmetadata.tsv:A user could also choose to give multiple output files the same name across submissions using the
name::pathsyntax:Bulk uploads with subfolders
The existing bulk uploads mechanism for extra files relied on (for each category) the user uploading a folder containing subfolders, where each subfolder was the submission ID for the files. An example folder for bulk
rawReadsupload:This structure can still remain the same - or a user can now upload any subfolder structure. But what is now required is a
files.rawReadscolumn in themetadata.tsv, with each file in a submission referenced byname::pathwherenameis the desired output file name in Loculus, andpathis the path to the file in the uploaded folder:Screenshots
Submission
fileName::filePathin the metadata file:This 'warning' is blocking - submission can't continue until they are resolved (an error toast would be displayed at submit).
Revision
files.{category}field is included in the downloaded original metadata for revisions, each file has a linked fileId:files.{category}field. Allows deletion of files by removing files from thefiles.{category}field, allows renaming of a file by reusing the fileId, allows adding new files (similar to initial submission).original:

revised:

PR Checklist
🚀 Preview: https://bulk-file-submissions.loculus.org