feat: theme-level weekly sessions and theme-grouped knowledge library
- 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:
@@ -242,6 +242,61 @@ export async function getLearnDone() { return false; }
|
||||
/** @deprecated learn_progress collection has been dropped. */
|
||||
export async function setLearnDone() { return null; }
|
||||
|
||||
// ── Theme Sessions ──────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Look up the cached theme session for a given (curriculum_version, week_number).
|
||||
* Returns null when no cache entry exists yet.
|
||||
*/
|
||||
export async function getThemeSession(curriculumVersionId, weekNumber) {
|
||||
try {
|
||||
const record = await pb.collection('theme_sessions').getFirstListItem(
|
||||
`curriculum_version = "${curriculumVersionId}" && week_number = ${weekNumber}`
|
||||
);
|
||||
return record;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upsert the theme session for a given (curriculum_version, week_number).
|
||||
*/
|
||||
export async function setThemeSession(curriculumVersionId, weekNumber, theme, content) {
|
||||
return pbUpsert(
|
||||
'theme_sessions',
|
||||
`curriculum_version = "${curriculumVersionId}" && week_number = ${weekNumber}`,
|
||||
{ theme, content },
|
||||
{ curriculum_version: curriculumVersionId, week_number: weekNumber, theme, content },
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the user completed the theme session for a given personal week?
|
||||
* Returns the completion record, or null.
|
||||
*/
|
||||
export async function getThemeSessionCompletion(userId, sessionWeek) {
|
||||
try {
|
||||
return await pb.collection('theme_session_completions').getFirstListItem(
|
||||
`team_member_id = "${userId}" && session_week = ${sessionWeek}`
|
||||
);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a theme session as completed for the user/week. Idempotent.
|
||||
*/
|
||||
export async function setThemeSessionCompletion(userId, themeSessionId, sessionWeek) {
|
||||
return pbUpsert(
|
||||
'theme_session_completions',
|
||||
`team_member_id = "${userId}" && session_week = ${sessionWeek}`,
|
||||
{ theme_session_id: themeSessionId },
|
||||
{ team_member_id: userId, theme_session_id: themeSessionId, session_week: sessionWeek },
|
||||
);
|
||||
}
|
||||
|
||||
// ── Leaderboard ───────────────────────────────────────────────────────────────
|
||||
|
||||
export async function getLeaderboard() {
|
||||
@@ -484,6 +539,8 @@ export async function resetForSmokeTest({
|
||||
'topics',
|
||||
'micro_learnings',
|
||||
'micro_learning_completions',
|
||||
'theme_session_completions',
|
||||
'theme_sessions',
|
||||
'test_results',
|
||||
];
|
||||
if (includeProgress) collections.push('leaderboard');
|
||||
|
||||
Reference in New Issue
Block a user