From 094f4fbde05d4e26f47c2ba319c998f8ac73c046 Mon Sep 17 00:00:00 2001 From: Pierre Le Fevre Date: Sat, 14 Mar 2026 10:55:00 +0100 Subject: [PATCH] Fix streak freeze bugs: extend streak on freeze use, idempotent migration When streak freezes bridge a gap, extend the streak by 1 for today's activity (previously the streak stayed flat, losing a day). Also handle duplicate column errors in migration runner so ALTER TABLE migrations don't panic on server restart. Co-Authored-By: Claude Opus 4.6 (1M context) --- api/src/db.rs | 13 +++++++++---- api/src/routes/progress.rs | 12 ++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/api/src/db.rs b/api/src/db.rs index fe6fedc..cd953c7 100644 --- a/api/src/db.rs +++ b/api/src/db.rs @@ -29,10 +29,15 @@ pub async fn run_migrations(pool: &SqlitePool) { if trimmed.is_empty() { continue; } - sqlx::query(trimmed) - .execute(pool) - .await - .expect("Failed to run migration"); + if let Err(e) = sqlx::query(trimmed).execute(pool).await { + // ALTER TABLE ADD COLUMN is not idempotent in SQLite — + // ignore "duplicate column" errors on restart. + let msg = e.to_string(); + if msg.contains("duplicate column") { + continue; + } + panic!("Failed to run migration: {e}"); + } } } } diff --git a/api/src/routes/progress.rs b/api/src/routes/progress.rs index 912ed40..eb735b5 100644 --- a/api/src/routes/progress.rs +++ b/api/src/routes/progress.rs @@ -156,8 +156,16 @@ pub async fn update_progress( .unwrap_or(i64::MAX); if missed_days > 0 && missed_days <= stats.streak_freezes as i64 { - // Consume freezes for each missed day, maintain streak (don't extend) - (stats.streak_days, stats.streak_freezes - missed_days as i32) + // Consume freezes for missed days, extend streak for today's activity + let extended = stats.streak_days + 1; + let freezes = stats.streak_freezes - missed_days as i32; + // Award a streak freeze every 7 days + let freezes = if extended > 0 && extended % 7 == 0 { + freezes + 1 + } else { + freezes + }; + (extended, freezes) } else { // Not enough freezes — reset streak (1, 0) -- 2.51.2