EPIC: Recurring Course Assignment

Updated June 26, 2026

Feature Overview

With recurring course assignment, admins can manage recurring training cycles within a single Learning Program (LP). Each certification cycle is a Course added to the LP, and an Active/Inactive toggle controls which cycles are current.

Today, when a customer needs to reassign training annually (e.g., compliance recertification), admins must manually recreate content and manage new assignments. There is no easy way to track completion across different cycles together.

With this feature, admins manage recurring training by adding new Courses to an existing LP and toggling previous cycles to Inactive. A "Use for next cycle" action deep-copies a Course and its content for the next certification period, giving the admin a content review touchpoint each cycle. Learners see their LP status reflect reality — it reverts to In Progress when a new cycle is due, and new hires only receive current (Active) cycles.

These capabilities deliver the annual compliance workflow and establish the foundational primitive for automated scheduling in future versions.

V1 Scope: Courses Only

LP components can be Courses, Flash Drills, or Channels. V1 applies Active/Inactive state to Course components only. Flash Drills and Channels are out of scope for this release — they behave exactly as they do in default-mode LPs (always assigned; Flash Drills count toward progress, Channels do not as they are open-ended).

Business Case

Customer retention

Recurring course assignment is one of the most frequently requested capabilities. Admins who manage compliance and certification programs are often key voices in vendor selection and renewal decisions — delivering this feature directly improves their satisfaction and strengthens the case for renewal. Beyond satisfaction, recurring assignment embeds Allego into essential internal processes like annual compliance workflows and certification renewal cycles. Once these processes run on Allego, the platform becomes stickier and harder to replace.

New sales and expansion

Recurring assignment is a frequently asked question in RFPs, and native support for it is rare among direct SE competitors. A well-designed solution gives prospects another reason to choose Allego and strengthens the platform consolidation argument by addressing a key advantage that LMS vendors have held. This becomes increasingly important as Allego targets larger enterprise customers with more stringent compliance requirements — recurring assignment is table stakes for that segment.

Customers who have requested related capabilities

Known Use Cases and Considerations

Why do customers need recurring course assignment?

Organizations with compliance, regulatory, or skills-maintenance requirements need learners to repeat training on a regular cadence. Common scenarios:

V1 targets the first scenario (annual compliance / fixed calendar schedule). The capabilities introduced generalize to individual-timing scenarios in future versions.

What does recurring course assignment entail?

The admin manages recurring training as a sequence of Courses within a single LP. Each Course represents one certification cycle. An Active/Inactive toggle controls which cycles are current for assignment and progress calculation.

Deep copy is required because content-item completion is global in the system. If the new cycle's Course references the same Quiz entity as the previous cycle, the system considers it already complete. "Use for next cycle" creates new content-item entities with their own IDs and empty completion records.

Before and after

Today, admins manage recertification using standalone Courses — one per cycle, completely independent of each other.

Before (standalone Courses)After (Courses in LP with Active/Inactive)
Creating next cycleAdmin creates a brand new Course with duplicated content. No connection to previous cycles.Admin clicks "Use for next cycle" — system deep-copies Course + content, adds to the same LP
Managing audiencesAdmin recreates audiences from scratch for each new CourseAudiences are on the LP — existing members automatically get the new Active component
Tracking cycles togetherNo system connection between cycles. Admin relies on naming conventions and tags to correlateAll cycles live in one LP. Each cycle is a Course within it — naturally grouped
Completion statusAdmin must check each standalone Course separately to understand a learner's certification historyLP status reflects current-cycle completion. Per-Course data shows cycle-by-cycle history
New hire experienceAdmin must ensure new hires are added to the current Course only, not outdated onesNew hires only receive Active components. Past cycles (Inactive) are automatically skipped

The foundational primitive

Active/Inactive is not a stopgap for v1 — it's the primitive that all future automation builds on. The v2 scheduling rules are automated triggers for the same state transition the admin performs manually in v1. Even in v1, task generation executes per-assignment (per individual audience member), so the execution path for per-learner scheduling in v2 is already built and tested.

Key Decisions and Concepts

  1. Fixed calendar schedule use case first. Annual compliance — where all learners follow the same calendar cycle — is the most common request and works fully with the capabilities in this release. Individual-timing use cases (badge renewal, regulatory clock) require scheduling rules and are deferred to a future release.
  2. Include "Use for next cycle" action. Admins need a streamlined way to set up the next certification cycle. Today's Course copy does not include copying content items — "Use for next cycle" deep-copies both the Course and its content items, creating new entities with their own IDs and empty completion records. This is required because content-item completion is global: same entity ID = same completion.
  3. Active/Inactive state on LP components requires a new LP mode. Each component (Course) in an LP can be set to Active or Inactive. This is only available on LPs created in the new recurring mode — existing "one and done" LPs are unaffected. Without this mode gate, enabling dynamic progress on all existing LPs could generate unexpected new tasks for learners who completed their LP long ago.
  4. What Active means:
  5. What Inactive means: New assignees don't receive a task. Existing tasks remain intact — completion records preserved, access unchanged. Do less harm; more aggressive actions (cancel, revoke) can be added as enhancements if customers need them.
  6. Manual toggle over scheduling rules for v1. Active/Inactive gives admins full control without building a scheduling engine. Scheduling rules layer on in v2 as automated triggers for the same state transition.

Workflow Overview

See the Workflow Illustration for visual walkthroughs of admin setup, learner timelines, and cycle transitions.

Admin workflow (managing cycles)

  1. Initial setup: Admin creates an LP, adds a Course, and marks it as Active. Admin assigns audiences as usual.
  2. Year 1: Learners complete the Course. LP status = Finished.
  3. Cycle transition: Admin opens the LP component page, selects the Course, and clicks "Use for next cycle."
  4. System response:
  5. Ongoing: New hires joining the LP only receive Active components. The previous Course (Inactive) is skipped.
  6. Repeat for subsequent cycles.

Learner experience

Initial learners (Year 1)

Existing learners (subsequent cycles)

New hires

Feature Breakdown

Active/Inactive state per LP component

Dynamic LP progress

Auto-assign Active components to existing members

"Use for next cycle"

Reporting — cycle-aware LP status

Scope TBD with PM for Analytics — see Reporting Considerations section

Reporting Considerations

This section captures topics for discussion with the PM for Analytics. Solutions are not prescribed — these are awareness items and conversation starters.

Learning Program Details Dashboard

Learning Programs have been "one and done" — current reporting is built around that assumption. The team should consider how the dynamic nature of LP status (reverting from Finished to In Progress each cycle) affects each dashboard widget and determine whether it's acceptable to leave as-is. A key starting question: do the dashboard widgets take the application's value for progress status, or do they compute their own? Showing the data as-is is one thing, but breaking widget logic because of changed system behavior is another.

(Note: from past experience, this review can be time-consuming for the team. AI-assisted code review could significantly accelerate it.)

Program Status — showing completion history

Per-cycle completion status is already visible at the component level (each Course shows its own status in the Assignee Progress Details table). The question is about the Program Status column — this likely shows the current value, which will now change dynamically. We need a way to show previous instances of completion. One option: when the user hovers over the Program Status value, also show previous completion records. Determine the best approach with the PM for Analytics.

Analytics Data Feed (ADF)

LP-level records are not sent in the ADF today, so the dynamic LP status change may not have a direct impact. Each time a new Active cycle is assigned, Task Activity will include a "received" record; when the learner completes, a "completed" record. This is incremental and consistent with existing behavior. However, new ADF data sets are being designed or implemented — the PM for Analytics should confirm whether any of those would be affected.

Assignment Stats — aggregate-level data

Assignment Stats provides good visuals on aggregate-level data across LPs and Courses. The dynamic nature of LP status (reverting from Finished to In Progress each cycle) will affect these visuals for LPs. May not require changes, but we need to understand the current behavior so we can prepare users and have a clear starting point for future enhancements.

Assignment Stats — LP component-level reporting

Assignment Stats currently cannot report on individual LP components. This means we can't use the existing visuals to show, for example, "Completion over time for the 2025 cycle" (which is a Course within the LP). This is a future enhancement need. The PM for Analytics should be aware so it can be planned alongside or after the recurring course assignment feature.

Interaction with Existing LP Settings

Active/Inactive controls whether a component is assigned. Existing LP settings control when, how, and to whom. This section documents how Active/Inactive interacts with each existing setting.

Guiding principle: Inactive overrides assignment. If a component is Inactive, no new tasks are generated regardless of other settings. Existing tasks for Inactive components remain intact.

LP mode requirement: Active/Inactive state and dynamic LP progress are only available on LPs created in the new recurring mode. Existing "one and done" LPs are unaffected — they retain today's sticky completion behavior and do not expose the Active/Inactive toggle.

LP audience-level settings

Configured per audience in the "Sharing and task assignment" panel.

Subscribe/enroll vs. Share only

Audience modeActive componentInactive component
Subscribe/enrollTasks generated for audience membersNo new tasks generated. Existing tasks remain.
Share onlyNo tasks generated (existing behavior)No tasks generated (same as today)

No interaction. "Share only" already prevents task generation; Inactive does the same for individual components within a "Subscribe/enroll" audience. These are independent controls at different levels.

Starting date ("Starting now" / "Starting on [date]")

The audience-level start date controls when the LP assignment begins for the audience. Active/Inactive operates after enrollment — a component's state is evaluated when tasks are generated for audience members, not when the audience is created.

No interaction. The audience start date determines when the LP becomes available; Active/Inactive determines which components within it generate tasks.

Late enrollee handling (enrollment option)

Enrollment optionActive componentInactive component
Align start/due dates to othersTask generated at current timeline positionSkipped — no task generated, even though alignment would normally "catch up" to past components
Shift start/due dates relative to enrollmentTask generated with shifted offsetsSkipped — no task generated. Gap stays in the shifted timeline.

Key scenario — late enrollee + past cycles: A late enrollee joins an LP where the current cycle is Active and past cycles are Inactive. Under "Align to others," they would normally receive tasks for all components available as of today. With Active/Inactive, they skip Inactive components entirely — this is the core "newcomer skip" behavior.

Timeline gap under "Shift relative": Inactive components are excluded from task generation, but their day offsets are not removed from the timeline. Example: if an Inactive component occupied Day 7 and the next Active component is at Day 14, the enrollee's schedule has a gap at Day 7. The admin can adjust offsets manually if tighter spacing is desired.

Due date ("Ending on [date]" / "Ending never")

The audience-level due date applies to the LP as a whole, not individual components. Active/Inactive operates at the component level.

No interaction. The LP due date is unaffected by component-level Active/Inactive state.

Notifications and reminders

When a component is set to Active and tasks are auto-assigned to existing audience members, those members should receive notifications per the audience's notification settings.

When a component is set to Inactive, no notification is needed — no assignment action is occurring.

LP component-level settings

Configured per component row on the Manage Collections page.

Start — "When assigned" / "Day N" / "After: [component]"

Start valueActiveInactive
"When assigned" (Day 0)Task generated immediately upon enrollment or activationNo task generated
"Day 1" through "Week 51"Task generated after the specified delayNo task generated. Offset preserved — if set back to Active, original offset resumes.
"After: [component]" (gating)Task generated after gating component is completedConstraint applies — see below

Gating constraint: If a component is used as a gating item (another component's Start is set to "After: [this component]"), it cannot be set to Inactive. The toggle is disabled with an explanatory message. This prevents broken dependency chains. In a chain A → B → C, only C (the tail) can be set to Inactive. To make B inactive, the admin must first change C's Start to something other than "After: B."

End — due date

The component-level End value is a due date that shows an "overdue" label on learner tasks. It has no system enforcement — does not cancel or revoke access.

ActiveInactive
End value setDue date applies to generated tasksNo task generated, due date not applicable. Value preserved on component.
No end valueNo due date on tasksNo task generated

For existing tasks on a component that becomes Inactive, the due date remains in effect — those tasks are not modified.

Subscribe/Enroll toggle (per component)

The component-level toggle determines whether a task is auto-generated (Enroll) or the learner can self-enroll (Subscribe).

ActiveInactive
EnrollTask auto-generatedNo task generated (Inactive overrides)
SubscribeLearner can self-enrollSelf-enrollment blocked

Inactive prevents self-enrollment. The analogous behavior on individual Courses is the "Do not assign to members of this audience after [date]" setting (not available on LPs, but the same mechanism). When that date passes, the assignment is excluded from the subscription pipeline — self-enrollment is effectively blocked. Following this precedent, Inactive also prevents self-enrollment. Existing subscriptions remain intact.

Notify Users (per component)

ActiveInactive
Notify onNotification sent when task is generatedNo task generated, no notification
Notify offTask generated silentlyNo task generated

No interaction. Notifications are a consequence of task generation. If no task is generated (Inactive), no notification is sent.

Story Breakdown

Cloud stories

Cloud Story 1: Data model for new LP mode and Active status

Cloud Story 2: System behavior for Active vs. Inactive components

May need to be broken down further during grooming.

Cloud Story 3: "Use for next cycle" support

Web stories

Web Story 1: LP Properties — mode designation

Web Story 2: Component-level Active status

Web Story 3: "Use for next cycle" UX

Web Story 4: LP index page — learner Active status

Cloud/Mobile stories

Cloud/Mobile: LP index page — learner Active status

Scope: V1 vs. After V1

V1

After V1 (scheduling & automation)

Supporting Assets