aggregateNeomageStats method
Aggregates stats from all Neomage sessions across all projects. Uses a disk cache to avoid reprocessing historical data.
Implementation
Future<NeomageStats> aggregateNeomageStats() async {
final allSessionFiles = await getAllSessionFiles();
if (allSessionFiles.isEmpty) {
return _getEmptyStats();
}
final updatedCache = await withStatsCacheLock(() async {
final cache = await loadStatsCache();
final yesterday = getYesterdayDateString();
var result = cache;
if (cache.lastComputedDate == null) {
// No cache — process all historical data.
final historicalStats = await processSessionFiles(
allSessionFiles,
options: ProcessOptions(toDate: yesterday),
);
if (historicalStats.sessionStats.isNotEmpty ||
historicalStats.dailyActivity.isNotEmpty) {
result = mergeCacheWithNewStats(
existingCache: cache,
newStats: historicalStats,
newLastComputedDate: yesterday,
);
await saveStatsCache(result);
}
} else if (isDateBefore(cache.lastComputedDate!, yesterday)) {
// Cache is stale — process new days.
final nextDay = getNextDay(cache.lastComputedDate!);
final newStats = await processSessionFiles(
allSessionFiles,
options: ProcessOptions(fromDate: nextDay, toDate: yesterday),
);
if (newStats.sessionStats.isNotEmpty ||
newStats.dailyActivity.isNotEmpty) {
result = mergeCacheWithNewStats(
existingCache: cache,
newStats: newStats,
newLastComputedDate: yesterday,
);
await saveStatsCache(result);
} else {
result = cache.copyWith(lastComputedDate: yesterday);
await saveStatsCache(result);
}
}
return result;
});
// Always process today's data live (it's incomplete).
final today = getTodayDateString();
final todayStats = await processSessionFiles(
allSessionFiles,
options: ProcessOptions(fromDate: today, toDate: today),
);
return cacheToStats(updatedCache, todayStats);
}