Course Enrollment
Data Entity
Description
Records a user's enrollment in a course, tracking enrollment status lifecycle from registration through completion or cancellation, and triggering downstream certificate generation upon successful completion.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Primary key — unique enrollment record identifier | PKrequiredunique |
course_id |
uuid |
Foreign key to the course the user is enrolling in | required |
user_id |
uuid |
Foreign key to the user (peer mentor or coordinator) who is enrolled | required |
organization_id |
uuid |
Organization context of the enrollment, used for multi-tenancy scoping and Bufdir reporting | required |
status |
enum |
Current lifecycle state of the enrollment | required |
enrolled_at |
datetime |
Timestamp when the enrollment was confirmed (not when pending) | - |
completed_at |
datetime |
Timestamp when the user completed the course; triggers certificate generation | - |
cancelled_at |
datetime |
Timestamp when the enrollment was cancelled | - |
cancellation_reason |
text |
Optional free-text reason for cancellation, used for coordinator reporting | - |
attendance_confirmed |
boolean |
Whether physical or digital attendance has been confirmed by the course administrator | required |
completion_score |
decimal |
Optional assessment score (0.00–100.00) if the course includes a scored component | - |
certificate_issued |
boolean |
Whether a digital certificate has been issued for this enrollment | required |
certificate_id |
uuid |
Foreign key to the issued certification record; populated after completion | - |
enrolled_by_user_id |
uuid |
User ID of the coordinator or admin who enrolled this user on their behalf; null if self-enrolled | - |
reminder_sent_at |
datetime |
Timestamp of the last automated reminder notification sent for this enrollment | - |
expiry_date |
datetime |
Date after which the enrollment expires if not completed; used by certificate-expiry-scheduler | - |
notes |
text |
Optional internal notes from coordinator or admin about this enrollment | - |
created_at |
datetime |
Record creation timestamp | required |
updated_at |
datetime |
Record last update timestamp | required |
Database Indexes
idx_course_enrollments_user_id
Columns: user_id
idx_course_enrollments_course_id
Columns: course_id
idx_course_enrollments_organization_id
Columns: organization_id
idx_course_enrollments_status
Columns: status
idx_course_enrollments_user_course_active
Columns: user_id, course_id, status
idx_course_enrollments_completed_at
Columns: completed_at
idx_course_enrollments_expiry_date
Columns: expiry_date
Validation Rules
valid_course_reference
error
Validation failed
valid_user_reference
error
Validation failed
valid_organization_reference
error
Validation failed
completion_score_range
error
Validation failed
completed_at_requires_completion_status
error
Validation failed
cancelled_at_requires_cancellation_status
error
Validation failed
expiry_date_future_on_create
error
Validation failed
cancellation_reason_on_post_start_cancel
error
Validation failed
Business Rules
no_duplicate_active_enrollment
A user cannot have more than one active enrollment (status: pending, enrolled, in_progress, or waitlisted) for the same course at the same time. Re-enrollment after cancellation or expiry is allowed.
certificate_issued_on_completion
When status transitions to 'completed' and attendance_confirmed is true, the system must trigger certificate generation and set certificate_issued = true. The certificate_id is populated after the certifications record is created.
attendance_required_before_completion
Status cannot be set to 'completed' unless attendance_confirmed is true. Prevents certificate generation for unconfirmed participants.
organization_scoped_enrollment
A user may only enroll in courses belonging to their own organization, or courses marked as platform-wide. Enforces tenant isolation.
valid_status_transition
Enrollment status must follow the defined state machine: pending → enrolled → in_progress → completed; pending/enrolled → cancelled; any → expired (by scheduler). Arbitrary status jumps are rejected.
proxy_enrollment_logged
When enrolled_by_user_id is set (coordinator enrolling on behalf of peer mentor), the action is recorded in the audit log for accountability.
expiry_triggers_status_update
When expiry_date passes and status is not 'completed' or 'cancelled', the scheduler sets status to 'expired'. HLF requirement: expired certification removes peer mentor from local association listings.