From 945c34590677e161a711ccaff0e1077197b1b178 Mon Sep 17 00:00:00 2001 From: Doot Agent Date: Mon, 6 Jul 2026 00:00:59 +0000 Subject: feat: remove Todoist integration entirely Native tasks (native_tasks table) fully replace Todoist. All Todoist API code, store functions, handlers, routes, templates, and tests have been removed. Migration 021 drops the now-unused tasks cache table. Co-Authored-By: Claude Sonnet 4.6 --- internal/models/atom.go | 30 ------------------------ internal/models/atom_test.go | 54 -------------------------------------------- internal/models/timeline.go | 2 +- internal/models/types.go | 6 ++--- internal/models/widget.go | 4 ++-- 5 files changed, 6 insertions(+), 90 deletions(-) (limited to 'internal/models') diff --git a/internal/models/atom.go b/internal/models/atom.go index 967b489..9f40de6 100644 --- a/internal/models/atom.go +++ b/internal/models/atom.go @@ -10,7 +10,6 @@ type AtomSource string const ( SourceTrello AtomSource = "trello" - SourceTodoist AtomSource = "todoist" SourceMeal AtomSource = "plantoeat" SourceGTasks AtomSource = "gtasks" SourceClaudomator AtomSource = "claudomator" @@ -74,35 +73,6 @@ func (a *Atom) ComputeUIFields() { a.HasSetTime = dueInTZ.Hour() != 0 || dueInTZ.Minute() != 0 } -// TaskToAtom converts a Todoist Task to an Atom -func TaskToAtom(t Task) Atom { - // Todoist priority: 1 (normal) to 4 (urgent) - // Keep as-is since it already matches our 1-4 scale - priority := t.Priority - if priority < 1 { - priority = 1 - } - if priority > 4 { - priority = 4 - } - - return Atom{ - ID: t.ID, - Title: t.Content, - Description: t.Description, - Source: SourceTodoist, - Type: TypeTask, - URL: t.URL, - DueDate: t.DueDate, - CreatedAt: t.CreatedAt, - Priority: priority, - SourceIcon: "🔴", // Red circle for Todoist - ColorClass: "border-red-500", - IsRecurring: t.IsRecurring, - Raw: t, - } -} - // NativeTaskToAtom converts a native doot Task to an Atom. func NativeTaskToAtom(t Task) Atom { priority := t.Priority diff --git a/internal/models/atom_test.go b/internal/models/atom_test.go index 53bf343..6f86949 100644 --- a/internal/models/atom_test.go +++ b/internal/models/atom_test.go @@ -5,60 +5,6 @@ import ( "time" ) -func TestTaskToAtom(t *testing.T) { - now := time.Now() - task := Task{ - ID: "task-123", - Content: "Test task", - Description: "Task description", - DueDate: &now, - Priority: 3, - URL: "https://todoist.com/task/123", - CreatedAt: now, - IsRecurring: true, - } - - atom := TaskToAtom(task) - - if atom.ID != "task-123" { - t.Errorf("Expected ID 'task-123', got '%s'", atom.ID) - } - if atom.Title != "Test task" { - t.Errorf("Expected title 'Test task', got '%s'", atom.Title) - } - if atom.Source != SourceTodoist { - t.Errorf("Expected source Todoist, got '%s'", atom.Source) - } - if atom.Type != TypeTask { - t.Errorf("Expected type Task, got '%s'", atom.Type) - } - if atom.Priority != 3 { - t.Errorf("Expected priority 3, got %d", atom.Priority) - } - if atom.SourceIcon != "🔴" { - t.Error("Expected red circle icon") - } - if !atom.IsRecurring { - t.Error("Expected IsRecurring to be true") - } -} - -func TestTaskToAtom_PriorityClamping(t *testing.T) { - // Test priority below 1 - lowTask := Task{Priority: 0} - lowAtom := TaskToAtom(lowTask) - if lowAtom.Priority != 1 { - t.Errorf("Priority should be clamped to 1, got %d", lowAtom.Priority) - } - - // Test priority above 4 - highTask := Task{Priority: 10} - highAtom := TaskToAtom(highTask) - if highAtom.Priority != 4 { - t.Errorf("Priority should be clamped to 4, got %d", highAtom.Priority) - } -} - func TestCardToAtom(t *testing.T) { now := time.Now() card := Card{ diff --git a/internal/models/timeline.go b/internal/models/timeline.go index c4196bd..ab486a8 100644 --- a/internal/models/timeline.go +++ b/internal/models/timeline.go @@ -39,7 +39,7 @@ type TimelineItem struct { IsOverdue bool `json:"is_overdue"` IsAllDay bool `json:"is_all_day"` // True if time is midnight (no specific time) DaySection DaySection `json:"day_section"` - Source string `json:"source"` // "todoist", "trello", "plantoeat", "calendar", "gtasks" + Source string `json:"source"` // "trello", "plantoeat", "calendar", "gtasks" // Source-specific metadata ListID string `json:"list_id,omitempty"` // For Google Tasks diff --git a/internal/models/types.go b/internal/models/types.go index 0b025ce..d9dd515 100644 --- a/internal/models/types.go +++ b/internal/models/types.go @@ -6,7 +6,7 @@ import ( "time" ) -// Task represents a task from Todoist +// Task represents a native task type Task struct { ID string `json:"id"` Content string `json:"content"` @@ -118,7 +118,7 @@ type Card struct { URL string `json:"url"` } -// Project represents a Todoist project +// Project represents a project (used for source config grouping) type Project struct { ID string `json:"id"` Name string `json:"name"` @@ -249,7 +249,7 @@ type CompletedTask struct { // SourceConfig represents a configurable item from a data source type SourceConfig struct { ID int64 `json:"id"` - Source string `json:"source"` // trello, todoist, gcal, gtasks + Source string `json:"source"` // trello, gcal, gtasks ItemType string `json:"item_type"` // board, project, calendar, tasklist ItemID string `json:"item_id"` ItemName string `json:"item_name"` diff --git a/internal/models/widget.go b/internal/models/widget.go index 94deec7..8d0bdd6 100644 --- a/internal/models/widget.go +++ b/internal/models/widget.go @@ -3,7 +3,7 @@ package models import "time" // WidgetItem is a single item in the widget API response. -// Source values: "todoist", "trello", "plantoeat", "calendar", "gtasks" +// Source values: "doot", "trello", "plantoeat", "calendar", "gtasks" // Type values: "task", "event" type WidgetItem struct { ID string `json:"id"` @@ -14,7 +14,7 @@ type WidgetItem struct { End *time.Time `json:"end,omitempty"` IsAllDay bool `json:"is_all_day"` URL string `json:"url,omitempty"` - Completable bool `json:"completable"` // true = todoist task (checkbox shown) + Completable bool `json:"completable"` // true = doot task (checkbox shown) } // WidgetResponse is the full /api/widget response body. -- cgit v1.2.3