Skip to content

The Enrollment Engine

Enrollment is KoAkademy’s deepest subsystem. It has two cooperating layers: an operational pipeline that moves individual enrollments through verification, and a policy engine (“Enrollment Blueprints”) that decides the rules — who may enroll, what they must provide, what they pay, and who approves.

EnrollmentService is the application façade. Every workflow mutation passes through EnrollmentWorkflowCoordinator, while EnrollmentTransitionEngine owns row locking, transactions, status and outcome projection, idempotency, and workflow events. A separate legacy adapter preserves enrollments created before policy activation.

  1. Application — created by staff or through public online enrollment (when enabled).
  2. Academic verification — registrar or department head verifies subjects, documents, and the computed assessment.
  3. Cashier verification — payment is confirmed or recorded; the enrollment becomes official.
  4. Post-enrollment — authorized transitions: undo, reopen, schedule-change notifications, class enrollment adjustments.

For policy enrollments, configured actions run in their listed order: entry-step actions during creation and target-step actions during transitions. An omitted action has no side effect. Every status change goes through the transition engine rather than direct edits, so the history of an enrollment is reconstructable. Assessment PDFs and notifications are queued only after the transaction commits (see Queues & PDF).

The engine lives in app/Enrollment/ and is configured from the admin workspace (React UI under System Management → Enrollment Policy): blueprint shell, rule editor, workflow editor, and simulation reports.

ComponentRole
PolicyRegistry / PolicyManagerKnown policy types, presets, and CRUD over blueprints
PolicyResolver / PolicyInheritanceServiceScope matching and inherit-and-override resolution (school → student type → program → period)
EnrollmentPolicyCompilerCompiles a published blueprint version into the executable policy the pipeline consults
PolicySimulationServiceDry-runs representative students against a draft, reporting blockers before publication
PolicyRolloutServiceStaged activation and rollback of published versions
EnrollmentTransitionEngine / EnrollmentWorkflowCoordinatorApproval timelines, branches, and post-commit actions
Strategies & handlersAssignment/billing strategies and integration action handlers (extension points)

Persistence: EnrollmentPolicy (the blueprint), EnrollmentPolicyVersion (immutable published versions), EnrollmentPolicySnapshot (what a given enrollment started with), and EnrollmentWorkflowEvent (the audit trail).

Key invariants:

  • Publication is immutable. A published version never changes; edits produce a new version.
  • Snapshots isolate in-flight enrollments. Activating a new version affects future enrollments only — active enrollments keep the snapshot they started with, and legacy enrollments stay legacy.
  • Simulation precedes activation. Operators are expected to resolve every simulated blocker before publishing.
  • Legacy behavior is isolated. Policy actions do not call legacy workflow methods, use ambient authentication, or open their own workflow transaction.
  • Operators configure blueprints without code — see the Enrollment Blueprints guides in the User Guide section (overview, quick start, scopes and inheritance, approvals, simulation and publication, troubleshooting).
  • Developers extend the engine through the documented contracts — rule handlers, action handlers, assignment/billing strategies, registry registration, and import envelopes. See Extending the enrollment engine.
  • Never mutate a published EnrollmentPolicyVersion; create a new version.
  • Route status changes through the transition engine so workflow events stay complete.
  • Route creation through EnrollmentSubmissionData and the coordinator so administrator, public, continuing, API, and Filament submissions resolve policies consistently.
  • New rule/action types must be registered in the registry and covered by compiler and simulation tests.
  • Keep the React blueprint editors in sync with the operator schema manifests the engine exposes.