| Age | Commit message (Collapse) | Author |
|
Three .Do() calls in google_calendar.go accepted a ctx parameter but
never chained .Context(ctx) into the actual SDK call, so the existing
global 60s request timeout never reached the blocking network call.
One hung Google Calendar request wedged every DB/session-touching
request path in production for three days (2026-08-01 through
2026-08-04), undetected because /health unconditionally returned 200
throughout.
- Wire .Context(ctx) into GetUpcomingEvents, GetEventsByDateRange, and
GetCalendarList.
- Bound aggregateData's four external fetches with a per-fetch
sub-context as defense-in-depth (only effective if the callee
actually honors ctx -- documented as such, not oversold).
- Make GetUpcomingEvents/GetEventsByDateRange fetch calendars
concurrently instead of sequentially: a review of this fix caught
that a shared per-fetch deadline over a sequential loop would starve
calendars past the first under any real latency, silently caching
partial results as complete. Concurrent fetches give every calendar
an equal shot at the same deadline instead.
- /health now does a real PingContext DB check instead of a static
"ok" (Handler.PingDB, tested for both healthy and closed-DB cases).
- Add internal/api/context_audit_test.go: an AST-based structural
guard that fails any future .Do() call in google_*.go missing
.Context(...) anywhere in its chain, so this class of bug can't
silently recur. Verified by deliberately reintroducing the original
bug against a backup and confirming the guard catches it.
- Add scripts/health-watchdog.sh: cron job restarts the service if
/health fails twice in a row, five minutes apart.
go test ./... -race is green. Deployed and live-verified.
|
|
The flat Tasks-tab atom list was silently dumping every chain step
(locked and unlocked) and dormant bucket-pool items in as ordinary
undated cards, with no chain/project context and no protection against
completing a locked step out of order.
- CompleteNativeTask now rejects completing a locked chain task
(ErrChainTaskLocked), mapped to 400 in both the widget and web
complete-atom handlers.
- Chain tasks and dormant bucket items are excluded from the flat atom
list; a new "Chains" section shows one card per active/paused chain
with the current step and N/M progress.
- New chain checklist modal (GET /chains/{id}) lists every position in
order with pause/resume/abandon -- the web view originally deferred
as Android-only.
- Fixed a real bug this surfaced: resuming a paused chain only flipped
the status flag, never unlocking the deferred successor, so a chain
paused right after a completion stayed stuck forever. SetChainStatus
now catches up the deferred advancement on resume, idempotently.
- Atom cards gained a project-name chip for general visibility.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
|
|
Backend, web timeline, and Android widget wiring for the last two
unimplemented items from doot-future-task-scheduling-ideas.
Chains: task_chains table + chain_id/chain_position/chain_unlocked on
native_tasks (migration 026), WIP-limit-1 advancement hooked into
CompleteNativeTask, locked tasks excluded from all date-based queries,
5 new /api/widget/chains* endpoints, an N/M position badge on web and
Android widget rows.
Buckets: maintenance_buckets table + bucket_id/bucket_state/
bucket_last_active_at on native_tasks (migration 027),
staleness-then-priority selection scoring, a new RunBucketCycleCheck
scheduler loop, 5 new endpoints including the distinct Defer action, a
Defer button on web and Android widget rows.
Also corrected stale "not yet approved" status headers on the two
already-shipped specs this work depended on (labels/projects, budgets/
availability) -- their headers were never updated after implementation.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
|
|
TimelineItemView wraps a TimelineItem with a per-render-day
MultiDayVariant (starts/ends/spans/none). HandleTimeline's bucketing now
places a multi-day event into both TodayItems and TomorrowItems when it
touches both, instead of only the list matching its start day.
|
|
Another session pushed 27 commits in parallel covering quick-add, event
detail popups, recurrence display, overdue badges, a manual refresh button,
and its own fix for the same overdue-tasks bug (via a separate
GetOverdueNativeTasks fetch folded into BuildTimeline, rather than widening
GetNativeTasksByDateRange's bound directly). Reconciled rather than blindly
taking one side:
- Reverted GetNativeTasksByDateRange to its original bounded query and kept
upstream's GetOverdueNativeTasks + BuildTimeline fold-in as the sole
overdue mechanism for native tasks, to avoid double-counting overdue
items (my widened query + their separate fetch would have both returned
them). Re-pointed the regression test at the now-correct contract and
added a store-level test for GetOverdueNativeTasks directly.
- Kept my GetGoogleTasksByDateRange fix as-is (single unbounded query) --
upstream never touched Google Tasks overdue handling, so there's no
duplication risk there.
- Rewove WidgetRoot's LazyColumn structure (added for scrolling) around
upstream's new header buttons, pinned all-day event rows, and the
enhanced TomorrowSection, none of which were written LazyColumn-aware
since that work landed on this side only.
- Combined both sides' additions to TaskDetailActivity/TaskDetailSheet
(description-edit detail popup + due-date reschedule label) and
WidgetRepository/Actions (optimistic local removal + refresh button
wiring) -- these were independent, non-overlapping features that both
needed to survive.
- Renumbered the migration collision: both sides independently added a
migration numbered 022. Card-description was already applied to the live
production DB under that filename earlier this session (migrations are
tracked by filename), so it keeps 022; the recurring-event-id migration,
never deployed under any name here, moves to 023.
Verified: go build clean, full test suite passes (only the two
pre-existing agent-handler failures and the pre-existing models package
build error remain, both confirmed unrelated via git stash before this
session began), and a dry run against a copy of the live production
database applies both migrations cleanly with no re-run conflicts.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
|
|
- Add description editing to the widget's task detail popup for
doot/gtasks/trello, backed by new GET /api/widget/detail and
POST /api/widget/update endpoints
- Make Google Tasks and Trello cards completable via the widget (Trello
completion archives the card); fix Trello description never being
fetched, which meant saving could silently wipe a card's real desc
- Fix google_tasks.due_date/updated_at (TEXT columns) never round-tripping
through sql.NullTime, which broke cached Google Tasks reads whenever
the cache was valid
- Fix native-task and Google-Task date-range queries excluding anything
due before the window start, which dropped incomplete tasks off the
widget the moment their due day passed (the "overdue tasks disappeared"
bug)
- Fix native task description edits blanking the task's title
- Make the widget's day list scroll (LazyColumn) instead of clipping
- Optimistically remove a task from the widget immediately on completion,
ahead of the authoritative background refresh
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
|
|
fetchCalendarEvents falls back to config.GoogleCalendarID whenever no
source_configs rows exist yet for the gcal source -- which is the
current live state (0 rows). GoogleCalendarID is a single env var that
itself holds a comma-separated list of calendar IDs, but the whole
joined string was being wrapped in a single-element []string{...} and
passed straight to SetCalendarIDs. Google's API takes one calendarId per
call, so every fetch failed with '404 Not Found' on the literal
comma-joined string -- confirmed live in production logs. This broke all
calendar events, in both the web dashboard and the widget, silently.
Now splits on commas and trims whitespace before use.
|
|
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>
|
|
Bug 1: BuildUnifiedAtomList never called GetNativeTasks(), so doot-sourced
tasks were absent from the web Tasks tab. Added GetNativeTasks() fetch and
NativeTaskToAtom conversion (new model helper, SourceDoot constant).
Bug 2: handleAtomToggle called getAtomDetails after CompleteNativeTask, but
GetNativeTasks filters WHERE completed=0, so the task was already gone and
the title came back blank. Moved getAtomDetails call to before the completion
switch so all sources (including doot) capture title/dueDate first.
Also fixed widget_test.go compile error: TestHandleWidgetComplete_NonTodoist
called HandleWidgetComplete as a package-level function but it is a method on
*Handler. Rewrote the file as package handlers (internal) and construct
&Handler{} directly.
Regression tests added for both bugs in atoms_test.go and handlers_test.go.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Calendar: fall back to GOOGLE_CALENDAR_ID config when no source_configs
synced yet (fixes blank calendar after fresh deploy)
- Meals: call fetchMeals in HandleTimeline so PlanToEat cache refreshes
on every timeline load, not just during manual refresh
- Tomorrow section: replace calendar-grid with flat chronological list
matching widget layout (time label | source bar | title)
- Add /health endpoint (no auth required) for deploy health checks
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
TODOIST_API_KEY is no longer required — native task management works
without it. Guards nil todoistClient in handleAtomToggle.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
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 <noreply@anthropic.com>
|
|
Adds GET /task?id=xxx&source=xxx route that renders a full mobile-friendly
task detail page (session-protected). Widget task rows now open this page
when tapped. HandleUpdateTask redirects back to the page after a non-HTMX
save. Android: threads serverUrl through composable chain to TaskRow.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Server seeds bg URL from a 5-minute time bucket so all open sessions
show the same image simultaneously. Client-side JS rotates in sync and
prefetches the next image on the same interval.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Update Google API interfaces with setters for list/calendar IDs
- Update fetchCalendarEvents and fetchGoogleTasks to use enabled IDs from source_configs
- Update timeline logic tests to reflect interface changes and seed config data
- Ensure dashboard respects user-selected lists from settings
|
|
- 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
|
|
|
|
- Delete Bug struct, BugToAtom, SourceBug, TypeBug, TypeNote
- Remove bug store methods (SaveBug, GetBugs, ResolveBug, etc.)
- Remove HandleGetBugs, HandleReportBug, bug branches in handlers
- Remove bug routes, bugs.html template, bug UI from index.html
- Remove AddMealToPlanner stub + interface method
- Migration 018: DROP TABLE IF EXISTS bugs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
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>
|
|
convertSyncItemToTask wrapper
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 <noreply@anthropic.com>
|
|
|
|
- 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>
|
|
- 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 <noreply@anthropic.com>
|
|
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>
|
|
- Display build commit hash in unobtrusive footer overlay
- Inject buildCommit/buildTime via ldflags in deploy.sh
- Add assertTemplateContains test helper, refactor existing template tests
- Add scripts/logs for fetching production journalctl via SSH
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
Moved 8 shopping-related handlers from handlers.go to shopping.go:
- HandleTabShopping
- HandleShoppingQuickAdd
- HandleShoppingToggle
- HandleShoppingMode
- HandleShoppingModeToggle
- HandleShoppingModeComplete
- HandleGetShoppingLists
- aggregateShoppingLists
handlers.go: 1633 → 1232 lines (24% reduction)
shopping.go: 415 lines (new)
All tests passing. No behavioral changes.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
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>
|
|
Shopping mode:
- Click to complete items (deletes user items, hides external items)
- Add print button with compact two-column print layout
- Fix CSRF token for HTMX requests
- Fix input clearing with proper htmx:afterRequest handler
- Remove "Quick Add" store option, require valid store
Navigation:
- Replace dropdown menu with flat nav showing all tabs
- Remove unused dropdown JS
Tests:
- Add TestHandleShoppingModeComplete for user and external items
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
- Add dynamic calendar clipping: show 1 hour before/after events instead of hardcoded 6am-10pm
- Add "NOW" line indicator showing current time position
- Improve time label readability with larger font and better contrast
- Add overlap detection with column-based indentation for concurrent events
- Apply calendar view to Tomorrow section (matching Today's layout)
- Fix auto-refresh switching to tasks tab (default was 'tasks' instead of 'timeline')
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
- #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 <noreply@anthropic.com>
|
|
- Add completed_tasks table to log task completions with title, due date,
and completion timestamp
- Extend agent context date range: 7 days back to 14 days forward
- Add completed_log to API response (last 50 completed tasks)
- Add day_section field to timeline items (overdue/today/tomorrow/later)
- Add calendar-style view for today's schedule (6am-10pm hourly grid)
- Add tabbed interface for Timeline vs Completed Log in HTML view
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
Bug fixes:
- #62: Increase FAB button z-index from z-40 to z-50
- #63: Combine multiple meals per date+mealType in Meals tab
- #64: Make /conditions route public (no auth required)
Changes:
- FAB button now z-50 (same as modals, appears on top when scrolling)
- Meals tab groups meals by date+mealType, joins recipe names with " + "
- Conditions page moved outside protected routes group
DESIGN.md updates:
- Updated z-index hierarchy table
- Added Meals View section
- Noted conditions page is public
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
The template was being called with define name "shopping-mode" but
standalone page templates should be called by filename "shopping-mode.html".
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
- 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 <noreply@anthropic.com>
|
|
- Full-screen view for one store at a time
- Tap items to toggle completion
- Completed items greyed and sorted to bottom
- Quick-add form at bottom of screen
- Store switcher pills for easy navigation
- "Shop" button on each store in shopping tab
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
- #54: Fix shopping item completion - now works for all sources
(trello, plantoeat, user) with state stored in local DB
- #48: Hide 12:00am times in timeline (all-day items)
- #49: Remove "Task" type label from timeline items for cleaner UI
- #51: Combine multiple PlanToEat meals for same date+mealType
- #52: Change Conditions tab to standard link to standalone page
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
- Add config/timezone.go with timezone utilities:
- SetDisplayTimezone(), GetDisplayTimezone()
- Now(), Today() - current time/date in display TZ
- ParseDateInDisplayTZ(), ToDisplayTZ() - parsing helpers
- Initialize timezone at startup in main.go
- Update all datetime logic to use configured timezone:
- handlers/handlers.go - all time.Now() calls
- handlers/timeline.go - date parsing
- handlers/timeline_logic.go - now calculation
- models/atom.go - ComputeUIFields()
- models/timeline.go - ComputeDaySection()
- api/plantoeat.go - meal date parsing
- api/todoist.go - due date parsing
- api/trello.go - due date parsing
This ensures all dates/times display correctly regardless
of server timezone setting.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
- Create atoms.go with BuildUnifiedAtomList, SortAtomsByUrgency, PartitionAtomsByTime
- Create helpers.go with parseFormOr400, requireFormValue
- Refactor HandleTabTasks from 95 lines to 25 lines using extracted functions
- Remove duplicate atomUrgencyTier function
- Update handlers to use parseFormOr400 helper
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
- Remove default password fallback - require DEFAULT_PASS in all environments
- Fix XSS vulnerabilities in HTML generation (handlers.go:795,920)
- Add security headers middleware (X-Frame-Options, CSP, HSTS, etc.)
- Add rate limiting on login endpoint (5 req/15min per IP)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
- Fix errcheck: handle all error return values in production code
- Fix errcheck: handle all error return values in test files
- Fix staticcheck: replace deprecated WithCredentialsFile with WithAuthCredentialsFile
- Remove unused code: authHeaders, planToEatPlannerItem, planToEatResponse
- Use defer func() { _ = x.Close() }() pattern for ignored close errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
- Extract parseEventTime() and deduplicateEvents() in google_calendar.go
- Add scanTask() and scanTasks() SQL helpers in sqlite.go
- Move completed-atom HTML to partial template
- Add loadTestTemplates() test helper for template-dependent tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
Phase 1: Bugs as First-Class Atoms (#28)
- Add resolved_at column to bugs table (migration 007)
- Add GetUnresolvedBugs(), ResolveBug(), UnresolveBug() store methods
- Include bugs in Tasks tab via BugToAtom() with completion toggle
- Add unit tests for bug resolution
Phase 2: Timeline as Default + Enhancements (#35, #37)
- Change default tab from tasks to timeline
- Add IsCompleted, DaySection, Source fields to TimelineItem
- Group timeline items by today/tomorrow/later sections
- Add completion checkboxes for tasks/cards, grey completed items
- Collapse tomorrow/later sections by default
Phase 3: Shopping Quick-Add (#33)
- Add user_shopping_items table (migration 008)
- Add SaveUserShoppingItem(), GetUserShoppingItems(), ToggleUserShoppingItem()
- Add HandleShoppingQuickAdd() and HandleShoppingToggle() handlers
- Add quick-add form to shopping tab
Phase 4: Mobile Swipe Navigation (#38)
- Add touch event handlers for swipe left/right tab switching
- 50px threshold triggers tab change
Phase 5: Consistent Background Opacity (#30)
- Add CSS variables for panel/card/input/modal backgrounds
- Update templates to use consistent opacity classes
Phase 6: Tab Reorganization (#37)
- Reorganize tabs: Timeline, Shopping, Conditions as main tabs
- Move Tasks, Planning, Meals under Details dropdown
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
Bug fixes:
- #36: Hide recurring tasks until due day (add IsRecurring to Task/Atom)
- Trello cards missing: change filter=visible to filter=open
- Build fix: add missing fmt import in atom.go
Infrastructure:
- Add scripts/bugs and scripts/resolve-bug for DB bug tracking
- Remove issues/ directory (bugs now tracked in DB)
- Add timeline_logic_test.go
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
- Standalone full-screen page at /conditions
- Tiled grid layout with autoplaying video feeds
- USGS Kilauea webcams (V1cam, V2cam) via YouTube embeds
- Windy weather maps (local Hawaii + national US)
- Opens in new tab from dashboard nav
Closes #29
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
Bug fixes:
- #25: Replace 📅 with 🗓️ to avoid misleading date display
- #30: Standardize background opacity (shopping items now use bg-white/5)
New feature:
- #11: Add Timeline view showing chronological events/tasks/meals
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
- New Shopping tab aggregates items from Trello Shopping board and PlanToEat
- Items grouped by store, then by category (for PlanToEat)
- Trello list names treated as store names
- Replace PlanToEat meals API with web scraping (uses session cookie)
- Add error logging for PlanToEat fetch operations
- Recipe links now point to cooking view (/recipes/{id}/cook/{event_id})
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
The uncomplete response was returning an empty body, causing HTMX to
swap the element with nothing before the refresh-tasks trigger fired.
Added HX-Reswap: none header to preserve the element while the refresh
event propagates.
Also fixed TestGetCardsByDateRange test data to include all required
columns (list_id, list_name, url).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
- Add BaseClient HTTP abstraction (internal/api/http.go) to eliminate
duplicated HTTP boilerplate across Todoist, Trello, and PlanToEat clients
- Add response helpers (internal/handlers/response.go) for JSON/HTML responses
- Add generic cache wrapper (internal/handlers/cache.go) using Go generics
- Consolidate HandleCompleteAtom/HandleUncompleteAtom into handleAtomToggle
- Merge TabsHandler into Handler, delete tabs.go
- Extract sortTasksByUrgency and filterAndSortTrelloTasks helpers
- Update tests to work with new BaseClient structure
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
|
Bug fixes:
- #24: Deduplicate calendar events across multiple calendars using
summary + start time as key
- #25: Change event icon from calendar to clock to avoid confusion
with date display
- #26: Add task uncomplete functionality via ReopenTask API for
Todoist and closed=false for Trello
- #27: Restructure planning view with sections for Scheduled (timed
events/tasks), Today (unscheduled), Quick Add, and Upcoming (3 days)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|