glp-companion/lib/features/health_sync/domain/entities/biometric_entry.dart

76 lines
2.3 KiB
Dart

/// Origin of a biometric reading.
///
/// Pure Dart (no framework imports); persisted as the enum [name] so the
/// database schema stays decoupled from domain types.
enum BiometricSource {
/// Imported from Apple HealthKit (iOS).
appleHealth,
/// Imported from Google Health Connect (Android).
healthConnect,
/// Typed in by the user (manual fallback on Web/Desktop or any platform).
manual,
/// Imported from a third-party cloud partner (MyFitnessPal, Withings, ...).
cloudSync;
/// Stable string persisted in the database.
String get persistenceKey => name;
/// Parses a persisted key; returns `null` for unknown/legacy values.
static BiometricSource? tryParse(String? raw) {
if (raw == null) return null;
for (final source in values) {
if (source.persistenceKey == raw) return source;
}
return null;
}
}
/// Immutable biometric sample: body weight plus optional active energy burn.
///
/// Pure Dart (no framework imports) so the entity can be shared by the health
/// sync use cases, the drift-backed repository, and the Riverpod presentation
/// layer without leaking infrastructure concerns into the domain.
class BiometricEntry {
const BiometricEntry({
this.id,
required this.timestamp,
required this.weightLbs,
this.activeCaloriesBurned,
required this.source,
});
/// Database primary key; `null` until the entry has been persisted.
final int? id;
/// When the sample was recorded (measurement time, not import time).
final DateTime timestamp;
/// Body weight in pounds.
final double weightLbs;
/// Active energy burned (kcal) attributed to [timestamp]; `null` when the
/// sample carries only a weight measurement.
final double? activeCaloriesBurned;
/// Where the sample originated.
final BiometricSource source;
/// Copy helper preserving the database identifier.
BiometricEntry copyWith({
int? id,
DateTime? timestamp,
double? weightLbs,
double? activeCaloriesBurned,
BiometricSource? source,
}) =>
BiometricEntry(
id: id ?? this.id,
timestamp: timestamp ?? this.timestamp,
weightLbs: weightLbs ?? this.weightLbs,
activeCaloriesBurned: activeCaloriesBurned ?? this.activeCaloriesBurned,
source: source ?? this.source,
);
}