Enrollment

1. Front Matter

  • Title: Enrollment

  • Author: Joshua Uriel Tribiana

  • Reviewers: Joylynne Esportuno ( teruterubozuuu )

  • Creation Date: 2026-06-29

  • Status: Approved

  • References:

    • Issue: [6.2] Enrollment

2. Introduction & Goals

  • Problem Summary
    Creators need a quick and efficient system to manage learner access to their quests. The Enrollment feature provides the necessary tools for creators to add learners individually or in bulk via CSV upload, track their status, and manage their access. This is a core function for distributing content within the WyzQuests platform.

  • Goals

    • Provide a UI for creators to enroll a single learner by name and email.

    • Provide a UI for creators to bulk-enroll learners by uploading a CSV file.

    • Send an email notification to newly enrolled learners.

    • Persist enrollment records, linking learners to quests.

    • Allow creators to view all enrolled learners for a quest.

    • Allow creators to update an enrollee's status (ongoing vs. finished).

    • Allow creators to delete an enrollment (revoke access).

  • Non-Goals

    • Self-enrollment via a public link.

    • Payment processing or paid course enrollment.

    • Automatic enrollment based on learner groups (this is a separate feature, [11.5]).

    • Detailed error reporting for individual failed rows in a CSV upload (noted as a scope gap).

  • Glossary

    • Enrollment: A record in the quest_enrollments table that links a learner (learner_id) to a specific quest (quest_id).

    • Enrollee: A learner who has been enrolled in a quest.

3. High-Level Architecture

  • System Diagram

    Learner Enrollment Workflow
     
    Creator Actions
    ───────────────
     
    +----------------------+
    | Add Learner |
    | (Manual Entry) |
    +----------------------+
    |
    |
    | +----------------------+
    | | Upload CSV File |
    | +----------------------+
    | |
    | v
    | +----------------------+
    | | Parse CSV |
    | +----------------------+
    | |
    +---------------+----------------+
    |
    v
    +----------------------+
    | Enrollment API |
    +----------------------+
    |
    v
    +----------------------+
    | Save Enrollment |
    | to Database |
    +----------------------+
    |
    v
    +----------------------+
    | Send Enrollment |
    | Email |
    +----------------------+
     
     
    Enrollment Management
    ─────────────────────
     
    +----------------------+
    | Open Enrollee List |
    +----------------------+
    |
    v
    +----------------------+
    | Retrieve |
    | Enrollments |
    +----------------------+
    |
    v
    +----------------------+
    | Display Enrollees |
    | in Table |
    +----------------------+

  • Technologies Used

    • Next.js: For API routes and frontend components.

    • React: For UI components like AddLearnerModal and EnrolleeTable.

    • Supabase (PostgreSQL): For storing quest_enrollments data.

    • Clerk: For authenticating the creator performing the enrollment.

    • Zod: For validating request bodies.

    • Papaparse: For client-side parsing of CSV files for bulk enrollment.

    • Nodemailer: For sending enrollment notification emails.

4. Detailed Design & Implementation

  • Data Model / Schema
    The feature primarily interacts with the quest_enrollments table.

    quest_enrollments Table:

    Column

    Type

    Description

    id

    UUID

    Primary Key.

    quest_id

    UUID

    Foreign key to the quests table.

    learner_id

    TEXT

    The Clerk ID of the enrolled learner.

    status

    TEXT

    Enrollment status (ongoing or finished).

    progress

    JSONB

    Stores learner's progress data.

    created_at

    TIMESTAMPTZ

    Timestamp of when the enrollment was created.

    updated_at

    TIMESTAMPTZ

    Timestamp of the last update.

  • API Specification

    • POST /api/creator/enrollment/create-enrollment

      • Auth: Creator must own the quest.

      • Body: { quest_id: string, learner_name: string, learner_email: string }

      • Action: Creates a single enrollment record. If the user doesn't exist, an app_users record is created first. Triggers an email notification.

    • POST /api/creator/enrollment/bulk-create

      • Auth: Creator must own the quest.

      • Body: { quest_id: string, learners: { name: string, email: string }[] }

      • Action: Creates multiple enrollment records in a transaction. Triggers email notifications for each new enrollee.

    • GET /api/creator/enrollment/list?quest_id=<uuid>

      • Auth: Creator must own the quest.

      • Action: Returns a list of all enrollees for the specified quest.

    • PATCH /api/creator/enrollment/update-status

      • Auth: Creator must own the quest.

      • Body: { enrollment_id: string, status: "ongoing" | "finished" }

      • Action: Updates the status of a single enrollment.

    • DELETE /api/creator/enrollment/delete

      • Auth: Creator must own the quest.

      • Body: { enrollment_id: string }

      • Action: Permanently deletes an enrollment record.

  • Logic & Workflows

    1. Single Enrollment:

      • The creator fills out the AddLearnerModal.

      • Client-side validation checks for a valid name and email format.

      • On submit, the EnrollmentService calls the create-enrollment API.

      • The API creates the enrollment, and the backend sends a notification email.

      • The UI optimistically updates the EnrolleeTable with the new learner.

    2. Bulk Enrollment (CSV):

      • The creator selects a CSV file with name and email columns.

      • papaparse parses the file on the client into an array of learner objects.

      • The EnrollmentService calls the bulk-create API with the array of learners.

      • The backend processes the learners in a batch, creating enrollments and sending emails.

      • The UI refetches the enrollment list to display the newly added learners.

  • Key Files:

    • app/quest-editor/[questID]/(sections)/enrollment/page.tsx: The main page that orchestrates the components.

    • lib/enrollment/enrollmentService.ts: The service layer abstracting all API calls.

    • components/creator/enrollment/AddLearnerModal.tsx: The modal for adding a single learner.

    • components/creator/enrollment/EnrolleeTable.tsx: The table for displaying and managing enrollees.

    • app/api/creator/enrollment/create-enrollment/route.ts: API for single enrollment.

    • app/api/creator/enrollment/bulk-create/route.ts: API for bulk enrollment.

5. Infrastructure & Operations

  • Dependencies

    • Internal: Relies on the quests and app_users tables.

    • External:

      • Supabase (PostgreSQL) for data storage.

      • An SMTP provider configured for Nodemailer to send emails.

  • Monitoring & Alerting

    • Standard monitoring for all /api/creator/enrollment/* endpoints.

    • Alerts should be configured for a high rate of 5xx errors, which could indicate a database or email service issue.

    • Log email sending failures with high severity.

  • Deployment Plan

    • Database Migrations: The quest_enrollments table and related RLS policies must be deployed.

    • Environment Variables: Ensure SMTP_HOST, SMTP_USER, SMTP_PASS, etc., are configured for the email service.

    • Rollout: The feature can be deployed directly as it is a core part of the quest editor workflow.

6. Testing & Quality Assurance

Test Strategy

As per the ENROLLMENT_REFACTORING.md documentation, this feature has comprehensive test coverage.

  • Unit Tests (enrollmentService.test.ts):

    • Mock fetch to test all methods in the EnrollmentService.

    • Verify correct API endpoints, methods, and body payloads are used.

    • Test both success and error responses from the mocked API.

  • Component Tests (AddLearnerModal.test.tsx):

    • Test rendering and visibility.

    • Test input validation for name (required) and email (required, format).

    • Test form submission, loading states, and error display.

  • End-to-End (E2E) / QA:

    • Flow 1 (Single Add): Add a new learner -> Verify they appear in the table -> Verify they receive an enrollment email.

    • Flow 2 (Bulk Add): Upload a valid CSV -> Verify all learners appear in the table.

    • Flow 3 (Manage): Change a learner's status -> Verify it updates. Delete a learner -> Verify they are removed.

    • Negative Test: Upload a malformed CSV; verify an error is shown.

Known Limitations

  • CSV Error Reporting: The current implementation has a basic "happy path" for CSV uploads. It does not provide detailed feedback on which specific rows failed during a bulk import. This is a known scope gap for future improvement.

7. Maintenance & Support

Troubleshooting

  • Learner not appearing in the table after being added:

    1. This is likely a client-side state issue or a failed API call.

    2. Check the browser's developer console for network errors on the create-enrollment or list API calls.

    3. Ask the user to refresh the page to force a refetch from the database.

  • Enrollment emails are not being sent:

    1. Check the server logs for errors from Nodemailer or the SMTP provider.

    2. Verify that SMTP environment variables are correctly configured in the deployment environment.

  • Bulk CSV upload fails:

    1. Ensure the CSV has name and email headers.

    2. Check for formatting issues in the CSV file (e.g., incorrect delimiters).

Changelog

1.0 - Approved, Feature refactored and documented, 2026-06-29


Was this article helpful?