Tipos primarios
1. slides
Apresentacao com elementos ricos.
{
"slides": [
{
"id": "uuid",
"layout": "title_content" | "two_column" | "image_focus" | "code_demo",
"elements": [
{ "type": "heading", "text": "...", "style": {} },
{ "type": "paragraph", "text": "..." },
{ "type": "image", "mediaAssetId": "uuid" },
{ "type": "list", "items": ["..."], "ordered": true },
{ "type": "code", "language": "python", "code": "..." },
{ "type": "callout", "variant": "info|warning|tip", "text": "..." }
]
}
],
"speakerNotes": { "slide-uuid": "Notas..." }
}
Viewer: components/lesson-viewer/slide-viewer.tsx (navegacao por teclado, fullscreen, speaker notes).
2. video
{
"source": "youtube" | "vimeo" | "upload",
"embedUrl": "https://...",
"videoUrl": "...",
"mediaAssetId": "uuid"
}
Suporta playback rate, captions, autoplay control. Auto-transcricao via Whisper quando mediaAssetId.
3. pdf_viewer
{
"mediaAssetId": "uuid",
"storageUrl": "...",
"initialPage": 1
}
Viewer com react-pdf, navegacao, zoom, full text search.
4. rich_text
{
"html": "<h1>...</h1><p>...</p>"
}
Editor: Tiptap com extensions (tables, code blocks com syntax highlighting, images, links, color, typography, math). HTML sanitizado server-side com sanitizeHtml().
5. quiz
{
"questions": [
{ "type": "multiple_choice", "question": "...", "options": ["A","B","C","D"],
"correctIndex": 0, "explanation": "...", "concepts": ["concept-id"] },
{ "type": "true_false", "question": "...", "correctIndex": 0 },
{ "type": "fill_blank", "question": "...", "blanks": [{"answer": "..."}] },
{ "type": "matching", "pairs": [{"left": "...", "right": "..."}] },
{ "type": "ordering", "items": ["..."] },
{ "type": "numeric", "answer": 42, "tolerance": 0.1 },
{ "type": "short_answer", "acceptedAnswers": ["..."] },
{ "type": "essay", "prompt": "..." }
],
"passingScore": 70,
"configuration": {
"maxAttempts": 3,
"timeLimitMinutes": 30,
"shuffleQuestions": true,
"shuffleOptions": true,
"accessCode": "...",
"scoringPolicy": "highest" | "latest" | "average",
"reviewMode": "after_submit" | "after_due_date" | "never"
}
}
Detalhes em Quiz Engine.
6. assignment
{
"instructions": "...",
"dueDate": "2026-06-15",
"maxScore": 100,
"submissionType": "text" | "file" | "both",
"rubricId": "uuid"
}
Submissoes vao para bucket privado submissions/{tenantId}/{courseId}/{lessonId}/{userId}/ (regra critica 122).
7. live_class
{
"liveClassId": "uuid"
}
LiveClass entity tem provider (BBB/Zoom/Teams/Meet), join URL, recording URL. Detalhes em Live Classes.
8. external_link
{
"url": "https://...",
"description": "...",
"openInNewTab": true
}
Subtypes interativos
Quando lesson.subtype !== null, renderiza viewer interativo dedicado:
interactive_video
Video com checkpoints (perguntas obrigatorias antes de continuar).
{
"videoUrl": "...",
"checkpoints": [
{ "timestampSec": 120, "question": { ... } }
]
}
drag_drop
{
"items": [{ "id": "1", "label": "Mitose" }],
"targets": [{ "id": "a", "label": "Divisao celular", "acceptedItemIds": ["1"] }]
}
fill_blanks
{
"text": "A capital da Franca e {{0}} e fica no continente {{1}}.",
"blanks": [
{ "id": 0, "acceptedAnswers": ["Paris"] },
{ "id": 1, "acceptedAnswers": ["Europa", "europeu"] }
]
}
flashcard_set
{
"cards": [
{ "id": "1", "front": "Qual e o teorema de Pitagoras?", "back": "a² + b² = c²" }
],
"srsEnabled": true
}
Algoritmo SRS SM-2 modificado. Schedules revisao em StudentFlashcardReview.
timeline
{
"events": [
{ "date": "1500", "title": "Descobrimento do Brasil", "description": "..." }
]
}
Linha do tempo interativa com zoom.
branching_scenario
Arvore de decisao para simulacoes (ex: caso clinico, dilema etico, negociacao).
{
"rootNodeId": "n1",
"nodes": {
"n1": {
"text": "Voce e um medico recebendo paciente com dor toracica...",
"choices": [
{ "text": "Solicitar ECG", "nextNodeId": "n2" },
{ "text": "Internar imediatamente", "nextNodeId": "n3" }
]
}
}
}
Editores (Lesson Builder)
Cada tipo tem editor visual dedicado em components/lesson-builder/:
- slides →
slides-editor.tsx(dnd-kit reorder, elementos drag-drop) - rich_text →
rich-text-editor.tsx(Tiptap) - quiz →
quiz-editor.tsx(com question bank picker + save dialog) - assignment →
assignment-editor.tsx(rubric picker, due date) - video →
video-editor.tsx(source select + embed) - pdf →
pdf-editor.tsx(upload + media picker) - live_class →
live-class-editor.tsx(provider select + schedule) - external_link →
external-link-editor.tsx - subtypes interativos → editors dedicados em
components/interactive/
Limitacoes
- Quiz tipo essay sem correcao automatica nativa — admin pode habilitar LLM grading (custo adicional)
- Subtypes interativos nao migram para H5P — Studeia format proprio
- Branching_scenario max depth 10 niveis — anti-loop infinito