This section captures the customer-facing documentation draft for Programs. It is written for end users and can later be adapted into public docs, onboarding content, or help-center material.
### Overview
Programs help you group multiple courses into one structured learning experience. Instead of treating every course as a separate training track, you can organize related courses, learners, and communication into a single program.
This is especially useful when training is delivered as a journey rather than a one-off course.
### When To Use Programs
Use Programs when:
- Learners should take more than one course as part of the same track.
- The same group of learners should be enrolled across multiple courses.
- You want one place to manage the people in that training path.
- You need a shared announcement space across several related courses.
- You want learners to experience the training as one program instead of a flat course list.
If you only need to deliver one standalone course, a course by itself may be enough. If you are running a structured pathway, a cohort, or a multi-step curriculum, Programs are usually the better fit.
### Common Use Cases
#### Employee onboarding
Create one program for new hires and include all required onboarding courses inside it.
Example:
- Company culture
- Security awareness
- IT setup training
- Role-specific onboarding
This makes it easy to enroll each new employee once and give them access to the full onboarding path.
#### Certification or compliance training
Use a program when learners must complete several courses to earn a certification or complete a compliance requirement.
Example:
- Safety fundamentals
- Practical assessment prep
- Final certification review
This keeps the full certification journey together and makes communication easier for instructors and learners.
#### Bootcamps and cohort-based learning
Programs work well for cohorts that move through a sequence of courses together.
Example:
- Week 1 foundations
- Week 2 intermediate material
- Week 3 project work
- Week 4 final review
The program becomes the hub for that cohort.
#### Customer education
If you train customers on your product in stages, Programs can bundle those courses into one learning path.
Example:
- Product basics
- Admin training
- Reporting and analytics
- Advanced workflows
This gives customers a clearer path through your learning content.
#### Partner or channel enablement
Programs can package the training a reseller, implementation partner, or external team needs to complete.
Example:
- Brand overview
- Sales certification
- Technical onboarding
- Support processes
This makes it easier to assign the same learning experience to many partner groups.
#### Internal academy or role-based development
If your organization runs structured learning for managers, sales reps, engineers, or support teams, a program can become the container for each pathway.
Example:
- New manager program
- Sales ramp-up program
- Support excellence program
### What A Program Includes
A program usually brings together four things:
- Courses: the learning content learners should complete.
- Members: the people assigned to the program.
- Roles: who can manage the program and who is participating in it.
- Newsfeed: a shared place for updates and announcements.
### How Programs Work
At a high level, Programs work like this:
1. Create a program.
2. Add the courses that belong in that program.
3. Add learners and tutors.
4. Use the program newsfeed for updates and communication.
5. Learners open the program and access the related courses from one place.
Programs help reduce repetitive admin work because you manage the training track as one unit instead of handling every course separately.
### Setting Up A Program
#### Step 1: Create the program
Start from the Programs section in your organization dashboard and create a new program.
Typical information to add:
- Program name
- Program description
Choose a name learners will understand immediately. Good program names are specific and outcome-based, such as:
- New Hire Onboarding
- Safety Certification Track
- Customer Success Bootcamp
- Manager Essentials Program
#### Step 2: Add courses
Once the program exists, add the courses that make up the learning path.
You can use this for:
- A short 2-course sequence
- A multi-week curriculum
- A full certification path
Try to keep the program focused. A strong program usually represents one coherent goal rather than a random bundle of unrelated courses.
#### Step 3: Add people
After adding courses, assign the people who should participate in the program.
This usually includes:
- Learners who need access to the training
- Tutors or trainers who will support the cohort
The main advantage here is that you do not need to think course by course. You can manage participation at the program level.
#### Step 4: Start communication
Use the program newsfeed to post updates that matter across the whole learning path.
This is useful for:
- Welcome messages
- Weekly announcements
- Schedule changes
- Program-wide reminders
- Encouragement before assessments or deadlines
### What Learners See
Learners can open Programs from their LMS view and see the training paths they have been enrolled in.
From there, they can:
- Open a program
- See the courses that belong to it
- Read program-wide updates in the newsfeed
- Move between related courses more easily
This makes the experience feel more guided and intentional than a flat list of separate courses.
### Roles Inside A Program
Programs support different responsibilities for different people.
Typical roles include:
- Admins: manage the program and its settings.
- Tutors: support delivery and help manage learners.
- Students: participate in the program and take the courses.
This makes Programs suitable for both internal teams and external learning groups.
### Program Statuses
Programs can move through different statuses as they progress.
#### Active
Use this when the program is currently running and available to learners.
#### Inactive
Use this when you want to keep the program and its structure but do not want it actively shown to learners in the same way as a live program.
#### Archived
Use this when the program is no longer part of your active training catalog and should be treated as historical.
### Best Practices
#### Build programs around one goal
Each program should represent one clear outcome, audience, or training pathway.
Good examples:
- Sales onboarding
- Compliance recertification
- Frontend engineering bootcamp
Less effective examples:
- Miscellaneous courses
- Team training library
#### Keep communication program-wide
Use the newsfeed for updates that affect everyone in the program. Keep course-specific communication inside the course when the message only applies to one course.
#### Name programs clearly
A learner should understand what a program is for just by reading its title.
Good naming patterns:
- Audience + goal
- Time period + goal
- Role + pathway
Examples:
- 2026 Graduate Trainee Program
- Support Team Onboarding
- ISO 27001 Readiness Track
#### Use programs for repeatable training
Programs are especially helpful when you run the same training structure more than once, such as onboarding every month or launching new cohorts every quarter.
### Examples Of Strong Program Designs
#### Example 1: New hire onboarding
Program name: New Hire Onboarding
Courses:
- Welcome to the company
- Security and compliance basics
- Internal tools training
- Team-specific workflow training
Why this works:
- One enrollment flow for every new hire
- One place for onboarding announcements
- A clear experience for learners
#### Example 2: Certification pathway
Program name: Health and Safety Certification
Courses:
- Safety fundamentals
- Incident reporting
- Practical safety review
- Final certification preparation
Why this works:
- Related content is grouped in one place
- Instructors can communicate with the full cohort
- Learners can follow a single path to completion
#### Example 3: Partner enablement
Program name: Certified Implementation Partner Program
Courses:
- Product foundations
- Solution setup
- Client handoff
- Support and escalation process
Why this works:
- External learners get a structured path
- The training team manages one program instead of many separate enrollments
### Frequently Asked Questions
#### Should I use one large program or several smaller ones?
Use one program when the courses belong to the same learner journey. Use separate programs when the audience, goal, or timeline is different.
#### Can a program contain multiple courses?
Yes. That is the main purpose of the feature.
#### Is a program better than a single course?
Not always. A single course is best for standalone training. A program is best when multiple courses should be delivered as one experience.
#### Who should use Programs most often?
Programs are especially useful for:
- Training organizations
- Companies onboarding employees
- Teams running certification tracks
- Bootcamps and cohort-based educators
- Customer education teams
Tip: if you already think about your training in terms of pathways, cohorts, tracks, academies, or onboarding journeys, Programs are likely the right structure for you.
Enable instructors and org admins to group multiple courses — along with a shared newsfeed — into a single **program**. Enrolling a student in a program auto-enrolls them in every course inside it, eliminating the need to manage per-course enrollment manually when delivering a structured learning path.
Currently, ClassroomIO has no entity above the individual course. Every course has its own independent enrollment roster. This creates several pain points:
- An instructor running a structured path (e.g., a bootcamp, onboarding track, or certification pathway) must enroll students in each constituent course one by one.
- There is no shared space for program-wide announcements or discussions that span multiple courses.
- Students cannot see a unified "program" view in the LMS — they only see a flat list of individual courses.
- Org admins have no way to bundle courses for a specific cohort of learners (e.g., "Q1 2026 New Hire Onboarding") without creating separate organizations or duplicating content.
## Confirmed Decisions
1.**Terminology**: "Program" in both the instructor-facing admin UI and the student-facing LMS.
2.**Auto-enrollment**: Joining a program automatically creates `groupmember` records for every course inside the program. Removing a student from a program does not remove them from individual course groups, preserving their submission and progress data.
3.**Newsfeed**: Each program has a newsfeed modelled exactly after `course_newsfeed` — same data shape (content, isPinned, reactions, comments), same service patterns, scoped to the program via `programId`.
5.**Org nav placement**: Programs are added to `/org/[slug]` as a top-level nav item alongside Courses and Community, following the exact same pattern used for those pages (`org-navigation.ts`).
6.**Program detail layout**: Opening a program follows the same `Sidebar.Provider` + `ProgramSidebar` + `ProgramHeader` pattern used for courses (`/courses/[id]`). The program detail lives at `/programs/[id]`.
7.**Sidebar items (v1)**: Newsfeed, Courses, People, Settings — in that order.
8.**Roles**: Program roles mirror the existing system (`ADMIN`/roleId 1, `TUTOR`/roleId 2, `STUDENT`/roleId 3). Program admins and tutors can manage the program; students get read access.
9.**Program status**: Programs can be `ACTIVE`, `INACTIVE`, or `ARCHIVED`. `INACTIVE` programs are hidden from students in the LMS but preserved for instructors. `ARCHIVED` programs are hidden everywhere.
10.**Course independence**: Courses in a program remain fully independent. A student enrolled in a program is a regular `groupmember` in each course — existing course pages, progress tracking, submissions, and grading are unchanged.
| Org admin nav | Courses, Community, Audience, Media, Tags nav items under `/org/[slug]` | "Programs" nav item needed |
| Newsfeed | `course_newsfeed` + `course_newsfeed_comment` tables, full service in `apps/api/src/services/newsfeed/newsfeed.ts` | Reuse shape; scope to program with `programId` |
| Student LMS view | Flat list of enrolled courses under `/lms/mylearning` | No program concept |
- Org admins and program tutors can add existing org courses to a program.
- A course can belong to multiple programs simultaneously.
- Adding a course to a program triggers auto-enrollment: all existing `STUDENT` program members are enrolled in the new course (a `groupmember` row is created in the course's `group` for each student not already enrolled).
- Table of all `program_member` rows joined to `profile`.
- Columns: Avatar + Full Name, Email (obscured, same pattern as course people page), Role badge (Admin / Tutor / Student), Actions.
- Search input: client-side filter by name or email.
- Role filter dropdown: All / Admin / Tutor / Student.
- "Add Members" button: opens a modal with email input + role selector. Supports batch add (array of `{ email, roleId }` pairs), same pattern as the course invitation modal.
- Per-row actions: change role (dropdown), remove member (with confirmation noting course enrollments are preserved).
- **General section**: Program name (text input), Description (textarea), Cover Image (upload via existing presigned upload flow).
- **Status section**: Status select (Active / Inactive / Archived). Inactive hides the program from students. Setting to Archived requires a confirmation dialog.
- Save button submits a `PUT /program/:programId`.
- "Programs" top-level nav item added to `org-navigation.ts` directly after "Courses", same structure as every other item (title, path, icon, matchPattern).
- Listing page shows all non-archived programs: name, cover image, course count, member count, status badge.
- "Create Program" button opens a creation form/modal.
- Clicking a program navigates to `/programs/[id]`.
- Follows the exact file and component structure of `apps/dashboard/src/routes/org/[slug]/courses/+page.svelte`.
├── ProgramHeader (program name + breadcrumb back to /org/[slug]/programs)
└── <slot /> (child routes)
```
**ProgramSidebar** — four items, role-gated, using the same `Sidebar.Group` / `Sidebar.Menu` / `Sidebar.MenuItem` primitives as `course-sidebar-navigation.svelte`:
| # | Label | Icon | Path | Visible to |
| --- | --- | --- | --- | --- |
| 1 | Newsfeed | `Newspaper` | `/programs/[id]/newsfeed` | All members |
| 2 | Courses | `BookOpen` | `/programs/[id]/courses` | All members |
| 3 | People | `Users` | `/programs/[id]/people` | Admin + Tutor only |
- "Programs" nav item in the LMS sidebar, shown conditionally only when `enrolledPrograms.length > 0`, positioned between "My Learning" and "Exercises".
-`/lms/programs` lists all ACTIVE programs the student is enrolled in: program name, cover image, course count, description.
- Clicking a program opens `/lms/programs/[programId]` — the program hub with two tabs: **Courses** (list by insertion order with per-course progress bars) and **Newsfeed** (read + react + comment; no post creation).
### 9. Access Control
- Only `ADMIN`/`TUTOR` program members (or org admins) can manage program content and membership.
- Students can read the newsfeed and course list, react to and comment on newsfeed posts.
- An `INACTIVE` program is hidden from students in the LMS; all data is preserved and accessible to admins/tutors.
1. For each member, resolve `profileId` from `email` (same pattern as `addGroupMember`).
2. Insert `program_member` row (skip if already a member).
3. If `roleId = 3` (STUDENT), fetch all courses (`getCoursesByProgram`). For each course, check if the student is already a `groupmember`; if not, insert a `groupmember` row with `roleId = 3`.
Returns all `ACTIVE` programs where the current user is a program member, including the course list with per-course progress. Used by LMS "My Programs" pages.
All page components live in `apps/dashboard/src/lib/features/program/pages/`. SvelteKit route files are thin wrappers that import and render the feature page component.
| Page | Feature file | Key UI elements |
| --- | --- | --- |
| Newsfeed | `newsfeed.svelte` | Post feed (pinned first), "New Post" editor (admin/tutor), reaction bar, comment threads |
| Courses | `courses.svelte` | Course list (insertion order), "Add Course" dropdown, remove per course (admin/tutor) |
| People | `people.svelte` | Member table with search + role filter, "Add Members" modal, role change + remove per row |
| Settings | `settings.svelte` | Name/description/cover image form, status select, save button |
- **Risk**: Auto-enrollment transaction for large programs (hundreds of students, many courses) times out or partially fails.
- **Mitigation**: Use a single transaction with Drizzle batch inserts. For very large programs (> 500 students), offload to a background job and return `202 Accepted` with a polling endpoint.
- **Risk**: Removing a course from a program confuses students who are still enrolled but no longer see it in the program hub.
- **Mitigation**: Show a confirmation dialog with the `program.remove_course_note` translation key: "Removing this course will not unenroll any students. They will still have access to it via My Learning."