summaryrefslogtreecommitdiff
path: root/internal/handlers/settings.go
AgeCommit message (Collapse)Author
2026-08-16Replace Google Tasks service-account auth with real OAuthPeter Stone
Service-account auth structurally cannot see a regular user's personal task lists (no equivalent of Calendar's per-item sharing model) -- confirmed via GetTaskLists returning exactly the service account's own empty "My Tasks" list, never the real user's three lists. Zero rows were ever cached in production as a result. Adds a standard 3-legged OAuth flow: /settings/google-tasks/connect redirects to Google's consent screen (AccessTypeOffline+ApprovalForce so a refresh_token is always issued), /callback exchanges the code and persists the token (new oauth_tokens table), /disconnect clears it. GoogleTasksClient now takes an option.ClientOption instead of a credentials file path; NewGoogleTasksOAuthClient wraps it with a dbTokenSource that reloads/refreshes from the DB on each access-token expiry and re-persists -- carefully preserving the original refresh_token when Google's refresh response omits one (it usually does), which would otherwise silently and permanently break future refreshes. Settings page shows connection status and a Connect/Disconnect button. Calendar keeps using service-account auth (that one actually works). Requires a one-time manual step: create an OAuth 2.0 Client ID in Google Cloud Console and set GOOGLE_OAUTH_CLIENT_ID/SECRET in .env -- documented in .env.example.
2026-08-07Wire the Tasks tab into nav; fold in buckets/projects/labels and recurrencePeter Stone
The Tasks tab (/tabs/tasks) existed server-side and was tested, but nothing in the nav linked to it -- it was pure dead weight in the other direction. Wiring it up as the natural home for everything that was either misplaced in Settings or missing a web UI entirely: - Maintenance Buckets, Projects, and Labels moved out of Settings and into the Tasks tab (restyled from Settings' opaque slate cards to the glass/backdrop-blur look already used by the tab's chain/atom cards -- they're now embedded in index.html's page shell, not a standalone page, so the shared bg-card/bg-input classes from that shell apply). Settings keeps only what's actually settings: Passkeys, Trusted Agents, Data Sources. - Added a Recurrence section to the task-detail modal (freq/interval/ weekday form, posting to a new POST /tasks/recurrence -- the HTMX counterpart to the widget API's HandleWidgetTaskRecurrence). Native task recurrence previously had zero web UI at all, only reachable via the Android widget's RecurrenceEditDialog. Also fixed a real bug found while touching this code: HandleGetTaskDetail's source switch only had a case for "trello" -- opening any native ("doot") task's detail modal, which is most tasks in this tab, showed a blank title and description. Factored both call sites (initial GET and the re-render after a recurrence edit) through one loadTaskDetailData helper and added the missing "doot" case. Also fixed task-detail.html's styling, which was still using pre-dark-theme classes (text-gray-900 etc.) -- functionally invisible text on the modal's dark background. Verified with a throwaway local server (real templates + real DB, not the MockRenderer the unit tests use) seeded with a recurring task, a bucket, a project, and a label -- confirmed all five touched routes render 200 with the expected content, including the populated Buckets/Projects/Labels sections and a real weekly-recurrence form with the correct weekdays pre-checked. Caught and fixed a copy bug this way too ("every 2 weeklys" -> "every 2 weeks"). Not committed; deleted after use. go build ./..., go vet ./..., and go test ./... all clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
2026-08-06Remove the feature toggle system (dead code)Peter Stone
Audited it (couldn't query the live DB directly -- auto-mode classifier blocks direct production reads without prior approval -- so this is a code-only audit): GetFeatureToggles/SetFeatureEnabled/IsFeatureEnabled/ CreateFeatureToggle/DeleteFeatureToggle had exactly one caller each, all inside their own CRUD handlers. Nothing anywhere else in the codebase read a toggle's Enabled state to gate any actual behavior -- confirmed by grepping every remaining .Enabled/IsFeatureEnabled reference back to either this dead code or its own tests. It was pure UI-managed CRUD with no consumer, unlike Trusted Agents (wired into agent.go/websocket.go) or Data Sources (wired into the sync pipeline) which stayed. Removes the Settings page section, the three /settings/features* routes and handlers, the five Store methods, the FeatureToggle model, and adds 028_drop_feature_toggles.sql (next free migration number, per this repo's convention of never renumbering -- see 021_drop_tasks.sql for the same drop-table-forward pattern) to drop the now-unused table. Also removed the now-dead tests for all of the above. go build ./... and go test ./... both clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
2026-07-18Add bucket CRUD and read-only Projects/Labels to Settings pagePeter Stone
New "Maintenance Buckets" section: create a bucket, add a pool item by title (creates the task and assigns it in one step), remove an item, delete a bucket (unbuckets its tasks rather than deleting them). New read-only Projects and Labels sections (name + color swatch) -- both are simple enough that read-only is the right call on web, per user direction, rather than duplicating the Android popup's editing UX. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
2026-07-16chore: remove dead code (unused atom constants, orphaned handler)Peter Stone
- SourceMeal/TypeMeal (AtomSource/AtomType): leftover from the removed MealToAtom conversion (b2d8fc4); zero references anywhere else. - HandleGetSourceOptions: never registered as a route, and its own test comment already noted "may fail if template not found, which is acceptable" -- the settings-source-options template it rendered doesn't exist in web/templates/ at all. Fully unreachable/broken, not just unused. go build/vet/test all clean, no behavior change for anything reachable. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
2026-07-06feat: remove Todoist integration entirelyDoot Agent
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 <noreply@anthropic.com>
2026-03-23feat: complete Agent Context API Phase 2 & 3 (Write/Create/Management)Peter Stone
- Implement write operations (complete, uncomplete, update due date, update task) - Implement create operations (create task, add shopping item) - Add Trusted Agents management UI in Settings with revocation support - Fix SQLite timestamp scanning bug for completed tasks - Add comprehensive unit tests for all new agent endpoints - Update worklog and feature documentation
2026-03-19refactor: RF-04/08 migrate inline HTML to templates, standardize form parsingClaude Agent
RF-04: Already complete in codebase (handlers use HTMLResponse + partials). RF-08: Migrate single-required-field handlers from Pattern A/B to Pattern C (requireFormValue). Affected: HandleCompleteTask, HandleCompleteCard, HandleReportBug, HandleCreateTask in handlers.go; HandleToggleFeature, HandleCreateFeature in settings.go. Reduces 6-8 lines of boilerplate to 2. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04feat: sync log, cache clear endpoint, Todoist projects from cached tasksPeter Stone
- migration 016: sync_log table - store: AddSyncLogEntry, GetRecentSyncLog, InvalidateAllCaches, GetProjectsFromTasks - settings: HandleClearCache (POST /settings/clear-cache), SyncLog in page data - settings: use GetProjectsFromTasks instead of deprecated Todoist REST /projects - handlers: populate atom projects from store - agent: log warning on registration failure instead of silently swallowing - google_tasks: simplify URL literal - tests: sync log CRUD, clear cache handler, settings page includes sync log, sync sources adds log entry, incremental sync paths, task completion response/headers, calendar cache fallback Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-07Fix passkey registration showing broken UI when WebAuthn not configuredPeter Stone
Root cause: WEBAUTHN_RP_ID and WEBAUTHN_ORIGIN env vars not set in production, so WebAuthn is nil and all passkey endpoints return 404. The settings page was unconditionally showing the passkey registration card, leading to confusing "Failed to start registration" errors. Fix: Pass WebAuthnEnabled flag from main.go through Handler to the settings template, which now conditionally renders the passkey card only when WebAuthn is properly configured. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07Fix timeline task completion replacing view, fix passkey registration CSRFPeter Stone
- Fix checkboxes in timeline calendar grid targeting #tab-content (replaced entire view). Now target closest .untimed-item/.calendar-event with outerHTML - Fix passkey registration 403 by passing CSRFToken from settings handler and exposing it via meta tag for JS to read - Add TDD workflow requirement to CLAUDE.md - Tests written first (red-green): template content assertions for checkbox targets and CSRF token presence, handler data struct verification Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-03Refactor template rendering with Renderer interface for testabilityPeter Stone
Introduce a Renderer interface to abstract template rendering, enabling tests to use MockRenderer instead of requiring real template files. Changes: - Add renderer.go with Renderer interface, TemplateRenderer, and MockRenderer - Update Handler struct to use Renderer instead of *template.Template - Update HTMLResponse() to accept Renderer interface - Replace all h.templates.ExecuteTemplate() calls with h.renderer.Render() - Update all tests to use MockRenderer, removing template file dependencies This eliminates 15+ tests that previously skipped with "Templates not available" and improves test isolation. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31Add feature toggles system with settings UI (#74)Peter Stone
- Add feature_toggles table (migration 012) - Add source_config table for future source selection (migration 013) - Create settings page at /settings with: - Feature toggle management (enable/disable/create/delete) - Data source configuration (sync and toggle boards/calendars) - Add store methods for feature toggles and source config - Add GetCalendarList and GetTaskLists to Google API clients - Document feature toggle workflow in DESIGN.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>