feat: live class sessions, CE workflow, and docs (#683)
Adds live-class session scheduling on lessons (join link, date/time, timezone) with automatic 24h and 1h reminder emails plus a calendar invite (.ics), a time-change notification with an updated invite, a teacher-authored welcome email and session invite on enrollment, and a "Notify students" quiz nudge. LMS gets an upcoming live-sessions card and Join buttons, plus a reusable live-session card component (3 states) in @cio/ui with a Storybook story. The sidebar content tree now reflects sequential progression locking like the content list, and the course-completion confetti regression is fixed. Org-based emails no longer reference ClassroomIO by name. Docs add live-class, welcome-email, and course-progression guides, expand the certificates guide (design, signatures, corrected labels), move plan-required callouts to the top, flatten how-to-guides to the docs root with redirects, and add screenshots. Includes an add-docs-image skill.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
export * from './media';
|
||||
export * from './emails';
|
||||
export * from './agent-course-generation';
|
||||
export * from './notifications';
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import type { JobsOptions } from 'bullmq';
|
||||
|
||||
import { JOB_NAMES, QUEUE_NAMES } from '../queues/names';
|
||||
import { QUEUE_DEFAULTS } from '../queues/defaults';
|
||||
import { getQueue } from '../queues/factories';
|
||||
import type { TNotifyCourseExercisePayload, TNotifyCourseSessionUpdatePayload } from '../payloads/notifications';
|
||||
|
||||
/**
|
||||
* Enqueue a `notifications:notify-course-exercise` job. Returns the BullMQ
|
||||
* job id so the dashboard can poll its status. Each click is a fresh nudge,
|
||||
* so we do NOT set a stable jobId (no dedupe across clicks).
|
||||
*/
|
||||
export async function enqueueNotifyCourseExercise(
|
||||
payload: TNotifyCourseExercisePayload,
|
||||
options: JobsOptions = {}
|
||||
): Promise<string | undefined> {
|
||||
const job = await getQueue(QUEUE_NAMES.notifications).add(JOB_NAMES.notifications.notifyCourseExercise, payload, {
|
||||
...QUEUE_DEFAULTS[QUEUE_NAMES.notifications],
|
||||
...options
|
||||
});
|
||||
|
||||
return job.id;
|
||||
}
|
||||
|
||||
/** Enqueue a one-off run of the session-reminder scan (manual trigger / on-demand). */
|
||||
export async function enqueueSessionReminderScan(options: JobsOptions = {}): Promise<string | undefined> {
|
||||
const job = await getQueue(QUEUE_NAMES.notifications).add(
|
||||
JOB_NAMES.notifications.sessionReminderScan,
|
||||
{},
|
||||
{ ...QUEUE_DEFAULTS[QUEUE_NAMES.notifications], ...options }
|
||||
);
|
||||
|
||||
return job.id;
|
||||
}
|
||||
|
||||
/** Enqueue a "session updated" notification that emails members an updated calendar invite. */
|
||||
export async function enqueueNotifyCourseSessionUpdate(
|
||||
payload: TNotifyCourseSessionUpdatePayload,
|
||||
options: JobsOptions = {}
|
||||
): Promise<string | undefined> {
|
||||
const job = await getQueue(QUEUE_NAMES.notifications).add(
|
||||
JOB_NAMES.notifications.notifyCourseSessionUpdate,
|
||||
payload,
|
||||
{
|
||||
...QUEUE_DEFAULTS[QUEUE_NAMES.notifications],
|
||||
...options
|
||||
}
|
||||
);
|
||||
|
||||
return job.id;
|
||||
}
|
||||
Reference in New Issue
Block a user