feat: productionize learning engine and classroom

This commit is contained in:
inman
2026-08-16 21:44:52 +08:00
parent 2d04197f3f
commit ba35adfbfa
124 changed files with 9071 additions and 796 deletions

View File

@@ -17,7 +17,8 @@ import { buildCourseModuleOutputDigest } from './module-digest';
const log = createLogger('CourseStore');
export const COURSE_FRAMEWORK_DIR =
process.env.COURSE_FRAMEWORK_DIR ?? path.join(process.cwd(), 'data', 'course-frameworks');
process.env.COURSE_FRAMEWORK_DIR ??
path.join(process.env.LEARNING_DATA_DIR ?? path.join(process.cwd(), 'data'), 'course-frameworks');
export function isValidCourseId(id: string): boolean {
return /^[a-zA-Z0-9_-]+$/.test(id);
@@ -146,10 +147,13 @@ export async function createCourseRecord(
courseId: string,
requirement: string,
options: {
ownerPrincipalId?: string;
enableWebSearch?: boolean;
enableImageGeneration?: boolean;
enableVideoGeneration?: boolean;
enableTTS?: boolean;
interactiveMode?: boolean;
taskEngineMode?: boolean;
pdfText?: string;
} = {},
): Promise<CourseRecord> {
@@ -159,10 +163,15 @@ export async function createCourseRecord(
status: 'queued',
requirement,
modules: [],
...(options.ownerPrincipalId ? { ownerPrincipalId: options.ownerPrincipalId } : {}),
...(options.enableWebSearch ? { enableWebSearch: true } : {}),
...(options.enableImageGeneration ? { enableImageGeneration: true } : {}),
...(options.enableVideoGeneration ? { enableVideoGeneration: true } : {}),
...(options.enableTTS ? { enableTTS: true } : {}),
// Persist the explicit false value: finalization uses it to decide whether
// narration bytes are mandatory or intentionally omitted.
enableTTS: options.enableTTS ?? true,
interactiveMode: options.interactiveMode ?? true,
...(options.taskEngineMode ? { taskEngineMode: true } : {}),
...(options.pdfText ? { pdfText: options.pdfText } : {}),
createdAt: now,
updatedAt: now,
@@ -306,6 +315,7 @@ export async function invalidateCourseModulesFrom(
...existing,
modules,
publication: undefined,
externalPublication: undefined,
status: 'generating',
error: undefined,
updatedAt: new Date().toISOString(),