feat(exercice): galerie de 5 images par exercice (ticket #35)

Étend le modèle Drift (tables.dart, app_database.dart/.g.dart), les
entités/use cases/repositories et exercise_library_screen.dart pour
supporter jusqu'à 5 images par exercice au lieu d'une seule. flutter
analyze propre, 63/63 tests verts, build APK debug validé.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 14:02:40 +02:00
parent 6419e2d9cc
commit 8bda4758f2
9 changed files with 2250 additions and 299 deletions

View File

@ -13,6 +13,7 @@ part 'app_database.g.dart';
ActiveWorkoutSessions,
ChangeLogEntries,
Exercises,
ExerciseImages,
MediaAssets,
ProgramExercises,
Programs,
@ -36,7 +37,7 @@ final class AppDatabase extends _$AppDatabase {
}
@override
int get schemaVersion => 4;
int get schemaVersion => 5;
@override
MigrationStrategy get migration {
@ -63,6 +64,9 @@ final class AppDatabase extends _$AppDatabase {
if (from < 4) {
await _migrateToSchema4();
}
if (from < 5) {
await _migrateToSchema5(migrator);
}
await _createIndexes();
},
beforeOpen: (details) async {
@ -95,6 +99,10 @@ final class AppDatabase extends _$AppDatabase {
'CREATE INDEX IF NOT EXISTS idx_program_exercises_program_id '
'ON program_exercises (program_id)',
);
await customStatement(
'CREATE INDEX IF NOT EXISTS idx_exercise_images_exercise_id '
'ON exercise_images (exercise_id)',
);
await customStatement(
'CREATE INDEX IF NOT EXISTS idx_workout_template_programs_template_id '
'ON workout_template_programs (workout_template_id)',
@ -147,6 +155,7 @@ const _syncableTableNames = [
'active_set_results',
'active_workout_sessions',
'exercises',
'exercise_images',
'media_assets',
'program_exercises',
'programs',
@ -226,4 +235,19 @@ extension on AppDatabase {
'default_target_score_time_ms > 0)',
);
}
Future<void> _migrateToSchema5(Migrator migrator) async {
await migrator.createTable(exerciseImages);
await customStatement(
'INSERT OR IGNORE INTO exercise_images (id, created_at, updated_at, '
'deleted_at, schema_version, sync_state, local_revision, '
'origin_device_id, future_owner_profile_id, last_synced_at, '
'remote_revision, exercise_id, media_asset_id, position) '
"SELECT 'exercise-image:' || id || ':0', created_at, updated_at, "
'deleted_at, schema_version, sync_state, local_revision, '
'origin_device_id, future_owner_profile_id, last_synced_at, '
'remote_revision, id, image_media_id, 0 FROM exercises '
'WHERE image_media_id IS NOT NULL',
);
}
}