chore(wip): consolidation intermédiaire multi-tickets (sprints Statistiques, UI, Bug resolution, Serveur-client)

Regroupe l'état de travail en cours réalisé dans un même worktree sur
plusieurs tickets/sprints (#85, #136, #145, #155-160, #162-164),
mélangeant des tickets QA et inProgress. Ne constitue pas une feature
terminée : commit de sauvegarde avant triage/split par ticket en
branches feature/* dédiées. Exclut les dossiers d'environnement de
build locaux et le heap dump parasite (.gitignore mis à jour).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-28 16:48:54 +02:00
parent 58272e354a
commit 917777e18b
279 changed files with 13546 additions and 674 deletions

View File

@ -40,7 +40,7 @@ void main() {
expect(projection.primaryAction, WatchPrimaryAction.startCurrentExercise);
});
test('projects running with duration timer before stopwatch score', () async {
test('projects running with step timer before stopwatch score', () async {
final now = DateTime.utc(2026, 7, 25, 12);
final session = _session(
timeEnabled: true,
@ -75,7 +75,7 @@ void main() {
now.millisecondsSinceEpoch,
);
expect(projection.secondaryTimers.map((timer) => timer.kind), [
WatchTimerKind.setTimer,
WatchTimerKind.scoreStopwatch,
]);
expect(projection.primaryAction, WatchPrimaryAction.pauseSession);
expect(
@ -85,7 +85,7 @@ void main() {
});
test(
'projects duration and stopwatch score with only duration timer visible',
'projects duration and stopwatch score with stopwatch timer visible',
() async {
final now = DateTime.utc(2026, 7, 25, 12);
final session = _session(
@ -108,7 +108,7 @@ void main() {
final projection = await projector.project(revision: 1);
expect(projection.phase, WatchSessionPhase.running);
expect(projection.dominantTimer?.kind, WatchTimerKind.setTimer);
expect(projection.dominantTimer?.kind, WatchTimerKind.scoreStopwatch);
expect(projection.secondaryTimers, isEmpty);
expect(projection.primaryAction, WatchPrimaryAction.pauseSession);
expect(
@ -118,6 +118,28 @@ void main() {
},
);
test(
'keeps set timer out of display timers while preserving phase',
() async {
final now = DateTime.utc(2026, 7, 25, 12);
final session = _session(timeEnabled: true, repsEnabled: false);
final repository = _FakeActiveSessionRepository()
..session = session
..setTimerStates['set'] = _setTimer(
sessionId: session.metadata.id,
startedAt: now.subtract(const Duration(seconds: 6)),
);
final projector = _projector(repository, _clock(now));
final projection = await projector.project(revision: 1);
expect(projection.phase, WatchSessionPhase.running);
expect(projection.dominantTimer, isNull);
expect(projection.secondaryTimers, isEmpty);
expect(projection.primaryAction, WatchPrimaryAction.pauseSession);
},
);
test('projects manual score state for the current set', () async {
final session = _session(scoreEnabled: true, targetScore: 8);
final repository = _FakeActiveSessionRepository()