diff --git a/.ideai/tickets/78/carnet.md b/.ideai/tickets/78/carnet.md index 1aafdee..0148e66 100644 --- a/.ideai/tickets/78/carnet.md +++ b/.ideai/tickets/78/carnet.md @@ -1,6 +1,6 @@ --- issueRef: "#78" -version: 1 -updatedBy: {"kind":"agent","agent_id":"f8f40941-ecf7-4830-b9de-8818a099f448"} -updatedAt: 1784547239512 +version: 2 +updatedBy: {"kind":"agent","agent_id":"57695b92-24d0-4876-837c-76116e70a6ae"} +updatedAt: 1784549136530 --- diff --git a/.ideai/tickets/78/issue.md b/.ideai/tickets/78/issue.md index 0564f00..45d5b75 100644 --- a/.ideai/tickets/78/issue.md +++ b/.ideai/tickets/78/issue.md @@ -2,15 +2,15 @@ id: "e7769413-3d3d-48af-b55e-361c69aef4b2" number: 78 title: "[DevFrontend] État d'exécution Chrono suivant prêt" -status: "open" +status: "qa" priority: "medium" sprint: null links: [{"target":"#73","kind":"relatesTo"},{"target":"#76","kind":"dependsOn"},{"target":"#77","kind":"dependsOn"}] agentRefs: [{"agentId":"9933c93a-b8a1-4164-a3bb-7063fdad747d","role":"assigned"}] createdBy: {"kind":"agent","agent_id":"f8f40941-ecf7-4830-b9de-8818a099f448"} -updatedBy: {"kind":"agent","agent_id":"f8f40941-ecf7-4830-b9de-8818a099f448"} +updatedBy: {"kind":"agent","agent_id":"57695b92-24d0-4876-837c-76116e70a6ae"} createdAt: 1784547239512 -updatedAt: 1784547239512 -version: 1 +updatedAt: 1784549136530 +version: 2 --- Adapter l'écran d'exécution des étapes pour afficher `Chrono suivant prêt` quand une étape Temps est prête après une étape Temps et que l'auto-enchaînement effectif est désactivé. Réutiliser `stoppedTimer` côté domaine; l'UI dérive le libellé/bouton depuis l'étape courante, le résultat précédent et la valeur effective. Bouton `Démarrer le chrono`, pas de pause séance, pas de rouge/erreur. Après kill/reprise, l'écran doit revenir à cet état sans démarrage automatique. \ No newline at end of file diff --git a/.ideai/tickets/index.json b/.ideai/tickets/index.json index 29e48b8..234d05f 100644 --- a/.ideai/tickets/index.json +++ b/.ideai/tickets/index.json @@ -883,13 +883,13 @@ "issueRef": "#78", "path": "78", "title": "[DevFrontend] État d'exécution Chrono suivant prêt", - "status": "open", + "status": "qa", "priority": "medium", "sprint": null, "assignedAgentIds": [ "9933c93a-b8a1-4164-a3bb-7063fdad747d" ], - "updatedAt": 1784547239512 + "updatedAt": 1784549136530 }, { "issueRef": "#79", diff --git a/test/application/use_cases_test.dart b/test/application/use_cases_test.dart index c70cda7..c195c99 100644 --- a/test/application/use_cases_test.dart +++ b/test/application/use_cases_test.dart @@ -1281,6 +1281,76 @@ void main() { }, ); + test( + 'step chaining disabled stops at first elapsed timed boundary after kill', + () async { + final clock = _FakeClock(DateTime.utc(2026, 7, 17, 12)); + final session = _sessionWithSnapshot( + currentProgramIndex: 0, + currentExerciseIndex: 0, + currentSetIndex: 0, + setsCount: 1, + targetReps: 1, + autoStartNextTimedStepSnapshot: false, + exerciseSteps: [ + ..._twoTimedSteps(), + _step( + id: 'step-3', + position: 2, + name: 'Centre', + type: ExerciseStepType.time, + defaultTargetValue: 1, + ), + ], + ); + final repository = _FakeActiveSessionRepository()..session = session; + + await ActiveExerciseStepUseCases( + sessionRepository: repository, + clock: clock, + ids: _FakeIds(), + originDeviceId: 'device-1', + ).startOrResumeProgress( + sessionId: session.metadata.id, + programIndex: 0, + exerciseIndex: 0, + setIndex: 0, + ); + await ActiveExerciseStepUseCases( + sessionRepository: repository, + clock: clock, + ids: _FakeIds(), + originDeviceId: 'device-1', + ).startTimer( + sessionId: session.metadata.id, + programIndex: 0, + exerciseIndex: 0, + setIndex: 0, + ); + clock.value = clock.value.add(const Duration(milliseconds: 4500)); + + final reconstructed = ActiveExerciseStepUseCases( + sessionRepository: repository, + clock: clock, + ids: _FakeIds(), + originDeviceId: 'device-1', + ); + final view = await reconstructed.startOrResumeProgress( + sessionId: session.metadata.id, + programIndex: 0, + exerciseIndex: 0, + setIndex: 0, + ); + + expect(view.state.status, ActiveExerciseStepProgressStatus.stoppedTimer); + expect(view.state.currentStepIndex, 1); + expect(view.state.startedAt, isNull); + expect(view.state.accumulatedMs, 0); + expect(repository.stepResults, hasLength(1)); + expect(repository.stepResults.single.stepIndex, 0); + }, + ); + test( 'step chaining resolution uses program override before exercise snapshot', () async {