Skip to main content

Module suotar

Module suotar 

Source
Expand description

Client for Suotar, the University of Helsinki study registry.

Every endpoint is a batch. Per-item outcomes arrive as HTTP 200 and are read from each item’s status and code; only request-level failures are 4xx/5xx and Err. Items are matched back by requestItemId, never by position.

Modules§

endpoints
One marker type per SuotarEndpoint, for SuotarClient::post.

Macros§

request_item 🔒

Structs§

CreditRange
Sisu’s credit range. Suotar refuses an import against one missing either bound.
DatePeriod
Sisu’s LocalDateRange: start inclusive, end exclusive, either end possibly open.
EnrolmentResolutionResult
An enrolment or attainment that cannot be read drops out alone rather than taking the item with it.
EnrolmentsListedResult
ImportAttainmentRequestItem
ImportAttainmentResult
One shape for every import result: sent, sisuTimeout and duplicateRequestItem fill the submitted pair, duplicateAttainment fills attainment, notImprovedAttainment fills previous_attainment.
ListByCourseRequestItem
Lists every realisation of the code; Suotar refuses the whole request if an item names one.
ListedEnrolment
Passed through from Suotar’s importer like SuotarEnrolment, so every field may be absent.
ListedPerson
LocalizedName
NoSuotarCallAudit
PersonResult
RequestLevelErrorBody 🔒
ResolveEnrolmentRequestItem
ResolvePersonRequestItem
SuotarAttainment
Covers the contract bodies: the bare {id, type} of verify’s registered, the fuller one behind import’s duplicateAttainment and notImprovedAttainment, and the ones an enrolment answer lists as already held, where every field but the id and type may be missing. A duplicateAttainment Suotar answers from its own recent sends names the AssessmentItemAttainment it submitted, and has no state or registrationDate.
SuotarBatchResponse
SuotarCallContext
Both fields are audit-row columns: worker_name separates the submitter from the verify poller from a manual retry, and the ids replace the identifiers scrubbing removes from stored bodies.
SuotarCallFinished
SuotarCallStarted
SuotarClient
SuotarEnrolment
An enrolment as Suotar passes it through from its importer. Only the id is required: a field that is missing or unreadable reads as absent rather than dropping the enrolment.
SuotarError
A Suotar call that got no batch response. SuotarError::variant and SuotarError::was_sent are what a caller decides by; the message and the source are for the logs and the audit trail.
SuotarItemError
SuotarResponseItem
UnpairedItemIds 🔒
The requestItemIds a response does not pair with what was sent.
ValidateCourseCodeRequestItem
ValidateCourseCodeResult
VerifyAttainmentRequestItem
VerifyAttainmentResult
registered fills attainment; submissionPending fills the submitted pair and retry_after.

Enums§

RequestLevelErrorDetail 🔒
The envelope’s {code, message}, or the bare string Suotar’s fall-through route answers with.
SuotarEndpoint
SuotarErrorVariant
How a call to Suotar failed at the request level. Per-item failures are not errors: they come back inside a successful batch response.
SuotarItemStatus

Constants§

CORRELATION_ID_HEADER
Carries suotar_api_calls.id so Suotar’s log and ours join on one value.
INTERACTIVE_REQUEST_TIMEOUT
Under the ingress’s 60 s, so an admin waiting on a call gets our answer rather than a 504.
MAX_REQUEST_BODY_BYTES
Suotar’s own body limit (Express 5mb), so an oversized batch is refused here rather than 413’d at the far end.
REFUSED_BEFORE_SENDING_CODE
The request_level_error_code of a call refused before it was sent. Suotar never sends this code; count_unreachable_run_since in models matches it by this literal.

Statics§

SUOTAR_HTTP_CLIENT 🔒
Separate from REQWEST_CLIENT for the keepalive: an import can sit silent on its socket for up to an hour, which NAT and proxies otherwise drop without telling either end.

Traits§

BatchEndpoint
The item and result types of one endpoint, tied together so a caller cannot pair an import item with a verify result.
SuotarCallAudit
Persists one suotar_api_calls row per call. A trait because the table is in the models crate, which depends on this one. Implementations must scrub the bodies.
SuotarRequestItem
Suotar echoes the requestItemId back, which is what makes a reordered or partial response safe to read.

Functions§

authorization_header_value 🔒
Suotar matches the Bearer prefix exactly: case-sensitive, one space.
body_for_audit 🔒
A body that is not JSON is still worth keeping; the scrubber takes a bare string too.
check_batch 🔒
Refuses our own bugs before a request goes out; both would come back as a request-level error rejecting the whole batch.
empty_batch_response 🔒
Nothing to ask, so an empty batch is never sent and leaves no audit row.
failed 🔒
lenient 🔒
A value that does not read as T reads as absent.
lenient_date 🔒
Importer dates arrive as YYYY-MM-DD or as an instant (Sisu’s UTC midnight), which means its UTC date. Anything else reads as absent.
lenient_id 🔒
A Sisu id that should be a string but, for at least gradeId, has arrived as a bare JSON number. A strict String field would fail to parse and drop the whole record in readable_elements, silencing whatever check depends on it. Coerces either shape into a String; anything else reads as absent.
lenient_instant 🔒
An RFC 3339 instant, or Sisu’s zoneless local date-time read as UTC, which is close enough to order enrolments by. Anything else reads as absent.
new_request_item_id
A fresh requestItemId for one item of one call.
readable_elements 🔒
Keeps the elements that parse and logs how many did not.
reconcile 🔒
Pairs the response against what was sent by requestItemId; order is not consulted.
request_level_error 🔒
suotar_client_builder 🔒
transport_variant 🔒
is_connect is the one case where the request provably never reached Suotar; everything else, a timeout above all, may have been processed.
unpaired_item_ids 🔒

Type Aliases§

Exchanged 🔒