Expand description
The credit registration pipeline: the phases that take a course module completion to a credit in Sisu through Suotar, the worker loops that run them, and the account-linking actions an admin or teacher sets off by hand.
Modules:
runtime: composition. The worker loop, the one-iteration dispatcher and the manual actions build a study registry and hand it to a use case.use_cases: one module per phase, andaccount_linkingfor the linking mail resend. They claim rows, ask the study registry, decide and write, calling the models crate directly.registry: the study registry as use cases see it: theStudyRegistryport a phase asks, theInteractiveStudyRegistrya manual action asks, their requests and their answers.workflow: the claim, the decision and its guarded write, and the accounting every phase shares.phase: which phases exist, which process owns each, and what each may be narrowed to.
Dependencies point from runtime to use_cases to registry and workflow, and from
workflow to registry. runtime::suotar implements both registry traits and is the only code
that names Suotar’s wire types and codes or sends through its client; the rest of runtime only
builds and passes the client, and nothing outside runtime can reach it.
Where to look:
- phase list, spec, scope support, owning process:
phase.rs - one iteration’s lifecycle and the phase dispatch:
runtime/dispatch.rs - worker loops:
runtime/worker_loop.rs - study registry operations:
registry/ - Suotar encoding, decoding, limiter and breakers:
runtime/suotar/, what each Suotar item code means inruntime/suotar/codes.rs, and the adapter’s contract tests inruntime/suotar/contract_tests.rs - what each move does to a row (state, error code, admin flag, backoff, timeline line): models’
library::credit_registration::outcomes - batch phase lifecycle (claim, send, split, apply, shutdown):
use_cases/batch_flow.rs - a decision and writing it to its row:
workflow/decision.rs - import:
use_cases/import/ - enrolment resolution:
use_cases/resolve_enrolments/ - verification:
use_cases/verify/ - roster listing and account-linking mails:
use_cases/enrolment_discovery/ - mail queue phases:
use_cases/link_emails.rs,use_cases/student_notifications.rs, sharinguse_cases/mail_queue.rs - manual account-linking actions:
runtime/manual.rs, and the resend inuse_cases/account_linking.rs - the admin “materialize now” button:
materialize_now, thematerializephase’s own body - an iteration’s error:
error.rs; what reaches the admin Errors page:error_reports.rs
Both the worker loops and the test tick endpoint go through run_phase_once, so a phase cannot
behave differently depending on who ran it.
Modules§
- account_
linking - The account-linking actions an admin or a teacher sets off by hand, what they answer, and the roster listing a student’s own visit books.
- error
- The error of a phase iteration that could not do its job. What a Suotar answer does to a row, a row another writer moved on, or a breaker holding a phase back are values, not errors.
- error_
reports 🔒 - Reports operator-visible worker failures to the shared error registry the admin Errors page
reads, the same table
ControllerErrorwrites 5xx responses to. - phase 🔒
- Which phases exist, which process runs each, and what each may be narrowed on.
- registry 🔒
- The study registry as the phases and the manual actions see it: what can be asked of it, in the pipeline’s terms. Request ids, wire items, the limiter, the breakers and audit bodies are the adapter’s; splitting a refused batch is the batch runner’s.
- registry_
health - What the dashboard and the test controls read of the study registry, or reset: its circuit breakers and limiter, and the Suotar endpoints each phase calls.
- runtime 🔒
- The composition root: the worker loop, the one-iteration dispatcher, the manual actions, and the Suotar adapter behind the study registry port, which nothing outside this module can name.
- use_
cases 🔒 - The application layer: one module per phase, and
account_linkingfor the linking mail resend, each reading its rows, asking the study registry through its port, deciding, and writing the decision back. - worker_
loop - The loop both credit registration workers run.
- workflow 🔒
- The workflow types the phases share: the claim a decision is written against, the decision and
its guarded write, what a refused row gets, and what an iteration counts. The moves themselves
are models’
outcomes.
Structs§
- Materialized
- The ledger rows one materialize pass created.
- Phase
Context - Everything a phase iteration needs from its caller: the worker loop or the test tick endpoint.
- Phase
Spec - Everything fixed about one phase, declared in one place.
- Scope
Support - Which of the scope’s dimensions a phase’s claim query can apply. Declared rather than assumed, so a phase added later cannot quietly ignore a scope and sweep the whole database.
Enums§
- Credit
Registration Phase - A pipeline phase.
CreditRegistrationPhase::as_stris canonical: it iscredit_registration_phase_state.phase, the tick endpoint’s?phase=and the audit log’starget_phase. - Phase
Skip Reason - Phase
Tick - What one dispatch attempt did.
- Runner
- Who runs a phase iteration.
- Worker
Process - The worker process that runs a phase’s loop. The two are separate OS processes, each with its own circuit breakers and limiter.
Functions§
- is_
waiting_ item - Whether an error item’s
codeonly says “not yet, check again later”, so the call log counts it as pending rather than as an error:submissionPending, verify’snotRegistered, and resolve’senrolmentNotFoundandenrolmentNotAccepted. - materialize_
now - Both statements that create ledger rows, bounded apart from each other: the phase’s body, and the admin “materialize now” button’s, so the two cannot drift apart.
- run_
phase_ once - Runs exactly one iteration of one phase.