Skip to content

Student Hold Form ​

Field reference for student registration holds.

Hold Type Definition ​

FieldTypeRequiredMax LengthValidationNotes
Hold Type IDIntegerAuto--System-generated identifier
Hold Type CodeTextYes50UniqueHold type code (e.g., ADVISOR, FINANCIAL)
NameTextYes200-Display name
DescriptionText AreaNo1000-Detailed description
Enforcement LevelSelectYes-BLOCK_ALL, BLOCK_COMPLETION, INFORMATIONALWhat the hold blocks. The only field that gates registration
CategorySelectYes20see belowDescriptive grouping; nothing enforces off it

Enforcement Levels ​

CodeLabelPlanningWaitlistRegister
BLOCK_ALLBlocks everythingNoNoNo
BLOCK_COMPLETIONBlocks completionYesYesNo
INFORMATIONALInformationalYesYesYes

The levels form a ladder: BLOCK_ALL refuses everything BLOCK_COMPLETION refuses, and more. Enforced by enforceHolds in internal/domain/registration/hold_gate.go, called from every write path that creates a plan, a waitlist entry or an enrollment.

Migration 177 added the column with a CHECK constraint. It replaced a single prevents_registration boolean derived from the code prefix by the ODS importer, which is why library-balance holds used to block registration.

Category Values ​

Grouping for filtering and reporting only: FINANCIAL, HEALTH, REGISTRATION, HOUSING, ADMISSIONS, ACADEMIC, DISCIPLINARY, OTHER. CHECK-constrained since migration 177.

Before 177 this column carried two incompatible vocabularies at once — BLOCKING/COMPLETING on seven hand-seeded rows, domain names on the 36 imported from Colleague — with no constraint, and the UI coloured its badges off it. That is why imported holds all rendered as mild advisories.

Hold Type Independent Flags ​

FieldTypeRequiredNotes
Prevents TranscriptBooleanNoWithholds transcripts. Orthogonal to enforcement level
Prevents GraduationBooleanNoBlocks graduation applications. Enforced in domain/audit
Student VisibleBooleanNoFalse hides the hold from the student; staff always see it. From Colleague REST_PRTL_DISPLAY_FLAG
Default SeveritySmallintNoColleague REST_SEVERITY, reference only

Hold Type Role Lists ​

Stored in records.hold_type_roles, one row per (hold type, role code) with can_place and can_clear booleans. Shaped after records.workflow_step_permissions.

FieldTypeNotes
Place RolesMulti-select (role codes)Roles that may place this hold
Clear RolesMulti-select (role codes)Roles that may clear this hold

Checked against the caller's active role, not the union of roles held. An empty list means superuser-only — deliberate fail-closed behaviour.

Replaced the single-FK create_role_id / clear_role_id columns, which were stored and displayed but never consulted by any code path.

Hold Type Administrative Fields ​

FieldTypeRequiredNotes
Resolution InstructionsText AreaNoDefault student-facing message. Imported from Colleague REST_PRTL_DISPLAY_DESC_DTL, sanitized to a small HTML allowlist
Contact OfficeTextNoOffice to contact. Parsed from the Colleague instruction text
Contact EmailEmailNoEmail for resolution
Contact PhoneTextNoPhone for resolution
Is ActiveBooleanNoHold type is in use. Set false by the import for restrictions Colleague has retired
Sort OrderIntegerNoDisplay order
Auto Create QueryText AreaNoNot implemented. Stored, never evaluated
Auto Clear QueryText AreaNoNot implemented. Stored, never evaluated
Auto Clear ScriptTextNoNot implemented. Stored, never evaluated

Student Hold Record ​

FieldTypeRequiredMax LengthValidationNotes
Student Hold IDUUIDAuto--System-generated identifier
StudentSelect (FK)Yes-Must existStudent with hold
Hold TypeSelect (FK)Yes-Must existType of hold
TermSelect (FK)No-Must existTerm-specific hold. Null means every term, which is what all imported holds are — Colleague restrictions carry no term
ReasonText AreaNo1000-Internal note. Never shown to the student
Custom MessageText AreaNo--Student-facing text for this hold, overriding the hold type's resolution instructions. Sanitized on save
SeveritySmallintNo--Colleague STR_SEVERITY for this hold
Expiration DateDateNo-Future dateAuto-expire date. Applied at query time as well as by the flag
Is ActiveBooleanYes--Hold is currently active

A hold counts as in force when is_active is true and the expiration date is absent or not yet passed. Nothing sweeps expired holds, so the date is checked in the query rather than trusted to a background job.

The API returns a resolved student_message alongside these: the custom message if set, otherwise the hold type's resolution instructions. Clients should render that rather than implementing the fallback themselves.

Hold Creation Fields ​

FieldTypeRequiredNotes
Created By PersonSelect (FK)ConditionalPerson who created hold
Created By SystemBooleanNoCreated automatically
Created AtDateTimeAutoWhen hold was created

Hold Clearing Fields ​

FieldTypeRequiredNotes
Cleared By PersonSelect (FK)ConditionalPerson who cleared hold
Cleared By SystemBooleanNoCleared automatically
Cleared AtDateTimeNoWhen hold was cleared
Clear ReasonText AreaNoReason for clearing

Hold Types in Use ​

Hold types are not hand-authored: the nightly import creates one per Colleague restriction code. The codes below are the ones seen on students enrolled in current terms; the full set is 36, of which 12 are marked retired in Colleague.

CodeColleague descriptionOwning office
FA001FA-Financial Clearance NeededStudent Financial Services
HS001HS-Need Health ClearanceHealth Services
RGTRNHigh School TranscriptEnrollment
FIADVAcademic Advisor Meeting(advisor)
SSCPBAcademic ProbationStudent Success Center
SSISSS-International StudentsStudent & Spiritual Life
FASUMFA-Summer Clearance NeededStudent Financial Services
SSHOUHousingStudent & Spiritual Life
AMCMTPioneers Commitment FormAdmissions
LCTRATranscripts - Loans/CollectionRegistrar and Records
RGMWMedical WithdrawalRegistrar and Records
SSCTDSS-Dismissal - Student LifeStudent & Spiritual Life
SSCTZSS-Student Life IssuesStudent & Spiritual Life
TIXCKTitle IX CheckTitle IX
SSTIXTitle IX Training RequiredStudent & Spiritual Life

Names come from cleanUp.dbo.RESTRICTIONS and are refreshed nightly. Enforcement level and role lists are local and are never overwritten by the import.

Computed Fields (Read-Only) ​

FieldDescription
Student NumberFrom student record
Student NameFrom person record
Hold Type NameFrom hold type
Enforcement DisplayHuman label for the enforcement level
Student MessageCustom message, else the hold type's resolution instructions
Days ActiveDays since creation
Status DisplayACTIVE or CLEARED

Validation Rules ​

  1. Student must exist
  2. Hold Type must be active
  3. Only one active hold per student per hold type (unless term-specific)
  4. Cleared By Person required if cleared manually
  5. Created By Person required if created manually
  6. Expiration Date should be in the future when set

Automation ​

The nightly Colleague import is the only thing that creates and removes holds automatically (internal/migration/daily/holds.go):

EventAction
Colleague applies a restrictionHold created
Colleague releases a restrictionHold removed
Colleague restriction deletedHold removed (delete-reconcile pass)
Expiration date passesHold stops being in force at query time

The import only reads restrictions currently in force. A hold cleared by hand in SIS is re-activated on the next run if Colleague still shows the restriction — release it in Colleague, not here.

The query-driven auto-evaluation described by auto_create_query, auto_clear_query and auto_clear_script does not exist. The fields are stored and never read, records.hold_evaluation_log has never held a row, and POST /registration/hold-types/{id}/run_auto_create returns 501 Not Implemented.

Student Information System Documentation