- 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)
87 lines
3.1 KiB
Markdown
87 lines
3.1 KiB
Markdown
# 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_progress` stores 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 |
|