Local-first Flutter app that identifies the single behavioral change most likely to extend lifespan using hazard-based modeling. Features: - Risk engine with hazard ratios from meta-analyses - 50 countries mapped to 4 mortality groups - 6 modifiable factors: smoking, alcohol, sleep, activity, driving, work hours - SQLite local storage (no cloud, no accounts) - Muted clinical UI theme - 23 unit tests for risk engine Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
78 lines
2.5 KiB
Dart
78 lines
2.5 KiB
Dart
import 'enums.dart';
|
|
|
|
class BehavioralInputs {
|
|
final SmokingStatus smoking;
|
|
final int cigarettesPerDay; // only relevant if smoking == current
|
|
final AlcoholLevel alcohol;
|
|
final double sleepHours;
|
|
final bool sleepConsistent;
|
|
final ActivityLevel activity;
|
|
final DrivingExposure driving;
|
|
final WorkHoursLevel workHours;
|
|
|
|
const BehavioralInputs({
|
|
required this.smoking,
|
|
this.cigarettesPerDay = 0,
|
|
required this.alcohol,
|
|
required this.sleepHours,
|
|
required this.sleepConsistent,
|
|
required this.activity,
|
|
required this.driving,
|
|
required this.workHours,
|
|
});
|
|
|
|
static const optimal = BehavioralInputs(
|
|
smoking: SmokingStatus.never,
|
|
cigarettesPerDay: 0,
|
|
alcohol: AlcoholLevel.none,
|
|
sleepHours: 7.5,
|
|
sleepConsistent: true,
|
|
activity: ActivityLevel.high,
|
|
driving: DrivingExposure.low,
|
|
workHours: WorkHoursLevel.normal,
|
|
);
|
|
|
|
Map<String, dynamic> toJson() => {
|
|
'smoking': smoking.name,
|
|
'cigarettesPerDay': cigarettesPerDay,
|
|
'alcohol': alcohol.name,
|
|
'sleepHours': sleepHours,
|
|
'sleepConsistent': sleepConsistent,
|
|
'activity': activity.name,
|
|
'driving': driving.name,
|
|
'workHours': workHours.name,
|
|
};
|
|
|
|
factory BehavioralInputs.fromJson(Map<String, dynamic> json) =>
|
|
BehavioralInputs(
|
|
smoking: SmokingStatus.values.byName(json['smoking'] as String),
|
|
cigarettesPerDay: json['cigarettesPerDay'] as int? ?? 0,
|
|
alcohol: AlcoholLevel.values.byName(json['alcohol'] as String),
|
|
sleepHours: (json['sleepHours'] as num).toDouble(),
|
|
sleepConsistent: json['sleepConsistent'] as bool,
|
|
activity: ActivityLevel.values.byName(json['activity'] as String),
|
|
driving: DrivingExposure.values.byName(json['driving'] as String),
|
|
workHours: WorkHoursLevel.values.byName(json['workHours'] as String),
|
|
);
|
|
|
|
BehavioralInputs copyWith({
|
|
SmokingStatus? smoking,
|
|
int? cigarettesPerDay,
|
|
AlcoholLevel? alcohol,
|
|
double? sleepHours,
|
|
bool? sleepConsistent,
|
|
ActivityLevel? activity,
|
|
DrivingExposure? driving,
|
|
WorkHoursLevel? workHours,
|
|
}) =>
|
|
BehavioralInputs(
|
|
smoking: smoking ?? this.smoking,
|
|
cigarettesPerDay: cigarettesPerDay ?? this.cigarettesPerDay,
|
|
alcohol: alcohol ?? this.alcohol,
|
|
sleepHours: sleepHours ?? this.sleepHours,
|
|
sleepConsistent: sleepConsistent ?? this.sleepConsistent,
|
|
activity: activity ?? this.activity,
|
|
driving: driving ?? this.driving,
|
|
workHours: workHours ?? this.workHours,
|
|
);
|
|
}
|