Commit graph

32 commits

Author SHA1 Message Date
Chris
01a84c3598
Fix: Bi-weekly recurring task scheduling for multi-day patterns (#1005)
* fix: correct bi-weekly recurring task scheduling for multi-day patterns

Fixes #1004

Previously, when a recurring task was set to repeat every N weeks (where N > 1)
on multiple weekdays that span a week boundary (e.g., Saturday + Sunday), the
algorithm incorrectly calculated the next occurrence dates.

The issue was in the calculateWeeklyRecurrence function, which didn't properly
determine when to add the interval skip for multi-weekday patterns. It would:
- Correctly handle Sat -> Sun (adjacent days, same cycle)
- Incorrectly handle Sun -> Sat (should skip weeks, but didn't)

This fix improves the logic to:
1. Detect when the current day is the last weekday in the pattern cycle
2. Account for Sunday (day 0) wrapping around in the day-of-week numbering
3. Only add interval skips when truly moving to a new cycle, not when moving
   between weekdays within the same cycle

Test coverage added for:
- Bi-weekly Saturday + Sunday pattern (the reported bug)
- Starting from different days in the pattern
- Bi-weekly Tuesday + Thursday pattern
- Tri-weekly Friday + Saturday + Sunday pattern

* docs: update MEMORY.md with GitHub template requirements

- Add detailed PR template requirements and structure
- Expand bug report template requirements with all fields
- Update last modified date
2026-04-12 08:52:13 +03:00
Chris
e8c7eed226
fix: prevent subtasks from disappearing when updating parent task (#984)
This commit addresses a critical bug where subtasks would disappear when
updating the parent task (e.g., assigning tags). The issue had multiple
potential causes:

1. Backend vulnerability: The updateSubtasks() function would delete all
   subtasks if an empty array was sent, treating it as "delete everything
   not in this list"

2. Frontend state management: After reloading a task, subtasks weren't
   being preserved if the backend response didn't include them

3. Unclear error messages: "Invalid parent task" errors didn't provide
   enough context for debugging

Changes:
- Added defensive logging in updateSubtasks() to warn when all subtasks
  are being deleted with an empty array
- Enhanced validateParentTaskAccess() error messages to provide detailed
  diagnostics (task not found vs. permission issues vs. wrong user)
- Updated handleTagsUpdate() in TaskDetails to explicitly preserve
  subtasks when reloading task after tag updates

This fix is defensive in nature and adds better observability for
diagnosing similar issues in the future.

Fixes issue reported by user where subtasks disappeared after assigning
tags to parent task, and "Invalid parent task" errors occurred when
trying to update the orphaned subtasks.
2026-04-01 17:37:20 +03:00
Chris
65b9bbce39
Fix initial due date calculation for weekly tasks with multiple weekdays (#974) (#975)
Fix calculateInitialDueDate() to properly handle recurrence_weekdays array
when creating or updating weekly recurring tasks with multiple weekdays.

Previously, the function only checked for recurrence_weekday (singular) and
ignored recurrence_weekdays (plural array), causing tasks with multiple
weekdays to incorrectly get today's date instead of the next occurrence.

Changes:
- Add support for recurrence_weekdays array in calculateInitialDueDate()
- Fix buildUpdateAttributes() to pass recurrence_weekdays parameter
- Add 8 unit tests covering multiple weekdays scenarios
- Add 3 integration tests for API CREATE and UPDATE operations
- Maintain backward compatibility with single recurrence_weekday

The fix mirrors the proven logic from calculateWeeklyRecurrence() in
recurringTaskService.js and properly handles edge cases like unsorted
arrays, wrapping to next week, and JSON string parsing.

Fixes #974
2026-03-26 17:19:59 +02:00
Chris
402d5b05e1
Fix Today page task completion issues (#970)
* Fix Today page task completion issues

- Fix completed task border color staying as priority color
  - Add isInCompletedSection prop to TaskItem for explicit completed state
  - Tasks in completed section now always show green border regardless of priority
  - Fixes race condition where status wasn't updated during optimistic UI update

- Fix completed task reappearing after unmarking and page refresh
  - Add defensive check in backend to force clear completed_at when status is not DONE
  - Add development logging in tasksService for debugging completion toggle
  - Ensures database state is consistent even if handleCompletionStatus doesn't clear it

- Update TaskList and TasksToday components to pass isInCompletedSection prop
  - Explicitly marks tasks rendered in the completed section
  - Prevents border color flickering during state transitions

* Add comprehensive logging to debug completion issues

* Fix duplicate API requests causing completion state issues

- Separate state update logic from API call in handleTaskUpdate
- Create new updateTaskInState function for state-only updates
- Pass onTaskCompletionToggle to completed section to avoid duplicate calls
- This fixes the persistence issue where unmarked tasks came back after refresh
- Completion toggles now only make ONE API call instead of two

* Add debug logging to updateTaskInState
2026-03-24 16:45:31 +02:00
Chris
077addadde
Fix recurring task initial due date calculation to match recurrence pattern (#965)
* Fix recurring task initial due date calculation to match recurrence pattern

Resolves #963

When creating a recurring task without an explicit due date, the system
was incorrectly setting it to "today" regardless of the recurrence pattern.
This caused issues where:
- Monthly tasks set to recur on a specific day (e.g., 28th) would show the
  wrong due date (today/yesterday instead of the 28th)
- Tasks wouldn't appear correctly in the Upcoming view
- The base due_date didn't match the recurrence_month_day setting

Changes:
- Add calculateInitialDueDate() helper to compute correct first occurrence
- For monthly recurrence with specific day: calculate next occurrence of that day
- For weekly recurrence with specific weekday: calculate next occurrence of that weekday
- For other types (daily, etc.): maintain current behavior (use today)
- Apply same logic to both task creation and updates

Tests:
- Add comprehensive test suite (9 new tests) covering:
  - Monthly recurrence with future day in current month
  - Monthly recurrence with past day (should use next month)
  - Weekly recurrence with specific weekday
  - Daily recurrence (should still default to today)
  - Edge cases (31st of month, explicitly provided dates)
  - Task updates adding recurrence

All 54 recurring task tests pass.

* Fix UTC timezone bug in recurring task expansion and add comprehensive tests

- Fix expandRecurringTasks() to use setUTCHours instead of setHours
- Add 42 unit tests for recurringTaskService UTC consistency
- Add 24 DST transition tests (spring forward/fall back)
- Verify no occurrence skips or duplicates during DST
- Test month-end handling, leap years, and timezone boundaries
2026-03-23 18:24:54 +02:00
Chris
2b71938c30
Fix project update API to support clearing nullable fields (#961)
Resolves #960

The update_project endpoint now properly handles clearing nullable fields
(due_date_at, area_id, priority, image_url) when set to null or empty string.

Previously, sending an empty string would not clear the field. Now empty
strings are explicitly converted to null for database consistency.

Changes:
- Convert empty strings to null for nullable fields in project update
- Add tests for clearing due_date_at with null and empty string
- Apply same fix to area_id, priority, and image_url for consistency
2026-03-22 22:17:23 +02:00
Chris
b63f684190
feat: Add MCP Integration with client-agnostic instructions (#953) 2026-03-20 16:55:49 +02:00
Chris
11cd77bedd
Fix Telegram notification spam with channel-level rate limiting (#951)
* Fix Telegram notification spam with channel-level rate limiting

Addresses issue #950 where Telegram notifications were sent excessively
(96-288 messages per day per task) due to the delete-and-recreate pattern
added in commit 105a913a to fix navbar notification pile-up.

Changes:
- Add channel_sent_at JSON field to notifications table to track when
  each channel (telegram, email, push) was last sent
- Add helper methods to notification model:
  - markChannelAsSent(channel): Records send timestamp
  - wasChannelRecentlySent(channel, threshold): Checks if sent within 24h
- Modify sendTelegramNotification() to check rate limit before sending
- Update service layer (dueTaskService, deferredTaskService,
  dueProjectService) to preserve channel_sent_at when recreating
  notifications
- Add comprehensive unit and integration tests (20 tests, all passing)

Impact:
- Reduces Telegram notifications from 96-288/day to 1/day per item
- Preserves in-app notification refresh behavior (every 5-15 min)
- Maintains navbar pile-up fix from original commit
- Rate limit configurable (default: 24 hours)

Fixes #950

* Fix linting and formatting issues

* Fix integration test that was trying to access private function

* Fix prettier formatting in integration test
2026-03-19 20:26:11 +02:00
Chris
105a913a8d
Fix notification deduplication to prevent pile-up in navbar (#945)
* Fix notification deduplication to prevent pile-up in navbar (#944)

When tasks/projects remained pending for multiple days, duplicate
notifications accumulated in the navbar instead of showing only the
most recent one.

Updated notification services to properly handle existing notifications:
- Delete unread notifications before creating new ones
- Respect dismissed notifications (don't recreate)
- Respect read notifications (don't duplicate)

Changes:
- Updated dueTaskService, deferredTaskService, and dueProjectService
- Added comprehensive unit tests with 8 test cases

Fixes #944

* Fix lint errors and add GitHub bug template reminder to docs
2026-03-14 19:45:24 +02:00
Chris
1d5de49b48
Add URL detection to inbox processing service (#942)
* fixup! Fix date format inconsistency in Defer Until field

* fixup! fixup! Fix date format inconsistency in Defer Until field

* fixup! fixup! fixup! Fix date format inconsistency in Defer Until field
2026-03-14 08:43:41 +02:00
Chris
7f7ffd8ac9
Fix subtask ordering to prevent random reordering (#930)
Added proper ordering configuration (separate: true and order clause)
to subtask queries in query-builders.js. This ensures subtasks are
always returned in the correct order based on the 'order' field and
'created_at' timestamp, preventing the intermittent reordering bug
that occurred after checking subtasks as complete and reloading.

Fixes #921
2026-03-10 00:17:26 +02:00
Chris
8fea7020bb
Fix: Show Projects with due dates in Upcoming view (#928)
* Add projects with due dates to upcoming view

Fetch and include projects with due_date_at in the upcoming range
when type=upcoming is requested. Projects are filtered by ownership
or permissions and exclude completed/archived projects.

Part of #925

* Display upcoming projects in Upcoming view

Add UI to show projects with due dates in the Upcoming view.
Projects are displayed in a separate section below tasks with
links to project details and formatted due dates.

Fixes #925

* Fix prettier formatting errors
2026-03-09 23:36:14 +02:00
Chris
3712d695fc
Show original task names for recurring tasks in search results (#914) (#915)
Recurring task templates had their names replaced with the recurrence
type label (e.g. "Weekly") in search results, making them unrecognizable.
Skip the display name transform when serializing tasks for search.
2026-03-06 08:57:10 +02:00
Chris
aa686702e9
Fix defer date validation for recurring task instances (#910)
* Fix defer date validation for recurring task instances

* fixup! Fix defer date validation for recurring task instances
2026-03-05 08:20:30 +02:00
Chris
3a3cb0bc36
Include task with subtasks (#907) 2026-03-04 21:44:45 +02:00
Chris
19b90ccc6a
Fix in-progress tasks not appearing in Today and All Tasks views (#894)
* Fix in-progress tasks not appearing in Today and All Tasks views

* fixup! Fix in-progress tasks not appearing in Today and All Tasks views
2026-03-03 17:11:13 +02:00
Chris
c3832464e2
Fix admin password update silently failing due to Sequelize VIRTUAL field (#893) 2026-03-03 15:44:41 +02:00
Chris
121cb70aa3
Fix deferred planned tasks not appearing in Today view after defer time (#892) 2026-03-03 12:52:53 +02:00
Chris
c656c2aa67
Fix bi-weekly+ recurring tasks reverting to weekly (#844) (#890) 2026-03-02 23:36:47 +02:00
Chris
edc9d214f6
Fix recurring tasks losing name and subtasks on status change (#886) 2026-03-01 13:17:54 +02:00
Chris
96db8c1362
Fix 819 (#869)
* Fix projects order persist to localstorage

* Fix tags page not showing completed tasks
2026-02-27 01:07:08 +02:00
Chris
1e69ae59cf
Fix cancelled control tasks and subtasks (#867) 2026-02-26 23:54:09 +02:00
Chris
782bed235b
Fix Telegram task display bug by escaping backslashes (#860)
* Fix Telegram task display bug by escaping backslashes

* fixup! Fix Telegram task display bug by escaping backslashes
2026-02-24 14:19:45 +02:00
Chris
65943e7599
Fix remaining multi-weekday recurrence bugs (#838) 2026-02-13 17:07:00 +02:00
Chris
45aec304a3
Fix project view due date timezone bug and recurring multi-weekday bug (#836) 2026-02-12 12:12:24 +02:00
Chris
5a1f0650ae
Fix isEmail validation failure on valid emails during Docker setup (#835) 2026-02-11 15:42:11 +02:00
Chris
55be092907
Change relative path (#794) 2026-01-23 23:17:38 +02:00
Chris
6922bc8916
Set stalled projects active without tasks (#793) 2026-01-23 23:06:35 +02:00
Chris
d2a9a6dc5a
Fix subtask completion auto-completing parent task (#792) 2026-01-23 20:04:58 +02:00
Chris Veleris
290f9ea5aa Fix an issue with state 2026-01-18 11:53:46 +02:00
Chris Veleris
46b33ef16f Fix issue with wrong path 2026-01-18 09:47:12 +02:00
Chris
542be2c1e9
Fix bug 366 (#764)
* Optimize DB

* Clean up names

* fixup! Clean up names

* fixup! fixup! Clean up names
2026-01-07 18:18:07 +02:00