115 lines
4.2 KiB
Dart
115 lines
4.2 KiB
Dart
import 'health_gateway_fallback.dart'
|
|
if (dart.library.io) 'health_gateway_mobile.dart' as impl;
|
|
|
|
/// Native health ecosystem backing the current device.
|
|
///
|
|
/// Kept in `core` (not the health_sync feature) so the platform layer never
|
|
/// imports feature code; the biometric controller maps this to the domain's
|
|
/// `BiometricSource` enum.
|
|
enum NativeHealthPlatform {
|
|
/// Apple HealthKit (iOS).
|
|
appleHealth,
|
|
|
|
/// Google Health Connect (Android).
|
|
healthConnect,
|
|
}
|
|
|
|
/// Scalar sample returned by the health gateway.
|
|
///
|
|
/// Pure value type: [unit] is a display string (`lb`, `kcal`) — unit
|
|
/// normalization (kg → lb, joules → kcal) happens inside the gateway so
|
|
/// consumers only ever deal in pounds and Calories.
|
|
class HealthMetric {
|
|
const HealthMetric({
|
|
required this.timestamp,
|
|
required this.value,
|
|
required this.unit,
|
|
});
|
|
|
|
/// When the sample was recorded.
|
|
final DateTime timestamp;
|
|
|
|
/// Normalized magnitude (pounds for weight, kilocalories for energy).
|
|
final double value;
|
|
|
|
/// Unit of [value] for display (e.g. `lb`, `kcal`).
|
|
final String unit;
|
|
}
|
|
|
|
/// Read-only access to biometrics that were logged locally on this device.
|
|
///
|
|
/// Implemented by the health_sync feature over the encrypted drift cache and
|
|
/// injected into the fallback gateway so Web/Windows/macOS builds serve
|
|
/// locally logged data instead of returning nothing. Declared in `core` to
|
|
/// keep the platform layer free of feature imports (architecture rule 2);
|
|
/// the dependency points inward: features implement core contracts.
|
|
abstract class ILocalBiometricReader {
|
|
/// Weight samples in pounds for `[start, end)`, newest first.
|
|
Future<List<HealthMetric>> readWeightRange({
|
|
required DateTime start,
|
|
required DateTime end,
|
|
});
|
|
|
|
/// Active energy burned (kcal) samples for `[start, end)`, newest first.
|
|
Future<List<HealthMetric>> readEnergyRange({
|
|
required DateTime start,
|
|
required DateTime end,
|
|
});
|
|
}
|
|
|
|
/// Cross-platform boundary over the OS health ecosystems (architecture rule
|
|
/// 2/3: platform-specific packages never leak past this interface).
|
|
///
|
|
/// * **Android / iOS:** implemented by `health_gateway_mobile.dart`, which
|
|
/// wraps the `health` package (Health Connect / HealthKit) behind
|
|
/// `kIsWeb` / `defaultTargetPlatform` guards.
|
|
/// * **Windows / macOS / Web:** implemented by `health_gateway_fallback.dart`,
|
|
/// a manual-entry mode that never touches platform channels; reads are
|
|
/// served from the drift-backed cache through an injected
|
|
/// [ILocalBiometricReader].
|
|
abstract class IHealthGateway {
|
|
/// Whether this device can read/write native health data. `false` on
|
|
/// Web/Windows/macOS, which signals the UI to offer manual entry.
|
|
bool get supportsNativeHealth;
|
|
|
|
/// Ecosystem backing [supportsNativeHealth], or `null` in fallback mode.
|
|
NativeHealthPlatform? get nativePlatform;
|
|
|
|
/// Requests read permission for weight and active energy; returns whether
|
|
/// access was granted. Always `false` in fallback mode.
|
|
Future<bool> requestPermissions();
|
|
|
|
/// Weight samples in pounds for `[start, end)`, newest first.
|
|
///
|
|
/// Returns an empty list (never throws) in fallback mode or when the OS
|
|
/// denies access.
|
|
Future<List<HealthMetric>> fetchWeightHistory({
|
|
required DateTime start,
|
|
required DateTime end,
|
|
});
|
|
|
|
/// Active energy burned (kcal) samples for `[start, end)`, newest first.
|
|
///
|
|
/// Returns an empty list (never throws) in fallback mode or when the OS
|
|
/// denies access.
|
|
Future<List<HealthMetric>> fetchActiveEnergyBurned({
|
|
required DateTime start,
|
|
required DateTime end,
|
|
});
|
|
|
|
/// Writes a weight measurement back to the native store; returns whether
|
|
/// the platform accepted it (always `false` in fallback mode).
|
|
Future<bool> writeWeight({
|
|
required double weightLbs,
|
|
required DateTime timestamp,
|
|
});
|
|
}
|
|
|
|
/// Platform-appropriate factory: native `health`-backed gateway on
|
|
/// Android/iOS, manual-entry fallback on Web/Windows/macOS.
|
|
///
|
|
/// [localReader] backs fallback reads with the locally logged biometric
|
|
/// cache; mobile platforms ignore it and query the native store directly.
|
|
IHealthGateway createHealthGateway({ILocalBiometricReader? localReader}) =>
|
|
impl.makeHealthGateway(localReader: localReader);
|