feat(exercice): modèle et migration pour l'auto-enchaînement des chronos d'étapes (ticket #75)

Étend le modèle Drift (migration schemaVersion 13→14, ADD COLUMN) et
la couche application (entités, use cases, repositories) pour
supporter l'auto-enchaînement des chronos d'étapes. flutter pub get
OK, build_runner OK, analyze propre (mêmes infos préexistantes),
141/141 tests verts, build APK debug validé. Premier ticket du
chantier "auto-enchaînement des chronos d'étapes" (#73).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-20 13:42:46 +02:00
parent f510053d55
commit e61365277b
8 changed files with 704 additions and 4 deletions

View File

@ -1881,6 +1881,7 @@ db.ExercisesCompanion _exerciseCompanion(domain.Exercise exercise) {
defaultTargetReps: Value(exercise.defaultTargetReps),
defaultTargetScore: Value(exercise.defaultTargetScore),
defaultTargetScoreTimeMs: Value(exercise.defaultTargetScoreTimeMs),
autoStartNextTimedStep: Value(exercise.autoStartNextTimedStep),
archivedAt: Value(_utcOrNull(exercise.archivedAt)),
);
}
@ -1907,6 +1908,7 @@ domain.Exercise _exerciseFromRow(
defaultTargetReps: row.defaultTargetReps,
defaultTargetScore: row.defaultTargetScore,
defaultTargetScoreTimeMs: row.defaultTargetScoreTimeMs,
autoStartNextTimedStep: row.autoStartNextTimedStep,
steps: steps,
archivedAt: _utcOrNull(row.archivedAt),
);
@ -2132,6 +2134,12 @@ db.ProgramExercisesCompanion _programExerciseCompanion(
exerciseStepsSnapshotJson: Value(
_encodeExerciseStepsSnapshot(exercise.exerciseStepsSnapshot),
),
autoStartNextTimedStepSnapshot: Value(
exercise.autoStartNextTimedStepSnapshot,
),
autoStartNextTimedStepOverride: Value(
exercise.autoStartNextTimedStepOverride,
),
exerciseVideoMediaIdSnapshot: Value(exercise.exerciseVideoMediaIdSnapshot),
exerciseArchivedSnapshot: Value(exercise.exerciseArchivedSnapshot),
availableTimeSnapshot: Value(exercise.availableTimeSnapshot),
@ -2170,6 +2178,8 @@ domain.ProgramExercise _programExerciseFromRow(db.ProgramExercise row) {
exerciseStepsSnapshot: _decodeExerciseStepsSnapshot(
row.exerciseStepsSnapshotJson,
),
autoStartNextTimedStepSnapshot: row.autoStartNextTimedStepSnapshot,
autoStartNextTimedStepOverride: row.autoStartNextTimedStepOverride,
exerciseVideoMediaIdSnapshot: row.exerciseVideoMediaIdSnapshot,
exerciseArchivedSnapshot: row.exerciseArchivedSnapshot,
availableTimeSnapshot: row.availableTimeSnapshot,
@ -2288,6 +2298,9 @@ _workoutTemplateExerciseOverrideCompanion(
targetRepsOverride: Value(override.targetRepsOverride),
targetScoreOverride: Value(override.targetScoreOverride),
targetScoreTimeMsOverride: Value(override.targetScoreTimeMsOverride),
autoStartNextTimedStepOverride: Value(
override.autoStartNextTimedStepOverride,
),
);
}
@ -2303,6 +2316,7 @@ domain.WorkoutTemplateExerciseOverride _workoutTemplateExerciseOverrideFromRow(
targetRepsOverride: row.targetRepsOverride,
targetScoreOverride: row.targetScoreOverride,
targetScoreTimeMsOverride: row.targetScoreTimeMsOverride,
autoStartNextTimedStepOverride: row.autoStartNextTimedStepOverride,
);
}
@ -2933,6 +2947,7 @@ Map<String, Object?> _exercisePayload(domain.Exercise exercise) => {
'defaultTargetReps': exercise.defaultTargetReps,
'defaultTargetScore': exercise.defaultTargetScore,
'defaultTargetScoreTimeMs': exercise.defaultTargetScoreTimeMs,
'autoStartNextTimedStep': exercise.autoStartNextTimedStep,
'steps': exercise.steps.map((step) => step.toSnapshotJson()).toList(),
'archivedAt': exercise.archivedAt?.toUtc().toIso8601String(),
};
@ -2991,6 +3006,8 @@ Map<String, Object?> _workoutTemplatePayload(domain.WorkoutTemplate template) =>
'targetRepsOverride': override.targetRepsOverride,
'targetScoreOverride': override.targetScoreOverride,
'targetScoreTimeMsOverride': override.targetScoreTimeMsOverride,
'autoStartNextTimedStepOverride':
override.autoStartNextTimedStepOverride,
},
)
.toList(),
@ -3030,6 +3047,8 @@ domain.Exercise _exerciseFromPayload(RemoteSyncedItem item) {
defaultTargetReps: payload['defaultTargetReps'] as int?,
defaultTargetScore: (payload['defaultTargetScore'] as num?)?.toDouble(),
defaultTargetScoreTimeMs: payload['defaultTargetScoreTimeMs'] as int?,
autoStartNextTimedStep:
payload['autoStartNextTimedStep'] as bool? ?? true,
steps: _stepsFromPayload(payload['steps']),
archivedAt: _dateTimeFromPayload(payload['archivedAt']),
);
@ -3133,6 +3152,10 @@ List<domain.ProgramExercise> _programExercisesFromPayload(
exerciseStepsSnapshot: _stepsFromPayload(
map['exerciseStepsSnapshot'],
),
autoStartNextTimedStepSnapshot:
map['autoStartNextTimedStepSnapshot'] as bool? ?? true,
autoStartNextTimedStepOverride:
map['autoStartNextTimedStepOverride'] as bool?,
exerciseArchivedSnapshot: map['exerciseArchivedSnapshot'] == true,
availableTimeSnapshot: map['availableTimeSnapshot'] == true,
availableRepsSnapshot: map['availableRepsSnapshot'] == true,
@ -3217,6 +3240,8 @@ _workoutTemplateOverridesFromPayload(
targetRepsOverride: map['targetRepsOverride'] as int?,
targetScoreOverride: (map['targetScoreOverride'] as num?)?.toDouble(),
targetScoreTimeMsOverride: map['targetScoreTimeMsOverride'] as int?,
autoStartNextTimedStepOverride:
map['autoStartNextTimedStepOverride'] as bool?,
);
})
.toList(growable: false);