recentMilestones function
Up to 6 most recent advancement events derived from allProgressProvider.
Heuristic: pick the latest progress rows with non-unstarted mastery,
sorted by lastStudiedAt (or updatedAt) descending. Topic titles are
resolved on the fly via getTopicById. If a streak ≥ 10 falls inside the
window it's added as an extra ochre milestone at the head.
Implementation
@riverpod
Future<List<Milestone>> recentMilestones(Ref ref) async {
final progress = await ref.watch(allProgressProvider.future);
final ds = ref.watch(supabaseDatasourceProvider);
final advancements = progress.where((p) => p.mastery != 'unstarted').toList()
..sort((a, b) {
final ta =
a.lastStudiedAt ??
a.updatedAt ??
DateTime.fromMillisecondsSinceEpoch(0);
final tb =
b.lastStudiedAt ??
b.updatedAt ??
DateTime.fromMillisecondsSinceEpoch(0);
return tb.compareTo(ta);
});
final picks = advancements.take(6).toList();
final milestones = <Milestone>[];
for (final p in picks) {
final topic = await ds.getTopicById(p.topicId);
final title = topic?.title ?? 'Topic';
final when = p.lastStudiedAt ?? p.updatedAt ?? DateTime.now();
milestones.add(
Milestone.fromMasteryTransition(
date: when,
topicTitle: title,
mastery: p.mastery,
),
);
}
return milestones;
}