Expand description
Handlers for /api/v0/exercise-services/client.
A generic native-client API for exercise services: over plain HTTP it plays the role an exercise serviceโs in-browser IFrame plays on the web (download a stub, edit locally, submit, poll grading, review old submissions). Specs and answers stay opaque plugin-owned blobs the host only forwards.
Which services this API serves is not hardcoded: an exercise service is served exactly when it
declares supports_native_client in its service info. The course/exercise queries filter on that
capability, and submit rejects a task whose service lacks it.
Structsยง
- Exercise
Services ๐Client Routes ApiDoc - Supported
Client - Extractor guarding every client route: reads
X-Client-Versionand rejects obsolete clients before the handler runs. Yields no data; its presence applies the check.
Constantsยง
- CLIENT_
VERSION_ ๐HEADER - Header a client sends to advertise its version, e.g.
0.39.4. - MINIMUM_
CLIENT_ ๐VERSION - Minimum client version the backend accepts.
Nonedisables the check; a"major.minor.patch"string rejects older clients with426 Upgrade Required.
Functionsยง
- _add_
routes - check_
client_ ๐version - Rejects clients older than
minimumwith426 Upgrade Required; aNoneminimum passes everything. When a minimum is set, a missing or unparseable client version counts as obsolete. - client_
tasks_ ๐from_ slide - Filters a slideโs tasks down to the ones whose exercise service can serve this client and
converts them to the client shape. Shared by the list and single-exercise views so their
visibility rules cannot drift apart. Model solutions are stripped unless
reveal_model_solution; the list view never reveals them. - course_
page_ ๐url - The public URL of a course material page, or
Nonewhenbase_urlis not a valid URL. - derive_
exercise_ ๐progress - Derives the client-facing per-exercise progress from an exerciseโs maximum score and the userโs exercise state.
- download_
submission ๐ - GET /api/v0/exercise-services/client/submissions/:id/downloadResolves an exercise-slide submission (by the id returned from the submissions list, or bya submitโs
slide_submission_id) to the files it was made from, so the client can restorean old submission. - exercise_
chapter ๐ - exercise_
progress ๐ - The userโs progress on an exercise of the given course, with
statetheir exercise state (absent when they have never touched the exercise). Reads the try counts only when they can decide the standing. - get_
course ๐ - GET /api/v0/exercise-services/client/courses/:idReturns the course with the given id.
- get_
course_ ๐exercises - GET /api/v0/exercise-services/client/courses/:id/exercisesReturns the userโs exercise slides for the given course.Does not return anything for chapters which are not open yet.Selects slides for exercises with no slide selected yet.Only returns slides which have tasks whose exercise service can serve this client.
- get_
course_ ๐progress - GET /api/v0/exercise-services/client/courses/:id/progressReturns the current userโs progress on every exercise of the course that lives in anopen chapter (the same visibility as
courses/:id/exercises): its awarded and maximumpoints, completed/attempted signals and standing. One round-trip; course totals arederivable by summing the returned entries. - get_
courses ๐ - GET /api/v0/exercise-services/client/coursesReturns the courses that the user is currently enrolled on that contain exercises thisclient can be served.
- get_
exercise ๐ - GET /api/v0/exercise-services/client/exercises/:idReturns an exercise slide for the user for the given exercise.
- get_
exercise_ ๐submissions - GET /api/v0/exercise-services/client/exercises/:id/submissionsReturns the current userโs past submissions to the given exercise, newestfirst, each annotated with its grading score and progress if graded.
- get_
submission_ ๐grading - GET /api/v0/exercise-services/client/submissions/:id/gradingReturns the grading status of the given submission.
- has_
received_ ๐full_ points - Full points as the course material judges them, tolerating float rounding.
None(never graded) is not full points even when the exercise is worth 0. - is_
being_ ๐graded - A grading still in progress can award full points, so the score is not final even when the last try is spent.
- map_
grading_ ๐progress - Maps the internal grading-progress enum to the exercise-services-api one.
- model_
answer_ ๐kind - The client APIโs answer kind as the modelโs. Two enums rather than one because the client crate stays free of server-internal dependencies.
- model_
solution_ ๐should_ be_ revealed - Mirrors the project-wide โsolvedโ reveal rule (
controllers/course_material/exercises.rs,domain/exercises.rs): full points, or the per-slide attempt limit exhausted. - native_
client_ ๐capable_ slugs - Slugs of the exercise services this API can serve: exactly those declaring
supports_native_client. - open_
chapters ๐ - The courseโs currently open chapters by id. Shared by the exercise list and progress views so their visibility rules cannot drift apart.
- parse_
version ๐ - Parses a
major.minor.patchversion string into a comparable tuple. Missing minor/patch components default to0; a malformed string returnsNone. - share_
submission ๐ - POST /api/v0/exercise-services/client/submissions/:id/shareMints a shareable link to an existing submission of the current user and returnsits URL.
- store_
client_ ๐uploads - Stores the multipart parts and binds them to the exercise and user, so that a failure to record the binding cannot leave uploads the reaper is unable to find.
- submission_
files_ ๐response - Turns the hostโs own file records into the download response. Every tracked file is reachable, not just the first, so a multi-file submission is fully restorable.
- submit_
exercise ๐ - POST /api/v0/exercise-services/client/exercises/:id/submitAccepts an exercise submission from the user. A
fileanswer names files previously storedthrough this exerciseโsfilesendpoint, in the order they are to be graded; those files are theanswer. An answer that names no files is a JSON answer, carried indata_json. - upload_
exercise_ ๐files - POST /api/v0/exercise-services/client/exercises/:id/filesStores files for a later submission to this exercise. Every multipart field name must be aUUID the client picks; the host assigns the ids a submit request then names. Uploads arebound to this exercise and user, and unreferenced ones are reaped, so a client should uploadimmediately before submitting.Gated on the caller being able to answer the exercise at all, so stored objects cannot beaccumulated past a deadline or a closed exam. The per-slide try limit is only checked across thewhole exercise here, because this route is bound to an exercise rather than a slide.
- verify_
enrolled ๐ - Rejects a user who is not enrolled on the exerciseโs course.
- verify_
slide_ ๐and_ task_ belong - The URL path authorizes
exercise_id; the slide/task ids come from the request body, so without this check a caller could submit into an unrelated exerciseโs slide/task. - verify_
submission_ ๐owner - Rejects access to a submission owned by a different user.
- verify_
task_ ๐is_ client_ capable - Rejects a submission to a task whose exercise service cannot serve a native client.