Assignment (SeriesProblem)
One problem attached to one series — where a library entry becomes something a participant can solve, and where the per-use configuration lives.
Ta strona jest po angielsku
SeriesProblem is one problem assigned to one
series. This is where a problem stops being a
library entry and becomes something a participant can solve, which is why the
per-use configuration lives here and not on the problem.
The same problem may be assigned several times within one activity with
different settings, so an assignment points at exactly one series. Only the
assignment's Slug is unique in an activity; the problem behind it is not.
ActivityId is denormalised from the series so that the database can enforce
that uniqueness across the whole activity rather than within one series. A
rule that spans two tables and is enforced only in a service is a rule two
concurrent requests can both pass.
Identity
| Field | Meaning |
|---|---|
Slug | the label a participant sees and the URL segment, defaulting to a copy of the problem's own slug. Unique across the whole activity |
Name | overrides the problem's name for this assignment when set |
Order | position within the series |
Which content version is judged
| Field | Meaning |
|---|---|
PinnedProblemVersionId | the content version this assignment evaluates against |
Set when the problem is attached, to the library's current version. Publishing a correction therefore does not change what a running round is judged against, and following it is a manager's deliberate act rather than a side effect of fixing a typo.
Null still means "the current version at the moment a job is created", which a manager may choose, and which is only safe where the statement is not being edited underneath a running series.
Three JSON documents, and why they are three
All three are jsonb and opaque to the Server. They differ in audience and
in how they fail.
| Field | Read by | If it is wrong |
|---|---|---|
Config | the Runner | a wrong result |
Spec | the Client | a broken submit form |
Props | the Client, for display | an ugly screen |
Config is anything that changes the verdict — time and memory limits, the
set of languages that may be submitted, whatever else the problem type enforces.
It is laid over the package's own config.yml, and it is the only layer over
it.
Config reaches the participant too, deliberately: limits and language ids
are exactly what a problem page should show. The package's own config.yml
stays unpublished, because it names the checker.
Spec is what the Client needs to draw and validate the submit form — which
fields it has, which languages the select offers, what each is called.
Where `spec` and `config` disagree about languages, `config` wins
The Runner refuses whatever the assignment did not allow, whatever the form happened to offer.
Null means none in all three. There is no {} — an empty object beside null
would be two ways of saying the same nothing.
Points
MaxPoints is what the problem is worth here — a point value, not a
multiplier, so a round's total is read off the column rather than worked out.
The Server rescales wherever it reports a number:
round(score / maxScore × MaxPoints).
Null keeps the Runner's own scale. A package marking out of 70 reports out of 70; the problem's own scoring is not replaced by a convention nobody chose.
Zero and negative are refused, on both write paths, with
assignment.maxPoints.invalid. Zero is not a problem worth nothing: it is a
problem whose every number is 0 / 0, which a board reads as full marks.
An ICPC board is unaffected either way — it counts solves and penalty minutes, and a point value has nowhere to land in it.
MaxPoints is a column rather than an entry in Config for the standing
reason: the Server applies it, and it cannot apply what it does not read.
Limits the Server enforces
MaxUploadBytes, MaxAttachments and MaxSubmissions narrow the
activity's. Null inherits.
Columns rather than entries in Config, on purpose: the Server rejects an
oversized or too-frequent submission before anything runs. Time and memory are
the Runner's and stay in the configuration chain, because they only become
knowable while the solution is running.