feat: theme-level weekly sessions and theme-grouped knowledge library
All checks were successful
On Push to Main / test (push) Successful in 46s
On Push to Main / publish (push) Successful in 1m28s
On Push to Main / deploy-dev (push) Successful in 2m9s

- New theme_sessions + theme_session_completions PocketBase collections
- Generate a detailed per-week theme summary covering every topic in the
  week's curriculum slot via EMIT_THEME_SESSION_TOOL; cache per
  (curriculum_version, week_number)
- Replace Leren.jsx "This Week's Topic" card with "This Week's Theme
  Session" that opens the new ThemeSessionView; per-topic micro-learnings
  remain reachable as optional practice from inside the session
- Group the Knowledge Library by topic.theme, pin the current week's
  theme on top, and badge topics already covered by the active session
- Mark week complete when the user finishes reading the theme session

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
RaymondVerhoef
2026-05-28 10:44:10 +02:00
parent 6a1f5556a9
commit d38c75beb1
7 changed files with 688 additions and 99 deletions

View File

@@ -213,6 +213,22 @@ export const replaceTakeawaysPatchSchema = z.object({
items: z.array(z.string().min(1)).min(1),
});
// ── Theme session schema ─────────────────────────────────────────────────────
const themeSessionTopicSection = z.object({
topic_id: z.string().min(1),
label: z.string().min(1),
summary: z.string().min(1),
});
export const themeSessionSchema = z.object({
title: z.string().min(1),
intro: z.string().min(1),
topicSections: z.array(themeSessionTopicSection).min(1),
connections: z.string().min(1),
keyTakeaways: z.array(z.string().min(1)).min(3),
});
/**
* Registry mapping known tool names to their input schemas. `callLLM`
* consults this when the caller does not pass an explicit `toolSchemas`
@@ -235,4 +251,5 @@ export const toolSchemaRegistry = {
add_section: addSectionPatchSchema,
remove_section: removeSectionPatchSchema,
replace_takeaways: replaceTakeawaysPatchSchema,
emit_theme_session: themeSessionSchema,
};