Study views
Inside /my-courses/{slug} after Overview. Shell tabs and chapter picker are in 04-dashboard-and-workspace.md. Heartbeat CourseStudyHeartbeat writes study_sessions while a study tab is open (not a labeled button).
Student IA (restored from Git c7fc162): Overview plus content tabs Notes, Formula sheet, Flashcards, Quiz, Exam, Exam review, Mistake fixes, Exercises. module_pack_items.item_type stays on tab= URLs. Learn / Practice / Review is not the primary navigation.
Ask Tutor remains the course-grounded AI panel (?panel=ai). Quiz/flashcard/exam viewers keep later backend (mastery, FSRS, exam timer). Course outline column from the later redesign is not shown.
Shared empty / gating copy (StudyWorkspaceState):
No study content yet/Return to the course overview or check back later.Not published yet/This chapter does not have any published study material yet./Pick another chapter…{Tool} is not in this chapter/Open {tool} instead./Return to the course overview.Loading study tool/Preparing this study tool./Hang tight — it will appear in a moment.{Tool} for this chapter is being prepared.Content is empty/Content unavailable/This study tool could not be loaded./Try another tab…
Shared reader chrome (markdown tabs): Version select; Save to library / Remove from library; Print; reader chapters list is mobile / below lg; On this page; empty headings Headings from this page will appear here as you read.; mobile Chapters drawer title Chapters / Close contents.
PAGE: /my-courses/{slug} (Overview) Purpose: Next recommended action, course roadmap, progress, upcoming assessment, flashcard (weak-area) summary. Access: logged-in + owns course Entry points: course card; breadcrumb course code; locked-tab fallbacks
SECTION: Continue
Copy: Start here or Pick up where you left off. Empty No study content is ready yet. Check back when new notes are published. CTA Start learning → / Continue learning →.
Data shown: content_progress, next playable module_pack_items
ELEMENT: Start learning → / Continue learning →
Action: navigate
Destination: study href for that tab (tab= remains the content identity)
Writes to: none
Reads from: next content item
SECTION: Course roadmap
Copy: Course roadmap. Row Chapter {n} status Not started / {pct}% / Done. Content-type availability uses restored tab names (Notes, Quiz, …). Fallback Study the core ideas and practice problems for {title}.
Data shown: course_modules, chapter progress, pack item types
ELEMENT: Chapter row
Action: toggle
Destination: expands available study tools for that chapter
Writes to: none
Reads from: course_modules.title
ELEMENT: Notes / Formula sheet / Flashcards / Quiz / Exam / Exam review / Mistake fixes / Exercises
Action: navigate
Destination: first matching tab= href for that type
Writes to: none
Reads from: pack item types
SECTION: Your progress
Copy: Your progress {n}% complete {started} of {total} chapter(s) started
Data shown: aggregated chapter / content progress
ELEMENT: none (display)
SECTION: Flashcard cue (embedded)
Copy: Flashcards {n} due · ~{m} min Review now
Data shown: due count + session duration estimate (median when enough history, otherwise ~30s/card). Does not duplicate the flashcard landing dashboard.
ELEMENT: Review now
Action: navigate
Destination: flashcards ?scope=course&autostart=scheduled
Writes to: none until session starts
Reads from: due count
Empty course: No published study material yet + back to dashboard.
PAGE: /my-courses/{slug}?tab=notes
Purpose: Chapter notes markdown (Learn).
Access: logged-in + owns course
Entry points: Overview, Learn tab, resume Resume lessons. Deep link tab=notes survives.
SECTION: Notes reader
Copy: Empty Notes for this chapter are being prepared. Type label Notes.
Data shown: module_pack_items.content_data (markdown); content_progress (content_type=notes)
ELEMENT: Version
Action: navigate
Destination: same tab with variant=
Writes to: none
Reads from: pack variants
ELEMENT: Save to library / Remove from library
Action: submit
Destination: none
Writes to: library_items (item_type=saved_note)
Reads from: saved-note status
ELEMENT: Print
Action: toggle
Destination: none (window.print)
Writes to: none
Reads from: none
ELEMENT: Chapters list Ch. {n} · {title}
Action: navigate
Destination: notes href for that module (flushes notes progress first)
Writes to: content_progress (notes, debounced)
Reads from: course_modules
ELEMENT: On this page heading
Action: navigate
Destination: #headingId
Writes to: localStorage notes resume heading
Reads from: markdown headings
ELEMENT: Previous / Next
Action: toggle
Destination: in-page section
Writes to: content_progress (notes)
Reads from: heading outline
ELEMENT: Practice this concept →
Action: navigate
Destination: tab=exercises else tab=quiz
Writes to: none
Reads from: available practice types
ELEMENT: Open reference →
Action: navigate
Destination: tab=formula_sheet (Review intent; contextual from Learn)
Writes to: none
Reads from: none
PAGE: /my-courses/{slug}?tab=formula_sheet Purpose: Printable formula markdown. Access: logged-in + owns course (public catalog may deep-link a free-preview module; unauthenticated users hit login)
SECTION: Formula sheet reader
Copy: Type Formula sheet. Empty Formula sheet for this chapter is being prepared. Same Version / Save / Print / Chapters / On this page as notes. Lesson Previous/Next does not write content_progress.
Data shown: module_pack_items.content_data
ELEMENT: Version / Save to library / Print / Chapters / On this page / Previous / Next
Action: same as Notes except progress write
Destination: formula_sheet href / print / in-page
Writes to: library_items on save only
Reads from: content_data
PAGE: /my-courses/{slug}?tab=flashcards Purpose: Spaced-repetition + practice/browse. Access: logged-in + owns course Entry points: tab strip; Overview Review {n} due; library Review →; resume Review flashcards
SECTION: Landing
Copy: {n} due · ~{m} min Review due cards Learn new cards More options Browse all Needs attention Flashcard settings chips Due Learning New caught-up You're caught up Next review {time} empty Nothing to study right now. loading Loading your flashcard deck... Loading course flashcard schedule... Could not load course flashcard schedule. Flashcards for this chapter are being prepared.
Hidden from default UI: mature cards, leeches, FSRS, raw retention, coverage dashboard.
Data shown: flashcard_card_states, flashcard_deck_settings, review logs
ELEMENT: Review due cards
Action: submit
Destination: reviewing phase (mode scheduled)
Writes to: flashcard_sessions insert
Reads from: due queue
ELEMENT: Learn new cards
Action: submit
Destination: reviewing (learn_new)
Writes to: flashcard_sessions
Reads from: new-card budget
ELEMENT: Browse all Action: toggle Destination: browse phase Writes to: none Reads from: cards
ELEMENT: Needs attention
Action: submit
Destination: reviewing (practice)
Writes to: flashcard_sessions
Reads from: weakCardIds + is_leech / attention_flagged_at
ELEMENT: Back to course Action: navigate Destination: overview Writes to: none Reads from: empty state
SECTION: Browse
Copy: Browse all cards Unscheduled browsing — ratings will not change your schedule. badge Needs attention
Data shown: cards + session flagged set
ELEMENT: Back Action: toggle Destination: landing Writes to: none Reads from: none
ELEMENT: Card row (front text) Action: toggle Destination: reviewing that card Writes to: may start browse session Reads from: card front
SECTION: Session header
Copy: Scheduled review / Learn new / Practice / Browse. Counters Learning {n} Review {n} New {n}
Data shown: session queue
ELEMENT: Undo
Action: submit
Destination: previous card
Writes to: undo_last_flashcard_rating → flashcard_card_states / review logs
Reads from: last rated card
SR: Last rating undone.
ELEMENT: End session
Action: submit
Destination: landing or completion
Writes to: flashcard_sessions update
Reads from: session stats
SECTION: Reviewer
Copy: Labels Question Answer Hint. Helper Again: missed it. Hard: recalled with effort. Good: knew it. Easy: too easy. Group aria Rate your recall. Keyboard Space reveals · 1–4 rate… Banner Needs attention. Link Review this in the lesson. Confirm Reset this card's scheduling?…
Data shown: current card; coarse interval previews on rating buttons
ELEMENT: Card actions Action: open modal Destination: menu Writes to: none Reads from: none
ELEMENT: Bury for today
Action: submit
Destination: next card
Writes to: bury_flashcard_card → flashcard_card_states
Reads from: card id
Toast: Card buried for today.
ELEMENT: Needs attention / Remove flag
Action: submit
Destination: none
Writes to: flag_flashcard_attention → flashcard_card_states.attention_flagged_at
Reads from: flagged set + is_leech
ELEMENT: Report issue
Action: submit
Destination: report dialog
Writes to: study_content_reports (fallback content_reports)
Reads from: card front/back + category
Toast: Thanks — we logged this card for review.
ELEMENT: Advanced → Reset scheduling
Action: submit
Destination: next card
Writes to: reset_flashcard_scheduling
Reads from: card
Toast: Card scheduling reset.
ELEMENT: Advanced → Suspend card
Action: submit
Destination: next / complete
Writes to: suspend_flashcard_card
Reads from: card
Toast: Card suspended.
ELEMENT: Hint / Hide hint
Action: toggle
Destination: none
Writes to: none
Reads from: card.hint
ELEMENT: Show answer Action: toggle Destination: none Writes to: none Reads from: none
ELEMENT: Review this in the lesson
Action: navigate
Destination: notes #section-{key} (stable content anchor; hash omitted if heading is gone)
Writes to: none
Reads from: sourceHeadingId / notesSource / conceptIds
ELEMENT: Again / Hard / Good / Easy (1 · {interval} …)
Action: submit
Destination: next card / waiting / complete
Writes to: Scheduled/learn: commit_flashcard_review → flashcard_card_states, flashcard_review_logs, then content_progress (flashcards). Practice/browse: no schedule write.
Reads from: rating previews
SECTION: Waiting
Copy: Waiting for learning card + countdown
ELEMENT: Finish for now
Action: submit
Destination: completion
Writes to: flashcard_sessions
Reads from: stats
ELEMENT: Study ahead
Action: submit
Destination: reviewing (+30m ahead)
Writes to: may continue flashcard_sessions
Reads from: queue
SECTION: Completion
Copy: Session complete / Practice complete {n} cards reviewed Recall Time spent Ratings Still due Next review {time} {n} card(s) marked needs attention this session Does not change your schedule (practice again)
ELEMENT: Back to flashcards Action: toggle Destination: landing Writes to: none (refresh reads) Reads from: none
ELEMENT: Return to course Action: navigate Destination: module flashcards or overview Writes to: none Reads from: backHref
ELEMENT: Practice again
Action: submit
Destination: reviewing (practice)
Writes to: flashcard_sessions
Reads from: none
Session errors (toasts): could not load/open/start/save/undo/bury/suspend/reset; Nothing to study in this mode right now.
PAGE: /my-courses/{slug}?tab=quiz Purpose: Multiple-choice practice with immediate explanation. Access: logged-in + owns course
SECTION: Intro
Copy: Eyebrow {moduleTitle} Practice quiz {n} questions · Immediate feedback Finishing this checks it off. Passing and mastery are separate. Empty Quiz for this chapter is being prepared.
Data shown: module_pack_items.content_data.questions
ELEMENT: Start quiz →
Action: toggle
Destination: answering (server presentation order when signed in)
Writes to: quiz_attempts in_progress (client_attempt_id)
Reads from: pack questions
SECTION: Answering / review
Copy: Question {i} of {n} explanation after select. Keys Keys 1-4 select / Enter continues / R retakes
Data shown: current question options
ELEMENT: Option 1…n
Action: toggle
Destination: review state for that question
Writes to: draft + saveQuizProgress until complete
Reads from: question.options
ELEMENT: Next question → Action: toggle Destination: next question Writes to: none Reads from: none
ELEMENT: See results
Action: submit
Destination: complete
Writes to: quiz_attempts (idempotent client_attempt_id); quiz_attempt_answers; content_progress completed at 100% on submit regardless of score; merged user_concept_mastery; optional user_mistake_patterns. Pass if score ≥ 80 (lib/study/quiz-policy.ts). Mastery is concept-level, not quiz completion.
Reads from: answers array; pack item questions on the server
SECTION: Complete
Copy: Quiz submitted {n} / {total} correct plus honest percent. Attempted is not the same as mastered. Pass copy from attemptHeadline. Concept summary from merged evidence: Strong / Developing / Needs work. One recommended next action. Per-question reasoning, not only the correct option.
ELEMENT: Retake quiz
Action: toggle
Destination: answering (new attempt id, server shuffle)
Writes to: new quiz_attempts row on start
Reads from: none
ELEMENT: Practice this weakness Action: toggle then submit Destination: follow-up question for that concept Writes to: practice concept outcomes (not a new full attempt) Reads from: question bank
PAGE: /my-courses/{slug}?tab=exam Purpose: Practice exam. Answers after submit. Optional timer. Access: logged-in + owns course
SECTION: Intro
Copy: Practice exam {n} questions · Answers after you submit
ELEMENT: Start untimed / Timed
Writes to: quiz_attempts mode=exam
Browser payload has no answer keys (stripExamAnswerKey).
SECTION: Complete
Copy: Exam submitted plus score. Same mastery / attempted language as quiz.
Scoring against pack item on the server. Retake starts a new UUID.
PAGE: /my-courses/{slug}?tab=exam_review Purpose: Exam-week markdown. Access: logged-in + owns course
SECTION: Reader
Copy: Type Exam review. Empty Exam review for this chapter is being prepared.
Data shown: module_pack_items.content_data
ELEMENT: Version / Save to library / Print / Chapters / On this page
Action: same as formula sheet
Destination: exam_review href / print
Writes to: library_items on save only
Reads from: content_data
PAGE: /my-courses/{slug}?tab=mistake_fixes Purpose: Recurring mistake patterns from tagged distractors, plus chapter trap markdown. Access: logged-in + owns course
SECTION: Your mistake patterns
Copy: Your mistake patterns empty After a few quizzes, recurring slips show up here.
Data shown: user_mistake_patterns, user_concept_mastery
SECTION: Reader
Copy: Type Common traps. Empty Common traps for this chapter are being prepared.
ELEMENT: Version / Save to library / Print / Chapters / On this page
Action: same as exam review
Destination: mistake_fixes href
Writes to: library_items on save
Reads from: content_data
PAGE: /my-courses/{slug}?tab=exercises Purpose: Practice-problem markdown. Access: logged-in + owns course
SECTION: Reader
Copy: Type Exercises. Empty Exercises for this chapter are being prepared.
ELEMENT: Version / Save to library / Print / Chapters / On this page
Action: same as exam review
Destination: exercises href
Writes to: library_items on save
Reads from: content_data
Write cheat sheet
| Surface | Writes |
|---|---|
| Notes scroll/sections | content_progress (notes); localStorage resume heading; optional library_items |
| Formula / exam review / mistake fixes / exercises | optional library_items only |
| Flashcards scheduled/learn ratings | flashcard_sessions, flashcard_card_states, flashcard_review_logs, content_progress (flashcards) |
| Flashcards bury/suspend/reset/undo | RPCs on card states / logs |
| Flashcards practice/browse ratings | session row; no schedule |
| Quiz/Exam complete | quiz_attempts, content_progress (quiz) |
| Open study tab | study_sessions via heartbeat |
| Course settings Save flashcard settings | flashcard_deck_settings |