feat(core): consolide le chainage type metier d'exercice -> strategie Health Services -> payload montre -> consommation Kotlin
Finalise #183 : modele/persistance des types metier d'exercice, mapping vers la strategie Health Services, propagation du payload dans le contrat watch bridge et consommation cote Kotlin montre. Perimetre complet QA vert. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -33,6 +33,17 @@ enum BusinessExerciseType {
|
||||
recovery,
|
||||
}
|
||||
|
||||
enum HealthServicesExerciseType {
|
||||
running('RUNNING'),
|
||||
walking('WALKING'),
|
||||
highIntensityIntervalTraining('HIGH_INTENSITY_INTERVAL_TRAINING'),
|
||||
workout('WORKOUT');
|
||||
|
||||
const HealthServicesExerciseType(this.wireName);
|
||||
|
||||
final String wireName;
|
||||
}
|
||||
|
||||
enum ActiveWorkoutStatus { running, paused, savedExit, completed, abandoned }
|
||||
|
||||
enum SetResultStatus { completed, skipped }
|
||||
@ -439,6 +450,11 @@ final class Exercise {
|
||||
? _businessTypesFromCategory(category)
|
||||
: businessTypes;
|
||||
|
||||
List<HealthServicesExerciseType> get healthServicesExerciseTypeStrategy =>
|
||||
healthServicesExerciseTypeStrategyForBusinessTypes(
|
||||
effectiveBusinessTypes,
|
||||
);
|
||||
|
||||
Exercise archive(DateTime now) {
|
||||
return copyWith(archivedAt: now, metadata: metadata.touch(now));
|
||||
}
|
||||
@ -639,6 +655,9 @@ final class ProgramExercise {
|
||||
this.exerciseImageMediaIdSnapshot,
|
||||
List<String> exerciseImageMediaIdsSnapshot = const [],
|
||||
this.exerciseVideoMediaIdSnapshot,
|
||||
List<HealthServicesExerciseType>
|
||||
healthServicesExerciseTypeStrategySnapshot =
|
||||
const [],
|
||||
List<ExerciseStep> exerciseStepsSnapshot = const [],
|
||||
this.autoStartNextTimedStepSnapshot = true,
|
||||
this.autoStartNextTimedStepOverride,
|
||||
@ -668,6 +687,12 @@ final class ProgramExercise {
|
||||
? [exerciseImageMediaIdSnapshot]
|
||||
: exerciseImageMediaIdsSnapshot,
|
||||
),
|
||||
healthServicesExerciseTypeStrategySnapshot =
|
||||
_validatedHealthServicesExerciseTypes(
|
||||
healthServicesExerciseTypeStrategySnapshot.isEmpty
|
||||
? legacyHealthServicesExerciseTypeStrategy
|
||||
: healthServicesExerciseTypeStrategySnapshot,
|
||||
),
|
||||
exerciseStepsSnapshot = _validatedExerciseSteps(exerciseStepsSnapshot) {
|
||||
_requireNonNegative(position, 'Position');
|
||||
_requirePositive(setsCount, 'Sets count');
|
||||
@ -712,6 +737,8 @@ final class ProgramExercise {
|
||||
final String? exerciseImageMediaIdSnapshot;
|
||||
final List<String> exerciseImageMediaIdsSnapshot;
|
||||
final String? exerciseVideoMediaIdSnapshot;
|
||||
final List<HealthServicesExerciseType>
|
||||
healthServicesExerciseTypeStrategySnapshot;
|
||||
final List<ExerciseStep> exerciseStepsSnapshot;
|
||||
final bool autoStartNextTimedStepSnapshot;
|
||||
final bool? autoStartNextTimedStepOverride;
|
||||
@ -761,6 +788,8 @@ final class ProgramExercise {
|
||||
exerciseImageMediaIdSnapshot: exercise.imageMediaId,
|
||||
exerciseImageMediaIdsSnapshot: exercise.imageMediaIds,
|
||||
exerciseVideoMediaIdSnapshot: exercise.videoMediaId,
|
||||
healthServicesExerciseTypeStrategySnapshot:
|
||||
exercise.healthServicesExerciseTypeStrategy,
|
||||
exerciseStepsSnapshot: exercise.steps,
|
||||
autoStartNextTimedStepSnapshot: exercise.autoStartNextTimedStep,
|
||||
exerciseArchivedSnapshot: exercise.archivedAt != null,
|
||||
@ -792,6 +821,10 @@ final class ProgramExercise {
|
||||
'exerciseImageMediaIdsSnapshot': exerciseImageMediaIdsSnapshot,
|
||||
'imageMediaIdsSnapshot': exerciseImageMediaIdsSnapshot,
|
||||
'exerciseVideoMediaIdSnapshot': exerciseVideoMediaIdSnapshot,
|
||||
'healthServicesExerciseTypeStrategy':
|
||||
healthServicesExerciseTypeStrategySnapshot
|
||||
.map((type) => type.wireName)
|
||||
.toList(),
|
||||
'exerciseStepsSnapshot': exerciseStepsSnapshot
|
||||
.map((step) => step.toSnapshotJson())
|
||||
.toList(),
|
||||
@ -2021,6 +2054,25 @@ List<BusinessExerciseType> _validatedBusinessExerciseTypes(
|
||||
return List.unmodifiable(unique);
|
||||
}
|
||||
|
||||
List<HealthServicesExerciseType> _validatedHealthServicesExerciseTypes(
|
||||
List<HealthServicesExerciseType> types,
|
||||
) {
|
||||
final unique = <HealthServicesExerciseType>[];
|
||||
for (final type in types) {
|
||||
if (!unique.contains(type)) {
|
||||
unique.add(type);
|
||||
}
|
||||
}
|
||||
return List.unmodifiable(unique);
|
||||
}
|
||||
|
||||
const legacyHealthServicesExerciseTypeStrategy = [
|
||||
HealthServicesExerciseType.running,
|
||||
HealthServicesExerciseType.walking,
|
||||
HealthServicesExerciseType.highIntensityIntervalTraining,
|
||||
HealthServicesExerciseType.workout,
|
||||
];
|
||||
|
||||
List<BusinessExerciseType> _businessTypesFromCategory(
|
||||
ExerciseCategory category,
|
||||
) {
|
||||
@ -2036,6 +2088,49 @@ List<BusinessExerciseType> _businessTypesFromCategory(
|
||||
};
|
||||
}
|
||||
|
||||
List<HealthServicesExerciseType>
|
||||
healthServicesExerciseTypeStrategyForBusinessTypes(
|
||||
List<BusinessExerciseType> types,
|
||||
) {
|
||||
if (types.isEmpty) {
|
||||
return legacyHealthServicesExerciseTypeStrategy;
|
||||
}
|
||||
final output = <HealthServicesExerciseType>[];
|
||||
void add(HealthServicesExerciseType type) {
|
||||
if (!output.contains(type)) {
|
||||
output.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
for (final type in types) {
|
||||
switch (type) {
|
||||
case BusinessExerciseType.dribble:
|
||||
case BusinessExerciseType.finishing:
|
||||
add(HealthServicesExerciseType.running);
|
||||
add(HealthServicesExerciseType.highIntensityIntervalTraining);
|
||||
add(HealthServicesExerciseType.workout);
|
||||
case BusinessExerciseType.conditioning:
|
||||
case BusinessExerciseType.highIntensity:
|
||||
case BusinessExerciseType.defense:
|
||||
add(HealthServicesExerciseType.highIntensityIntervalTraining);
|
||||
add(HealthServicesExerciseType.running);
|
||||
add(HealthServicesExerciseType.workout);
|
||||
case BusinessExerciseType.mobility:
|
||||
case BusinessExerciseType.recovery:
|
||||
add(HealthServicesExerciseType.walking);
|
||||
add(HealthServicesExerciseType.running);
|
||||
add(HealthServicesExerciseType.workout);
|
||||
case BusinessExerciseType.shoot:
|
||||
case BusinessExerciseType.freeThrows:
|
||||
add(HealthServicesExerciseType.highIntensityIntervalTraining);
|
||||
add(HealthServicesExerciseType.running);
|
||||
add(HealthServicesExerciseType.walking);
|
||||
add(HealthServicesExerciseType.workout);
|
||||
}
|
||||
}
|
||||
return List.unmodifiable(output);
|
||||
}
|
||||
|
||||
void _requireAtLeastOneMeasure({
|
||||
required bool hasTime,
|
||||
required bool hasReps,
|
||||
|
||||
Reference in New Issue
Block a user