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:
@ -1681,6 +1681,76 @@ final class WorkoutTelemetrySample {
|
||||
final double? caloriesKcal;
|
||||
}
|
||||
|
||||
final class ActiveWorkoutTelemetryWindowState {
|
||||
ActiveWorkoutTelemetryWindowState({
|
||||
required String sessionId,
|
||||
required this.windowStartedActiveMs,
|
||||
required this.latestCapturedAt,
|
||||
this.programIndex,
|
||||
this.exerciseIndex,
|
||||
this.setIndex,
|
||||
this.passageIndex,
|
||||
this.stepIndex,
|
||||
this.programSnapshotId,
|
||||
this.exerciseSnapshotId,
|
||||
this.stepSnapshotId,
|
||||
this.heartRateBpm,
|
||||
this.distanceMeters,
|
||||
this.caloriesKcal,
|
||||
}) : sessionId = _nonBlank(sessionId, 'Telemetry window session id') {
|
||||
_requireNonNegative(windowStartedActiveMs, 'Telemetry window active ms');
|
||||
_requireNullableNonNegative(programIndex, 'Program index');
|
||||
_requireNullableNonNegative(exerciseIndex, 'Exercise index');
|
||||
_requireNullableNonNegative(setIndex, 'Set index');
|
||||
_requireNullableNonNegative(passageIndex, 'Passage index');
|
||||
_requireNullableNonNegative(stepIndex, 'Step index');
|
||||
_requireNullablePositive(heartRateBpm, 'Heart rate bpm');
|
||||
_requireNullableNonNegativeDouble(distanceMeters, 'Distance meters');
|
||||
_requireNullableNonNegativeDouble(caloriesKcal, 'Calories kcal');
|
||||
if (heartRateBpm == null &&
|
||||
distanceMeters == null &&
|
||||
caloriesKcal == null) {
|
||||
throw const DomainException(
|
||||
'Telemetry window state must contain at least one metric.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final String sessionId;
|
||||
final int windowStartedActiveMs;
|
||||
final DateTime latestCapturedAt;
|
||||
final int? programIndex;
|
||||
final int? exerciseIndex;
|
||||
final int? setIndex;
|
||||
final int? passageIndex;
|
||||
final int? stepIndex;
|
||||
final String? programSnapshotId;
|
||||
final String? exerciseSnapshotId;
|
||||
final String? stepSnapshotId;
|
||||
final int? heartRateBpm;
|
||||
final double? distanceMeters;
|
||||
final double? caloriesKcal;
|
||||
|
||||
WorkoutTelemetrySample toSample(String id) {
|
||||
return WorkoutTelemetrySample(
|
||||
id: id,
|
||||
sessionId: sessionId,
|
||||
capturedAt: latestCapturedAt,
|
||||
programIndex: programIndex,
|
||||
exerciseIndex: exerciseIndex,
|
||||
setIndex: setIndex,
|
||||
passageIndex: passageIndex,
|
||||
stepIndex: stepIndex,
|
||||
programSnapshotId: programSnapshotId,
|
||||
exerciseSnapshotId: exerciseSnapshotId,
|
||||
stepSnapshotId: stepSnapshotId,
|
||||
heartRateBpm: heartRateBpm,
|
||||
distanceMeters: distanceMeters,
|
||||
caloriesKcal: caloriesKcal,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final class WorkoutTelemetryAggregate {
|
||||
WorkoutTelemetryAggregate({
|
||||
required String sessionId,
|
||||
@ -1793,6 +1863,51 @@ final class WorkoutTelemetryGraphSeries {
|
||||
final int? maxHeartRateBpm;
|
||||
}
|
||||
|
||||
final class ScopeInstanceDescriptor {
|
||||
ScopeInstanceDescriptor({
|
||||
required this.scope,
|
||||
this.programIndex,
|
||||
this.exerciseIndex,
|
||||
this.setIndex,
|
||||
this.passageIndex,
|
||||
this.stepIndex,
|
||||
required this.ordinal,
|
||||
required DateTime firstCapturedAt,
|
||||
}) : firstCapturedAt = firstCapturedAt.toUtc() {
|
||||
_requireNullableNonNegative(programIndex, 'Program index');
|
||||
_requireNullableNonNegative(exerciseIndex, 'Exercise index');
|
||||
_requireNullableNonNegative(setIndex, 'Set index');
|
||||
_requireNullableNonNegative(passageIndex, 'Passage index');
|
||||
_requireNullableNonNegative(stepIndex, 'Step index');
|
||||
_requirePositive(ordinal, 'Scope instance ordinal');
|
||||
}
|
||||
|
||||
final WorkoutTelemetryAggregateScope scope;
|
||||
final int? programIndex;
|
||||
final int? exerciseIndex;
|
||||
final int? setIndex;
|
||||
final int? passageIndex;
|
||||
final int? stepIndex;
|
||||
final int ordinal;
|
||||
final DateTime firstCapturedAt;
|
||||
}
|
||||
|
||||
enum ScopeMarkerBoundary { start, end }
|
||||
|
||||
final class ScopeMarker {
|
||||
ScopeMarker({
|
||||
required this.elapsedMs,
|
||||
required String label,
|
||||
required this.boundary,
|
||||
}) : label = _nonBlank(label, 'Scope marker label') {
|
||||
_requireNonNegative(elapsedMs, 'Scope marker elapsed ms');
|
||||
}
|
||||
|
||||
final int elapsedMs;
|
||||
final String label;
|
||||
final ScopeMarkerBoundary boundary;
|
||||
}
|
||||
|
||||
final class WorkoutHistorySetResult {
|
||||
WorkoutHistorySetResult({
|
||||
required this.metadata,
|
||||
|
||||
Reference in New Issue
Block a user