<feed xmlns='http://www.w3.org/2005/Atom'>
<title>doot.git/internal/handlers/timeline_logic.go, branch master</title>
<subtitle>doot — personal productivity web app
</subtitle>
<id>https://git.terst.org/doot.git/atom?h=master</id>
<link rel='self' href='https://git.terst.org/doot.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.terst.org/doot.git/'/>
<updated>2026-07-12T11:06:32+00:00</updated>
<entry>
<title>feat(widget): capture and forward RecurringEventID for calendar events</title>
<updated>2026-07-12T11:06:32+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-07-12T11:06:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/doot.git/commit/?id=f31b4722243b8b69564c94e47e07678153c31815'/>
<id>urn:sha1:f31b4722243b8b69564c94e47e07678153c31815</id>
<content type='text'>
</content>
</entry>
<entry>
<title>fix(timeline): include overdue native tasks in timeline and widget</title>
<updated>2026-07-12T07:40:30+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-07-12T07:40:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/doot.git/commit/?id=f01b2924bf0b62fc20af0d09581d101418455b1c'/>
<id>urn:sha1:f01b2924bf0b62fc20af0d09581d101418455b1c</id>
<content type='text'>
GetNativeTasksByDateRange's SQL bound (due_date &gt;= start) excluded any
task overdue from a previous day before ComputeDaySection ever got a
chance to mark it IsOverdue, so both the web Timeline view and the
widget API (which both call BuildTimeline with start = today) silently
dropped overdue tasks entirely -- only the Tasks tab (unbounded
GetNativeTasks) showed them. Added GetOverdueNativeTasks and folded its
results into BuildTimeline alongside the ranged fetch.

Co-Authored-By: Claude Sonnet 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
</content>
</entry>
<entry>
<title>feat: remove Todoist integration entirely</title>
<updated>2026-07-06T00:00:59+00:00</updated>
<author>
<name>Doot Agent</name>
<email>agent@doot.local</email>
</author>
<published>2026-07-06T00:00:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/doot.git/commit/?id=945c34590677e161a711ccaff0e1077197b1b178'/>
<id>urn:sha1:945c34590677e161a711ccaff0e1077197b1b178</id>
<content type='text'>
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 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat: native task management + Todoist migration</title>
<updated>2026-06-29T08:53:48+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-06-29T08:53:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/doot.git/commit/?id=3fbfdd1f9441299eb146bf215449f238977deb66'/>
<id>urn:sha1:3fbfdd1f9441299eb146bf215449f238977deb66</id>
<content type='text'>
Adds doot-owned task storage (native_tasks table) so tasks can be
managed without Todoist. CompleteTask for 'doot' source just updates
the DB — no external API call, no token dependency.

Migration path:
  POST /settings/import-from-todoist  — copies Todoist cache → native_tasks
  Then remove TODOIST_TOKEN from .env to disable Todoist

Changes:
- migration 020: native_tasks table
- store: GetNativeTasks, GetNativeTasksByDateRange, GetUndatedNativeTasks,
  CreateNativeTask, CompleteNativeTask, UncompleteNativeTask,
  UpdateNativeTask, ImportFromTodoist
- timeline: native tasks appear as source="doot" (teal)
- handleAtomToggle: "doot" case — no external API needed
- HandleWidgetComplete: method on Handler, handles "doot" natively
- HandleUnifiedAdd: "doot" source creates in native_tasks
- widget: "doot" tasks are completable, teal color indicator

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat: unify Google Tasks with main system via caching and integrated UI</title>
<updated>2026-03-23T08:13:02+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-03-23T08:13:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/doot.git/commit/?id=b2d8fc460be3105ac383098e7cdc92171e5026ec'/>
<id>urn:sha1:b2d8fc460be3105ac383098e7cdc92171e5026ec</id>
<content type='text'>
- 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
</content>
</entry>
<entry>
<title>fix: parse Todoist local datetimes, show near-future tasks, add undated tasks to timeline</title>
<updated>2026-03-23T00:42:44+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-03-23T00:42:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/doot.git/commit/?id=6c767194d9470b368f8d337e0719795f235f683c'/>
<id>urn:sha1:6c767194d9470b368f8d337e0719795f235f683c</id>
<content type='text'>
- parseDueDate: handle date field containing "YYYY-MM-DDTHH:MM:SS" (local time,
  no tz offset) — Todoist REST API v1 uses this format for recurring tasks with
  a set time, causing due dates to silently parse as nil
- IsFuture threshold: widen from tomorrow to 7 days out so tasks due this week
  show in the main tasks section with dates visible (not collapsed)
- BuildTimeline: include undated Todoist tasks in the Today section (mirrors
  existing Google Tasks behavior)
- GetUndatedTasks: new store method for tasks with due_date IS NULL

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>refactor: RF-03/06 extract groupMeals helper, eliminate convertSyncItemToTask wrapper</title>
<updated>2026-03-18T10:04:57+00:00</updated>
<author>
<name>Claude</name>
<email>agent@claude.ai</email>
</author>
<published>2026-03-18T10:04:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/doot.git/commit/?id=e85b42d373de55781af9d699b246c0d6a492aec1'/>
<id>urn:sha1:e85b42d373de55781af9d699b246c0d6a492aec1</id>
<content type='text'>
RF-03: Extract shared groupMeals helper into internal/handlers/meals.go.
Both HandleTabMeals and BuildTimeline now call groupMeals instead of
duplicating the date+mealType grouping algorithm inline. CombinedMeal
gains ID and Meals fields to carry the first-meal ID and original records
needed by BuildTimeline when constructing TimelineItems.

RF-06: Add api.ConvertSyncItemToTask for single-item conversion.
ConvertSyncItemsToTasks now delegates to it, eliminating duplication.
The Handler.convertSyncItemToTask wrapper (which allocated a one-element
slice just to unwrap it) is deleted; its caller uses api.ConvertSyncItemToTask
directly. Covered by TestConvertSyncItemToTask in internal/api/todoist_test.go.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Add calendar cache layer, incremental sync tests, completion assertions</title>
<updated>2026-02-18T00:43:42+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-02-18T00:43:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/doot.git/commit/?id=ec7d895c00c571b37ad9255b99b2e1756776c9e1'/>
<id>urn:sha1:ec7d895c00c571b37ad9255b99b2e1756776c9e1</id>
<content type='text'>
- Google Calendar events now cached via CacheFetcher pattern with
  stale-cache fallback on API errors (new migration 015, store methods,
  fetchCalendarEvents handler, BuildTimeline reads from store)
- Todoist incremental sync path covered by 5 new tests
- Task completion tests assert response body, headers, and template data

Co-Authored-By: Claude Opus 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Fix timeline calendar view and shopping UI bugs (#56, #65-73)</title>
<updated>2026-02-01T07:23:56+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-02-01T07:23:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/doot.git/commit/?id=f9127d5272042f4980ece8b39a47613f95eeaf8e'/>
<id>urn:sha1:f9127d5272042f4980ece8b39a47613f95eeaf8e</id>
<content type='text'>
- #56: Add overflow-hidden to card/panel classes to prevent content overflow
- #65: Fix Google Tasks not showing by including tasks without due dates
- #66: Add no-cache headers to prevent stale template responses
- #67: Increase dropdown z-index to 100 for proper layering
- #69: Implement calendar-style Today section with hourly grid (6am-10pm),
       duration-based event heights, and compact overdue/all-day section
- #70: Only reset shopping-mode form on successful submission
- #71: Remove checkboxes from shopping tab (only show in shopping mode)
- #72: Add inline add-item input at end of each store section
- #73: Add Grouped/Flat view toggle for shopping list

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Add Google Tasks integration (#43)</title>
<updated>2026-01-27T06:55:50+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-01-27T06:55:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/doot.git/commit/?id=a3156a2f399ea03c645ee23b0099d9d722ce7e1e'/>
<id>urn:sha1:a3156a2f399ea03c645ee23b0099d9d722ce7e1e</id>
<content type='text'>
- New GoogleTasksClient for fetching and managing Google Tasks
- Tasks appear in Timeline view with yellow indicator dot
- Tap checkbox to complete/uncomplete tasks via Google API
- Shares credentials file with Google Calendar (GOOGLE_CREDENTIALS_FILE)
- Configure task list via GOOGLE_TASKS_LIST_ID env var (default: @default)
- Supports comma-separated list IDs for multiple lists

New files:
- internal/api/google_tasks.go - Google Tasks API client

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
