Files
GameTime/lib/application/ports.dart
Blomios d521bdffb6 feat(domain): fondation domain du score chronométré (ticket #25)
Étend le modèle Drift (tables.dart, app_database.dart/.g.dart), les
entités du domaine, les ports et use cases pour poser les fondations
du score chronométré. build_runner OK, flutter analyze propre, 39/39
tests verts, build APK debug validé.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 01:10:14 +02:00

135 lines
3.8 KiB
Dart

import '../domain/domain.dart';
abstract interface class Clock {
DateTime now();
}
final class SystemClock implements Clock {
const SystemClock();
@override
DateTime now() => DateTime.now().toUtc();
}
abstract interface class IdGenerator {
String newId();
}
abstract interface class ExerciseRepository {
Future<Exercise?> findById(String id);
Future<List<Exercise>> listActive();
Future<bool> isReferencedByProgram(String id);
Future<void> save(Exercise exercise);
}
final class StoredMediaFile {
const StoredMediaFile({
required this.localUri,
required this.mimeType,
required this.sizeBytes,
this.width,
this.height,
this.durationMs,
});
final String localUri;
final String? mimeType;
final int sizeBytes;
final int? width;
final int? height;
final int? durationMs;
}
abstract interface class LocalMediaStorage {
Future<StoredMediaFile> importFile({
required String sourcePath,
required MediaKind kind,
required String stableFileName,
});
Future<Set<String>> listManagedLocalUris();
Future<void> deleteByLocalUri(String localUri);
}
abstract interface class MediaAssetRepository {
Future<MediaAsset?> findById(String id);
Future<List<MediaAsset>> listActive();
Future<void> save(MediaAsset mediaAsset);
}
abstract interface class ProgramRepository {
Future<Program?> findById(String id);
Future<List<Program>> listActive();
Future<void> save(Program program);
Future<void> saveExercise(ProgramExercise exercise);
Future<void> replaceExercises(Program program, DateTime deletedAt);
}
abstract interface class WorkoutTemplateRepository {
Future<WorkoutTemplate?> findById(String id);
Future<List<WorkoutTemplate>> listActive();
Future<void> save(WorkoutTemplate template);
Future<void> saveProgram(WorkoutTemplateProgram program);
Future<void> saveOverride(WorkoutTemplateExerciseOverride override);
Future<void> replaceComposition(WorkoutTemplate template, DateTime deletedAt);
}
abstract interface class ActiveSessionRepository {
Future<ActiveWorkoutSession?> findById(String id);
Future<ActiveWorkoutSession?> findOpen();
Future<void> save(ActiveWorkoutSession session);
Future<void> saveSetResult(ActiveSetResult result);
Future<void> saveRestState(ActiveRestState restState);
Future<void> saveScoreStopwatchState(ActiveScoreStopwatchState state);
Future<void> deleteScoreStopwatchState({
required String sessionId,
required int programIndex,
required int exerciseIndex,
required int setIndex,
required DateTime deletedAt,
});
Future<ActiveRestState?> findRestStateById(String id);
Future<ActiveScoreStopwatchState?> findScoreStopwatchState({
required String sessionId,
required int programIndex,
required int exerciseIndex,
required int setIndex,
});
Future<List<ActiveSetResult>> listSetResults(String sessionId);
Future<List<ActiveRestState>> listRestStates(String sessionId);
Future<List<ActiveScoreStopwatchState>> listScoreStopwatchStates(
String sessionId,
);
}
abstract interface class WorkoutHistoryRepository {
Future<WorkoutHistory?> findById(String id);
Future<List<WorkoutHistory>> listActive();
Future<void> save(WorkoutHistory history);
Future<void> saveSetResult(WorkoutHistorySetResult result);
Future<void> delete(String id, DateTime deletedAt);
}
final class SyncRunSummary {
const SyncRunSummary({
required this.pushedChanges,
required this.pulledChanges,
});
final int pushedChanges;
final int pulledChanges;
}
abstract interface class SyncGateway {
Future<SyncRunSummary> synchronize();
}
final class NoOpSyncGateway implements SyncGateway {
const NoOpSyncGateway();
@override
Future<SyncRunSummary> synchronize() async {
return const SyncRunSummary(pushedChanges: 0, pulledChanges: 0);
}
}