import 'muscle_group.dart'; /// One logged resistance-training working set group: the exercise performed, /// the muscle group it targeted, and the volume/LOAD prescription. /// /// Pure Dart (no framework imports) so the entity can be shared by the /// repository contract and the Riverpod presentation layer without leaking /// infrastructure concerns into the domain. class ExerciseEntry { const ExerciseEntry({ required this.id, required this.timestamp, required this.muscleGroup, required this.exerciseName, required this.sets, required this.reps, this.weightLbs = 0, }); /// UUID primary key assigned when the entry is first materialized. final String id; /// When the working set was performed. final DateTime timestamp; /// Muscle group trained (drives grouping and weekly frequency rollups). final MuscleGroup muscleGroup; /// Free-text exercise name (e.g. "Back Squat", "Lat Pulldown"). final String exerciseName; /// Number of working sets performed. final int sets; /// Repetitions per set. final int reps; /// Load moved per set in pounds; `0` for bodyweight work. final double weightLbs; /// Human-readable prescription, e.g. `3 × 8 @ 135 lb` or `3 × 12` /// for bodyweight work. String get volumeLabel { final load = weightLbs > 0 ? ' @ ${formatWeight(weightLbs)} lb' : ''; return '$sets × $reps$load'; } /// Formats a weight: whole numbers drop the decimal (`135`), fractional /// loads keep one digit (`137.5`). static String formatWeight(double weightLbs) { final rounded = weightLbs.roundToDouble(); return rounded == weightLbs ? rounded.toStringAsFixed(0) : weightLbs.toStringAsFixed(1); } @override String toString() => 'ExerciseEntry($id, ${exerciseName.trim()}, ${muscleGroup.name}, ' '$volumeLabel @ $timestamp)'; }