feat: implement curriculum management system including automated generation, enrichment, and versioning workflows

This commit is contained in:
RaymondVerhoef
2026-05-24 19:50:20 +02:00
parent 8e01b21a50
commit c5e23c77cd
15 changed files with 1354 additions and 623 deletions

View File

@@ -9,7 +9,7 @@ import {
ARTICLE_PATCH_TOOLS,
} from './llmTools';
import { applyAndValidate } from './articlePatches';
import { getCurriculumTopic } from './curriculumService';
import { getCurrentWeekContent } from './curriculumService';
const CONTENT_GENERATION_SYSTEM = `You are an expert learning content writer for Respellion, an internal IT company.
You write training material for employees based on knowledge topics.
@@ -32,23 +32,27 @@ const INSTRUCTIONS_BY_TYPE = {
};
/**
* Get the assigned topic for a given week.
* Curriculum-first: checks the curriculum collection for the current year.
* Get the assigned primary topic for a given week.
* Curriculum v2: checks the active curriculum version for the given ISO week.
* Falls back to hash-based assignment if no curriculum is configured.
*/
export async function getAssignedTopic(userId, weekNumber) {
export async function getAssignedTopic(userId, isoWeekNumber) {
try {
const { topic } = await getCurriculumTopic(weekNumber);
if (topic && topic.learning_relevance !== 'exclude') return topic;
const weekContent = await getCurrentWeekContent(isoWeekNumber);
if (weekContent && weekContent.topics && weekContent.topics.length > 0) {
// For single-topic compatibility, return the first topic
return weekContent.topics[0];
}
} catch (e) {
console.warn('[Learn] Curriculum lookup failed, falling back to hash:', e.message);
}
// Fallback hash-based assignment
const allTopics = await db.getTopics();
const topics = allTopics.filter(t => t.type !== 'fact' && t.learning_relevance !== 'exclude');
if (!topics || topics.length === 0) return null;
const str = `${userId}:${weekNumber}`;
const str = `${userId}:${isoWeekNumber}`;
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash = (hash << 5) - hash + str.charCodeAt(i);
@@ -58,6 +62,24 @@ export async function getAssignedTopic(userId, weekNumber) {
return topics[index];
}
/**
* Get all assigned topics for a given week.
*/
export async function getAssignedTopics(userId, isoWeekNumber) {
try {
const weekContent = await getCurrentWeekContent(isoWeekNumber);
if (weekContent && weekContent.topics && weekContent.topics.length > 0) {
return weekContent.topics;
}
} catch (e) {
console.warn('[Learn] Curriculum lookup failed, falling back to hash:', e.message);
}
// Fallback hash-based assignment
const topic = await getAssignedTopic(userId, isoWeekNumber);
return topic ? [topic] : [];
}
export async function getCachedContent(topicId) {
return db.getContent(topicId);
}