diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-01-22 11:15:08 -1000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-01-22 11:15:08 -1000 |
| commit | b41d38e0161d49fac23c1d552622e7b8310b1c68 (patch) | |
| tree | cef7af2b1b0a5586082121965639ae947c7b54ad /issues | |
| parent | 7fd381a242f68b7c6f10db4e3ae0bb3d06e36a16 (diff) | |
Add deploy script and remove resolved issues
- Add deployment/deploy script for server-side deploys
- Remove 10 completed issue files (001-016 batch)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'issues')
| -rw-r--r-- | issues/001-hide-future-tasks-behind-fold.md | 51 | ||||
| -rw-r--r-- | issues/002-modal-menu-quick-add-bug-report.md | 47 | ||||
| -rw-r--r-- | issues/003-fix-tap-to-expand.md | 48 | ||||
| -rw-r--r-- | issues/005-visual-task-timing-differentiation.md | 61 | ||||
| -rw-r--r-- | issues/006-reorder-tasks-by-urgency.md | 63 | ||||
| -rw-r--r-- | issues/007-fix-outdated-todoist-link.md | 54 | ||||
| -rw-r--r-- | issues/009-keep-completed-tasks-visible.md | 54 | ||||
| -rw-r--r-- | issues/010-fix-quick-add-timestamp.md | 76 | ||||
| -rw-r--r-- | issues/015-random-landscape-background.md | 77 | ||||
| -rw-r--r-- | issues/016-click-task-edit-details.md | 80 |
10 files changed, 0 insertions, 611 deletions
diff --git a/issues/001-hide-future-tasks-behind-fold.md b/issues/001-hide-future-tasks-behind-fold.md deleted file mode 100644 index f6012fe..0000000 --- a/issues/001-hide-future-tasks-behind-fold.md +++ /dev/null @@ -1,51 +0,0 @@ -# [FEATURE] Hide future tasks behind a fold - -## Description -Hide tasks more than 3-7 days out behind a fold. - -## User Story -As a user, I want tasks more than N days out hidden by default so that I can focus on immediate priorities. - -## Technical Context -- Affects: `internal/handlers/handlers.go` (task filtering), `web/templates/partials/todoist-tasks.html` or `tasks-tab.html` -- Data already has `due_date`; filtering is a presentation concern - -## Test Strategy - -### Unit Test (Red) -**File:** `internal/handlers/handlers_test.go` - -Test a new filter function `FilterTasksByHorizon(tasks []Task, days int)` returns only tasks within range. - -```go -func TestFilterTasksByHorizon(t *testing.T) { - // Given tasks with varying due dates - // When filtered with horizon of 7 days - // Then only tasks within 7 days are in "visible" slice - // And remaining tasks are in "deferred" slice -} -``` - -### E2E Test (Red) -Verify collapsed section renders with count badge; click expands to show deferred tasks. - -## Proposed Approach - -1. Add config param `task_horizon_days` (default 7) -2. Partition tasks in handler into "visible" vs "deferred" -3. Render deferred in a collapsible `<details>` element with HTMX swap -4. Show count badge on collapsed header (e.g., "+12 later") - -## Affected Components -- `internal/handlers/handlers.go` -- `internal/config/config.go` -- `web/templates/partials/todoist-tasks.html` -- `web/templates/partials/tasks-tab.html` - -## Definition of Done -- [ ] Tasks beyond horizon hidden by default -- [ ] Collapsible UI shows count of hidden tasks -- [ ] Click to expand shows all deferred tasks -- [ ] Horizon days configurable -- [ ] Unit tests pass -- [ ] E2E test confirms behavior diff --git a/issues/002-modal-menu-quick-add-bug-report.md b/issues/002-modal-menu-quick-add-bug-report.md deleted file mode 100644 index b518cf3..0000000 --- a/issues/002-modal-menu-quick-add-bug-report.md +++ /dev/null @@ -1,47 +0,0 @@ -# [FEATURE] Quick add & bug report in modal menu - -## Description -Put quick add (rename "add" to "quick add") and bug report in a unified modal menu. - -## User Story -As a user, I want quick-add and bug-report behind a unified modal so the UI is cleaner. - -## Technical Context -- Affects: `web/templates/index.html` (modal container), new partial `partials/modal-menu.html` -- Existing handlers for quick-add and bug already exist; this is UI consolidation -- Note: Issue #14 is a duplicate of this - -## Test Strategy - -### E2E/Integration Test (Red) -Test modal opens on trigger, contains both forms, submits correctly. - -``` -1. Click menu trigger -> modal opens -2. Assert "Add Task" and "Report Bug" tabs/options visible -3. Fill quick-add form -> submit -> task created -4. Switch to bug tab -> fill -> submit -> bug created -5. Modal closes after successful submit -``` - -## Proposed Approach - -1. Create shared modal partial with tab/toggle between "Add Task" and "Report Bug" -2. Use HTMX `hx-get` to lazy-load modal content -3. Add keyboard shortcut (e.g., `Cmd+K` or `Ctrl+K`) to invoke -4. Rename "Add" button to "Quick Add" throughout UI -5. Single FAB or menu button replaces separate add/bug buttons - -## Affected Components -- `web/templates/index.html` -- `web/templates/partials/modal-menu.html` (new) -- `web/static/` (JS for keyboard shortcut) -- Existing quick-add and bug handlers (no changes, just UI consolidation) - -## Definition of Done -- [ ] Single modal contains both forms -- [ ] Tab/toggle switches between quick-add and bug report -- [ ] Keyboard shortcut opens modal -- [ ] Both forms submit correctly -- [ ] Modal closes on successful submit -- [ ] Old separate UI elements removed diff --git a/issues/003-fix-tap-to-expand.md b/issues/003-fix-tap-to-expand.md deleted file mode 100644 index a1cfd8c..0000000 --- a/issues/003-fix-tap-to-expand.md +++ /dev/null @@ -1,48 +0,0 @@ -# [BUG] Tap to expand doesn't work - -## Description -Tap to expand doesn't work on task items. - -## Technical Context -- Likely a JS/HTMX event binding issue in task list items -- Affects: `partials/todoist-tasks.html` or `tasks-tab.html`, possibly JS in `web/static/` -- May be related to event delegation on dynamically-loaded content - -## Test Strategy - -### E2E Test (Red) -Playwright/browser test: click task row -> assert expanded content visible. - -``` -1. Load tasks page -2. Click on a task row -3. Assert expanded details section becomes visible -4. Assert expanded content contains expected task details -``` - -## Proposed Approach - -1. Inspect current expand trigger mechanism: - - Is it `hx-get` with `hx-trigger="click"`? - - Is it a JS click handler? - - Is it a `<details>` element? -2. Check for missing `hx-trigger` or event delegation issues on dynamically-loaded content -3. Ensure `htmx:afterSwap` rebinds event listeners if needed -4. Test on both desktop (click) and mobile (tap) - -## Debugging Steps -1. Open browser dev tools -> check for JS errors on click -2. Inspect element -> verify HTMX attributes present -3. Check Network tab -> see if request fires on click -4. If using JS handlers, verify they're attached after HTMX swaps - -## Affected Components -- `web/templates/partials/todoist-tasks.html` -- `web/templates/partials/tasks-tab.html` -- `web/static/` (if JS-based) - -## Definition of Done -- [ ] Clicking/tapping a task expands its details -- [ ] Works on desktop and mobile -- [ ] Works on initial load and after HTMX swaps -- [ ] E2E test confirms behavior diff --git a/issues/005-visual-task-timing-differentiation.md b/issues/005-visual-task-timing-differentiation.md deleted file mode 100644 index 4cc40b4..0000000 --- a/issues/005-visual-task-timing-differentiation.md +++ /dev/null @@ -1,61 +0,0 @@ -# [FEATURE] Visual differentiation for task timing - -## Description -Tasks after today should be grayed out, past deadline should be emphasized. - -## User Story -As a user, I want past-due tasks highlighted and future tasks dimmed so urgency is immediately visible. - -## Technical Context -- Pure presentation logic in template -- Affects: `partials/todoist-tasks.html`, `partials/tasks-tab.html` -- Requires comparing task `due_date` against current date - -## Test Strategy - -### Unit Test (Red) -**File:** `internal/handlers/handlers_test.go` - -Test helper function returns correct urgency class. - -```go -func TestTaskUrgencyClass(t *testing.T) { - tests := []struct { - name string - dueDate time.Time - expected string - }{ - {"overdue yesterday", yesterday, "overdue"}, - {"due today", today, "today"}, - {"due tomorrow", tomorrow, "future"}, - {"no due date", zeroTime, "none"}, - } - // ... -} -``` - -### E2E Test (Red) -Assert CSS classes applied correctly to tasks based on due date. - -## Proposed Approach - -1. Add template helper or compute urgency class in handler -2. Return struct with `UrgencyClass` field for each task -3. Apply Tailwind classes based on urgency: - - `text-red-600 font-bold` (overdue) - - `text-inherit` or default (today) - - `text-gray-400` (future) -4. Consider adding visual indicator icon (e.g., warning for overdue) - -## Affected Components -- `internal/handlers/handlers.go` -- `internal/models/types.go` (if adding field to view model) -- `web/templates/partials/todoist-tasks.html` -- `web/templates/partials/tasks-tab.html` - -## Definition of Done -- [ ] Overdue tasks visually emphasized (red/bold) -- [ ] Future tasks grayed out -- [ ] Today's tasks normal styling -- [ ] Unit tests for urgency calculation -- [ ] E2E test verifies correct classes applied diff --git a/issues/006-reorder-tasks-by-urgency.md b/issues/006-reorder-tasks-by-urgency.md deleted file mode 100644 index 8a5f968..0000000 --- a/issues/006-reorder-tasks-by-urgency.md +++ /dev/null @@ -1,63 +0,0 @@ -# [FEATURE] Reorder task list by urgency - -## Description -List past due tasks, then tasks with a specific time today, then 12am (all-day) tasks today, then future tasks. - -## User Story -As a user, I want tasks sorted by urgency tiers so I see what needs attention first. - -## Technical Context -- Affects: `internal/handlers/handlers.go` — sorting logic before template render -- Requires distinguishing "has specific time" vs "all-day" (midnight/00:00) -- Todoist API may return all-day tasks with time set to 00:00:00 - -## Test Strategy - -### Unit Test (Red) -**File:** `internal/handlers/handlers_test.go` - -```go -func TestSortTasksByUrgency(t *testing.T) { - tasks := []Task{ - {Name: "future", DueDate: tomorrow}, - {Name: "overdue", DueDate: yesterday}, - {Name: "today-timed", DueDate: todayAt(14, 30)}, - {Name: "today-allday", DueDate: todayAt(0, 0)}, - } - - sorted := SortTasksByUrgency(tasks) - - // Expected order: overdue, today-timed, today-allday, future - assert.Equal(t, "overdue", sorted[0].Name) - assert.Equal(t, "today-timed", sorted[1].Name) - assert.Equal(t, "today-allday", sorted[2].Name) - assert.Equal(t, "future", sorted[3].Name) -} -``` - -## Proposed Approach - -1. Define sort buckets with priority: - - Priority 0: Overdue (due_date < today) - - Priority 1: Today with specific time (due_date == today && time != 00:00) - - Priority 2: Today all-day (due_date == today && time == 00:00) - - Priority 3: Future (due_date > today) -2. Within each bucket, sort by due_date ascending -3. Implement stable sort to preserve original order within equal items - -## Traps to Avoid -- **Timezone handling:** Ensure consistent timezone (user's local or UTC?) for date comparisons -- **Null due dates:** Decide where tasks with no due date should appear (suggest: after future tasks) -- **All-day detection:** Todoist may use different conventions; verify API response format - -## Affected Components -- `internal/handlers/handlers.go` -- `internal/handlers/handlers_test.go` - -## Definition of Done -- [ ] Tasks sorted in specified order -- [ ] Overdue tasks appear first -- [ ] Timed tasks today before all-day tasks today -- [ ] Future tasks appear last -- [ ] Null due date tasks handled gracefully -- [ ] Unit tests cover all buckets and edge cases diff --git a/issues/007-fix-outdated-todoist-link.md b/issues/007-fix-outdated-todoist-link.md deleted file mode 100644 index 5d628f2..0000000 --- a/issues/007-fix-outdated-todoist-link.md +++ /dev/null @@ -1,54 +0,0 @@ -# [BUG] Fix outdated Todoist task link - -## Description -Fix outdated Todoist task link. - -## Technical Context -- Affects: `internal/api/todoist.go` (URL construction) or stored `url` field in DB -- Todoist may have changed their URL scheme -- Current URLs may be returning 404 or redirecting incorrectly - -## Test Strategy - -### Unit Test (Red) -**File:** `internal/api/todoist_test.go` - -```go -func TestBuildTaskURL(t *testing.T) { - taskID := "123456789" - url := BuildTaskURL(taskID) - - // Assert current Todoist URL format - // Option A: https://todoist.com/showTask?id=123456789 - // Option B: https://todoist.com/app/task/123456789 - assert.Equal(t, "https://todoist.com/app/task/123456789", url) -} -``` - -## Proposed Approach - -1. Research current Todoist web URL format: - - Check Todoist docs or inspect working links in browser - - Likely format: `https://todoist.com/app/task/{task_id}` or `https://todoist.com/showTask?id={task_id}` -2. Update URL builder in `internal/api/todoist.go` -3. Consider migration for existing cached URLs in database: - - Option A: Update on read (lazy migration) - - Option B: Run migration script to update all stored URLs -4. If URL comes from API response directly, verify we're using the correct field - -## Debugging Steps -1. Find a task ID in the database -2. Try current URL format in browser -3. Try alternative formats to find working one -4. Check Todoist API response for canonical URL field - -## Affected Components -- `internal/api/todoist.go` -- `internal/api/todoist_test.go` -- Potentially `internal/store/sqlite.go` (if migration needed) - -## Definition of Done -- [ ] Task links open correct Todoist page -- [ ] URL builder uses current format -- [ ] Existing cached URLs updated or migrated -- [ ] Unit test validates URL format diff --git a/issues/009-keep-completed-tasks-visible.md b/issues/009-keep-completed-tasks-visible.md deleted file mode 100644 index b80eaca..0000000 --- a/issues/009-keep-completed-tasks-visible.md +++ /dev/null @@ -1,54 +0,0 @@ -# [FEATURE] Keep completed tasks visible until refresh - -## Description -Leave completed tasks in view until refresh and don't confirm completion. - -## User Story -As a user, I want completed tasks to stay visible (struck through) until I refresh so I can see my progress and undo mistakes. - -## Technical Context -- Affects: `partials/todoist-tasks.html` (HTMX swap behavior), possibly JS state -- Currently completion likely removes item via `hx-swap="delete"` or similar -- Need to change to in-place update with completed styling - -## Test Strategy - -### E2E Test (Red) -``` -1. Load tasks page with uncompleted task -2. Click complete button on task -3. Assert task still visible with .completed class (strikethrough) -4. Assert no confirmation dialog appeared -5. Refresh page -6. Assert completed task no longer visible -``` - -## Proposed Approach - -1. **Change completion endpoint response:** - - Instead of empty response (for delete), return updated task HTML - - Task HTML includes completed styling (strikethrough, muted colors) - -2. **Update HTMX swap:** - - Change from `hx-swap="delete"` or `hx-swap="outerHTML"` with empty - - To `hx-swap="outerHTML"` with completed task HTML - -3. **Remove confirmation:** - - Remove any `hx-confirm` attribute on complete button - - Or remove JS confirmation dialog if present - -4. **Completed task styling:** - - Add `.completed` class with `line-through text-gray-400` - - Optionally add "undo" button that appears on completed tasks - -## Affected Components -- `internal/handlers/handlers.go` (completion endpoint response) -- `web/templates/partials/todoist-tasks.html` -- `web/templates/partials/task-item.html` (if exists, for completed variant) - -## Definition of Done -- [ ] Completing a task keeps it visible with strikethrough -- [ ] No confirmation dialog on completion -- [ ] Task disappears on page refresh -- [ ] Optional: Undo button on completed tasks -- [ ] E2E test confirms behavior diff --git a/issues/010-fix-quick-add-timestamp.md b/issues/010-fix-quick-add-timestamp.md deleted file mode 100644 index 3c59325..0000000 --- a/issues/010-fix-quick-add-timestamp.md +++ /dev/null @@ -1,76 +0,0 @@ -# [BUG] Quick add date defaults to tomorrow in evening - -## Description -The date pre-filled in quick add defaults to tomorrow when used during the evening. - -## Symptom -When adding a task in the evening, the date field pre-fills with tomorrow's date instead of today. - -## Technical Context -- Likely a timezone or date boundary issue -- Server may be using UTC while user expects local time -- Or JavaScript date handling crossing midnight boundary incorrectly - -## Test Strategy - -### Unit Test (Red) -**File:** `internal/handlers/handlers_test.go` - -```go -func TestQuickAddDefaultDate(t *testing.T) { - tests := []struct { - name string - serverTime time.Time - userTZ string - expectedDate string - }{ - { - name: "evening in US Eastern", - serverTime: time.Date(2026, 1, 21, 23, 0, 0, 0, time.UTC), // 6pm ET - userTZ: "America/New_York", - expectedDate: "2026-01-21", // Should be today, not tomorrow - }, - { - name: "late night edge case", - serverTime: time.Date(2026, 1, 22, 4, 0, 0, 0, time.UTC), // 11pm ET - userTZ: "America/New_York", - expectedDate: "2026-01-21", - }, - } - // ... -} -``` - -## Proposed Approach - -1. **Identify the source:** - - Check quick-add handler: how is default date determined? - - Check template: is date set server-side or client-side JS? - - Check if using `time.Now()` (server's timezone) vs user's timezone - -2. **Likely fix:** - - If server-side: pass user's timezone preference and convert - - If client-side: use `new Date()` which uses browser's local time - - Ensure consistent timezone handling throughout - -3. **Verify date calculation:** - - `today` should be based on user's local date, not UTC date - - Evening in US Eastern (UTC-5) at 8pm = UTC next day 1am - -## Debugging Steps -1. Check current time on server vs browser -2. Inspect what value is sent in quick-add form -3. Check JavaScript date initialization if client-side -4. Check Go `time.Now()` usage if server-side - -## Affected Components -- `internal/handlers/handlers.go` (quick-add endpoint/template data) -- `web/templates/partials/` (quick-add form) -- `web/static/` (if JS sets date) -- Potentially user preferences for timezone - -## Definition of Done -- [ ] Quick add defaults to user's local today, regardless of time -- [ ] Works correctly in evening hours -- [ ] Works across timezone boundaries -- [ ] Unit test covers evening edge case diff --git a/issues/015-random-landscape-background.md b/issues/015-random-landscape-background.md deleted file mode 100644 index 4f65c98..0000000 --- a/issues/015-random-landscape-background.md +++ /dev/null @@ -1,77 +0,0 @@ -# [FEATURE] Random landscape background image - -## Description -Use a random open licensed landscape image as the background, and replace it with a new one each refresh. - -## User Story -As a user, I want a fresh landscape background on each visit for visual variety. - -## Technical Context -- Affects page container/body styling -- Needs external image source with open license -- Consider performance and loading states - -## Test Strategy - -### Integration Test (Red) -Test image endpoint returns valid image URL with appropriate license. - -```go -func TestGetRandomBackgroundURL(t *testing.T) { - url := GetRandomBackgroundURL() - - assert.NotEmpty(t, url) - assert.Contains(t, url, "unsplash") // or other source - - // Verify URL is accessible - resp, err := http.Head(url) - assert.NoError(t, err) - assert.Equal(t, 200, resp.StatusCode) -} -``` - -## Proposed Approach - -1. **Image Source Options:** - - **Unsplash Source API:** `https://source.unsplash.com/1920x1080/?landscape,nature` - - Free, no API key needed for basic use - - Redirects to random image - - **Pexels API:** Requires API key - - **Local curated set:** Bundle images, no external dependency - -2. **Implementation:** - - Set CSS `background-image` on body or main container - - Add loading state (solid color) while image loads - - Use `background-size: cover` and `background-position: center` - -3. **Template change:** - ```html - <body style="background-image: url('{{.BackgroundURL}}'); background-size: cover;"> - ``` - - Or with CSS class and CSS variable. - -4. **Handler:** - - Generate/fetch random URL on each page load - - Pass to template context - -## Traps to Avoid -- **Slow loads:** Large images can delay page render - - Use appropriate resolution (1920x1080 max) - - Consider lazy loading or progressive enhancement -- **Image fails to load:** Have solid color fallback -- **Caching:** Browser may cache image; ensure URL changes per request -- **Dark text visibility:** May need overlay or text shadow for readability - -## Affected Components -- `internal/handlers/handlers.go` (add background URL to context) -- `web/templates/index.html` (apply background style) -- `web/static/css/` (fallback and loading styles) - -## Definition of Done -- [ ] Background image displays on page load -- [ ] Different image on each refresh -- [ ] Images are openly licensed -- [ ] Fallback color while loading -- [ ] Text remains readable over images -- [ ] Integration test verifies URL validity diff --git a/issues/016-click-task-edit-details.md b/issues/016-click-task-edit-details.md deleted file mode 100644 index a1687c9..0000000 --- a/issues/016-click-task-edit-details.md +++ /dev/null @@ -1,80 +0,0 @@ -# [FEATURE] Click task to open editable details - -## Description -When I click a task, open details and let me update description. - -## User Story -As a user, I want to click a task to view and edit its description inline. - -## Technical Context -- Extends existing task display with detail view -- Requires new endpoints for fetching and updating task details -- HTMX-powered modal or slide-out panel - -## Test Strategy - -### Unit Test (Red) -**File:** `internal/handlers/handlers_test.go` - -```go -func TestUpdateTaskDescription(t *testing.T) { - // Setup mock Todoist client - mockClient := &MockTodoistClient{} - handler := NewHandler(mockClient) - - // Call update endpoint - req := httptest.NewRequest("PUT", "/tasks/123", - strings.NewReader(`{"description": "Updated desc"}`)) - - // Assert Todoist API called with correct params - mockClient.AssertCalled(t, "UpdateTask", "123", "Updated desc") -} -``` - -### E2E Test (Red) -``` -1. Click on a task row -2. Assert modal/drawer opens with task details -3. Assert description field is editable -4. Edit description and save -5. Assert modal closes -6. Assert description persisted (re-open to verify) -``` - -## Proposed Approach - -1. **Endpoints:** - - `GET /tasks/{id}/detail` — fetch task with full details - - `PUT /tasks/{id}` — update task (description, etc.) - -2. **UI Flow:** - - Click task row triggers `hx-get="/tasks/{id}/detail"` - - Response loads into modal or slide-out panel - - Form with editable description (textarea) - - Save button triggers `hx-put="/tasks/{id}"` - - On success, close modal and optionally update task row - -3. **Template:** - - New partial: `partials/task-detail.html` - - Contains: title (read-only or editable), description (editable), due date, labels, save/cancel buttons - -4. **API Integration:** - - Update Todoist via API when saving - - Update local cache - -## Affected Components -- `internal/handlers/handlers.go` (new endpoints) -- `internal/handlers/handlers_test.go` -- `internal/api/todoist.go` (UpdateTask method if not exists) -- `web/templates/partials/task-detail.html` (new) -- `web/templates/partials/todoist-tasks.html` (add click handler) -- `web/templates/index.html` (modal container if needed) - -## Definition of Done -- [ ] Clicking task opens detail view -- [ ] Description field is editable -- [ ] Save persists to Todoist -- [ ] Local cache updated -- [ ] Modal/drawer closes on save -- [ ] Unit tests for update handler -- [ ] E2E test for full flow |
