feat(platform): ship AI fallback stack and entity-scoped course planning

Unifies the new LangGraph-driven course-plan/media flow with robust provider fallbacks, admin AI provider settings, editable book-style materials, and strict entity isolation across LMS/course-plan APIs. Adds admin-only entity membership management in the Entities UI so users can switch linked entities directly from the platform.

Made-with: Cursor
This commit is contained in:
Yamen Ahmad
2026-04-26 02:34:52 +04:00
parent c2a07a6e5c
commit b4b5868223
23 changed files with 2502 additions and 199 deletions

View File

@@ -40,10 +40,23 @@ function buildAnswerMap(sections: ExamSessionSection[]) {
const map = new Map<number, ExamAnswer>();
for (const sec of sections) {
for (const q of sec.questions) {
// The backend `/api/exam/<id>/session` endpoint returns a
// `saved_answer` per question whenever a previous attempt is
// resumed (browser refresh, network drop, accidental tab-close).
// Seed the local map from that value so the student picks up
// exactly where they left off — without this, autosaved answers
// were silently dropped on every reload.
const saved = (q as unknown as { saved_answer?: unknown }).saved_answer;
const flagged = Boolean(
(q as unknown as { flagged?: boolean }).flagged,
);
map.set(q.id, {
question_id: q.id,
answer: null,
flagged: false,
answer:
saved === undefined || saved === null
? null
: (saved as ExamAnswer["answer"]),
flagged,
time_spent_ms: 0,
});
}