A PDF statement travels in a bundle - #99
Merged
Merged
Conversation
Two halves, and either alone leaves it broken: the exchange module read `.md` only, so `content.pdf` went in with the ordinary files and the Server refused the publish; and the upload Blob carried no media type, so a PDF that did arrive was stored under the name `content.md` and drawn as Markdown. `partition` moves into a module of its own so `check:exchange` can drive the routing rather than only the predicate it asks.
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.
A bundle carrying a PDF statement could not be imported, and this is both halves of why.
The first half — the name is filed under the wrong side
statementLanguageinsrc/exchange/types.tsmatched.mdalone, soisStatement("content.pdf")wasfalse,partitionput it among a version's ordinaryfiles, and the Server refusescontent.*there outright —version.file.isStatement,ProblemService.cs. The import dies part way through, after problems have already been created.src/content/types.tshad already solved this on 2026-08-26, for the same reason and with a comment saying so; the exchange module never got the same amendment. It now asks that module rather than answering the question a third time in a third regex, andstatementFileLanguageis exported for it.The second half — the bytes arrive untyped
uploadAllsentnew Blob([bytes]), which has notype, so the multipart part carriedapplication/octet-stream,FileServicerecorded that, andPackageNames.StatementExtensionreads anything that is notapplication/pdfas Markdown. So even with the first half fixed, a PDF statement is stored under the namecontent.md— andProblemPagedecides how to draw a statement from that name, so PDF bytes reach markdown-it.mediaTypeOfnames the type from the file's own name, which in a bundle is the version's own file name. Anything not in the table keeps the oldapplication/octet-stream;svgis deliberately absent.Why
partitionmovedcheck:exchangedoes not compileapply.ts— it talks to the API, and its header says so. With the split inside it, the only thing a check could reach was the predicate, and a file routed to the wrong side stayed invisible.src/exchange/partition.tsis pure and is now driven directly.This is not only the exchange bundle's problem
Every UVa import stores its statement as
content.pdf, so exporting a UVa problem from a real installation already produced a bundle that could not be imported anywhere. The ZawodyWeb converter writes the same name for a problem whose text was a PDF.What checks it
check:exchangegains the naming cases, the routing through the realpartition, the media types, and a cross-repository assertion that every name this product writes is one both sides call a statement. The round-trip fixture's own default statement is now a PDF with a Polish translation beside it.Sabotaged both ways before it was believed:
statementLanguageto.md-onlycontent.pdfandcontent-pl.pdf, including the two routing onesmediaTypeOfto alwaysapplication/octet-streamAll twelve offline gate steps pass, and
check:uiis green.