feat(server): implemente synchronisation et serveur avec fixtures (#187)

- Implémente la couche de synchronisation avec le serveur
- Ajoute les fixtures versionnées pour les tests
- Met à jour Drift database et repositories pour le support sync
- Améliore les tests de synchronisation
- Corrige et améliore le watch companion pour la collecte de métriques

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-04 23:07:31 +02:00
parent d1edb2397e
commit fe3608cc4a
31 changed files with 5056 additions and 394 deletions

View File

@ -1,14 +1,15 @@
import '../../domain/domain.dart';
import '../ports.dart';
const int starterSeedVersion = 1;
const int starterSeedVersion = 2;
final class StarterExerciseSeed {
const StarterExerciseSeed({
required this.id,
required this.name,
required this.description,
required this.category,
this.category = ExerciseCategory.uncategorized,
this.businessTypes = const [],
this.hasTimeMeasure = false,
this.hasRepsMeasure = false,
this.hasScoreMeasure = false,
@ -19,6 +20,7 @@ final class StarterExerciseSeed {
this.defaultTargetReps,
this.defaultTargetScore,
this.defaultTargetScoreTimeMs,
this.tags = const [],
this.steps = const [],
});
@ -26,6 +28,7 @@ final class StarterExerciseSeed {
final String name;
final String description;
final ExerciseCategory category;
final List<BusinessExerciseType> businessTypes;
final bool hasTimeMeasure;
final bool hasRepsMeasure;
final bool hasScoreMeasure;
@ -36,6 +39,7 @@ final class StarterExerciseSeed {
final int? defaultTargetReps;
final double? defaultTargetScore;
final int? defaultTargetScoreTimeMs;
final List<String> tags;
final List<StarterExerciseStepSeed> steps;
}
@ -59,12 +63,14 @@ final class StarterProgramSeed {
required this.name,
required this.defaultRestSeconds,
required this.exercises,
this.tags = const [],
});
final String id;
final String name;
final int defaultRestSeconds;
final List<StarterProgramExerciseSeed> exercises;
final List<String> tags;
}
final class StarterProgramExerciseSeed {
@ -96,11 +102,13 @@ final class StarterWorkoutTemplateSeed {
required this.id,
required this.name,
required this.programSnapshotId,
this.tags = const [],
});
final String id;
final String name;
final String programSnapshotId;
final List<String> tags;
}
StarterContent buildStarterContent({
@ -127,7 +135,9 @@ StarterContent buildStarterContent({
defaultTargetScore: seed.defaultTargetScore,
defaultTargetScoreTimeMs: seed.defaultTargetScoreTimeMs,
category: seed.category,
businessTypes: seed.businessTypes,
isExample: true,
tags: seed.tags,
steps: [
for (var index = 0; index < seed.steps.length; index += 1)
ExerciseStep(
@ -170,6 +180,7 @@ StarterContent buildStarterContent({
name: programSeed.name,
defaultRestSeconds: programSeed.defaultRestSeconds,
isExample: true,
tags: programSeed.tags,
exercises: programExercises,
);
final templateProgram = WorkoutTemplateProgram.snapshotFromProgram(
@ -182,6 +193,7 @@ StarterContent buildStarterContent({
metadata: _metadata(templateSeed.id, now, originDeviceId),
name: templateSeed.name,
isExample: true,
tags: templateSeed.tags,
programs: [templateProgram],
);