Skip to content

Conversation

@christenbc
Copy link

Fix: Add DTSTART to recurrence rules during task creation

Problem

When creating a task with recurrence, the recurrence field was set without DTSTART (e.g., FREQ=DAILY;INTERVAL=3). This caused Google Calendar sync to fail on initial creation because the convertToGoogleRecurrence() function requires DTSTART to properly convert the recurrence rule.

However, when editing that same task, the system would automatically add DTSTART (e.g., DTSTART:20260128T093000Z;FREQ=DAILY;INTERVAL=30), which then allowed Google Calendar sync to work correctly.

Root Cause

  1. During Task Creation: The recurrence field was set directly from the modal/form without DTSTART:

    • TaskCreationModal.buildTaskData() passed recurrence directly without DTSTART
    • Default recurrence in TaskService.applyTaskCreationDefaults() created simple FREQ rules without DTSTART
  2. During Task Editing: TaskService.updateTask() automatically added DTSTART to recurrence rules that didn't have one by calling addDTSTARTToRecurrenceRule() in three scenarios:

    • Editing the recurrence rule
    • Converting non-recurring to recurring
    • Updating scheduled date for recurring tasks
  3. Google Calendar Sync: The convertToGoogleRecurrence() function requires DTSTART to be present in the recurrence rule. Without it, the conversion returns null and Google Calendar events are not created with recurrence.

Solution

Added logic in TaskService.createTask() to automatically add DTSTART to recurrence rules during task creation, ensuring consistency between creation and editing flows.

Changes

File: src/services/TaskService.ts

  • Added check after building completeTaskData object to detect recurrence rules without DTSTART
  • Calls addDTSTARTToRecurrenceRule() to add DTSTART using the task's scheduled date (or dateCreated as fallback)
  • Updates the recurrence field before it's saved to frontmatter

Code Location

// After building completeTaskData object (line ~347)
if (
  completeTaskData.recurrence &&
  typeof completeTaskData.recurrence === "string" &&
  !completeTaskData.recurrence.includes("DTSTART:")
) {
  const tempTaskInfo: TaskInfo = {
    ...completeTaskData,
    title: title,
    status: status,
    priority: priority,
    path: "", // Path not yet known, but not needed for DTSTART calculation
    archived: false,
  };
  const recurrenceWithDTSTART = addDTSTARTToRecurrenceRule(tempTaskInfo);
  if (recurrenceWithDTSTART) {
    completeTaskData.recurrence = recurrenceWithDTSTART;
  }
}

Impact

Benefits

Consistent behavior: Tasks with recurrence now have DTSTART from creation, matching the behavior after editing

Google Calendar sync works immediately: The convertToGoogleRecurrence() function can now properly parse the recurrence rule on first sync

No breaking changes: Existing logic in updateTask() serves as a safety net for any edge cases

Backward compatible: Existing tasks without DTSTART will still work correctly (the edit flow adds it)

Testing Recommendations

  1. Create a new task with recurrence:

    • Create a task with FREQ=DAILY;INTERVAL=3 recurrence
    • Verify the saved recurrence includes DTSTART (e.g., DTSTART:20260128T093000Z;FREQ=DAILY;INTERVAL=3)
    • Verify Google Calendar sync creates the event with correct recurrence
  2. Verify existing behavior:

    • Edit an existing recurring task
    • Confirm the edit flow still works correctly
    • Verify no duplicate DTSTART is added
  3. Edge cases:

    • Task with recurrence but no scheduled date (should use dateCreated)
    • Task with recurrence and scheduled date with time component
    • Task with recurrence and scheduled date without time component

Related

  • Fixes issue where Google Calendar events were not created with recurrence on initial task creation
  • Ensures consistency between task creation and editing flows

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant