Course
A structured learning track inside a theme: ordered modules, the content and question blocks inside them, and the answers learners submit.
See also: theme (parent), cohort (scheduled runs + enrollments), user (authors of answers and reviews).
Tables
COURSE
A structured learning track. One course per theme. Contains ordered modules, carries free-form tags, and is what cohorts actually run against. Carries a publishing lifecycle: status (draft → published → archived) keeps in-progress edits out of learners' view, author_id records who owns the content, version bumps per published revision, and published_at / archived_at timestamp the transitions.
id crs_01_gratitude
theme_id thm_01_gratitude
author_id usr_09_teacher
title 30 Days of Gratitude
description A month of short daily practices to build a gratitude habit.
category practice
tags ["beginner", "daily", "reflection"]
status published
version 3
published_at 2026-03-01T09:00:00Z
archived_at null
MODULE
An ordered unit inside a course (position defines sequence). Modules are containers for the content and questions that make up a single learning session.
id mod_01_day1
course_id crs_01_gratitude
position 1
title Day 1 — What is gratitude?
description Introducing the practice and what we'll cover.
COURSE_CONTENT_BLOCK
A piece of teaching content inside a module. md is the canonical body — the single source of truth that editors write. html_cached is a nullable, derived render of that markdown kept for fast reads; it's regenerated whenever md changes and is never edited directly, which avoids the source-of-truth drift you'd get from storing both as first-class fields. image_urls holds imagery the block references.
id blk_01_day1_intro
module_id mod_01_day1
position 1
title Why gratitude matters
md ## Why it matters\nGratitude has been linked to higher wellbeing in dozens of studies...
html_cached <h2>Why it matters</h2><p>Gratitude has been linked...</p>
image_urls ["https://cdn.afh.example/blk/01_intro.jpg"]
QUESTION_BLOCK
A prompt or quiz inside a module. format is either freeform or multiple_choice; multiple_choices holds the options and correct_answer the key (nullable for ungraded reflection prompts).
id q_01_day1_reflect
module_id mod_01_day1
position 2
question_text Write down 3 things you're grateful for today.
format freeform
correct_answer null
multiple_choices null
QUESTION_ANSWER
A user's response to a QUESTION_BLOCK, scoped to their ENROLLMENT so re-takes in a new cohort start clean. attempt increments per retry. For multiple-choice questions choice and correct are set; for freeform, text is set and correct is left null — instead, a USER (teacher or champion) can populate reviewer_id, reviewed_at, and feedback.
id ans_2026_04_03_001
user_id usr_42_maya
question_id q_01_day1_reflect
enrollment_id enr_01_april_maya
attempt 1
text My morning coffee, the spring sun on the walk in, my mum's text.
choice null
correct null
reviewer_id usr_09_teacher
reviewed_at 2026-04-04T11:10:00Z
feedback Lovely specifics — naming the *spring sun* makes it vivid.
submitted_at 2026-04-03T08:30:00Z