feat: implement 52-week annual curriculum system with admin management and automated topic progression

This commit is contained in:
RaymondVerhoef
2026-05-18 19:49:05 +02:00
parent 228d0d7a54
commit 08f5b1fe18
10 changed files with 945 additions and 16 deletions

View File

@@ -2,7 +2,7 @@
Welcome, fellow AI agent! If you are reading this, you are tasked with maintaining or extending the Respellion Learning Platform. This document provides the critical context, architectural patterns, and design standards you need to successfully work on this codebase.
> **Last updated:** 2026-05-17 — Reflects selective content generation (3 types), ISO week alignment, GitHub sync folder change, and AI extraction token limits.
> **Last updated:** 2026-05-18 Adds 52-week annual curriculum system (§12). Reflects selective content generation (3 types), ISO week alignment, GitHub sync folder change, and AI extraction token limits.
## 1. Architectural Overview
This is a single-page React application built with **Vite**, backed by **PocketBase** as the database and auth layer.
@@ -26,6 +26,7 @@ All persistent data lives in **PocketBase**. The data access layer is in `src/li
* `leaderboard` — Points ledger (`user_id`, `name`, `points`, `tests_completed`).
* `team_members` — Registered users with PIN auth (`name`, `role`, `pin`).
* `sources` — Uploaded source documents and their extraction status (`name`, `status`, `error`).
* `curriculum` — Annual learning schedule (`year`, `week_number`, `topic_id`, `theme`, `quarter`, `is_review_week`, `sort_order`). One entry per week per year. Managed via the admin Curriculum tab.
* `settings` — Key/value store for app-wide settings (`key`, `value`).
**localStorage** is only used for **admin browser settings** (not user data):
@@ -40,6 +41,8 @@ All persistent data lives in **PocketBase**. The data access layer is in `src/li
**Week Number:** The current ISO-8601 week number is calculated dynamically on app load via `getWeekNumber(new Date())` in `src/store/AppContext.jsx`. It is **not** stored in the database. The `ADVANCE_WEEK` action still exists for admin use, but initial state always reflects the real calendar week.
**Curriculum Year:** The curriculum year is derived from `new Date().getFullYear()` via `getCurriculumYear()` in `src/lib/curriculumService.js`. It is not stored — always computed.
**Important:** All `db.js` functions are `async`. Always `await` them — omitting `await` will silently pass a Promise where data is expected.
**Auto-Cancellation:** The PocketBase JS SDK has auto-cancellation enabled by default. This causes concurrent identical requests (like `db.getTopics()` during React StrictMode renders or concurrent Promise.all) to abort with `ClientResponseError 0`. This feature is **globally disabled** in `src/lib/pb.js` via `pb.autoCancellation(false)` to prevent UI crashes during concurrent fetching.
@@ -128,4 +131,17 @@ The platform ships a global chatbot avatar called **R42**, rendered as the Respe
* **AI token budget.** If you see `[Pipeline] AI returned non-JSON response` in the logs, the response was truncated. Increase the topic cap prompt constraint before raising `max_tokens`.
* **PocketBase auto-cancellation is OFF.** `pb.autoCancellation(false)` is set globally in `src/lib/pb.js`. Never re-enable it — it causes abort errors during concurrent fetches in React StrictMode.
## 12. Annual Curriculum System
The platform uses a **52-week annual curriculum** so every employee covers all knowledge-base topics in one calendar year.
* **Service:** `src/lib/curriculumService.js` — curriculum engine with topic lookup, progress tracking, and auto-generation.
* **DB functions:** `db.getCurriculum(year)`, `db.getCurriculumWeek(year, week)`, `db.setCurriculumWeek(...)`, `db.bulkSetCurriculum(year, weeks[])`.
* **Admin UI:** `src/components/admin/CurriculumManager.jsx` — accessed via the "Curriculum" tab in the admin panel. Admins can auto-generate a schedule from KB topics or manually assign topics per week.
* **Same topic for everyone:** All employees study the same topic each week — this is by design to enable team discussion and shared quizzes.
* **Quarterly structure:** Weeks 113 (Q1), 1426 (Q2), 2739 (Q3), 4052 (Q4). Review/recap weeks at 13, 26, 39, 52.
* **Fallback:** If no curriculum exists for the current year, `getAssignedTopic()` falls back to the legacy hash-based assignment for backward compatibility.
* **Progress tracking:** `getYearProgress(userId)` and `getQuarterProgress(userId, quarter)` compute completion from the `learn_progress` collection against the curriculum.
* **Auto-generate:** `autoGenerateCurriculum(year)` distributes all non-fact topics across 48 content weeks + 4 review weeks. If there are fewer topics than weeks, they cycle. If more, excess topics remain in the self-service library.
* **Do not remove the hash fallback** — it ensures the platform works even without a configured curriculum.
Good luck! You are building a platform that empowers continuous learning. Keep it fast, keep it beautiful, and keep the user engaged.