feat: implement curriculum service and learning automation infrastructure
All checks were successful
On Push to Main / test (push) Successful in 30s
On Push to Main / publish (push) Successful in 57s
On Push to Main / deploy-dev (push) Successful in 1m33s

This commit is contained in:
RaymondVerhoef
2026-05-20 11:44:58 +02:00
parent 2752fb95d9
commit 6fe66bbd93
5 changed files with 12 additions and 9 deletions

View File

@@ -44,7 +44,7 @@ const CurriculumManager = () => {
db.getTopics(), db.getTopics(),
]); ]);
setCurriculum(currData); setCurriculum(currData);
setTopics(topicData.filter(t => t.type !== 'fact')); setTopics(topicData.filter(t => t.type !== 'fact' && t.learning_relevance !== 'exclude'));
setIsLoading(false); setIsLoading(false);
}; };

View File

@@ -87,9 +87,9 @@ export async function getCurriculumTopic(weekNumber, year) {
return { topic: null, curriculumEntry: entry || null }; return { topic: null, curriculumEntry: entry || null };
} }
// Resolve the topic from the topics collection // Resolve the topic from the topics collection (ensure it is not excluded)
const topics = await db.getTopics(); const topics = await db.getTopics();
const topic = topics.find(t => t.id === entry.topic_id) || null; const topic = topics.find(t => t.id === entry.topic_id && t.learning_relevance !== 'exclude') || null;
return { topic, curriculumEntry: entry }; return { topic, curriculumEntry: entry };
} }
@@ -178,8 +178,8 @@ export async function autoGenerateCurriculum(year) {
const currYear = year ?? getCurriculumYear(); const currYear = year ?? getCurriculumYear();
const topics = await db.getTopics(); const topics = await db.getTopics();
// Filter out 'fact' type topics — those are for the knowledge graph only // Filter out 'fact' type topics and 'exclude' relevance topics
const learningTopics = topics.filter(t => t.type !== 'fact'); const learningTopics = topics.filter(t => t.type !== 'fact' && t.learning_relevance !== 'exclude');
const weeks = []; const weeks = [];
const reviewWeeks = [13, 26, 39, 52]; const reviewWeeks = [13, 26, 39, 52];

View File

@@ -56,13 +56,15 @@ export async function getAssignedTopic(userId, weekNumber) {
// Try curriculum first // Try curriculum first
try { try {
const { topic } = await getCurriculumTopic(weekNumber); const { topic } = await getCurriculumTopic(weekNumber);
if (topic) return topic; if (topic && topic.learning_relevance !== 'exclude') return topic;
} catch (e) { } catch (e) {
console.warn('[Learn] Curriculum lookup failed, falling back to hash:', e.message); console.warn('[Learn] Curriculum lookup failed, falling back to hash:', e.message);
} }
// Fallback: hash-based assignment (backwards compatible) // Fallback: hash-based assignment (backwards compatible)
const topics = await db.getTopics(); const allTopics = await db.getTopics();
// Filter out 'fact' type topics and 'exclude' relevance topics
const topics = allTopics.filter(t => t.type !== 'fact' && t.learning_relevance !== 'exclude');
if (!topics || topics.length === 0) return null; if (!topics || topics.length === 0) return null;
const str = `${userId}:${weekNumber}`; const str = `${userId}:${weekNumber}`;

View File

@@ -8,7 +8,8 @@ Always write in clear, professional English.
ALWAYS return valid JSON only — no markdown code blocks, no extra text.`; ALWAYS return valid JSON only — no markdown code blocks, no extra text.`;
async function selectTestTopics(userId, weekNumber) { async function selectTestTopics(userId, weekNumber) {
const topics = await db.getTopics(); const allTopics = await db.getTopics();
const topics = allTopics.filter(t => t.type !== 'fact' && t.learning_relevance !== 'exclude');
if (!topics || topics.length === 0) return { primaryTopic: null, reviewTopics: [], isReviewWeek: false }; if (!topics || topics.length === 0) return { primaryTopic: null, reviewTopics: [], isReviewWeek: false };
// Try curriculum-based selection first // Try curriculum-based selection first

View File

@@ -295,7 +295,7 @@ const Leren = () => {
} }
// ── Overview ────────────────────────────────────────────── // ── Overview ──────────────────────────────────────────────
const otherTopics = allTopics.filter(t => t.id !== assignedTopic?.id && t.type !== 'fact'); const otherTopics = allTopics.filter(t => t.id !== assignedTopic?.id && t.type !== 'fact' && t.learning_relevance !== 'exclude');
const currentQuarter = getQuarterForWeek(state.weekNumber); const currentQuarter = getQuarterForWeek(state.weekNumber);
const currentQuarterName = getQuarterName(state.weekNumber); const currentQuarterName = getQuarterName(state.weekNumber);