getReviewSummariesForDomain method
- String domainId
Per-topic review summary for a domain. For each topic with at least one
review card, returns the longest interval_days and whether any of its
cards are due (next_review_at <= now). Topics with no cards are absent
from the returned map.
Implementation
Future<Map<String, ({int? intervalDays, bool due})>>
getReviewSummariesForDomain(String domainId) async {
final userId = _client.auth.currentUser?.id;
if (userId == null) return {};
final allRows = await _client
.from('review_cards')
.select('topic_id, interval_days, topics!inner(domain_id)')
.eq('user_id', userId)
.eq('topics.domain_id', domainId);
final now = DateTime.now().toIso8601String();
final dueRows = await _client
.from('review_cards')
.select('topic_id, topics!inner(domain_id)')
.eq('user_id', userId)
.eq('topics.domain_id', domainId)
.lte('next_review_at', now);
final dueTopicIds = (dueRows as List<dynamic>)
.map((r) => (r as Map<String, dynamic>)['topic_id'] as String)
.toSet();
final summaries = <String, ({int? intervalDays, bool due})>{};
for (final row in allRows as List<dynamic>) {
final r = row as Map<String, dynamic>;
final topicId = r['topic_id'] as String;
final interval = r['interval_days'] as int?;
final prev = summaries[topicId];
final newInterval = prev == null
? interval
: (interval == null
? prev.intervalDays
: (prev.intervalDays == null
? interval
: (interval > prev.intervalDays!
? interval
: prev.intervalDays)));
summaries[topicId] = (
intervalDays: newInterval,
due: dueTopicIds.contains(topicId),
);
}
return summaries;
}