feat(workout): complete mobile session flow

Make Workout Copilot behave like a finished phone-first session: rest/next state, progress, undo recovery, finish/export, replayable local log, and host proof controls tucked behind product states.

req: examples/001

req: local/001

req: local/003

req: local/004

req: host/002
This commit is contained in:
slhx agent
2026-06-11 23:15:55 +02:00
parent bf7560b7a8
commit a514237b09
7 changed files with 561 additions and 161 deletions
+6 -1
View File
@@ -52,6 +52,8 @@ fn workout_is_e2e_working_over_http() {
assert_eq!(home.status, 200);
assert!(home.header("content-type").contains("text/html"));
assert!(home.text().contains("Now-first Workout Copilot"));
assert!(home.text().contains("Finish & recover"));
assert!(home.text().contains("Undo last action"));
assert!(home.text().contains("Private event log"));
assert!(home.text().contains("Replay export"));
assert!(home
@@ -65,6 +67,7 @@ fn workout_is_e2e_working_over_http() {
assert_eq!(css.status, 200);
assert!(css.header("content-type").contains("text/css"));
assert!(css.text().contains(".command-slate"));
assert!(css.text().contains(".finish-card"));
assert!(css.text().contains("min-height: var(--tap)"));
let runtime = get(&server, runtime_js_path());
@@ -80,7 +83,9 @@ fn workout_is_e2e_working_over_http() {
assert_effect_response(&completed);
let completed_batch = completed.effects();
assert_payload_contains(&completed_batch, "completed Goblet squat set 1");
assert_payload_contains(&completed_batch, "Next: Goblet squat set 2/3");
assert_payload_contains(&completed_batch, "Rest 90s · next: Goblet squat set 2");
assert_payload_contains(&completed_batch, "Start Goblet squat set 2");
assert_payload_contains(&completed_batch, "1 of 5 sets · 20% complete");
let replayed = post(
&server,