Skip to content

Tutorial Progress Tracking Demo

This demo walks through the FCC Tutorial Tracking subsystem -- a progress monitoring system for learning modules with checkpoint tracking, completion rates, and optional EventBus integration.


Table of Contents

  1. Overview
  2. Prerequisites
  3. Step 1: Define Tutorial Modules
  4. Step 2: Register and Track Progress
  5. Step 3: Query Completion Rates
  6. Step 4: Build a Learner Progress Snapshot
  7. Step 5: Integrate with the EventBus
  8. Screenshots
  9. Next Steps

Overview

The fcc.tutorials module provides a lightweight progress tracking system built on frozen dataclasses. It consists of three models and a tracker:

Component Description
ProgressCheckpoint A single checkpoint with completion status, optional score, and timestamp
TutorialModule A module containing ordered checkpoints with a computed completion_rate
LearnerProgress A snapshot of all registered modules for a given learner
TutorialTracker The tracker engine that manages modules and emits events

The tracker optionally integrates with the FCC EventBus, emitting TUTORIAL_PROGRESS_UPDATED and TUTORIAL_COMPLETED events as learners advance through checkpoints.


Prerequisites

  • Python 3.10+ with FCC installed: pip install -e ".[dev]"
  • No external dependencies required

Step 1: Define Tutorial Modules

Create tutorial modules with checkpoints. Each module has a unique ID, title, description, and an ordered tuple of checkpoints.

from fcc.tutorials import TutorialModule, ProgressCheckpoint

# Define a module with three checkpoints
persona_module = TutorialModule(
    module_id="mod-personas",
    title="Understanding FCC Personas",
    description="Learn about the 147 personas (102 core + 45 vertical) and their R.I.S.C.E.A.R. specs.",
    checkpoints=(
        ProgressCheckpoint(checkpoint_id="cp-1", title="Load the PersonaRegistry"),
        ProgressCheckpoint(checkpoint_id="cp-2", title="Explore persona categories"),
        ProgressCheckpoint(checkpoint_id="cp-3", title="Read a R.I.S.C.E.A.R. spec"),
    ),
)

print(f"Module: {persona_module.title}")
print(f"Checkpoints: {len(persona_module.checkpoints)}")
print(f"Completion rate: {persona_module.completion_rate:.0%}")

# Define a second module
workflow_module = TutorialModule(
    module_id="mod-workflows",
    title="FCC Workflow Graphs",
    description="Explore the 7 workflow graph definitions and action engine.",
    checkpoints=(
        ProgressCheckpoint(checkpoint_id="cp-1", title="Load a workflow graph"),
        ProgressCheckpoint(checkpoint_id="cp-2", title="Traverse graph nodes"),
        ProgressCheckpoint(checkpoint_id="cp-3", title="Run an action"),
        ProgressCheckpoint(checkpoint_id="cp-4", title="Generate a workflow trace"),
    ),
)

Step 2: Register and Track Progress

The TutorialTracker manages module registration and checkpoint updates. Because TutorialModule and ProgressCheckpoint are frozen dataclasses, updates create new instances internally.

from fcc.tutorials import TutorialTracker

tracker = TutorialTracker()

# Register modules
tracker.register_module(persona_module)
tracker.register_module(workflow_module)

print(f"Registered modules: {len(tracker.all_modules())}")

# Complete a checkpoint
updated_cp = tracker.update_progress(
    module_id="mod-personas",
    checkpoint_id="cp-1",
    completed=True,
    score=0.95,
)
print(f"Updated: {updated_cp.title}")
print(f"Completed: {updated_cp.completed}")
print(f"Score: {updated_cp.score}")
print(f"Completed at: {updated_cp.completed_at}")

# Complete another checkpoint
tracker.update_progress("mod-personas", "cp-2", completed=True, score=1.0)

Step 3: Query Completion Rates

Check progress at the module level using completion_rate() and get_progress().

# Module completion rate
rate = tracker.completion_rate("mod-personas")
print(f"Personas module: {rate:.0%} complete")

rate = tracker.completion_rate("mod-workflows")
print(f"Workflows module: {rate:.0%} complete")

# Get the full module state
module = tracker.get_progress("mod-personas")
if module:
    print(f"\n{module.title}:")
    for cp in module.checkpoints:
        status = "[x]" if cp.completed else "[ ]"
        score_str = f" (score={cp.score})" if cp.score is not None else ""
        print(f"  {status} {cp.title}{score_str}")

Step 4: Build a Learner Progress Snapshot

The get_learner_progress() method produces a frozen LearnerProgress snapshot containing all registered modules and their current state.

progress = tracker.get_learner_progress(learner_id="alice")
print(f"Learner: {progress.learner_id}")
print(f"Modules tracked: {len(progress.modules)}")
for mod in progress.modules:
    print(f"  [{mod.module_id}] {mod.title}: {mod.completion_rate:.0%}")

Step 5: Integrate with the EventBus

Wire the tracker to an EventBus to receive progress events. The tracker emits TUTORIAL_PROGRESS_UPDATED for each checkpoint update and TUTORIAL_COMPLETED when all checkpoints in a module are done.

from fcc.messaging.bus import EventBus
from fcc.messaging.events import Event

bus = EventBus()

# Create a tracker with EventBus integration
tracker = TutorialTracker(event_bus=bus)
tracker.register_module(persona_module)

# Subscribe to events
received_events: list[Event] = []

def event_handler(event: Event) -> None:
    received_events.append(event)
    print(f"  Event: {event.event_type.value}")
    print(f"  Payload: {event.payload}")

bus.subscribe(event_handler)

# Complete all checkpoints -- triggers PROGRESS_UPDATED + COMPLETED events
tracker.update_progress("mod-personas", "cp-1", completed=True)
tracker.update_progress("mod-personas", "cp-2", completed=True)
tracker.update_progress("mod-personas", "cp-3", completed=True)

print(f"\nTotal events emitted: {len(received_events)}")
# 3 TUTORIAL_PROGRESS_UPDATED + 1 TUTORIAL_COMPLETED = 4 events

Screenshots

Tutorial Tracker Streamlit app showing progress

The Tutorial Tracker Streamlit app provides a visual dashboard showing module completion progress, individual checkpoint status, and score distributions for each learner.


Next Steps

  • Explore the Knowledge Graph Demo to see how tutorial concepts connect to the knowledge graph.
  • Try the Persona Dimensions Demo to understand the persona model that tutorials teach.
  • See the Messaging Realtime Demo for details on how tutorial events flow through the EventBus to the browser.
  • Browse src/fcc/tutorials/ for the full source code.
  • Check notebooks/ for Jupyter notebooks that function as interactive tutorials.