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> readWeightRange({ required DateTime start, required DateTime end, }); /// Active energy burned (kcal) samples for `[start, end)`, newest first. Future> 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 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> 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> 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 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);