<feed xmlns='http://www.w3.org/2005/Atom'>
<title>doot.git/internal/store/native_tasks.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-12T07:40:30+00:00</updated>
<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>fix(widget): surface unmatched task IDs instead of silently no-opping</title>
<updated>2026-07-12T05:36:32+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-07-12T05:36:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/doot.git/commit/?id=9a87f9db5af943ea253b814d4196020341e3c2ba'/>
<id>urn:sha1:9a87f9db5af943ea253b814d4196020341e3c2ba</id>
<content type='text'>
CompleteNativeTask/UncompleteNativeTask/RescheduleNativeTask ran a plain
UPDATE ... WHERE id = ? and returned whatever error Exec gave back --
which is nil even when 0 rows match, since that's not a SQL error. A
stale or wrong id from the widget looked identical to a real completion:
HTTP 200, nothing changed in the database. Real incident: 1 of 3 widget
completeTask taps silently no-opped this way.

Now checks RowsAffected() and returns ErrNativeTaskNotFound (mirrors the
existing pattern in sqlite.go's ApproveAgentSession/DenyAgentSession).
HandleWidgetComplete and HandleWidgetReschedule surface this as 404
instead of a fake 200, so the widget can tell 'nothing changed' apart
from 'it worked.'
</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: reschedule tasks from widget bottom sheet</title>
<updated>2026-06-29T09:31:37+00:00</updated>
<author>
<name>Peter Stone</name>
<email>thepeterstone@gmail.com</email>
</author>
<published>2026-06-29T09:31:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.terst.org/doot.git/commit/?id=e7aee6b9d0c2be22530f7813bf677c0c8bff99e4'/>
<id>urn:sha1:e7aee6b9d0c2be22530f7813bf677c0c8bff99e4</id>
<content type='text'>
Tapping a doot task shows a date picker. On confirm, POSTs to
/api/widget/reschedule, updates due_date in native_tasks, refreshes
widget. Reschedule button only shows for source="doot" tasks.

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>
</feed>
