From 0baf1134ea2d415aa55079ff98476afd0acf5811 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Tue, 14 Jul 2026 20:11:31 +0000 Subject: feat(tasks): add recurrence columns and model fields for native tasks recurrence_series_id != "" is the real recurring indicator (IsRecurring predates this feature and is never set). Adds parseWeekdays/formatWeekdays for the comma-separated weekday-list column, and threads the five new columns through scanNativeTasks and all four existing SELECT queries. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD --- internal/store/native_tasks_test.go | 76 ++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) (limited to 'internal/store/native_tasks_test.go') diff --git a/internal/store/native_tasks_test.go b/internal/store/native_tasks_test.go index 5c11d3a..0a87bfa 100644 --- a/internal/store/native_tasks_test.go +++ b/internal/store/native_tasks_test.go @@ -7,6 +7,8 @@ import ( "testing" "time" + "task-dashboard/internal/models" + _ "github.com/mattn/go-sqlite3" ) @@ -33,7 +35,12 @@ func newNativeTasksTestStore(t *testing.T) *Store { completed BOOLEAN DEFAULT 0, labels TEXT DEFAULT '[]', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, + recurrence_freq TEXT DEFAULT '', + recurrence_interval INTEGER DEFAULT 1, + recurrence_weekdays TEXT DEFAULT '', + recurrence_series_id TEXT DEFAULT '', + next_occurrence_override TEXT DEFAULT '' ) `); err != nil { t.Fatal(err) @@ -94,3 +101,70 @@ func TestRescheduleNativeTask_UnknownID_ReturnsErrNotFound(t *testing.T) { t.Fatalf("expected ErrNativeTaskNotFound, got %v", err) } } + +func TestGetNativeTasks_ParsesRecurrenceFields(t *testing.T) { + s := newNativeTasksTestStore(t) + if _, err := s.db.Exec(` + INSERT INTO native_tasks (id, content, due_date, recurrence_freq, recurrence_interval, recurrence_weekdays, recurrence_series_id, next_occurrence_override) + VALUES ('rec-1', 'Recurring task', '2026-07-13', 'weekly', 2, '1,3,5', 'series-abc', '2026-07-27') + `); err != nil { + t.Fatal(err) + } + + tasks, err := s.GetNativeTasks() + if err != nil { + t.Fatalf("GetNativeTasks: %v", err) + } + + var found *models.Task + for i := range tasks { + if tasks[i].ID == "rec-1" { + found = &tasks[i] + } + } + if found == nil { + t.Fatal("expected to find rec-1") + } + if found.RecurrenceFreq != "weekly" { + t.Errorf("RecurrenceFreq = %q, want %q", found.RecurrenceFreq, "weekly") + } + if found.RecurrenceInterval != 2 { + t.Errorf("RecurrenceInterval = %d, want 2", found.RecurrenceInterval) + } + if len(found.RecurrenceWeekdays) != 3 || found.RecurrenceWeekdays[0] != 1 || found.RecurrenceWeekdays[1] != 3 || found.RecurrenceWeekdays[2] != 5 { + t.Errorf("RecurrenceWeekdays = %v, want [1 3 5]", found.RecurrenceWeekdays) + } + if found.RecurrenceSeriesID != "series-abc" { + t.Errorf("RecurrenceSeriesID = %q, want %q", found.RecurrenceSeriesID, "series-abc") + } + if found.NextOccurrenceOverride == nil || found.NextOccurrenceOverride.Format("2006-01-02") != "2026-07-27" { + t.Errorf("NextOccurrenceOverride = %v, want 2026-07-27", found.NextOccurrenceOverride) + } +} + +func TestGetNativeTasks_NonRecurringTask_HasEmptyRecurrenceFields(t *testing.T) { + s := newNativeTasksTestStore(t) + // "real-1" (inserted by newNativeTasksTestStore) has no recurrence columns set. + tasks, err := s.GetNativeTasks() + if err != nil { + t.Fatalf("GetNativeTasks: %v", err) + } + var found *models.Task + for i := range tasks { + if tasks[i].ID == "real-1" { + found = &tasks[i] + } + } + if found == nil { + t.Fatal("expected to find real-1") + } + if found.RecurrenceSeriesID != "" { + t.Errorf("expected empty RecurrenceSeriesID for non-recurring task, got %q", found.RecurrenceSeriesID) + } + if found.RecurrenceWeekdays != nil { + t.Errorf("expected nil RecurrenceWeekdays for non-recurring task, got %v", found.RecurrenceWeekdays) + } + if found.NextOccurrenceOverride != nil { + t.Errorf("expected nil NextOccurrenceOverride for non-recurring task, got %v", found.NextOccurrenceOverride) + } +} -- cgit v1.2.3