Completion tracking

There are three read views. All of them are read-only — reading them never triggers recalculation. Statuses are recomputed by a separate background/batch process, so each response includes a last_calculated_at timestamp telling you how fresh the data is.

Cohort stats (aggregate)

completion_breakdown returns member counts across four buckets:

BucketComposed of
completedcompleted + completed elsewhere
in_progressstarted
overdueoverdue + never started
not_startedmembers with no activity record yet (the remainder)

Note that at the aggregate level, "completed elsewhere" folds into completed and "never started" folds into overdue — there are only four buckets.

Per-member enrollment status

The per-member view is more granular and keeps the statuses distinct:

Invited, NotStarted, InProgress, Completed, CompletedElsewhere, Overdue, OverdueNeverStarted.

You can filter the member list by any one of these values.

Progress (single member / current user)

Progress is reported as counts, not a percentage: completed_count and total_count, plus a per-section, per-item breakdown with completion timestamps. Compute a percentage from the two counts if you need one.