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, forSuotarClient::post.
Macros§
Structs§
- Credit
Range - Sisu’s credit range. Suotar refuses an import against one missing either bound.
- Date
Period - Sisu’s
LocalDateRange: start inclusive, end exclusive, either end possibly open. - Enrolment
Resolution Result - An enrolment or attainment that cannot be read drops out alone rather than taking the item with it.
- Enrolments
Listed Result - Import
Attainment Request Item - Import
Attainment Result - One shape for every import result:
sent,sisuTimeoutandduplicateRequestItemfill the submitted pair,duplicateAttainmentfillsattainment,notImprovedAttainmentfillsprevious_attainment. - List
ByCourse Request Item - Lists every realisation of the code; Suotar refuses the whole request if an item names one.
- Listed
Enrolment - Passed through from Suotar’s importer like
SuotarEnrolment, so every field may be absent. - Listed
Person - Localized
Name - NoSuotar
Call Audit - Person
Result - Request
Level 🔒Error Body - Resolve
Enrolment Request Item - Resolve
Person Request Item - Suotar
Attainment - Covers the contract bodies: the bare
{id, type}of verify’sregistered, the fuller one behind import’sduplicateAttainmentandnotImprovedAttainment, and the ones an enrolment answer lists as already held, where every field but the id and type may be missing. AduplicateAttainmentSuotar answers from its own recent sends names theAssessmentItemAttainmentit submitted, and has nostateorregistrationDate. - Suotar
Batch Response - Suotar
Call Context - Both fields are audit-row columns:
worker_nameseparates the submitter from the verify poller from a manual retry, and the ids replace the identifiers scrubbing removes from stored bodies. - Suotar
Call Finished - Suotar
Call Started - Suotar
Client - Suotar
Enrolment - 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.
- Suotar
Error - A Suotar call that got no batch response.
SuotarError::variantandSuotarError::was_sentare what a caller decides by; the message and the source are for the logs and the audit trail. - Suotar
Item Error - Suotar
Response Item - Unpaired
Item 🔒Ids - The requestItemIds a response does not pair with what was sent.
- Validate
Course Code Request Item - Validate
Course Code Result - Verify
Attainment Request Item - Verify
Attainment Result registeredfillsattainment;submissionPendingfills the submitted pair andretry_after.
Enums§
- Request
Level 🔒Error Detail - The envelope’s
{code, message}, or the bare string Suotar’s fall-through route answers with. - Suotar
Endpoint - Suotar
Error Variant - How a call to Suotar failed at the request level. Per-item failures are not errors: they come back inside a successful batch response.
- Suotar
Item Status
Constants§
- CORRELATION_
ID_ HEADER - Carries
suotar_api_calls.idso 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_codeof a call refused before it was sent. Suotar never sends this code;count_unreachable_run_sincein models matches it by this literal.
Statics§
- SUOTAR_
HTTP_ 🔒CLIENT - Separate from
REQWEST_CLIENTfor 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§
- Batch
Endpoint - The item and result types of one endpoint, tied together so a caller cannot pair an import item with a verify result.
- Suotar
Call Audit - Persists one
suotar_api_callsrow per call. A trait because the table is in the models crate, which depends on this one. Implementations must scrub the bodies. - Suotar
Request Item - Suotar echoes the requestItemId back, which is what makes a reordered or partial response safe to read.
Functions§
- authorization_
header_ 🔒value - Suotar matches the
Bearerprefix 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
Treads as absent. - lenient_
date 🔒 - Importer dates arrive as
YYYY-MM-DDor 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 strictStringfield would fail to parse and drop the whole record inreadable_elements, silencing whatever check depends on it. Coerces either shape into aString; 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_connectis the one case where the request provably never reached Suotar; everything else, a timeout above all, may have been processed.- unpaired_
item_ 🔒ids