F2: Streak no longer counts aborted sessions
getDistinctSessionDays() now filters on status = 'completed' like every other stat query, so starting and immediately exiting a session does not extend the streak. Adds a regression test (completed today + aborted yesterday => streak 1). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
13f3b305bd
commit
cd8636546a
|
|
@ -158,7 +158,7 @@ export const executionLogRepository = {
|
||||||
|
|
||||||
async getDistinctSessionDays() {
|
async getDistinctSessionDays() {
|
||||||
return db.selectAll(
|
return db.selectAll(
|
||||||
`SELECT DATE(started_at) AS day FROM execution_log GROUP BY DATE(started_at) ORDER BY day DESC`,
|
`SELECT DATE(started_at) AS day FROM execution_log WHERE status = 'completed' GROUP BY DATE(started_at) ORDER BY day DESC`,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ Step 9 — Statistics
|
||||||
- test_stats_volume_chart_renders: Volume chart canvas renders when sessions have weight data
|
- test_stats_volume_chart_renders: Volume chart canvas renders when sessions have weight data
|
||||||
- test_stats_progression_chart_renders: Progression chart renders after selecting an exercise
|
- test_stats_progression_chart_renders: Progression chart renders after selecting an exercise
|
||||||
- test_stats_streak_consecutive_days: Streak counts consecutive days with sessions
|
- test_stats_streak_consecutive_days: Streak counts consecutive days with sessions
|
||||||
|
- test_stats_streak_ignores_aborted_sessions: Aborted sessions do not extend the streak
|
||||||
"""
|
"""
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
|
|
||||||
|
|
@ -115,6 +116,7 @@ def _create_log_with_items(
|
||||||
reps: int = 10,
|
reps: int = 10,
|
||||||
weight: float = 0.0,
|
weight: float = 0.0,
|
||||||
completed: bool = True,
|
completed: bool = True,
|
||||||
|
status: str = 'completed',
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Seed one execution log with one item."""
|
"""Seed one execution log with one item."""
|
||||||
finished_at = started_at # same timestamp is fine for tests
|
finished_at = started_at # same timestamp is fine for tests
|
||||||
|
|
@ -123,7 +125,8 @@ def _create_log_with_items(
|
||||||
const logId = await window.__repos.executionLogs.create({{
|
const logId = await window.__repos.executionLogs.create({{
|
||||||
session_id: '{session_id}',
|
session_id: '{session_id}',
|
||||||
started_at: '{started_at}',
|
started_at: '{started_at}',
|
||||||
finished_at: '{finished_at}'
|
finished_at: '{finished_at}',
|
||||||
|
status: {repr(status)}
|
||||||
}})
|
}})
|
||||||
await window.__repos.executionLogs.addItem({{
|
await window.__repos.executionLogs.addItem({{
|
||||||
log_id: logId,
|
log_id: logId,
|
||||||
|
|
@ -510,3 +513,28 @@ def test_stats_streak_consecutive_days(page: Page, app_url: str):
|
||||||
|
|
||||||
streak_val = page.locator('[data-testid="stats-streak"] .stat-value').text_content()
|
streak_val = page.locator('[data-testid="stats-streak"] .stat-value').text_content()
|
||||||
assert int(streak_val) >= 3, f"Expected streak ≥ 3, got {streak_val}"
|
assert int(streak_val) >= 3, f"Expected streak ≥ 3, got {streak_val}"
|
||||||
|
|
||||||
|
|
||||||
|
def test_stats_streak_ignores_aborted_sessions(page: Page, app_url: str):
|
||||||
|
"""Aborted sessions do not extend the streak: one completed log today plus
|
||||||
|
one aborted log yesterday must give a streak of 1, not 2."""
|
||||||
|
_wait_for_db(page, app_url)
|
||||||
|
_delete_all_logs(page)
|
||||||
|
_delete_all_exercises(page)
|
||||||
|
_delete_all_sessions(page)
|
||||||
|
|
||||||
|
ex_id = _create_exercise(page, 'Aborted Streak Exercise')
|
||||||
|
sess_id = _create_session(page, 'Aborted Streak Session')
|
||||||
|
|
||||||
|
_create_log_with_items(page, sess_id, ex_id, _iso_days_ago(0), status='completed')
|
||||||
|
_create_log_with_items(page, sess_id, ex_id, _iso_days_ago(1), status='aborted')
|
||||||
|
|
||||||
|
page.reload()
|
||||||
|
page.wait_for_function(
|
||||||
|
"document.documentElement.getAttribute('data-db-ready') === 'true'",
|
||||||
|
timeout=15000,
|
||||||
|
)
|
||||||
|
_go_to_stats(page)
|
||||||
|
|
||||||
|
streak_val = page.locator('[data-testid="stats-streak"] .stat-value').text_content()
|
||||||
|
assert int(streak_val) == 1, f"Expected streak 1 (aborted must not count), got {streak_val}"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue