- Drop first/second-person voice; reference-style prose throughout - Remove stale information; align with current code (argon2id primary, hybrid cookie/Bearer auth, sliding 24h idle, AES-256-GCM PHI at rest, backup codes, node-pg-migrate, collation-drift guard, multi-arch Docker, auto-version pipeline) - Preserve all technical accuracy and code examples - Remove any remaining references to separate PedsHub Quiz app - Keep consistent tone across files (tables + code blocks, imperatives where needed) - api-reference.md and developer-guide.md route tables expanded to reflect current routes (billing, sessions)
3.1 KiB
3.1 KiB
Learning Hub
A CMS + content-delivery module for clinical education material inside the app. Supports articles, clinical pearls, quizzes, and Marp-rendered presentations with PPTX export. Quiz questions are stored alongside article content and can optionally be generated by AI from uploaded source material.
Content types
| Type | Description |
|---|---|
article |
Rich HTML body with an optional attached quiz |
pearl |
Short clinical snippet (no quiz, no heavy media) |
quiz |
Standalone quiz (no article body) |
presentation |
Marp markdown rendered as slides; PPTX export supported |
User-facing features
- Browse by category.
- Three search modes:
- Keyword — Postgres full-text.
- Semantic — pgvector cosine similarity on the embedding column.
- Hybrid — weighted merge of both result sets.
- Articles render with sanitized HTML (DOMPurify, loaded via SRI-pinned cdnjs).
- Quizzes: multiple-choice, multi-select, true/false. Score computed on submit, per-question explanations revealed after.
- Presentation viewer: modal with keyboard / swipe navigation.
- Progress:
learning_progressstores per-attempt score + total.
CMS (moderator / admin)
- Tiptap rich-text editor for article body.
- Draft / published toggle.
- Category assignment.
- Quiz builder: add/remove questions, add/remove options, mark correct, enter explanation.
- Marp editor for presentations with live preview.
AI content generation
POST /api/admin/learning/generate takes one of:
| Input | Notes |
|---|---|
topic |
Plain-text description of the topic |
| Uploaded files | PDF / TXT / MD / HTML / CSV / JSON, ≤ 100 MB each, max 10 files |
| WebDAV path | Pulled from the user's connected Nextcloud instance |
Parameters: model (from the provider whitelist), slideCount for
presentations, wordCount for articles.
File uploads pass the src/utils/fileType.js magic-byte check so a
mismatched extension is rejected before it reaches the parser.
Marp → PPTX export
Uses pptxgenjs.
- 16:9 widescreen.
- Bottom-right slide numbers.
- Supported Markdown elements: headings, sub-headings, bold, italic, inline code, numbered + bulleted lists, code blocks (grey background), blockquotes (blue accent bar), tables with alternating rows.
- Mixed content per slide allowed.
Semantic search
| Store | pgvector on learning_content.embedding VECTOR(768) |
| Index | IVFFLAT, cosine distance |
| Primary model | Google Vertex text-embedding-005 (768 dims) |
| Fallback model | OpenAI text-embedding-3-small (truncated to 768 to match the column) |
Embeddings are generated on content publish + on every edit. If the embedding provider is unreachable, the content still saves — keyword search remains available.
Tables
| Table | Purpose |
|---|---|
learning_categories |
Top-level groupings |
learning_content |
Articles / pearls / quizzes / presentations. Body + embedding vector. |
learning_questions |
Quiz question prompts (FK to content) |
learning_options |
Answer options (FK to question) |
learning_progress |
Per-user attempt history |