summaryrefslogtreecommitdiff
path: root/internal/store/sqlite.go
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-03-23 08:13:02 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-03-23 08:13:02 +0000
commitb2d8fc460be3105ac383098e7cdc92171e5026ec (patch)
treecd5ba3f3008e6b3310680d785880f1f32ed090c5 /internal/store/sqlite.go
parentb0688c8819da1b7fcb4a97b6ec1fa58050e4841e (diff)
feat: unify Google Tasks with main system via caching and integrated UI
- Implement SQLite caching layer for Google Tasks - Integrate Google Tasks into unified Atoms loop (showing in Tasks tab) - Update Planning tab to include cached Google Tasks - Enhance Quick Add form with Todoist project selector - Remove orphaned HandleTasksTab/HandleRefreshTab methods - Update tests to reflect new BuildTimeline signature and data structures
Diffstat (limited to 'internal/store/sqlite.go')
-rw-r--r--internal/store/sqlite.go109
1 files changed, 107 insertions, 2 deletions
diff --git a/internal/store/sqlite.go b/internal/store/sqlite.go
index 3879395..f9c9a6b 100644
--- a/internal/store/sqlite.go
+++ b/internal/store/sqlite.go
@@ -23,6 +23,7 @@ const (
CacheKeyTrelloBoards = "trello_boards"
CacheKeyPlanToEatMeals = "plantoeat_meals"
CacheKeyGoogleCalendar = "google_calendar"
+ CacheKeyGoogleTasks = "google_tasks"
)
type Store struct {
@@ -867,6 +868,110 @@ func (s *Store) GetCalendarEventsByDateRange(start, end time.Time) ([]models.Cal
return events, rows.Err()
}
+// Google Tasks operations
+
+// SaveGoogleTasks replaces all cached Google Tasks
+func (s *Store) SaveGoogleTasks(tasks []models.GoogleTask) error {
+ tx, err := s.db.Begin()
+ if err != nil {
+ return err
+ }
+ defer func() { _ = tx.Rollback() }()
+
+ if _, err := tx.Exec(`DELETE FROM google_tasks`); err != nil {
+ return err
+ }
+
+ stmt, err := tx.Prepare(`
+ INSERT INTO google_tasks (id, title, notes, status, completed, due_date, updated_at, list_id, url)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
+ `)
+ if err != nil {
+ return err
+ }
+ defer func() { _ = stmt.Close() }()
+
+ for _, t := range tasks {
+ _, err = stmt.Exec(t.ID, t.Title, t.Notes, t.Status, t.Completed, t.DueDate, t.UpdatedAt, t.ListID, t.URL)
+ if err != nil {
+ return err
+ }
+ }
+
+ return tx.Commit()
+}
+
+// GetGoogleTasks retrieves all cached Google Tasks
+func (s *Store) GetGoogleTasks() ([]models.GoogleTask, error) {
+ rows, err := s.db.Query(`
+ SELECT id, title, notes, status, completed, due_date, updated_at, list_id, url
+ FROM google_tasks
+ ORDER BY completed ASC, CASE WHEN due_date IS NULL THEN 1 ELSE 0 END, due_date ASC
+ `)
+ if err != nil {
+ return nil, err
+ }
+ defer func() { _ = rows.Close() }()
+
+ var tasks []models.GoogleTask
+ for rows.Next() {
+ var t models.GoogleTask
+ var dueDate, updatedAt sql.NullTime
+
+ err := rows.Scan(&t.ID, &t.Title, &t.Notes, &t.Status, &t.Completed, &dueDate, &updatedAt, &t.ListID, &t.URL)
+ if err != nil {
+ return nil, err
+ }
+
+ if dueDate.Valid {
+ t.DueDate = &dueDate.Time
+ }
+ if updatedAt.Valid {
+ t.UpdatedAt = updatedAt.Time
+ }
+
+ tasks = append(tasks, t)
+ }
+
+ return tasks, rows.Err()
+}
+
+// GetGoogleTasksByDateRange retrieves cached Google Tasks in a date range
+func (s *Store) GetGoogleTasksByDateRange(start, end time.Time) ([]models.GoogleTask, error) {
+ rows, err := s.db.Query(`
+ SELECT id, title, notes, status, completed, due_date, updated_at, list_id, url
+ FROM google_tasks
+ WHERE due_date IS NULL OR (due_date >= ? AND due_date < ?)
+ ORDER BY completed ASC, CASE WHEN due_date IS NULL THEN 1 ELSE 0 END, due_date ASC
+ `, start, end)
+ if err != nil {
+ return nil, err
+ }
+ defer func() { _ = rows.Close() }()
+
+ var tasks []models.GoogleTask
+ for rows.Next() {
+ var t models.GoogleTask
+ var dueDate, updatedAt sql.NullTime
+
+ err := rows.Scan(&t.ID, &t.Title, &t.Notes, &t.Status, &t.Completed, &dueDate, &updatedAt, &t.ListID, &t.URL)
+ if err != nil {
+ return nil, err
+ }
+
+ if dueDate.Valid {
+ t.DueDate = &dueDate.Time
+ }
+ if updatedAt.Valid {
+ t.UpdatedAt = updatedAt.Time
+ }
+
+ tasks = append(tasks, t)
+ }
+
+ return tasks, rows.Err()
+}
+
// Agent operations
// CreateAgentSession creates a new pending agent session
@@ -1403,8 +1508,8 @@ func (s *Store) SyncSourceConfigs(source, itemType string, items []models.Source
// InvalidateAllCaches removes cache metadata for all known cache keys
func (s *Store) InvalidateAllCaches() error {
- _, err := s.db.Exec(`DELETE FROM cache_metadata WHERE key IN (?, ?, ?, ?)`,
- CacheKeyTodoistTasks, CacheKeyTrelloBoards, CacheKeyPlanToEatMeals, CacheKeyGoogleCalendar)
+ _, err := s.db.Exec(`DELETE FROM cache_metadata WHERE key IN (?, ?, ?, ?, ?)`,
+ CacheKeyTodoistTasks, CacheKeyTrelloBoards, CacheKeyPlanToEatMeals, CacheKeyGoogleCalendar, CacheKeyGoogleTasks)
return err
}