feat(exécution): dernière performance et meilleur score par exercice (ticket #81)
Ajoute la migration Drift v17 (colonne sourceExerciseIdSnapshot sur workout_history_set_results et workout_history_step_results, index associés), le port ExercisePerformanceReferenceRepository et son implémentation Drift, et le use case ExercisePerformanceReferenceUseCase (dernière performance + meilleur score par métrique active pour un exercice donné). Validé GO par Main : dart analyze propre (1 lint mineur de style), 178 tests (4 échecs préexistants sans rapport avec ce lot). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -13,6 +13,7 @@ abstract interface class AppDependencies {
|
|||||||
ActiveExerciseStepUseCases get activeExerciseStepUseCases;
|
ActiveExerciseStepUseCases get activeExerciseStepUseCases;
|
||||||
CloseWorkoutSessionUseCase get closeWorkoutSessionUseCase;
|
CloseWorkoutSessionUseCase get closeWorkoutSessionUseCase;
|
||||||
WorkoutHistoryUseCases get workoutHistoryUseCases;
|
WorkoutHistoryUseCases get workoutHistoryUseCases;
|
||||||
|
ExercisePerformanceReferenceUseCase get exercisePerformanceReferenceUseCase;
|
||||||
SyncUseCases get syncUseCases;
|
SyncUseCases get syncUseCases;
|
||||||
ShareUseCases get shareUseCases;
|
ShareUseCases get shareUseCases;
|
||||||
}
|
}
|
||||||
@ -29,6 +30,7 @@ final class AppBootstrap implements AppDependencies {
|
|||||||
required this.activeExerciseStepUseCases,
|
required this.activeExerciseStepUseCases,
|
||||||
required this.closeWorkoutSessionUseCase,
|
required this.closeWorkoutSessionUseCase,
|
||||||
required this.workoutHistoryUseCases,
|
required this.workoutHistoryUseCases,
|
||||||
|
required this.exercisePerformanceReferenceUseCase,
|
||||||
required this.syncUseCases,
|
required this.syncUseCases,
|
||||||
required this.shareUseCases,
|
required this.shareUseCases,
|
||||||
required this.syncGateway,
|
required this.syncGateway,
|
||||||
@ -54,6 +56,8 @@ final class AppBootstrap implements AppDependencies {
|
|||||||
@override
|
@override
|
||||||
final WorkoutHistoryUseCases workoutHistoryUseCases;
|
final WorkoutHistoryUseCases workoutHistoryUseCases;
|
||||||
@override
|
@override
|
||||||
|
final ExercisePerformanceReferenceUseCase exercisePerformanceReferenceUseCase;
|
||||||
|
@override
|
||||||
final SyncUseCases syncUseCases;
|
final SyncUseCases syncUseCases;
|
||||||
@override
|
@override
|
||||||
final ShareUseCases shareUseCases;
|
final ShareUseCases shareUseCases;
|
||||||
@ -77,6 +81,8 @@ final class AppBootstrap implements AppDependencies {
|
|||||||
final templateRepository = DriftWorkoutTemplateRepository(database);
|
final templateRepository = DriftWorkoutTemplateRepository(database);
|
||||||
final activeSessionRepository = DriftActiveSessionRepository(database);
|
final activeSessionRepository = DriftActiveSessionRepository(database);
|
||||||
final historyRepository = DriftWorkoutHistoryRepository(database);
|
final historyRepository = DriftWorkoutHistoryRepository(database);
|
||||||
|
final performanceReferenceRepository =
|
||||||
|
DriftExercisePerformanceReferenceRepository(database);
|
||||||
final ids = LocalIdGenerator();
|
final ids = LocalIdGenerator();
|
||||||
const clock = SystemClock();
|
const clock = SystemClock();
|
||||||
const originDeviceId = 'local-device';
|
const originDeviceId = 'local-device';
|
||||||
@ -159,6 +165,9 @@ final class AppBootstrap implements AppDependencies {
|
|||||||
repository: historyRepository,
|
repository: historyRepository,
|
||||||
clock: clock,
|
clock: clock,
|
||||||
),
|
),
|
||||||
|
exercisePerformanceReferenceUseCase: ExercisePerformanceReferenceUseCase(
|
||||||
|
repository: performanceReferenceRepository,
|
||||||
|
),
|
||||||
syncUseCases: SyncUseCases(
|
syncUseCases: SyncUseCases(
|
||||||
tokenStore: const SecureStorageAuthTokenStore(),
|
tokenStore: const SecureStorageAuthTokenStore(),
|
||||||
remoteSyncApi: remoteSyncApi,
|
remoteSyncApi: remoteSyncApi,
|
||||||
|
|||||||
@ -466,6 +466,106 @@ abstract interface class WorkoutHistoryRepository {
|
|||||||
Future<void> delete(String id, DateTime deletedAt);
|
Future<void> delete(String id, DateTime deletedAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class ActivePerformanceMeasures {
|
||||||
|
const ActivePerformanceMeasures({
|
||||||
|
required this.timeEnabled,
|
||||||
|
required this.repsEnabled,
|
||||||
|
required this.scoreEnabled,
|
||||||
|
this.scoreInputMode = ScoreInputMode.manual,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool timeEnabled;
|
||||||
|
final bool repsEnabled;
|
||||||
|
final bool scoreEnabled;
|
||||||
|
final ScoreInputMode scoreInputMode;
|
||||||
|
|
||||||
|
bool get hasAny => timeEnabled || repsEnabled || scoreEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PerformanceMetric { score, reps, time }
|
||||||
|
|
||||||
|
final class WorkoutHistorySetPerformance {
|
||||||
|
const WorkoutHistorySetPerformance({
|
||||||
|
required this.workoutHistoryId,
|
||||||
|
required this.startedAt,
|
||||||
|
required this.setIndex,
|
||||||
|
required this.exerciseNameSnapshot,
|
||||||
|
required this.scoreInputModeSnapshot,
|
||||||
|
this.actualTimeMs,
|
||||||
|
this.actualReps,
|
||||||
|
this.actualScore,
|
||||||
|
this.actualScoreTimeMs,
|
||||||
|
this.completedAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String workoutHistoryId;
|
||||||
|
final DateTime startedAt;
|
||||||
|
final int setIndex;
|
||||||
|
final String exerciseNameSnapshot;
|
||||||
|
final ScoreInputMode scoreInputModeSnapshot;
|
||||||
|
final int? actualTimeMs;
|
||||||
|
final int? actualReps;
|
||||||
|
final double? actualScore;
|
||||||
|
final int? actualScoreTimeMs;
|
||||||
|
final DateTime? completedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class WorkoutHistoryMetricPerformance {
|
||||||
|
const WorkoutHistoryMetricPerformance({
|
||||||
|
required this.workoutHistoryId,
|
||||||
|
required this.startedAt,
|
||||||
|
required this.setIndex,
|
||||||
|
required this.exerciseNameSnapshot,
|
||||||
|
required this.metric,
|
||||||
|
required this.scoreInputModeSnapshot,
|
||||||
|
this.actualTimeMs,
|
||||||
|
this.actualReps,
|
||||||
|
this.actualScore,
|
||||||
|
this.actualScoreTimeMs,
|
||||||
|
this.completedAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String workoutHistoryId;
|
||||||
|
final DateTime startedAt;
|
||||||
|
final int setIndex;
|
||||||
|
final String exerciseNameSnapshot;
|
||||||
|
final PerformanceMetric metric;
|
||||||
|
final ScoreInputMode scoreInputModeSnapshot;
|
||||||
|
final int? actualTimeMs;
|
||||||
|
final int? actualReps;
|
||||||
|
final double? actualScore;
|
||||||
|
final int? actualScoreTimeMs;
|
||||||
|
final DateTime? completedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class ExercisePerformanceReference {
|
||||||
|
const ExercisePerformanceReference({
|
||||||
|
required this.hasAnyHistoryForExercise,
|
||||||
|
this.last,
|
||||||
|
this.record,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool hasAnyHistoryForExercise;
|
||||||
|
final WorkoutHistorySetPerformance? last;
|
||||||
|
final WorkoutHistoryMetricPerformance? record;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract interface class ExercisePerformanceReferenceRepository {
|
||||||
|
Future<bool> hasAnyCompletedHistoryForExercise(String exerciseId);
|
||||||
|
|
||||||
|
Future<WorkoutHistorySetPerformance?> findLatestSetPerformance({
|
||||||
|
required String exerciseId,
|
||||||
|
required ActivePerformanceMeasures activeMeasures,
|
||||||
|
required int currentSetIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
Future<WorkoutHistoryMetricPerformance?> findBestMetricPerformance({
|
||||||
|
required String exerciseId,
|
||||||
|
required PerformanceMetric metric,
|
||||||
|
required ScoreInputMode scoreInputMode,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
final class SyncRunSummary {
|
final class SyncRunSummary {
|
||||||
const SyncRunSummary({
|
const SyncRunSummary({
|
||||||
required this.pushedChanges,
|
required this.pushedChanges,
|
||||||
|
|||||||
@ -3329,6 +3329,9 @@ final class CloseWorkoutSessionUseCase {
|
|||||||
final stepResults = await sessionRepository.listExerciseStepResults(
|
final stepResults = await sessionRepository.listExerciseStepResults(
|
||||||
sessionId,
|
sessionId,
|
||||||
);
|
);
|
||||||
|
final snapshots = _exerciseSnapshotsById(
|
||||||
|
session.resolvedTemplateSnapshotJson,
|
||||||
|
);
|
||||||
final historyId = ids.newId();
|
final historyId = ids.newId();
|
||||||
final historyResults = _historyResultsFromActiveResults(
|
final historyResults = _historyResultsFromActiveResults(
|
||||||
historyId: historyId,
|
historyId: historyId,
|
||||||
@ -3341,6 +3344,7 @@ final class CloseWorkoutSessionUseCase {
|
|||||||
final historyStepResults = _historyStepResultsFromActiveResults(
|
final historyStepResults = _historyStepResultsFromActiveResults(
|
||||||
historyId: historyId,
|
historyId: historyId,
|
||||||
results: stepResults,
|
results: stepResults,
|
||||||
|
resolvedTemplateSnapshotJson: session.resolvedTemplateSnapshotJson,
|
||||||
now: now,
|
now: now,
|
||||||
ids: ids,
|
ids: ids,
|
||||||
originDeviceId: originDeviceId,
|
originDeviceId: originDeviceId,
|
||||||
@ -3377,6 +3381,8 @@ final class CloseWorkoutSessionUseCase {
|
|||||||
'scoreInputModeSnapshot': result.scoreInputModeSnapshot.name,
|
'scoreInputModeSnapshot': result.scoreInputModeSnapshot.name,
|
||||||
'scoreLabelSnapshot': result.scoreLabelSnapshot,
|
'scoreLabelSnapshot': result.scoreLabelSnapshot,
|
||||||
'scoreUnitSnapshot': result.scoreUnitSnapshot,
|
'scoreUnitSnapshot': result.scoreUnitSnapshot,
|
||||||
|
'sourceExerciseIdSnapshot':
|
||||||
|
snapshots[result.exerciseSnapshotId]?.sourceExerciseId,
|
||||||
'status': result.status.name,
|
'status': result.status.name,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -3407,6 +3413,8 @@ final class CloseWorkoutSessionUseCase {
|
|||||||
'actualScore': result.actualScore,
|
'actualScore': result.actualScore,
|
||||||
'actualScoreTimeMs': result.actualScoreTimeMs,
|
'actualScoreTimeMs': result.actualScoreTimeMs,
|
||||||
'note': result.note,
|
'note': result.note,
|
||||||
|
'sourceExerciseIdSnapshot':
|
||||||
|
snapshots[result.exerciseSnapshotId]?.sourceExerciseId,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.toList(),
|
.toList(),
|
||||||
@ -3571,6 +3579,59 @@ void _validateExerciseSteps(List<ExerciseStep> steps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class ExercisePerformanceReferenceUseCase {
|
||||||
|
const ExercisePerformanceReferenceUseCase({required this.repository});
|
||||||
|
|
||||||
|
final ExercisePerformanceReferenceRepository repository;
|
||||||
|
|
||||||
|
Future<ExercisePerformanceReference> getExercisePerformanceReference({
|
||||||
|
required String exerciseId,
|
||||||
|
required ActivePerformanceMeasures activeMeasures,
|
||||||
|
required int currentSetIndex,
|
||||||
|
}) async {
|
||||||
|
final hasAnyHistory = await repository.hasAnyCompletedHistoryForExercise(
|
||||||
|
exerciseId,
|
||||||
|
);
|
||||||
|
if (!activeMeasures.hasAny) {
|
||||||
|
return ExercisePerformanceReference(
|
||||||
|
hasAnyHistoryForExercise: hasAnyHistory,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final last = await repository.findLatestSetPerformance(
|
||||||
|
exerciseId: exerciseId,
|
||||||
|
activeMeasures: activeMeasures,
|
||||||
|
currentSetIndex: currentSetIndex,
|
||||||
|
);
|
||||||
|
final recordMetric = _recordMetricFor(activeMeasures);
|
||||||
|
final record = recordMetric == null
|
||||||
|
? null
|
||||||
|
: await repository.findBestMetricPerformance(
|
||||||
|
exerciseId: exerciseId,
|
||||||
|
metric: recordMetric,
|
||||||
|
scoreInputMode: activeMeasures.scoreInputMode,
|
||||||
|
);
|
||||||
|
return ExercisePerformanceReference(
|
||||||
|
hasAnyHistoryForExercise: hasAnyHistory,
|
||||||
|
last: last,
|
||||||
|
record: record,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PerformanceMetric? _recordMetricFor(ActivePerformanceMeasures measures) {
|
||||||
|
if (measures.scoreEnabled) {
|
||||||
|
return PerformanceMetric.score;
|
||||||
|
}
|
||||||
|
if (measures.repsEnabled) {
|
||||||
|
return PerformanceMetric.reps;
|
||||||
|
}
|
||||||
|
if (measures.timeEnabled) {
|
||||||
|
return PerformanceMetric.time;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
void _validateAuthInput({required String email, required String password}) {
|
void _validateAuthInput({required String email, required String password}) {
|
||||||
final normalizedEmail = email.trim();
|
final normalizedEmail = email.trim();
|
||||||
final hasBasicEmailShape = RegExp(
|
final hasBasicEmailShape = RegExp(
|
||||||
@ -4055,6 +4116,7 @@ List<WorkoutHistorySetResult> _historyResultsFromActiveResults({
|
|||||||
result.scoreLabelSnapshot ?? snapshot?.scoreLabelSnapshot,
|
result.scoreLabelSnapshot ?? snapshot?.scoreLabelSnapshot,
|
||||||
scoreUnitSnapshot:
|
scoreUnitSnapshot:
|
||||||
result.scoreUnitSnapshot ?? snapshot?.scoreUnitSnapshot,
|
result.scoreUnitSnapshot ?? snapshot?.scoreUnitSnapshot,
|
||||||
|
sourceExerciseIdSnapshot: snapshot?.sourceExerciseId,
|
||||||
startedAt: result.startedAt,
|
startedAt: result.startedAt,
|
||||||
completedAt: result.completedAt,
|
completedAt: result.completedAt,
|
||||||
status: result.status,
|
status: result.status,
|
||||||
@ -4089,6 +4151,7 @@ Map<String, _ResolvedExerciseSnapshot> _exerciseSnapshotsById(
|
|||||||
exerciseSnapshotId: id,
|
exerciseSnapshotId: id,
|
||||||
programNameSnapshot: programName,
|
programNameSnapshot: programName,
|
||||||
exerciseNameSnapshot: exercise['exerciseNameSnapshot'] as String? ?? id,
|
exerciseNameSnapshot: exercise['exerciseNameSnapshot'] as String? ?? id,
|
||||||
|
sourceExerciseId: exercise['sourceExerciseId'] as String?,
|
||||||
timeEnabled: exercise['timeEnabled'] == true,
|
timeEnabled: exercise['timeEnabled'] == true,
|
||||||
repsEnabled: exercise['repsEnabled'] == true,
|
repsEnabled: exercise['repsEnabled'] == true,
|
||||||
scoreEnabled: exercise['scoreEnabled'] == true,
|
scoreEnabled: exercise['scoreEnabled'] == true,
|
||||||
@ -4118,6 +4181,7 @@ final class _ResolvedExerciseSnapshot {
|
|||||||
required this.exerciseSnapshotId,
|
required this.exerciseSnapshotId,
|
||||||
required this.programNameSnapshot,
|
required this.programNameSnapshot,
|
||||||
required this.exerciseNameSnapshot,
|
required this.exerciseNameSnapshot,
|
||||||
|
this.sourceExerciseId,
|
||||||
required this.timeEnabled,
|
required this.timeEnabled,
|
||||||
required this.repsEnabled,
|
required this.repsEnabled,
|
||||||
required this.scoreEnabled,
|
required this.scoreEnabled,
|
||||||
@ -4136,6 +4200,7 @@ final class _ResolvedExerciseSnapshot {
|
|||||||
final String exerciseSnapshotId;
|
final String exerciseSnapshotId;
|
||||||
final String programNameSnapshot;
|
final String programNameSnapshot;
|
||||||
final String exerciseNameSnapshot;
|
final String exerciseNameSnapshot;
|
||||||
|
final String? sourceExerciseId;
|
||||||
final bool timeEnabled;
|
final bool timeEnabled;
|
||||||
final bool repsEnabled;
|
final bool repsEnabled;
|
||||||
final bool scoreEnabled;
|
final bool scoreEnabled;
|
||||||
@ -4181,11 +4246,14 @@ List<ExerciseStep> _exerciseStepsFromSnapshot(Object? value) {
|
|||||||
List<WorkoutHistoryStepResult> _historyStepResultsFromActiveResults({
|
List<WorkoutHistoryStepResult> _historyStepResultsFromActiveResults({
|
||||||
required String historyId,
|
required String historyId,
|
||||||
required List<ActiveExerciseStepResult> results,
|
required List<ActiveExerciseStepResult> results,
|
||||||
|
required String resolvedTemplateSnapshotJson,
|
||||||
required DateTime now,
|
required DateTime now,
|
||||||
required IdGenerator ids,
|
required IdGenerator ids,
|
||||||
required String originDeviceId,
|
required String originDeviceId,
|
||||||
}) {
|
}) {
|
||||||
|
final snapshots = _exerciseSnapshotsById(resolvedTemplateSnapshotJson);
|
||||||
return results.map((result) {
|
return results.map((result) {
|
||||||
|
final snapshot = snapshots[result.exerciseSnapshotId];
|
||||||
return WorkoutHistoryStepResult(
|
return WorkoutHistoryStepResult(
|
||||||
metadata: _newMetadata(ids, originDeviceId, now),
|
metadata: _newMetadata(ids, originDeviceId, now),
|
||||||
workoutHistoryId: historyId,
|
workoutHistoryId: historyId,
|
||||||
@ -4214,6 +4282,7 @@ List<WorkoutHistoryStepResult> _historyStepResultsFromActiveResults({
|
|||||||
actualScore: result.actualScore,
|
actualScore: result.actualScore,
|
||||||
actualScoreTimeMs: result.actualScoreTimeMs,
|
actualScoreTimeMs: result.actualScoreTimeMs,
|
||||||
note: result.note,
|
note: result.note,
|
||||||
|
sourceExerciseIdSnapshot: snapshot?.sourceExerciseId,
|
||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1444,6 +1444,7 @@ final class WorkoutHistorySetResult {
|
|||||||
this.scoreInputModeSnapshot = ScoreInputMode.manual,
|
this.scoreInputModeSnapshot = ScoreInputMode.manual,
|
||||||
this.scoreLabelSnapshot,
|
this.scoreLabelSnapshot,
|
||||||
this.scoreUnitSnapshot,
|
this.scoreUnitSnapshot,
|
||||||
|
this.sourceExerciseIdSnapshot,
|
||||||
this.startedAt,
|
this.startedAt,
|
||||||
this.completedAt,
|
this.completedAt,
|
||||||
this.status = SetResultStatus.completed,
|
this.status = SetResultStatus.completed,
|
||||||
@ -1493,6 +1494,7 @@ final class WorkoutHistorySetResult {
|
|||||||
final ScoreInputMode scoreInputModeSnapshot;
|
final ScoreInputMode scoreInputModeSnapshot;
|
||||||
final String? scoreLabelSnapshot;
|
final String? scoreLabelSnapshot;
|
||||||
final String? scoreUnitSnapshot;
|
final String? scoreUnitSnapshot;
|
||||||
|
final String? sourceExerciseIdSnapshot;
|
||||||
final DateTime? startedAt;
|
final DateTime? startedAt;
|
||||||
final DateTime? completedAt;
|
final DateTime? completedAt;
|
||||||
final SetResultStatus status;
|
final SetResultStatus status;
|
||||||
@ -1527,6 +1529,7 @@ final class WorkoutHistoryStepResult {
|
|||||||
this.actualScore,
|
this.actualScore,
|
||||||
this.actualScoreTimeMs,
|
this.actualScoreTimeMs,
|
||||||
this.note,
|
this.note,
|
||||||
|
this.sourceExerciseIdSnapshot,
|
||||||
}) {
|
}) {
|
||||||
_validateExerciseStepResult(
|
_validateExerciseStepResult(
|
||||||
programIndex: programIndex,
|
programIndex: programIndex,
|
||||||
@ -1577,6 +1580,7 @@ final class WorkoutHistoryStepResult {
|
|||||||
final double? actualScore;
|
final double? actualScore;
|
||||||
final int? actualScoreTimeMs;
|
final int? actualScoreTimeMs;
|
||||||
final String? note;
|
final String? note;
|
||||||
|
final String? sourceExerciseIdSnapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _nonBlank(String? value, String label) {
|
String _nonBlank(String? value, String label) {
|
||||||
|
|||||||
@ -48,7 +48,7 @@ final class AppDatabase extends _$AppDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 16;
|
int get schemaVersion => 17;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MigrationStrategy get migration {
|
MigrationStrategy get migration {
|
||||||
@ -113,6 +113,9 @@ final class AppDatabase extends _$AppDatabase {
|
|||||||
if (from < 16) {
|
if (from < 16) {
|
||||||
await _migrateToSchema16(migrator);
|
await _migrateToSchema16(migrator);
|
||||||
}
|
}
|
||||||
|
if (from < 17) {
|
||||||
|
await _migrateToSchema17();
|
||||||
|
}
|
||||||
await _createIndexes();
|
await _createIndexes();
|
||||||
},
|
},
|
||||||
beforeOpen: (details) async {
|
beforeOpen: (details) async {
|
||||||
@ -229,10 +232,24 @@ final class AppDatabase extends _$AppDatabase {
|
|||||||
'CREATE INDEX IF NOT EXISTS idx_workout_history_set_results_history_id '
|
'CREATE INDEX IF NOT EXISTS idx_workout_history_set_results_history_id '
|
||||||
'ON workout_history_set_results (workout_history_id)',
|
'ON workout_history_set_results (workout_history_id)',
|
||||||
);
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS '
|
||||||
|
'idx_workout_history_set_results_source_exercise '
|
||||||
|
'ON workout_history_set_results (source_exercise_id_snapshot, '
|
||||||
|
'set_index) WHERE deleted_at IS NULL AND '
|
||||||
|
'source_exercise_id_snapshot IS NOT NULL',
|
||||||
|
);
|
||||||
await customStatement(
|
await customStatement(
|
||||||
'CREATE INDEX IF NOT EXISTS idx_workout_history_step_results_history_id '
|
'CREATE INDEX IF NOT EXISTS idx_workout_history_step_results_history_id '
|
||||||
'ON workout_history_step_results (workout_history_id)',
|
'ON workout_history_step_results (workout_history_id)',
|
||||||
);
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS '
|
||||||
|
'idx_workout_history_step_results_source_exercise '
|
||||||
|
'ON workout_history_step_results (source_exercise_id_snapshot, '
|
||||||
|
'set_index, step_index) WHERE deleted_at IS NULL AND '
|
||||||
|
'source_exercise_id_snapshot IS NOT NULL',
|
||||||
|
);
|
||||||
await customStatement(
|
await customStatement(
|
||||||
'CREATE INDEX IF NOT EXISTS idx_change_log_entity '
|
'CREATE INDEX IF NOT EXISTS idx_change_log_entity '
|
||||||
'ON change_log (entity_type, entity_id)',
|
'ON change_log (entity_type, entity_id)',
|
||||||
@ -697,6 +714,79 @@ CREATE TABLE IF NOT EXISTS active_set_timer_states (
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _migrateToSchema17() async {
|
||||||
|
await _addColumnIfMissing(
|
||||||
|
tableName: 'workout_history_set_results',
|
||||||
|
columnName: 'source_exercise_id_snapshot',
|
||||||
|
definition: 'source_exercise_id_snapshot TEXT',
|
||||||
|
);
|
||||||
|
await _addColumnIfMissing(
|
||||||
|
tableName: 'workout_history_step_results',
|
||||||
|
columnName: 'source_exercise_id_snapshot',
|
||||||
|
definition: 'source_exercise_id_snapshot TEXT',
|
||||||
|
);
|
||||||
|
await _backfillWorkoutHistorySetSourceExerciseIds();
|
||||||
|
await _backfillWorkoutHistoryStepSourceExerciseIds();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _backfillWorkoutHistorySetSourceExerciseIds() async {
|
||||||
|
await customStatement(r'''
|
||||||
|
UPDATE workout_history_set_results AS result
|
||||||
|
SET source_exercise_id_snapshot = (
|
||||||
|
SELECT json_extract(exercise.value, '$.sourceExerciseId')
|
||||||
|
FROM workout_history AS history,
|
||||||
|
json_each(
|
||||||
|
COALESCE(
|
||||||
|
json_extract(
|
||||||
|
history.history_snapshot_json,
|
||||||
|
'$.resolvedTemplateSnapshotJson'
|
||||||
|
),
|
||||||
|
history.history_snapshot_json
|
||||||
|
),
|
||||||
|
'$.programs'
|
||||||
|
) AS program,
|
||||||
|
json_each(
|
||||||
|
json_extract(program.value, '$.programSnapshotJson'),
|
||||||
|
'$.exercises'
|
||||||
|
) AS exercise
|
||||||
|
WHERE history.id = result.workout_history_id
|
||||||
|
AND json_extract(program.value, '$.id') = result.program_snapshot_id
|
||||||
|
AND json_extract(exercise.value, '$.id') = result.exercise_snapshot_id
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
WHERE result.source_exercise_id_snapshot IS NULL
|
||||||
|
''');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _backfillWorkoutHistoryStepSourceExerciseIds() async {
|
||||||
|
await customStatement(r'''
|
||||||
|
UPDATE workout_history_step_results AS result
|
||||||
|
SET source_exercise_id_snapshot = (
|
||||||
|
SELECT json_extract(exercise.value, '$.sourceExerciseId')
|
||||||
|
FROM workout_history AS history,
|
||||||
|
json_each(
|
||||||
|
COALESCE(
|
||||||
|
json_extract(
|
||||||
|
history.history_snapshot_json,
|
||||||
|
'$.resolvedTemplateSnapshotJson'
|
||||||
|
),
|
||||||
|
history.history_snapshot_json
|
||||||
|
),
|
||||||
|
'$.programs'
|
||||||
|
) AS program,
|
||||||
|
json_each(
|
||||||
|
json_extract(program.value, '$.programSnapshotJson'),
|
||||||
|
'$.exercises'
|
||||||
|
) AS exercise
|
||||||
|
WHERE history.id = result.workout_history_id
|
||||||
|
AND json_extract(program.value, '$.id') = result.program_snapshot_id
|
||||||
|
AND json_extract(exercise.value, '$.id') = result.exercise_snapshot_id
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
WHERE result.source_exercise_id_snapshot IS NULL
|
||||||
|
''');
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _addColumnIfMissing({
|
Future<void> _addColumnIfMissing({
|
||||||
required String tableName,
|
required String tableName,
|
||||||
required String columnName,
|
required String columnName,
|
||||||
|
|||||||
@ -24020,6 +24020,17 @@ class $WorkoutHistorySetResultsTable extends WorkoutHistorySetResults
|
|||||||
type: DriftSqlType.string,
|
type: DriftSqlType.string,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
);
|
);
|
||||||
|
static const VerificationMeta _sourceExerciseIdSnapshotMeta =
|
||||||
|
const VerificationMeta('sourceExerciseIdSnapshot');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> sourceExerciseIdSnapshot =
|
||||||
|
GeneratedColumn<String>(
|
||||||
|
'source_exercise_id_snapshot',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
static const VerificationMeta _startedAtMeta = const VerificationMeta(
|
static const VerificationMeta _startedAtMeta = const VerificationMeta(
|
||||||
'startedAt',
|
'startedAt',
|
||||||
);
|
);
|
||||||
@ -24087,6 +24098,7 @@ class $WorkoutHistorySetResultsTable extends WorkoutHistorySetResults
|
|||||||
actualScoreTimeMs,
|
actualScoreTimeMs,
|
||||||
scoreLabelSnapshot,
|
scoreLabelSnapshot,
|
||||||
scoreUnitSnapshot,
|
scoreUnitSnapshot,
|
||||||
|
sourceExerciseIdSnapshot,
|
||||||
startedAt,
|
startedAt,
|
||||||
completedAt,
|
completedAt,
|
||||||
status,
|
status,
|
||||||
@ -24410,6 +24422,15 @@ class $WorkoutHistorySetResultsTable extends WorkoutHistorySetResults
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('source_exercise_id_snapshot')) {
|
||||||
|
context.handle(
|
||||||
|
_sourceExerciseIdSnapshotMeta,
|
||||||
|
sourceExerciseIdSnapshot.isAcceptableOrUnknown(
|
||||||
|
data['source_exercise_id_snapshot']!,
|
||||||
|
_sourceExerciseIdSnapshotMeta,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
if (data.containsKey('started_at')) {
|
if (data.containsKey('started_at')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_startedAtMeta,
|
_startedAtMeta,
|
||||||
@ -24575,6 +24596,10 @@ class $WorkoutHistorySetResultsTable extends WorkoutHistorySetResults
|
|||||||
DriftSqlType.string,
|
DriftSqlType.string,
|
||||||
data['${effectivePrefix}score_unit_snapshot'],
|
data['${effectivePrefix}score_unit_snapshot'],
|
||||||
),
|
),
|
||||||
|
sourceExerciseIdSnapshot: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}source_exercise_id_snapshot'],
|
||||||
|
),
|
||||||
startedAt: attachedDatabase.typeMapping.read(
|
startedAt: attachedDatabase.typeMapping.read(
|
||||||
DriftSqlType.dateTime,
|
DriftSqlType.dateTime,
|
||||||
data['${effectivePrefix}started_at'],
|
data['${effectivePrefix}started_at'],
|
||||||
@ -24631,6 +24656,7 @@ class WorkoutHistorySetResult extends DataClass
|
|||||||
final int? actualScoreTimeMs;
|
final int? actualScoreTimeMs;
|
||||||
final String? scoreLabelSnapshot;
|
final String? scoreLabelSnapshot;
|
||||||
final String? scoreUnitSnapshot;
|
final String? scoreUnitSnapshot;
|
||||||
|
final String? sourceExerciseIdSnapshot;
|
||||||
final DateTime? startedAt;
|
final DateTime? startedAt;
|
||||||
final DateTime? completedAt;
|
final DateTime? completedAt;
|
||||||
final String status;
|
final String status;
|
||||||
@ -24668,6 +24694,7 @@ class WorkoutHistorySetResult extends DataClass
|
|||||||
this.actualScoreTimeMs,
|
this.actualScoreTimeMs,
|
||||||
this.scoreLabelSnapshot,
|
this.scoreLabelSnapshot,
|
||||||
this.scoreUnitSnapshot,
|
this.scoreUnitSnapshot,
|
||||||
|
this.sourceExerciseIdSnapshot,
|
||||||
this.startedAt,
|
this.startedAt,
|
||||||
this.completedAt,
|
this.completedAt,
|
||||||
required this.status,
|
required this.status,
|
||||||
@ -24740,6 +24767,11 @@ class WorkoutHistorySetResult extends DataClass
|
|||||||
if (!nullToAbsent || scoreUnitSnapshot != null) {
|
if (!nullToAbsent || scoreUnitSnapshot != null) {
|
||||||
map['score_unit_snapshot'] = Variable<String>(scoreUnitSnapshot);
|
map['score_unit_snapshot'] = Variable<String>(scoreUnitSnapshot);
|
||||||
}
|
}
|
||||||
|
if (!nullToAbsent || sourceExerciseIdSnapshot != null) {
|
||||||
|
map['source_exercise_id_snapshot'] = Variable<String>(
|
||||||
|
sourceExerciseIdSnapshot,
|
||||||
|
);
|
||||||
|
}
|
||||||
if (!nullToAbsent || startedAt != null) {
|
if (!nullToAbsent || startedAt != null) {
|
||||||
map['started_at'] = Variable<DateTime>(startedAt);
|
map['started_at'] = Variable<DateTime>(startedAt);
|
||||||
}
|
}
|
||||||
@ -24815,6 +24847,9 @@ class WorkoutHistorySetResult extends DataClass
|
|||||||
scoreUnitSnapshot: scoreUnitSnapshot == null && nullToAbsent
|
scoreUnitSnapshot: scoreUnitSnapshot == null && nullToAbsent
|
||||||
? const Value.absent()
|
? const Value.absent()
|
||||||
: Value(scoreUnitSnapshot),
|
: Value(scoreUnitSnapshot),
|
||||||
|
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot == null && nullToAbsent
|
||||||
|
? const Value.absent()
|
||||||
|
: Value(sourceExerciseIdSnapshot),
|
||||||
startedAt: startedAt == null && nullToAbsent
|
startedAt: startedAt == null && nullToAbsent
|
||||||
? const Value.absent()
|
? const Value.absent()
|
||||||
: Value(startedAt),
|
: Value(startedAt),
|
||||||
@ -24890,6 +24925,9 @@ class WorkoutHistorySetResult extends DataClass
|
|||||||
scoreUnitSnapshot: serializer.fromJson<String?>(
|
scoreUnitSnapshot: serializer.fromJson<String?>(
|
||||||
json['scoreUnitSnapshot'],
|
json['scoreUnitSnapshot'],
|
||||||
),
|
),
|
||||||
|
sourceExerciseIdSnapshot: serializer.fromJson<String?>(
|
||||||
|
json['sourceExerciseIdSnapshot'],
|
||||||
|
),
|
||||||
startedAt: serializer.fromJson<DateTime?>(json['startedAt']),
|
startedAt: serializer.fromJson<DateTime?>(json['startedAt']),
|
||||||
completedAt: serializer.fromJson<DateTime?>(json['completedAt']),
|
completedAt: serializer.fromJson<DateTime?>(json['completedAt']),
|
||||||
status: serializer.fromJson<String>(json['status']),
|
status: serializer.fromJson<String>(json['status']),
|
||||||
@ -24938,6 +24976,9 @@ class WorkoutHistorySetResult extends DataClass
|
|||||||
'actualScoreTimeMs': serializer.toJson<int?>(actualScoreTimeMs),
|
'actualScoreTimeMs': serializer.toJson<int?>(actualScoreTimeMs),
|
||||||
'scoreLabelSnapshot': serializer.toJson<String?>(scoreLabelSnapshot),
|
'scoreLabelSnapshot': serializer.toJson<String?>(scoreLabelSnapshot),
|
||||||
'scoreUnitSnapshot': serializer.toJson<String?>(scoreUnitSnapshot),
|
'scoreUnitSnapshot': serializer.toJson<String?>(scoreUnitSnapshot),
|
||||||
|
'sourceExerciseIdSnapshot': serializer.toJson<String?>(
|
||||||
|
sourceExerciseIdSnapshot,
|
||||||
|
),
|
||||||
'startedAt': serializer.toJson<DateTime?>(startedAt),
|
'startedAt': serializer.toJson<DateTime?>(startedAt),
|
||||||
'completedAt': serializer.toJson<DateTime?>(completedAt),
|
'completedAt': serializer.toJson<DateTime?>(completedAt),
|
||||||
'status': serializer.toJson<String>(status),
|
'status': serializer.toJson<String>(status),
|
||||||
@ -24978,6 +25019,7 @@ class WorkoutHistorySetResult extends DataClass
|
|||||||
Value<int?> actualScoreTimeMs = const Value.absent(),
|
Value<int?> actualScoreTimeMs = const Value.absent(),
|
||||||
Value<String?> scoreLabelSnapshot = const Value.absent(),
|
Value<String?> scoreLabelSnapshot = const Value.absent(),
|
||||||
Value<String?> scoreUnitSnapshot = const Value.absent(),
|
Value<String?> scoreUnitSnapshot = const Value.absent(),
|
||||||
|
Value<String?> sourceExerciseIdSnapshot = const Value.absent(),
|
||||||
Value<DateTime?> startedAt = const Value.absent(),
|
Value<DateTime?> startedAt = const Value.absent(),
|
||||||
Value<DateTime?> completedAt = const Value.absent(),
|
Value<DateTime?> completedAt = const Value.absent(),
|
||||||
String? status,
|
String? status,
|
||||||
@ -25034,6 +25076,9 @@ class WorkoutHistorySetResult extends DataClass
|
|||||||
scoreUnitSnapshot: scoreUnitSnapshot.present
|
scoreUnitSnapshot: scoreUnitSnapshot.present
|
||||||
? scoreUnitSnapshot.value
|
? scoreUnitSnapshot.value
|
||||||
: this.scoreUnitSnapshot,
|
: this.scoreUnitSnapshot,
|
||||||
|
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot.present
|
||||||
|
? sourceExerciseIdSnapshot.value
|
||||||
|
: this.sourceExerciseIdSnapshot,
|
||||||
startedAt: startedAt.present ? startedAt.value : this.startedAt,
|
startedAt: startedAt.present ? startedAt.value : this.startedAt,
|
||||||
completedAt: completedAt.present ? completedAt.value : this.completedAt,
|
completedAt: completedAt.present ? completedAt.value : this.completedAt,
|
||||||
status: status ?? this.status,
|
status: status ?? this.status,
|
||||||
@ -25129,6 +25174,9 @@ class WorkoutHistorySetResult extends DataClass
|
|||||||
scoreUnitSnapshot: data.scoreUnitSnapshot.present
|
scoreUnitSnapshot: data.scoreUnitSnapshot.present
|
||||||
? data.scoreUnitSnapshot.value
|
? data.scoreUnitSnapshot.value
|
||||||
: this.scoreUnitSnapshot,
|
: this.scoreUnitSnapshot,
|
||||||
|
sourceExerciseIdSnapshot: data.sourceExerciseIdSnapshot.present
|
||||||
|
? data.sourceExerciseIdSnapshot.value
|
||||||
|
: this.sourceExerciseIdSnapshot,
|
||||||
startedAt: data.startedAt.present ? data.startedAt.value : this.startedAt,
|
startedAt: data.startedAt.present ? data.startedAt.value : this.startedAt,
|
||||||
completedAt: data.completedAt.present
|
completedAt: data.completedAt.present
|
||||||
? data.completedAt.value
|
? data.completedAt.value
|
||||||
@ -25173,6 +25221,7 @@ class WorkoutHistorySetResult extends DataClass
|
|||||||
..write('actualScoreTimeMs: $actualScoreTimeMs, ')
|
..write('actualScoreTimeMs: $actualScoreTimeMs, ')
|
||||||
..write('scoreLabelSnapshot: $scoreLabelSnapshot, ')
|
..write('scoreLabelSnapshot: $scoreLabelSnapshot, ')
|
||||||
..write('scoreUnitSnapshot: $scoreUnitSnapshot, ')
|
..write('scoreUnitSnapshot: $scoreUnitSnapshot, ')
|
||||||
|
..write('sourceExerciseIdSnapshot: $sourceExerciseIdSnapshot, ')
|
||||||
..write('startedAt: $startedAt, ')
|
..write('startedAt: $startedAt, ')
|
||||||
..write('completedAt: $completedAt, ')
|
..write('completedAt: $completedAt, ')
|
||||||
..write('status: $status')
|
..write('status: $status')
|
||||||
@ -25215,6 +25264,7 @@ class WorkoutHistorySetResult extends DataClass
|
|||||||
actualScoreTimeMs,
|
actualScoreTimeMs,
|
||||||
scoreLabelSnapshot,
|
scoreLabelSnapshot,
|
||||||
scoreUnitSnapshot,
|
scoreUnitSnapshot,
|
||||||
|
sourceExerciseIdSnapshot,
|
||||||
startedAt,
|
startedAt,
|
||||||
completedAt,
|
completedAt,
|
||||||
status,
|
status,
|
||||||
@ -25256,6 +25306,7 @@ class WorkoutHistorySetResult extends DataClass
|
|||||||
other.actualScoreTimeMs == this.actualScoreTimeMs &&
|
other.actualScoreTimeMs == this.actualScoreTimeMs &&
|
||||||
other.scoreLabelSnapshot == this.scoreLabelSnapshot &&
|
other.scoreLabelSnapshot == this.scoreLabelSnapshot &&
|
||||||
other.scoreUnitSnapshot == this.scoreUnitSnapshot &&
|
other.scoreUnitSnapshot == this.scoreUnitSnapshot &&
|
||||||
|
other.sourceExerciseIdSnapshot == this.sourceExerciseIdSnapshot &&
|
||||||
other.startedAt == this.startedAt &&
|
other.startedAt == this.startedAt &&
|
||||||
other.completedAt == this.completedAt &&
|
other.completedAt == this.completedAt &&
|
||||||
other.status == this.status);
|
other.status == this.status);
|
||||||
@ -25296,6 +25347,7 @@ class WorkoutHistorySetResultsCompanion
|
|||||||
final Value<int?> actualScoreTimeMs;
|
final Value<int?> actualScoreTimeMs;
|
||||||
final Value<String?> scoreLabelSnapshot;
|
final Value<String?> scoreLabelSnapshot;
|
||||||
final Value<String?> scoreUnitSnapshot;
|
final Value<String?> scoreUnitSnapshot;
|
||||||
|
final Value<String?> sourceExerciseIdSnapshot;
|
||||||
final Value<DateTime?> startedAt;
|
final Value<DateTime?> startedAt;
|
||||||
final Value<DateTime?> completedAt;
|
final Value<DateTime?> completedAt;
|
||||||
final Value<String> status;
|
final Value<String> status;
|
||||||
@ -25334,6 +25386,7 @@ class WorkoutHistorySetResultsCompanion
|
|||||||
this.actualScoreTimeMs = const Value.absent(),
|
this.actualScoreTimeMs = const Value.absent(),
|
||||||
this.scoreLabelSnapshot = const Value.absent(),
|
this.scoreLabelSnapshot = const Value.absent(),
|
||||||
this.scoreUnitSnapshot = const Value.absent(),
|
this.scoreUnitSnapshot = const Value.absent(),
|
||||||
|
this.sourceExerciseIdSnapshot = const Value.absent(),
|
||||||
this.startedAt = const Value.absent(),
|
this.startedAt = const Value.absent(),
|
||||||
this.completedAt = const Value.absent(),
|
this.completedAt = const Value.absent(),
|
||||||
this.status = const Value.absent(),
|
this.status = const Value.absent(),
|
||||||
@ -25373,6 +25426,7 @@ class WorkoutHistorySetResultsCompanion
|
|||||||
this.actualScoreTimeMs = const Value.absent(),
|
this.actualScoreTimeMs = const Value.absent(),
|
||||||
this.scoreLabelSnapshot = const Value.absent(),
|
this.scoreLabelSnapshot = const Value.absent(),
|
||||||
this.scoreUnitSnapshot = const Value.absent(),
|
this.scoreUnitSnapshot = const Value.absent(),
|
||||||
|
this.sourceExerciseIdSnapshot = const Value.absent(),
|
||||||
this.startedAt = const Value.absent(),
|
this.startedAt = const Value.absent(),
|
||||||
this.completedAt = const Value.absent(),
|
this.completedAt = const Value.absent(),
|
||||||
this.status = const Value.absent(),
|
this.status = const Value.absent(),
|
||||||
@ -25428,6 +25482,7 @@ class WorkoutHistorySetResultsCompanion
|
|||||||
Expression<int>? actualScoreTimeMs,
|
Expression<int>? actualScoreTimeMs,
|
||||||
Expression<String>? scoreLabelSnapshot,
|
Expression<String>? scoreLabelSnapshot,
|
||||||
Expression<String>? scoreUnitSnapshot,
|
Expression<String>? scoreUnitSnapshot,
|
||||||
|
Expression<String>? sourceExerciseIdSnapshot,
|
||||||
Expression<DateTime>? startedAt,
|
Expression<DateTime>? startedAt,
|
||||||
Expression<DateTime>? completedAt,
|
Expression<DateTime>? completedAt,
|
||||||
Expression<String>? status,
|
Expression<String>? status,
|
||||||
@ -25480,6 +25535,8 @@ class WorkoutHistorySetResultsCompanion
|
|||||||
if (scoreLabelSnapshot != null)
|
if (scoreLabelSnapshot != null)
|
||||||
'score_label_snapshot': scoreLabelSnapshot,
|
'score_label_snapshot': scoreLabelSnapshot,
|
||||||
if (scoreUnitSnapshot != null) 'score_unit_snapshot': scoreUnitSnapshot,
|
if (scoreUnitSnapshot != null) 'score_unit_snapshot': scoreUnitSnapshot,
|
||||||
|
if (sourceExerciseIdSnapshot != null)
|
||||||
|
'source_exercise_id_snapshot': sourceExerciseIdSnapshot,
|
||||||
if (startedAt != null) 'started_at': startedAt,
|
if (startedAt != null) 'started_at': startedAt,
|
||||||
if (completedAt != null) 'completed_at': completedAt,
|
if (completedAt != null) 'completed_at': completedAt,
|
||||||
if (status != null) 'status': status,
|
if (status != null) 'status': status,
|
||||||
@ -25521,6 +25578,7 @@ class WorkoutHistorySetResultsCompanion
|
|||||||
Value<int?>? actualScoreTimeMs,
|
Value<int?>? actualScoreTimeMs,
|
||||||
Value<String?>? scoreLabelSnapshot,
|
Value<String?>? scoreLabelSnapshot,
|
||||||
Value<String?>? scoreUnitSnapshot,
|
Value<String?>? scoreUnitSnapshot,
|
||||||
|
Value<String?>? sourceExerciseIdSnapshot,
|
||||||
Value<DateTime?>? startedAt,
|
Value<DateTime?>? startedAt,
|
||||||
Value<DateTime?>? completedAt,
|
Value<DateTime?>? completedAt,
|
||||||
Value<String>? status,
|
Value<String>? status,
|
||||||
@ -25563,6 +25621,8 @@ class WorkoutHistorySetResultsCompanion
|
|||||||
actualScoreTimeMs: actualScoreTimeMs ?? this.actualScoreTimeMs,
|
actualScoreTimeMs: actualScoreTimeMs ?? this.actualScoreTimeMs,
|
||||||
scoreLabelSnapshot: scoreLabelSnapshot ?? this.scoreLabelSnapshot,
|
scoreLabelSnapshot: scoreLabelSnapshot ?? this.scoreLabelSnapshot,
|
||||||
scoreUnitSnapshot: scoreUnitSnapshot ?? this.scoreUnitSnapshot,
|
scoreUnitSnapshot: scoreUnitSnapshot ?? this.scoreUnitSnapshot,
|
||||||
|
sourceExerciseIdSnapshot:
|
||||||
|
sourceExerciseIdSnapshot ?? this.sourceExerciseIdSnapshot,
|
||||||
startedAt: startedAt ?? this.startedAt,
|
startedAt: startedAt ?? this.startedAt,
|
||||||
completedAt: completedAt ?? this.completedAt,
|
completedAt: completedAt ?? this.completedAt,
|
||||||
status: status ?? this.status,
|
status: status ?? this.status,
|
||||||
@ -25688,6 +25748,11 @@ class WorkoutHistorySetResultsCompanion
|
|||||||
if (scoreUnitSnapshot.present) {
|
if (scoreUnitSnapshot.present) {
|
||||||
map['score_unit_snapshot'] = Variable<String>(scoreUnitSnapshot.value);
|
map['score_unit_snapshot'] = Variable<String>(scoreUnitSnapshot.value);
|
||||||
}
|
}
|
||||||
|
if (sourceExerciseIdSnapshot.present) {
|
||||||
|
map['source_exercise_id_snapshot'] = Variable<String>(
|
||||||
|
sourceExerciseIdSnapshot.value,
|
||||||
|
);
|
||||||
|
}
|
||||||
if (startedAt.present) {
|
if (startedAt.present) {
|
||||||
map['started_at'] = Variable<DateTime>(startedAt.value);
|
map['started_at'] = Variable<DateTime>(startedAt.value);
|
||||||
}
|
}
|
||||||
@ -25739,6 +25804,7 @@ class WorkoutHistorySetResultsCompanion
|
|||||||
..write('actualScoreTimeMs: $actualScoreTimeMs, ')
|
..write('actualScoreTimeMs: $actualScoreTimeMs, ')
|
||||||
..write('scoreLabelSnapshot: $scoreLabelSnapshot, ')
|
..write('scoreLabelSnapshot: $scoreLabelSnapshot, ')
|
||||||
..write('scoreUnitSnapshot: $scoreUnitSnapshot, ')
|
..write('scoreUnitSnapshot: $scoreUnitSnapshot, ')
|
||||||
|
..write('sourceExerciseIdSnapshot: $sourceExerciseIdSnapshot, ')
|
||||||
..write('startedAt: $startedAt, ')
|
..write('startedAt: $startedAt, ')
|
||||||
..write('completedAt: $completedAt, ')
|
..write('completedAt: $completedAt, ')
|
||||||
..write('status: $status, ')
|
..write('status: $status, ')
|
||||||
@ -26171,6 +26237,17 @@ class $WorkoutHistoryStepResultsTable extends WorkoutHistoryStepResults
|
|||||||
type: DriftSqlType.string,
|
type: DriftSqlType.string,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
);
|
);
|
||||||
|
static const VerificationMeta _sourceExerciseIdSnapshotMeta =
|
||||||
|
const VerificationMeta('sourceExerciseIdSnapshot');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> sourceExerciseIdSnapshot =
|
||||||
|
GeneratedColumn<String>(
|
||||||
|
'source_exercise_id_snapshot',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
List<GeneratedColumn> get $columns => [
|
List<GeneratedColumn> get $columns => [
|
||||||
id,
|
id,
|
||||||
@ -26210,6 +26287,7 @@ class $WorkoutHistoryStepResultsTable extends WorkoutHistoryStepResults
|
|||||||
actualScore,
|
actualScore,
|
||||||
actualScoreTimeMs,
|
actualScoreTimeMs,
|
||||||
note,
|
note,
|
||||||
|
sourceExerciseIdSnapshot,
|
||||||
];
|
];
|
||||||
@override
|
@override
|
||||||
String get aliasedName => _alias ?? actualTableName;
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
@ -26560,6 +26638,15 @@ class $WorkoutHistoryStepResultsTable extends WorkoutHistoryStepResults
|
|||||||
note.isAcceptableOrUnknown(data['note']!, _noteMeta),
|
note.isAcceptableOrUnknown(data['note']!, _noteMeta),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('source_exercise_id_snapshot')) {
|
||||||
|
context.handle(
|
||||||
|
_sourceExerciseIdSnapshotMeta,
|
||||||
|
sourceExerciseIdSnapshot.isAcceptableOrUnknown(
|
||||||
|
data['source_exercise_id_snapshot']!,
|
||||||
|
_sourceExerciseIdSnapshotMeta,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26720,6 +26807,10 @@ class $WorkoutHistoryStepResultsTable extends WorkoutHistoryStepResults
|
|||||||
DriftSqlType.string,
|
DriftSqlType.string,
|
||||||
data['${effectivePrefix}note'],
|
data['${effectivePrefix}note'],
|
||||||
),
|
),
|
||||||
|
sourceExerciseIdSnapshot: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}source_exercise_id_snapshot'],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26768,6 +26859,7 @@ class WorkoutHistoryStepResult extends DataClass
|
|||||||
final double? actualScore;
|
final double? actualScore;
|
||||||
final int? actualScoreTimeMs;
|
final int? actualScoreTimeMs;
|
||||||
final String? note;
|
final String? note;
|
||||||
|
final String? sourceExerciseIdSnapshot;
|
||||||
const WorkoutHistoryStepResult({
|
const WorkoutHistoryStepResult({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
@ -26806,6 +26898,7 @@ class WorkoutHistoryStepResult extends DataClass
|
|||||||
this.actualScore,
|
this.actualScore,
|
||||||
this.actualScoreTimeMs,
|
this.actualScoreTimeMs,
|
||||||
this.note,
|
this.note,
|
||||||
|
this.sourceExerciseIdSnapshot,
|
||||||
});
|
});
|
||||||
@override
|
@override
|
||||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
@ -26883,6 +26976,11 @@ class WorkoutHistoryStepResult extends DataClass
|
|||||||
if (!nullToAbsent || note != null) {
|
if (!nullToAbsent || note != null) {
|
||||||
map['note'] = Variable<String>(note);
|
map['note'] = Variable<String>(note);
|
||||||
}
|
}
|
||||||
|
if (!nullToAbsent || sourceExerciseIdSnapshot != null) {
|
||||||
|
map['source_exercise_id_snapshot'] = Variable<String>(
|
||||||
|
sourceExerciseIdSnapshot,
|
||||||
|
);
|
||||||
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26956,6 +27054,9 @@ class WorkoutHistoryStepResult extends DataClass
|
|||||||
? const Value.absent()
|
? const Value.absent()
|
||||||
: Value(actualScoreTimeMs),
|
: Value(actualScoreTimeMs),
|
||||||
note: note == null && nullToAbsent ? const Value.absent() : Value(note),
|
note: note == null && nullToAbsent ? const Value.absent() : Value(note),
|
||||||
|
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot == null && nullToAbsent
|
||||||
|
? const Value.absent()
|
||||||
|
: Value(sourceExerciseIdSnapshot),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27018,6 +27119,9 @@ class WorkoutHistoryStepResult extends DataClass
|
|||||||
actualScore: serializer.fromJson<double?>(json['actualScore']),
|
actualScore: serializer.fromJson<double?>(json['actualScore']),
|
||||||
actualScoreTimeMs: serializer.fromJson<int?>(json['actualScoreTimeMs']),
|
actualScoreTimeMs: serializer.fromJson<int?>(json['actualScoreTimeMs']),
|
||||||
note: serializer.fromJson<String?>(json['note']),
|
note: serializer.fromJson<String?>(json['note']),
|
||||||
|
sourceExerciseIdSnapshot: serializer.fromJson<String?>(
|
||||||
|
json['sourceExerciseIdSnapshot'],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@override
|
@override
|
||||||
@ -27065,6 +27169,9 @@ class WorkoutHistoryStepResult extends DataClass
|
|||||||
'actualScore': serializer.toJson<double?>(actualScore),
|
'actualScore': serializer.toJson<double?>(actualScore),
|
||||||
'actualScoreTimeMs': serializer.toJson<int?>(actualScoreTimeMs),
|
'actualScoreTimeMs': serializer.toJson<int?>(actualScoreTimeMs),
|
||||||
'note': serializer.toJson<String?>(note),
|
'note': serializer.toJson<String?>(note),
|
||||||
|
'sourceExerciseIdSnapshot': serializer.toJson<String?>(
|
||||||
|
sourceExerciseIdSnapshot,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27106,6 +27213,7 @@ class WorkoutHistoryStepResult extends DataClass
|
|||||||
Value<double?> actualScore = const Value.absent(),
|
Value<double?> actualScore = const Value.absent(),
|
||||||
Value<int?> actualScoreTimeMs = const Value.absent(),
|
Value<int?> actualScoreTimeMs = const Value.absent(),
|
||||||
Value<String?> note = const Value.absent(),
|
Value<String?> note = const Value.absent(),
|
||||||
|
Value<String?> sourceExerciseIdSnapshot = const Value.absent(),
|
||||||
}) => WorkoutHistoryStepResult(
|
}) => WorkoutHistoryStepResult(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
createdAt: createdAt ?? this.createdAt,
|
createdAt: createdAt ?? this.createdAt,
|
||||||
@ -27160,6 +27268,9 @@ class WorkoutHistoryStepResult extends DataClass
|
|||||||
? actualScoreTimeMs.value
|
? actualScoreTimeMs.value
|
||||||
: this.actualScoreTimeMs,
|
: this.actualScoreTimeMs,
|
||||||
note: note.present ? note.value : this.note,
|
note: note.present ? note.value : this.note,
|
||||||
|
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot.present
|
||||||
|
? sourceExerciseIdSnapshot.value
|
||||||
|
: this.sourceExerciseIdSnapshot,
|
||||||
);
|
);
|
||||||
WorkoutHistoryStepResult copyWithCompanion(
|
WorkoutHistoryStepResult copyWithCompanion(
|
||||||
WorkoutHistoryStepResultsCompanion data,
|
WorkoutHistoryStepResultsCompanion data,
|
||||||
@ -27256,6 +27367,9 @@ class WorkoutHistoryStepResult extends DataClass
|
|||||||
? data.actualScoreTimeMs.value
|
? data.actualScoreTimeMs.value
|
||||||
: this.actualScoreTimeMs,
|
: this.actualScoreTimeMs,
|
||||||
note: data.note.present ? data.note.value : this.note,
|
note: data.note.present ? data.note.value : this.note,
|
||||||
|
sourceExerciseIdSnapshot: data.sourceExerciseIdSnapshot.present
|
||||||
|
? data.sourceExerciseIdSnapshot.value
|
||||||
|
: this.sourceExerciseIdSnapshot,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27298,7 +27412,8 @@ class WorkoutHistoryStepResult extends DataClass
|
|||||||
..write('actualReps: $actualReps, ')
|
..write('actualReps: $actualReps, ')
|
||||||
..write('actualScore: $actualScore, ')
|
..write('actualScore: $actualScore, ')
|
||||||
..write('actualScoreTimeMs: $actualScoreTimeMs, ')
|
..write('actualScoreTimeMs: $actualScoreTimeMs, ')
|
||||||
..write('note: $note')
|
..write('note: $note, ')
|
||||||
|
..write('sourceExerciseIdSnapshot: $sourceExerciseIdSnapshot')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
@ -27342,6 +27457,7 @@ class WorkoutHistoryStepResult extends DataClass
|
|||||||
actualScore,
|
actualScore,
|
||||||
actualScoreTimeMs,
|
actualScoreTimeMs,
|
||||||
note,
|
note,
|
||||||
|
sourceExerciseIdSnapshot,
|
||||||
]);
|
]);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
@ -27383,7 +27499,8 @@ class WorkoutHistoryStepResult extends DataClass
|
|||||||
other.actualReps == this.actualReps &&
|
other.actualReps == this.actualReps &&
|
||||||
other.actualScore == this.actualScore &&
|
other.actualScore == this.actualScore &&
|
||||||
other.actualScoreTimeMs == this.actualScoreTimeMs &&
|
other.actualScoreTimeMs == this.actualScoreTimeMs &&
|
||||||
other.note == this.note);
|
other.note == this.note &&
|
||||||
|
other.sourceExerciseIdSnapshot == this.sourceExerciseIdSnapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
class WorkoutHistoryStepResultsCompanion
|
class WorkoutHistoryStepResultsCompanion
|
||||||
@ -27425,6 +27542,7 @@ class WorkoutHistoryStepResultsCompanion
|
|||||||
final Value<double?> actualScore;
|
final Value<double?> actualScore;
|
||||||
final Value<int?> actualScoreTimeMs;
|
final Value<int?> actualScoreTimeMs;
|
||||||
final Value<String?> note;
|
final Value<String?> note;
|
||||||
|
final Value<String?> sourceExerciseIdSnapshot;
|
||||||
final Value<int> rowid;
|
final Value<int> rowid;
|
||||||
const WorkoutHistoryStepResultsCompanion({
|
const WorkoutHistoryStepResultsCompanion({
|
||||||
this.id = const Value.absent(),
|
this.id = const Value.absent(),
|
||||||
@ -27464,6 +27582,7 @@ class WorkoutHistoryStepResultsCompanion
|
|||||||
this.actualScore = const Value.absent(),
|
this.actualScore = const Value.absent(),
|
||||||
this.actualScoreTimeMs = const Value.absent(),
|
this.actualScoreTimeMs = const Value.absent(),
|
||||||
this.note = const Value.absent(),
|
this.note = const Value.absent(),
|
||||||
|
this.sourceExerciseIdSnapshot = const Value.absent(),
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
});
|
});
|
||||||
WorkoutHistoryStepResultsCompanion.insert({
|
WorkoutHistoryStepResultsCompanion.insert({
|
||||||
@ -27504,6 +27623,7 @@ class WorkoutHistoryStepResultsCompanion
|
|||||||
this.actualScore = const Value.absent(),
|
this.actualScore = const Value.absent(),
|
||||||
this.actualScoreTimeMs = const Value.absent(),
|
this.actualScoreTimeMs = const Value.absent(),
|
||||||
this.note = const Value.absent(),
|
this.note = const Value.absent(),
|
||||||
|
this.sourceExerciseIdSnapshot = const Value.absent(),
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
}) : id = Value(id),
|
}) : id = Value(id),
|
||||||
createdAt = Value(createdAt),
|
createdAt = Value(createdAt),
|
||||||
@ -27563,6 +27683,7 @@ class WorkoutHistoryStepResultsCompanion
|
|||||||
Expression<double>? actualScore,
|
Expression<double>? actualScore,
|
||||||
Expression<int>? actualScoreTimeMs,
|
Expression<int>? actualScoreTimeMs,
|
||||||
Expression<String>? note,
|
Expression<String>? note,
|
||||||
|
Expression<String>? sourceExerciseIdSnapshot,
|
||||||
Expression<int>? rowid,
|
Expression<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
return RawValuesInsertable({
|
return RawValuesInsertable({
|
||||||
@ -27610,6 +27731,8 @@ class WorkoutHistoryStepResultsCompanion
|
|||||||
if (actualScore != null) 'actual_score': actualScore,
|
if (actualScore != null) 'actual_score': actualScore,
|
||||||
if (actualScoreTimeMs != null) 'actual_score_time_ms': actualScoreTimeMs,
|
if (actualScoreTimeMs != null) 'actual_score_time_ms': actualScoreTimeMs,
|
||||||
if (note != null) 'note': note,
|
if (note != null) 'note': note,
|
||||||
|
if (sourceExerciseIdSnapshot != null)
|
||||||
|
'source_exercise_id_snapshot': sourceExerciseIdSnapshot,
|
||||||
if (rowid != null) 'rowid': rowid,
|
if (rowid != null) 'rowid': rowid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -27652,6 +27775,7 @@ class WorkoutHistoryStepResultsCompanion
|
|||||||
Value<double?>? actualScore,
|
Value<double?>? actualScore,
|
||||||
Value<int?>? actualScoreTimeMs,
|
Value<int?>? actualScoreTimeMs,
|
||||||
Value<String?>? note,
|
Value<String?>? note,
|
||||||
|
Value<String?>? sourceExerciseIdSnapshot,
|
||||||
Value<int>? rowid,
|
Value<int>? rowid,
|
||||||
}) {
|
}) {
|
||||||
return WorkoutHistoryStepResultsCompanion(
|
return WorkoutHistoryStepResultsCompanion(
|
||||||
@ -27694,6 +27818,8 @@ class WorkoutHistoryStepResultsCompanion
|
|||||||
actualScore: actualScore ?? this.actualScore,
|
actualScore: actualScore ?? this.actualScore,
|
||||||
actualScoreTimeMs: actualScoreTimeMs ?? this.actualScoreTimeMs,
|
actualScoreTimeMs: actualScoreTimeMs ?? this.actualScoreTimeMs,
|
||||||
note: note ?? this.note,
|
note: note ?? this.note,
|
||||||
|
sourceExerciseIdSnapshot:
|
||||||
|
sourceExerciseIdSnapshot ?? this.sourceExerciseIdSnapshot,
|
||||||
rowid: rowid ?? this.rowid,
|
rowid: rowid ?? this.rowid,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -27820,6 +27946,11 @@ class WorkoutHistoryStepResultsCompanion
|
|||||||
if (note.present) {
|
if (note.present) {
|
||||||
map['note'] = Variable<String>(note.value);
|
map['note'] = Variable<String>(note.value);
|
||||||
}
|
}
|
||||||
|
if (sourceExerciseIdSnapshot.present) {
|
||||||
|
map['source_exercise_id_snapshot'] = Variable<String>(
|
||||||
|
sourceExerciseIdSnapshot.value,
|
||||||
|
);
|
||||||
|
}
|
||||||
if (rowid.present) {
|
if (rowid.present) {
|
||||||
map['rowid'] = Variable<int>(rowid.value);
|
map['rowid'] = Variable<int>(rowid.value);
|
||||||
}
|
}
|
||||||
@ -27866,6 +27997,7 @@ class WorkoutHistoryStepResultsCompanion
|
|||||||
..write('actualScore: $actualScore, ')
|
..write('actualScore: $actualScore, ')
|
||||||
..write('actualScoreTimeMs: $actualScoreTimeMs, ')
|
..write('actualScoreTimeMs: $actualScoreTimeMs, ')
|
||||||
..write('note: $note, ')
|
..write('note: $note, ')
|
||||||
|
..write('sourceExerciseIdSnapshot: $sourceExerciseIdSnapshot, ')
|
||||||
..write('rowid: $rowid')
|
..write('rowid: $rowid')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
@ -45147,6 +45279,7 @@ typedef $$WorkoutHistorySetResultsTableCreateCompanionBuilder =
|
|||||||
Value<int?> actualScoreTimeMs,
|
Value<int?> actualScoreTimeMs,
|
||||||
Value<String?> scoreLabelSnapshot,
|
Value<String?> scoreLabelSnapshot,
|
||||||
Value<String?> scoreUnitSnapshot,
|
Value<String?> scoreUnitSnapshot,
|
||||||
|
Value<String?> sourceExerciseIdSnapshot,
|
||||||
Value<DateTime?> startedAt,
|
Value<DateTime?> startedAt,
|
||||||
Value<DateTime?> completedAt,
|
Value<DateTime?> completedAt,
|
||||||
Value<String> status,
|
Value<String> status,
|
||||||
@ -45187,6 +45320,7 @@ typedef $$WorkoutHistorySetResultsTableUpdateCompanionBuilder =
|
|||||||
Value<int?> actualScoreTimeMs,
|
Value<int?> actualScoreTimeMs,
|
||||||
Value<String?> scoreLabelSnapshot,
|
Value<String?> scoreLabelSnapshot,
|
||||||
Value<String?> scoreUnitSnapshot,
|
Value<String?> scoreUnitSnapshot,
|
||||||
|
Value<String?> sourceExerciseIdSnapshot,
|
||||||
Value<DateTime?> startedAt,
|
Value<DateTime?> startedAt,
|
||||||
Value<DateTime?> completedAt,
|
Value<DateTime?> completedAt,
|
||||||
Value<String> status,
|
Value<String> status,
|
||||||
@ -45395,6 +45529,11 @@ class $$WorkoutHistorySetResultsTableFilterComposer
|
|||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnFilters<String> get sourceExerciseIdSnapshot => $composableBuilder(
|
||||||
|
column: $table.sourceExerciseIdSnapshot,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
ColumnFilters<DateTime> get startedAt => $composableBuilder(
|
ColumnFilters<DateTime> get startedAt => $composableBuilder(
|
||||||
column: $table.startedAt,
|
column: $table.startedAt,
|
||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
@ -45603,6 +45742,11 @@ class $$WorkoutHistorySetResultsTableOrderingComposer
|
|||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<String> get sourceExerciseIdSnapshot => $composableBuilder(
|
||||||
|
column: $table.sourceExerciseIdSnapshot,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
ColumnOrderings<DateTime> get startedAt => $composableBuilder(
|
ColumnOrderings<DateTime> get startedAt => $composableBuilder(
|
||||||
column: $table.startedAt,
|
column: $table.startedAt,
|
||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
@ -45799,6 +45943,11 @@ class $$WorkoutHistorySetResultsTableAnnotationComposer
|
|||||||
builder: (column) => column,
|
builder: (column) => column,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get sourceExerciseIdSnapshot => $composableBuilder(
|
||||||
|
column: $table.sourceExerciseIdSnapshot,
|
||||||
|
builder: (column) => column,
|
||||||
|
);
|
||||||
|
|
||||||
GeneratedColumn<DateTime> get startedAt =>
|
GeneratedColumn<DateTime> get startedAt =>
|
||||||
$composableBuilder(column: $table.startedAt, builder: (column) => column);
|
$composableBuilder(column: $table.startedAt, builder: (column) => column);
|
||||||
|
|
||||||
@ -45906,6 +46055,7 @@ class $$WorkoutHistorySetResultsTableTableManager
|
|||||||
Value<int?> actualScoreTimeMs = const Value.absent(),
|
Value<int?> actualScoreTimeMs = const Value.absent(),
|
||||||
Value<String?> scoreLabelSnapshot = const Value.absent(),
|
Value<String?> scoreLabelSnapshot = const Value.absent(),
|
||||||
Value<String?> scoreUnitSnapshot = const Value.absent(),
|
Value<String?> scoreUnitSnapshot = const Value.absent(),
|
||||||
|
Value<String?> sourceExerciseIdSnapshot = const Value.absent(),
|
||||||
Value<DateTime?> startedAt = const Value.absent(),
|
Value<DateTime?> startedAt = const Value.absent(),
|
||||||
Value<DateTime?> completedAt = const Value.absent(),
|
Value<DateTime?> completedAt = const Value.absent(),
|
||||||
Value<String> status = const Value.absent(),
|
Value<String> status = const Value.absent(),
|
||||||
@ -45944,6 +46094,7 @@ class $$WorkoutHistorySetResultsTableTableManager
|
|||||||
actualScoreTimeMs: actualScoreTimeMs,
|
actualScoreTimeMs: actualScoreTimeMs,
|
||||||
scoreLabelSnapshot: scoreLabelSnapshot,
|
scoreLabelSnapshot: scoreLabelSnapshot,
|
||||||
scoreUnitSnapshot: scoreUnitSnapshot,
|
scoreUnitSnapshot: scoreUnitSnapshot,
|
||||||
|
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot,
|
||||||
startedAt: startedAt,
|
startedAt: startedAt,
|
||||||
completedAt: completedAt,
|
completedAt: completedAt,
|
||||||
status: status,
|
status: status,
|
||||||
@ -45984,6 +46135,7 @@ class $$WorkoutHistorySetResultsTableTableManager
|
|||||||
Value<int?> actualScoreTimeMs = const Value.absent(),
|
Value<int?> actualScoreTimeMs = const Value.absent(),
|
||||||
Value<String?> scoreLabelSnapshot = const Value.absent(),
|
Value<String?> scoreLabelSnapshot = const Value.absent(),
|
||||||
Value<String?> scoreUnitSnapshot = const Value.absent(),
|
Value<String?> scoreUnitSnapshot = const Value.absent(),
|
||||||
|
Value<String?> sourceExerciseIdSnapshot = const Value.absent(),
|
||||||
Value<DateTime?> startedAt = const Value.absent(),
|
Value<DateTime?> startedAt = const Value.absent(),
|
||||||
Value<DateTime?> completedAt = const Value.absent(),
|
Value<DateTime?> completedAt = const Value.absent(),
|
||||||
Value<String> status = const Value.absent(),
|
Value<String> status = const Value.absent(),
|
||||||
@ -46022,6 +46174,7 @@ class $$WorkoutHistorySetResultsTableTableManager
|
|||||||
actualScoreTimeMs: actualScoreTimeMs,
|
actualScoreTimeMs: actualScoreTimeMs,
|
||||||
scoreLabelSnapshot: scoreLabelSnapshot,
|
scoreLabelSnapshot: scoreLabelSnapshot,
|
||||||
scoreUnitSnapshot: scoreUnitSnapshot,
|
scoreUnitSnapshot: scoreUnitSnapshot,
|
||||||
|
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot,
|
||||||
startedAt: startedAt,
|
startedAt: startedAt,
|
||||||
completedAt: completedAt,
|
completedAt: completedAt,
|
||||||
status: status,
|
status: status,
|
||||||
@ -46135,6 +46288,7 @@ typedef $$WorkoutHistoryStepResultsTableCreateCompanionBuilder =
|
|||||||
Value<double?> actualScore,
|
Value<double?> actualScore,
|
||||||
Value<int?> actualScoreTimeMs,
|
Value<int?> actualScoreTimeMs,
|
||||||
Value<String?> note,
|
Value<String?> note,
|
||||||
|
Value<String?> sourceExerciseIdSnapshot,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
typedef $$WorkoutHistoryStepResultsTableUpdateCompanionBuilder =
|
typedef $$WorkoutHistoryStepResultsTableUpdateCompanionBuilder =
|
||||||
@ -46176,6 +46330,7 @@ typedef $$WorkoutHistoryStepResultsTableUpdateCompanionBuilder =
|
|||||||
Value<double?> actualScore,
|
Value<double?> actualScore,
|
||||||
Value<int?> actualScoreTimeMs,
|
Value<int?> actualScoreTimeMs,
|
||||||
Value<String?> note,
|
Value<String?> note,
|
||||||
|
Value<String?> sourceExerciseIdSnapshot,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -46401,6 +46556,11 @@ class $$WorkoutHistoryStepResultsTableFilterComposer
|
|||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnFilters<String> get sourceExerciseIdSnapshot => $composableBuilder(
|
||||||
|
column: $table.sourceExerciseIdSnapshot,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
$$WorkoutHistoriesTableFilterComposer get workoutHistoryId {
|
$$WorkoutHistoriesTableFilterComposer get workoutHistoryId {
|
||||||
final $$WorkoutHistoriesTableFilterComposer composer = $composerBuilder(
|
final $$WorkoutHistoriesTableFilterComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
@ -46614,6 +46774,11 @@ class $$WorkoutHistoryStepResultsTableOrderingComposer
|
|||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<String> get sourceExerciseIdSnapshot => $composableBuilder(
|
||||||
|
column: $table.sourceExerciseIdSnapshot,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
$$WorkoutHistoriesTableOrderingComposer get workoutHistoryId {
|
$$WorkoutHistoriesTableOrderingComposer get workoutHistoryId {
|
||||||
final $$WorkoutHistoriesTableOrderingComposer composer = $composerBuilder(
|
final $$WorkoutHistoriesTableOrderingComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
@ -46807,6 +46972,11 @@ class $$WorkoutHistoryStepResultsTableAnnotationComposer
|
|||||||
GeneratedColumn<String> get note =>
|
GeneratedColumn<String> get note =>
|
||||||
$composableBuilder(column: $table.note, builder: (column) => column);
|
$composableBuilder(column: $table.note, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get sourceExerciseIdSnapshot => $composableBuilder(
|
||||||
|
column: $table.sourceExerciseIdSnapshot,
|
||||||
|
builder: (column) => column,
|
||||||
|
);
|
||||||
|
|
||||||
$$WorkoutHistoriesTableAnnotationComposer get workoutHistoryId {
|
$$WorkoutHistoriesTableAnnotationComposer get workoutHistoryId {
|
||||||
final $$WorkoutHistoriesTableAnnotationComposer composer = $composerBuilder(
|
final $$WorkoutHistoriesTableAnnotationComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
@ -46910,6 +47080,7 @@ class $$WorkoutHistoryStepResultsTableTableManager
|
|||||||
Value<double?> actualScore = const Value.absent(),
|
Value<double?> actualScore = const Value.absent(),
|
||||||
Value<int?> actualScoreTimeMs = const Value.absent(),
|
Value<int?> actualScoreTimeMs = const Value.absent(),
|
||||||
Value<String?> note = const Value.absent(),
|
Value<String?> note = const Value.absent(),
|
||||||
|
Value<String?> sourceExerciseIdSnapshot = const Value.absent(),
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) => WorkoutHistoryStepResultsCompanion(
|
}) => WorkoutHistoryStepResultsCompanion(
|
||||||
id: id,
|
id: id,
|
||||||
@ -46949,6 +47120,7 @@ class $$WorkoutHistoryStepResultsTableTableManager
|
|||||||
actualScore: actualScore,
|
actualScore: actualScore,
|
||||||
actualScoreTimeMs: actualScoreTimeMs,
|
actualScoreTimeMs: actualScoreTimeMs,
|
||||||
note: note,
|
note: note,
|
||||||
|
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot,
|
||||||
rowid: rowid,
|
rowid: rowid,
|
||||||
),
|
),
|
||||||
createCompanionCallback:
|
createCompanionCallback:
|
||||||
@ -46990,6 +47162,7 @@ class $$WorkoutHistoryStepResultsTableTableManager
|
|||||||
Value<double?> actualScore = const Value.absent(),
|
Value<double?> actualScore = const Value.absent(),
|
||||||
Value<int?> actualScoreTimeMs = const Value.absent(),
|
Value<int?> actualScoreTimeMs = const Value.absent(),
|
||||||
Value<String?> note = const Value.absent(),
|
Value<String?> note = const Value.absent(),
|
||||||
|
Value<String?> sourceExerciseIdSnapshot = const Value.absent(),
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) => WorkoutHistoryStepResultsCompanion.insert(
|
}) => WorkoutHistoryStepResultsCompanion.insert(
|
||||||
id: id,
|
id: id,
|
||||||
@ -47029,6 +47202,7 @@ class $$WorkoutHistoryStepResultsTableTableManager
|
|||||||
actualScore: actualScore,
|
actualScore: actualScore,
|
||||||
actualScoreTimeMs: actualScoreTimeMs,
|
actualScoreTimeMs: actualScoreTimeMs,
|
||||||
note: note,
|
note: note,
|
||||||
|
sourceExerciseIdSnapshot: sourceExerciseIdSnapshot,
|
||||||
rowid: rowid,
|
rowid: rowid,
|
||||||
),
|
),
|
||||||
withReferenceMapper: (p0) => p0
|
withReferenceMapper: (p0) => p0
|
||||||
|
|||||||
@ -1602,6 +1602,138 @@ final class DriftWorkoutHistoryRepository implements WorkoutHistoryRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class DriftExercisePerformanceReferenceRepository
|
||||||
|
implements ExercisePerformanceReferenceRepository {
|
||||||
|
const DriftExercisePerformanceReferenceRepository(this.database);
|
||||||
|
|
||||||
|
final db.AppDatabase database;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> hasAnyCompletedHistoryForExercise(String exerciseId) async {
|
||||||
|
final row = await database
|
||||||
|
.customSelect(
|
||||||
|
'SELECT 1 FROM workout_history_set_results AS result '
|
||||||
|
'INNER JOIN workout_history AS history '
|
||||||
|
'ON history.id = result.workout_history_id '
|
||||||
|
'WHERE result.deleted_at IS NULL '
|
||||||
|
'AND history.deleted_at IS NULL '
|
||||||
|
'AND history.completed = 1 '
|
||||||
|
'AND result.status = ? '
|
||||||
|
'AND result.source_exercise_id_snapshot = ? '
|
||||||
|
'LIMIT 1',
|
||||||
|
variables: [
|
||||||
|
const Variable<String>('completed'),
|
||||||
|
Variable<String>(exerciseId),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.getSingleOrNull();
|
||||||
|
return row != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<WorkoutHistorySetPerformance?> findLatestSetPerformance({
|
||||||
|
required String exerciseId,
|
||||||
|
required ActivePerformanceMeasures activeMeasures,
|
||||||
|
required int currentSetIndex,
|
||||||
|
}) async {
|
||||||
|
final valuePredicate = _activeMeasuresPredicate(activeMeasures);
|
||||||
|
if (valuePredicate == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final row = await database
|
||||||
|
.customSelect(
|
||||||
|
'''
|
||||||
|
WITH candidates AS (
|
||||||
|
SELECT
|
||||||
|
result.workout_history_id,
|
||||||
|
history.started_at AS history_started_at,
|
||||||
|
result.set_index,
|
||||||
|
result.exercise_name_snapshot,
|
||||||
|
result.score_input_mode_snapshot,
|
||||||
|
result.actual_time_ms,
|
||||||
|
result.actual_reps,
|
||||||
|
result.actual_score,
|
||||||
|
result.actual_score_time_ms,
|
||||||
|
result.completed_at
|
||||||
|
FROM workout_history_set_results AS result
|
||||||
|
INNER JOIN workout_history AS history
|
||||||
|
ON history.id = result.workout_history_id
|
||||||
|
WHERE result.deleted_at IS NULL
|
||||||
|
AND history.deleted_at IS NULL
|
||||||
|
AND history.completed = 1
|
||||||
|
AND result.status = ?
|
||||||
|
AND result.source_exercise_id_snapshot = ?
|
||||||
|
AND ($valuePredicate)
|
||||||
|
),
|
||||||
|
latest_history AS (
|
||||||
|
SELECT workout_history_id
|
||||||
|
FROM candidates
|
||||||
|
ORDER BY history_started_at DESC
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
SELECT *
|
||||||
|
FROM candidates
|
||||||
|
WHERE workout_history_id = (SELECT workout_history_id FROM latest_history)
|
||||||
|
ORDER BY
|
||||||
|
CASE WHEN set_index = ? THEN 0 ELSE 1 END,
|
||||||
|
set_index DESC
|
||||||
|
LIMIT 1
|
||||||
|
''',
|
||||||
|
variables: [
|
||||||
|
const Variable<String>('completed'),
|
||||||
|
Variable<String>(exerciseId),
|
||||||
|
Variable<int>(currentSetIndex),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.getSingleOrNull();
|
||||||
|
return row == null ? null : _setPerformanceFromRow(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<WorkoutHistoryMetricPerformance?> findBestMetricPerformance({
|
||||||
|
required String exerciseId,
|
||||||
|
required PerformanceMetric metric,
|
||||||
|
required domain.ScoreInputMode scoreInputMode,
|
||||||
|
}) async {
|
||||||
|
final metricSql = _metricSql(metric, scoreInputMode);
|
||||||
|
final row = await database
|
||||||
|
.customSelect(
|
||||||
|
'''
|
||||||
|
SELECT
|
||||||
|
result.workout_history_id,
|
||||||
|
history.started_at AS history_started_at,
|
||||||
|
result.set_index,
|
||||||
|
result.exercise_name_snapshot,
|
||||||
|
result.score_input_mode_snapshot,
|
||||||
|
result.actual_time_ms,
|
||||||
|
result.actual_reps,
|
||||||
|
result.actual_score,
|
||||||
|
result.actual_score_time_ms,
|
||||||
|
result.completed_at
|
||||||
|
FROM workout_history_set_results AS result
|
||||||
|
INNER JOIN workout_history AS history
|
||||||
|
ON history.id = result.workout_history_id
|
||||||
|
WHERE result.deleted_at IS NULL
|
||||||
|
AND history.deleted_at IS NULL
|
||||||
|
AND history.completed = 1
|
||||||
|
AND result.status = ?
|
||||||
|
AND result.source_exercise_id_snapshot = ?
|
||||||
|
AND ${metricSql.predicate}
|
||||||
|
ORDER BY ${metricSql.ordering},
|
||||||
|
history.started_at DESC,
|
||||||
|
result.completed_at DESC
|
||||||
|
LIMIT 1
|
||||||
|
''',
|
||||||
|
variables: [
|
||||||
|
const Variable<String>('completed'),
|
||||||
|
Variable<String>(exerciseId),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.getSingleOrNull();
|
||||||
|
return row == null ? null : _metricPerformanceFromRow(row, metric: metric);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _upsertWithChangeLog({
|
Future<void> _upsertWithChangeLog({
|
||||||
required db.AppDatabase database,
|
required db.AppDatabase database,
|
||||||
required String tableName,
|
required String tableName,
|
||||||
@ -2863,6 +2995,94 @@ domain.ActiveRestState _activeRestStateFromCustomRow(QueryRow row) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WorkoutHistorySetPerformance _setPerformanceFromRow(QueryRow row) {
|
||||||
|
final data = row.data;
|
||||||
|
return WorkoutHistorySetPerformance(
|
||||||
|
workoutHistoryId: data['workout_history_id'] as String,
|
||||||
|
startedAt: _dateTimeFromData(data, 'history_started_at'),
|
||||||
|
setIndex: data['set_index'] as int,
|
||||||
|
exerciseNameSnapshot: data['exercise_name_snapshot'] as String,
|
||||||
|
scoreInputModeSnapshot: _scoreInputModeFromDb(
|
||||||
|
data['score_input_mode_snapshot'] as String,
|
||||||
|
),
|
||||||
|
actualTimeMs: data['actual_time_ms'] as int?,
|
||||||
|
actualReps: data['actual_reps'] as int?,
|
||||||
|
actualScore: (data['actual_score'] as num?)?.toDouble(),
|
||||||
|
actualScoreTimeMs: data['actual_score_time_ms'] as int?,
|
||||||
|
completedAt: _dateTimeOrNullFromData(data, 'completed_at'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkoutHistoryMetricPerformance _metricPerformanceFromRow(
|
||||||
|
QueryRow row, {
|
||||||
|
required PerformanceMetric metric,
|
||||||
|
}) {
|
||||||
|
final set = _setPerformanceFromRow(row);
|
||||||
|
return WorkoutHistoryMetricPerformance(
|
||||||
|
workoutHistoryId: set.workoutHistoryId,
|
||||||
|
startedAt: set.startedAt,
|
||||||
|
setIndex: set.setIndex,
|
||||||
|
exerciseNameSnapshot: set.exerciseNameSnapshot,
|
||||||
|
metric: metric,
|
||||||
|
scoreInputModeSnapshot: set.scoreInputModeSnapshot,
|
||||||
|
actualTimeMs: set.actualTimeMs,
|
||||||
|
actualReps: set.actualReps,
|
||||||
|
actualScore: set.actualScore,
|
||||||
|
actualScoreTimeMs: set.actualScoreTimeMs,
|
||||||
|
completedAt: set.completedAt,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String? _activeMeasuresPredicate(ActivePerformanceMeasures measures) {
|
||||||
|
final predicates = <String>[];
|
||||||
|
if (measures.scoreEnabled) {
|
||||||
|
predicates.add(
|
||||||
|
measures.scoreInputMode == domain.ScoreInputMode.stopwatch
|
||||||
|
? "(result.score_input_mode_snapshot = 'stopwatch' "
|
||||||
|
'AND result.actual_score_time_ms IS NOT NULL)'
|
||||||
|
: "(result.score_input_mode_snapshot = 'manual' "
|
||||||
|
'AND result.actual_score IS NOT NULL)',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (measures.repsEnabled) {
|
||||||
|
predicates.add('result.actual_reps IS NOT NULL');
|
||||||
|
}
|
||||||
|
if (measures.timeEnabled) {
|
||||||
|
predicates.add('result.actual_time_ms IS NOT NULL');
|
||||||
|
}
|
||||||
|
return predicates.isEmpty ? null : predicates.join(' OR ');
|
||||||
|
}
|
||||||
|
|
||||||
|
({String predicate, String ordering}) _metricSql(
|
||||||
|
PerformanceMetric metric,
|
||||||
|
domain.ScoreInputMode scoreInputMode,
|
||||||
|
) {
|
||||||
|
return switch (metric) {
|
||||||
|
PerformanceMetric.score =>
|
||||||
|
scoreInputMode == domain.ScoreInputMode.stopwatch
|
||||||
|
? (
|
||||||
|
predicate:
|
||||||
|
"result.score_input_mode_snapshot = 'stopwatch' "
|
||||||
|
'AND result.actual_score_time_ms IS NOT NULL',
|
||||||
|
ordering: 'result.actual_score_time_ms ASC',
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
predicate:
|
||||||
|
"result.score_input_mode_snapshot = 'manual' "
|
||||||
|
'AND result.actual_score IS NOT NULL',
|
||||||
|
ordering: 'result.actual_score DESC',
|
||||||
|
),
|
||||||
|
PerformanceMetric.reps => (
|
||||||
|
predicate: 'result.actual_reps IS NOT NULL',
|
||||||
|
ordering: 'result.actual_reps DESC',
|
||||||
|
),
|
||||||
|
PerformanceMetric.time => (
|
||||||
|
predicate: 'result.actual_time_ms IS NOT NULL',
|
||||||
|
ordering: 'result.actual_time_ms DESC',
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
db.ActiveScoreStopwatchStatesCompanion _activeScoreStopwatchStateCompanion(
|
db.ActiveScoreStopwatchStatesCompanion _activeScoreStopwatchStateCompanion(
|
||||||
domain.ActiveScoreStopwatchState state,
|
domain.ActiveScoreStopwatchState state,
|
||||||
) {
|
) {
|
||||||
@ -3108,6 +3328,7 @@ db.WorkoutHistorySetResultsCompanion _workoutHistorySetResultCompanion(
|
|||||||
actualScoreTimeMs: Value(result.actualScoreTimeMs),
|
actualScoreTimeMs: Value(result.actualScoreTimeMs),
|
||||||
scoreLabelSnapshot: Value(result.scoreLabelSnapshot),
|
scoreLabelSnapshot: Value(result.scoreLabelSnapshot),
|
||||||
scoreUnitSnapshot: Value(result.scoreUnitSnapshot),
|
scoreUnitSnapshot: Value(result.scoreUnitSnapshot),
|
||||||
|
sourceExerciseIdSnapshot: Value(result.sourceExerciseIdSnapshot),
|
||||||
startedAt: Value(_utcOrNull(result.startedAt)),
|
startedAt: Value(_utcOrNull(result.startedAt)),
|
||||||
completedAt: Value(_utcOrNull(result.completedAt)),
|
completedAt: Value(_utcOrNull(result.completedAt)),
|
||||||
status: Value(_setResultStatusToDb(result.status)),
|
status: Value(_setResultStatusToDb(result.status)),
|
||||||
@ -3160,6 +3381,7 @@ db.WorkoutHistoryStepResultsCompanion _workoutHistoryStepResultCompanion(
|
|||||||
actualScore: Value<double?>(result.actualScore),
|
actualScore: Value<double?>(result.actualScore),
|
||||||
actualScoreTimeMs: Value<int?>(result.actualScoreTimeMs),
|
actualScoreTimeMs: Value<int?>(result.actualScoreTimeMs),
|
||||||
note: Value<String?>(result.note),
|
note: Value<String?>(result.note),
|
||||||
|
sourceExerciseIdSnapshot: Value<String?>(result.sourceExerciseIdSnapshot),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3210,6 +3432,7 @@ domain.WorkoutHistorySetResult _workoutHistorySetResultFromRow(
|
|||||||
actualScoreTimeMs: row.actualScoreTimeMs,
|
actualScoreTimeMs: row.actualScoreTimeMs,
|
||||||
scoreLabelSnapshot: row.scoreLabelSnapshot,
|
scoreLabelSnapshot: row.scoreLabelSnapshot,
|
||||||
scoreUnitSnapshot: row.scoreUnitSnapshot,
|
scoreUnitSnapshot: row.scoreUnitSnapshot,
|
||||||
|
sourceExerciseIdSnapshot: row.sourceExerciseIdSnapshot,
|
||||||
startedAt: _utcOrNull(row.startedAt),
|
startedAt: _utcOrNull(row.startedAt),
|
||||||
completedAt: _utcOrNull(row.completedAt),
|
completedAt: _utcOrNull(row.completedAt),
|
||||||
status: _setResultStatusFromDb(row.status),
|
status: _setResultStatusFromDb(row.status),
|
||||||
@ -3249,6 +3472,7 @@ domain.WorkoutHistoryStepResult _workoutHistoryStepResultFromRow(
|
|||||||
actualScore: row.actualScore,
|
actualScore: row.actualScore,
|
||||||
actualScoreTimeMs: row.actualScoreTimeMs,
|
actualScoreTimeMs: row.actualScoreTimeMs,
|
||||||
note: row.note,
|
note: row.note,
|
||||||
|
sourceExerciseIdSnapshot: row.sourceExerciseIdSnapshot,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -745,6 +745,7 @@ class WorkoutHistorySetResults extends SyncableTable {
|
|||||||
IntColumn get actualScoreTimeMs => integer().nullable()();
|
IntColumn get actualScoreTimeMs => integer().nullable()();
|
||||||
TextColumn get scoreLabelSnapshot => text().nullable()();
|
TextColumn get scoreLabelSnapshot => text().nullable()();
|
||||||
TextColumn get scoreUnitSnapshot => text().nullable()();
|
TextColumn get scoreUnitSnapshot => text().nullable()();
|
||||||
|
TextColumn get sourceExerciseIdSnapshot => text().nullable()();
|
||||||
DateTimeColumn get startedAt => dateTime().nullable()();
|
DateTimeColumn get startedAt => dateTime().nullable()();
|
||||||
DateTimeColumn get completedAt => dateTime().nullable()();
|
DateTimeColumn get completedAt => dateTime().nullable()();
|
||||||
TextColumn get status => text().withDefault(const Constant('completed'))();
|
TextColumn get status => text().withDefault(const Constant('completed'))();
|
||||||
@ -821,6 +822,7 @@ class WorkoutHistoryStepResults extends SyncableTable {
|
|||||||
RealColumn get actualScore => real().nullable()();
|
RealColumn get actualScore => real().nullable()();
|
||||||
IntColumn get actualScoreTimeMs => integer().nullable()();
|
IntColumn get actualScoreTimeMs => integer().nullable()();
|
||||||
TextColumn get note => text().nullable()();
|
TextColumn get note => text().nullable()();
|
||||||
|
TextColumn get sourceExerciseIdSnapshot => text().nullable()();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<String> get customConstraints => [
|
List<String> get customConstraints => [
|
||||||
|
|||||||
@ -14,6 +14,8 @@ void main() {
|
|||||||
late local.DriftActiveSessionRepository activeRepository;
|
late local.DriftActiveSessionRepository activeRepository;
|
||||||
late local.DriftWorkoutTemplateRepository templateRepository;
|
late local.DriftWorkoutTemplateRepository templateRepository;
|
||||||
late local.DriftWorkoutHistoryRepository historyRepository;
|
late local.DriftWorkoutHistoryRepository historyRepository;
|
||||||
|
late local.DriftExercisePerformanceReferenceRepository
|
||||||
|
performanceReferenceRepository;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
database = local.AppDatabase(NativeDatabase.memory());
|
database = local.AppDatabase(NativeDatabase.memory());
|
||||||
@ -22,6 +24,8 @@ void main() {
|
|||||||
activeRepository = local.DriftActiveSessionRepository(database);
|
activeRepository = local.DriftActiveSessionRepository(database);
|
||||||
templateRepository = local.DriftWorkoutTemplateRepository(database);
|
templateRepository = local.DriftWorkoutTemplateRepository(database);
|
||||||
historyRepository = local.DriftWorkoutHistoryRepository(database);
|
historyRepository = local.DriftWorkoutHistoryRepository(database);
|
||||||
|
performanceReferenceRepository =
|
||||||
|
local.DriftExercisePerformanceReferenceRepository(database);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() async {
|
||||||
@ -843,6 +847,265 @@ void main() {
|
|||||||
expect(restored.results.single.actualReps, 10);
|
expect(restored.results.single.actualReps, 10);
|
||||||
expect(restored.results.single.actualScore, 80);
|
expect(restored.results.single.actualScore, 80);
|
||||||
expect(restored.results.single.scoreUnitSnapshot, 'kg');
|
expect(restored.results.single.scoreUnitSnapshot, 'kg');
|
||||||
|
expect(restored.results.single.sourceExerciseIdSnapshot, 'exercise-1');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'performance reference ignores skipped and null values for latest set',
|
||||||
|
() async {
|
||||||
|
final now = DateTime.utc(2026, 7, 22, 10);
|
||||||
|
await historyRepository.save(
|
||||||
|
_history(
|
||||||
|
id: 'history-old',
|
||||||
|
startedAt: now.subtract(const Duration(days: 2)),
|
||||||
|
result: _historySetResult(
|
||||||
|
id: 'result-old',
|
||||||
|
historyId: 'history-old',
|
||||||
|
sourceExerciseId: 'exercise-1',
|
||||||
|
setIndex: 0,
|
||||||
|
startedAt: now.subtract(const Duration(days: 2)),
|
||||||
|
actualReps: 8,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await historyRepository.save(
|
||||||
|
_history(
|
||||||
|
id: 'history-new',
|
||||||
|
startedAt: now,
|
||||||
|
results: [
|
||||||
|
_historySetResult(
|
||||||
|
id: 'result-skipped',
|
||||||
|
historyId: 'history-new',
|
||||||
|
sourceExerciseId: 'exercise-1',
|
||||||
|
setIndex: 0,
|
||||||
|
startedAt: now,
|
||||||
|
status: SetResultStatus.skipped,
|
||||||
|
),
|
||||||
|
_historySetResult(
|
||||||
|
id: 'result-null',
|
||||||
|
historyId: 'history-new',
|
||||||
|
sourceExerciseId: 'exercise-1',
|
||||||
|
setIndex: 1,
|
||||||
|
startedAt: now,
|
||||||
|
),
|
||||||
|
_historySetResult(
|
||||||
|
id: 'result-value',
|
||||||
|
historyId: 'history-new',
|
||||||
|
sourceExerciseId: 'exercise-1',
|
||||||
|
setIndex: 2,
|
||||||
|
startedAt: now,
|
||||||
|
actualReps: 11,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final latest = await performanceReferenceRepository
|
||||||
|
.findLatestSetPerformance(
|
||||||
|
exerciseId: 'exercise-1',
|
||||||
|
activeMeasures: const ActivePerformanceMeasures(
|
||||||
|
timeEnabled: false,
|
||||||
|
repsEnabled: true,
|
||||||
|
scoreEnabled: false,
|
||||||
|
),
|
||||||
|
currentSetIndex: 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(latest, isNotNull);
|
||||||
|
expect(latest!.workoutHistoryId, 'history-new');
|
||||||
|
expect(latest.setIndex, 2);
|
||||||
|
expect(latest.actualReps, 11);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test('performance reference uses same set when available', () async {
|
||||||
|
final now = DateTime.utc(2026, 7, 22, 11);
|
||||||
|
await historyRepository.save(
|
||||||
|
_history(
|
||||||
|
id: 'history-sets',
|
||||||
|
startedAt: now,
|
||||||
|
results: [
|
||||||
|
_historySetResult(
|
||||||
|
id: 'result-set-0',
|
||||||
|
historyId: 'history-sets',
|
||||||
|
sourceExerciseId: 'exercise-1',
|
||||||
|
setIndex: 0,
|
||||||
|
startedAt: now,
|
||||||
|
actualReps: 7,
|
||||||
|
),
|
||||||
|
_historySetResult(
|
||||||
|
id: 'result-set-1',
|
||||||
|
historyId: 'history-sets',
|
||||||
|
sourceExerciseId: 'exercise-1',
|
||||||
|
setIndex: 1,
|
||||||
|
startedAt: now,
|
||||||
|
actualReps: 9,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final latest = await performanceReferenceRepository
|
||||||
|
.findLatestSetPerformance(
|
||||||
|
exerciseId: 'exercise-1',
|
||||||
|
activeMeasures: const ActivePerformanceMeasures(
|
||||||
|
timeEnabled: false,
|
||||||
|
repsEnabled: true,
|
||||||
|
scoreEnabled: false,
|
||||||
|
),
|
||||||
|
currentSetIndex: 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(latest, isNotNull);
|
||||||
|
expect(latest!.setIndex, 0);
|
||||||
|
expect(latest.actualReps, 7);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('performance reference finds records by metric rules', () async {
|
||||||
|
final now = DateTime.utc(2026, 7, 22, 12);
|
||||||
|
await historyRepository.save(
|
||||||
|
_history(
|
||||||
|
id: 'history-records',
|
||||||
|
startedAt: now,
|
||||||
|
results: [
|
||||||
|
_historySetResult(
|
||||||
|
id: 'result-reps-low',
|
||||||
|
historyId: 'history-records',
|
||||||
|
sourceExerciseId: 'exercise-1',
|
||||||
|
setIndex: 0,
|
||||||
|
startedAt: now,
|
||||||
|
actualTimeMs: 30000,
|
||||||
|
actualReps: 6,
|
||||||
|
actualScore: 15,
|
||||||
|
),
|
||||||
|
_historySetResult(
|
||||||
|
id: 'result-reps-high',
|
||||||
|
historyId: 'history-records',
|
||||||
|
sourceExerciseId: 'exercise-1',
|
||||||
|
setIndex: 1,
|
||||||
|
startedAt: now,
|
||||||
|
actualTimeMs: 45000,
|
||||||
|
actualReps: 12,
|
||||||
|
actualScore: 20,
|
||||||
|
),
|
||||||
|
_historySetResult(
|
||||||
|
id: 'result-stopwatch-slow',
|
||||||
|
historyId: 'history-records',
|
||||||
|
sourceExerciseId: 'exercise-1',
|
||||||
|
setIndex: 2,
|
||||||
|
startedAt: now,
|
||||||
|
scoreInputMode: ScoreInputMode.stopwatch,
|
||||||
|
actualScoreTimeMs: 11000,
|
||||||
|
),
|
||||||
|
_historySetResult(
|
||||||
|
id: 'result-stopwatch-fast',
|
||||||
|
historyId: 'history-records',
|
||||||
|
sourceExerciseId: 'exercise-1',
|
||||||
|
setIndex: 3,
|
||||||
|
startedAt: now,
|
||||||
|
scoreInputMode: ScoreInputMode.stopwatch,
|
||||||
|
actualScoreTimeMs: 9000,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final reps = await performanceReferenceRepository.findBestMetricPerformance(
|
||||||
|
exerciseId: 'exercise-1',
|
||||||
|
metric: PerformanceMetric.reps,
|
||||||
|
scoreInputMode: ScoreInputMode.manual,
|
||||||
|
);
|
||||||
|
final time = await performanceReferenceRepository.findBestMetricPerformance(
|
||||||
|
exerciseId: 'exercise-1',
|
||||||
|
metric: PerformanceMetric.time,
|
||||||
|
scoreInputMode: ScoreInputMode.manual,
|
||||||
|
);
|
||||||
|
final manualScore = await performanceReferenceRepository
|
||||||
|
.findBestMetricPerformance(
|
||||||
|
exerciseId: 'exercise-1',
|
||||||
|
metric: PerformanceMetric.score,
|
||||||
|
scoreInputMode: ScoreInputMode.manual,
|
||||||
|
);
|
||||||
|
final stopwatchScore = await performanceReferenceRepository
|
||||||
|
.findBestMetricPerformance(
|
||||||
|
exerciseId: 'exercise-1',
|
||||||
|
metric: PerformanceMetric.score,
|
||||||
|
scoreInputMode: ScoreInputMode.stopwatch,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(reps!.actualReps, 12);
|
||||||
|
expect(time!.actualTimeMs, 45000);
|
||||||
|
expect(manualScore!.actualScore, 20);
|
||||||
|
expect(stopwatchScore!.actualScoreTimeMs, 9000);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('performance reference matches archived source exercise id', () async {
|
||||||
|
final now = DateTime.utc(2026, 7, 22, 13);
|
||||||
|
await exerciseRepository.save(
|
||||||
|
Exercise(
|
||||||
|
metadata: _metadata('exercise-archived', now),
|
||||||
|
name: 'Archived drill',
|
||||||
|
hasTimeMeasure: false,
|
||||||
|
hasRepsMeasure: true,
|
||||||
|
hasScoreMeasure: false,
|
||||||
|
archivedAt: now,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await historyRepository.save(
|
||||||
|
_history(
|
||||||
|
id: 'history-archived',
|
||||||
|
startedAt: now,
|
||||||
|
result: _historySetResult(
|
||||||
|
id: 'result-archived',
|
||||||
|
historyId: 'history-archived',
|
||||||
|
sourceExerciseId: 'exercise-archived',
|
||||||
|
setIndex: 0,
|
||||||
|
startedAt: now,
|
||||||
|
actualReps: 13,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await performanceReferenceRepository.hasAnyCompletedHistoryForExercise(
|
||||||
|
'exercise-archived',
|
||||||
|
),
|
||||||
|
isTrue,
|
||||||
|
);
|
||||||
|
final latest = await performanceReferenceRepository
|
||||||
|
.findLatestSetPerformance(
|
||||||
|
exerciseId: 'exercise-archived',
|
||||||
|
activeMeasures: const ActivePerformanceMeasures(
|
||||||
|
timeEnabled: false,
|
||||||
|
repsEnabled: true,
|
||||||
|
scoreEnabled: false,
|
||||||
|
),
|
||||||
|
currentSetIndex: 0,
|
||||||
|
);
|
||||||
|
expect(latest!.actualReps, 13);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'performance reference use case prioritizes record score metric',
|
||||||
|
() async {
|
||||||
|
final repository = _FakePerformanceReferenceRepository();
|
||||||
|
final useCase = ExercisePerformanceReferenceUseCase(
|
||||||
|
repository: repository,
|
||||||
|
);
|
||||||
|
|
||||||
|
final reference = await useCase.getExercisePerformanceReference(
|
||||||
|
exerciseId: 'exercise-1',
|
||||||
|
activeMeasures: const ActivePerformanceMeasures(
|
||||||
|
timeEnabled: true,
|
||||||
|
repsEnabled: true,
|
||||||
|
scoreEnabled: true,
|
||||||
|
),
|
||||||
|
currentSetIndex: 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(reference.hasAnyHistoryForExercise, isTrue);
|
||||||
|
expect(repository.requestedMetric, PerformanceMetric.score);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -858,6 +1121,7 @@ String _resolvedSnapshot() {
|
|||||||
'exercises': [
|
'exercises': [
|
||||||
{
|
{
|
||||||
'id': 'exercise-snapshot-1',
|
'id': 'exercise-snapshot-1',
|
||||||
|
'sourceExerciseId': 'exercise-1',
|
||||||
'exerciseNameSnapshot': 'Squat',
|
'exerciseNameSnapshot': 'Squat',
|
||||||
'setsCount': 1,
|
'setsCount': 1,
|
||||||
'timeEnabled': true,
|
'timeEnabled': true,
|
||||||
@ -888,6 +1152,71 @@ EntityMetadata _metadata(String id, DateTime now, [int localRevision = 0]) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WorkoutHistory _history({
|
||||||
|
required String id,
|
||||||
|
required DateTime startedAt,
|
||||||
|
WorkoutHistorySetResult? result,
|
||||||
|
List<WorkoutHistorySetResult>? results,
|
||||||
|
}) {
|
||||||
|
return WorkoutHistory(
|
||||||
|
metadata: _metadata(id, startedAt),
|
||||||
|
nameSnapshot: id,
|
||||||
|
startedAt: startedAt,
|
||||||
|
endedAt: startedAt.add(const Duration(minutes: 5)),
|
||||||
|
totalActiveMs: 300000,
|
||||||
|
completed: true,
|
||||||
|
historySnapshotJson: '{"name":"$id"}',
|
||||||
|
results: results ?? [result!],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkoutHistorySetResult _historySetResult({
|
||||||
|
required String id,
|
||||||
|
required String historyId,
|
||||||
|
required String sourceExerciseId,
|
||||||
|
required int setIndex,
|
||||||
|
required DateTime startedAt,
|
||||||
|
int? actualTimeMs,
|
||||||
|
int? actualReps,
|
||||||
|
double? actualScore,
|
||||||
|
int? actualScoreTimeMs,
|
||||||
|
ScoreInputMode scoreInputMode = ScoreInputMode.manual,
|
||||||
|
SetResultStatus status = SetResultStatus.completed,
|
||||||
|
}) {
|
||||||
|
final scoreEnabled = actualScore != null || actualScoreTimeMs != null;
|
||||||
|
return WorkoutHistorySetResult(
|
||||||
|
metadata: _metadata(id, startedAt),
|
||||||
|
workoutHistoryId: historyId,
|
||||||
|
programSnapshotId: 'program-snapshot',
|
||||||
|
exerciseSnapshotId: 'exercise-snapshot-$sourceExerciseId',
|
||||||
|
programIndex: 0,
|
||||||
|
exerciseIndex: 0,
|
||||||
|
setIndex: setIndex,
|
||||||
|
programNameSnapshot: 'Program',
|
||||||
|
exerciseNameSnapshot: 'Exercise',
|
||||||
|
timeEnabledSnapshot: actualTimeMs != null,
|
||||||
|
repsEnabledSnapshot:
|
||||||
|
actualReps != null || (actualTimeMs == null && !scoreEnabled),
|
||||||
|
scoreEnabledSnapshot: scoreEnabled,
|
||||||
|
actualTimeMs: actualTimeMs,
|
||||||
|
actualReps: actualReps,
|
||||||
|
actualScore: actualScore,
|
||||||
|
actualScoreTimeMs: actualScoreTimeMs,
|
||||||
|
scoreInputModeSnapshot: scoreInputMode,
|
||||||
|
scoreLabelSnapshot: scoreEnabled && scoreInputMode == ScoreInputMode.manual
|
||||||
|
? 'Score'
|
||||||
|
: null,
|
||||||
|
scoreUnitSnapshot: scoreEnabled && scoreInputMode == ScoreInputMode.manual
|
||||||
|
? 'pts'
|
||||||
|
: null,
|
||||||
|
sourceExerciseIdSnapshot: sourceExerciseId,
|
||||||
|
completedAt: status == SetResultStatus.completed
|
||||||
|
? startedAt.add(const Duration(minutes: 1))
|
||||||
|
: null,
|
||||||
|
status: status,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
ProgramExercise _programExercise(
|
ProgramExercise _programExercise(
|
||||||
String id,
|
String id,
|
||||||
DateTime now, {
|
DateTime now, {
|
||||||
@ -1019,3 +1348,40 @@ final class _FakeIds implements IdGenerator {
|
|||||||
return 'id-$_next';
|
return 'id-$_next';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class _FakePerformanceReferenceRepository
|
||||||
|
implements ExercisePerformanceReferenceRepository {
|
||||||
|
PerformanceMetric? requestedMetric;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> hasAnyCompletedHistoryForExercise(String exerciseId) async {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<WorkoutHistorySetPerformance?> findLatestSetPerformance({
|
||||||
|
required String exerciseId,
|
||||||
|
required ActivePerformanceMeasures activeMeasures,
|
||||||
|
required int currentSetIndex,
|
||||||
|
}) async {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<WorkoutHistoryMetricPerformance?> findBestMetricPerformance({
|
||||||
|
required String exerciseId,
|
||||||
|
required PerformanceMetric metric,
|
||||||
|
required ScoreInputMode scoreInputMode,
|
||||||
|
}) async {
|
||||||
|
requestedMetric = metric;
|
||||||
|
return WorkoutHistoryMetricPerformance(
|
||||||
|
workoutHistoryId: 'history-1',
|
||||||
|
startedAt: DateTime.utc(2026, 7, 22),
|
||||||
|
setIndex: 0,
|
||||||
|
exerciseNameSnapshot: 'Exercise',
|
||||||
|
metric: metric,
|
||||||
|
scoreInputModeSnapshot: scoreInputMode,
|
||||||
|
actualScore: 10,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -211,6 +211,9 @@ final class _FakeBootstrap implements AppDependencies {
|
|||||||
workoutHistoryUseCases = WorkoutHistoryUseCases(
|
workoutHistoryUseCases = WorkoutHistoryUseCases(
|
||||||
repository: _FakeWorkoutHistoryRepository(),
|
repository: _FakeWorkoutHistoryRepository(),
|
||||||
clock: _FakeClock(DateTime.utc(2026, 7, 17, 12)),
|
clock: _FakeClock(DateTime.utc(2026, 7, 17, 12)),
|
||||||
|
),
|
||||||
|
exercisePerformanceReferenceUseCase = ExercisePerformanceReferenceUseCase(
|
||||||
|
repository: _FakeExercisePerformanceReferenceRepository(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -245,6 +248,9 @@ final class _FakeBootstrap implements AppDependencies {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
final WorkoutHistoryUseCases workoutHistoryUseCases;
|
final WorkoutHistoryUseCases workoutHistoryUseCases;
|
||||||
|
|
||||||
|
@override
|
||||||
|
final ExercisePerformanceReferenceUseCase exercisePerformanceReferenceUseCase;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _sessionSnapshot() {
|
String _sessionSnapshot() {
|
||||||
@ -704,3 +710,29 @@ final class _FakeWorkoutHistoryRepository implements WorkoutHistoryRepository {
|
|||||||
@override
|
@override
|
||||||
Future<void> saveStepResult(WorkoutHistoryStepResult result) async {}
|
Future<void> saveStepResult(WorkoutHistoryStepResult result) async {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class _FakeExercisePerformanceReferenceRepository
|
||||||
|
implements ExercisePerformanceReferenceRepository {
|
||||||
|
@override
|
||||||
|
Future<bool> hasAnyCompletedHistoryForExercise(String exerciseId) async {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<WorkoutHistorySetPerformance?> findLatestSetPerformance({
|
||||||
|
required String exerciseId,
|
||||||
|
required ActivePerformanceMeasures activeMeasures,
|
||||||
|
required int currentSetIndex,
|
||||||
|
}) async {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<WorkoutHistoryMetricPerformance?> findBestMetricPerformance({
|
||||||
|
required String exerciseId,
|
||||||
|
required PerformanceMetric metric,
|
||||||
|
required ScoreInputMode scoreInputMode,
|
||||||
|
}) async {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user