Skip to content
This repository was archived by the owner on May 26, 2026. It is now read-only.

Refactor tasks (tasks.org/OpenTasks) to separate layers for storage + mapping #116

Closed as duplicate
5 of 11 issues completed
Closed as duplicate

Description

@rfc2822

See also: https://github.com/bitfireAT/davx5/issues/670

We can use the new event architecture (at.bitfire.synctools.{icalendar,mapping.calendar,storage.calendar}) as a template.

Done when:

  • Storage, mapping and iCalendar access are separated
  • No separate data class (Task) required anymore
  • Storage API is in at.bitfire.synctools.storage.tasks package
  • Mapping API is in at.bitfire.synctools.mapping.tasks package
  • iCalendar API is in at.bitfire.synctools.icalendar package
  • All classes have proper tests

Issues + PRs

Activity

  1. changed the title [-]Refactor tasks to separate layers for storage + mapping[/-] [+]Refactor tasks (tasks.org/OpenTasks) to separate layers for storage + mapping[/+] on Oct 26, 2025
  2. added theissue type on Oct 26, 2025
  3. added
    tasksRegarding tasks / everything that's stored in a task app provider
    on Nov 10, 2025
  4. sunkup commented on May 5, 2026

    @sunkup
    Member

    In order to finish the remaining task refactoring I asked AI to come up with a meta issue description and a list of sub-issues, preferably to be worked on in parallel, which I tried to analyse and play through in my head. I think it makes sense, but I am also still inexperienced in planning multiple refactoring issues ahead, so maybe there is room for improvement with this plan? ( @rfc2822 ) It assumes #182 will be finished (first sub-issue).

    General idea:

    1. finish the new storage-level DmfsTask API (existing PR Refactor DmfsTask, introducing Entity as data object #182 ),
    2. introduce task-side builder/handler extension points,
    3. split the large task writer into smaller builder classes,
    4. split the large task reader into smaller handler classes,
    5. move all Task mapping out of the storage layer,
    6. remove the temporary legacy compatibility bridge.

    The builder/handler issue splits are supposed to be designed so several of them can be worked on in parallel.

    List of issues

    synctools task refactor issue drafts

    These issue drafts split the remaining work from synctools#116 into smaller, parallelizable units.

    Assumption used here: include the current WIP synctools#182 as issue 1.

    Common labels to apply: refactoring, tasks


    Meta issue: Complete the remaining task refactor analog to events

    Replaces synctools#116 to track work needed to finish splitting task storage access from task mapping/business logic, analogous to the event architecture already present in synctools.

    • Issue 1: Finalize entity-based DmfsTask storage API
    • Issue 2: Introduce task field-builder and field-handler extension points
    • Issue 3: Split task main-row builder into dedicated field builders
    • Issue 4: Split task time and recurrence builder logic
    • Issue 5: Split task property builders for alarms, categories, comments, relations, and unknown properties
    • Issue 6: Split task row-to-Task mapping into dedicated field handlers
    • Issue 7: Split task time, recurrence, and property mapping handlers
    • Issue 8: Move Task mapping out of storage-level DmfsTask
    • Issue 9: Remove deprecated legacy DmfsTask compatibility APIs

    Issue 1: Finalize entity-based DmfsTask storage API

    Depends on: none
    Parallel work: none; foundation issue

    Description

    Finalize the storage.tasks.DmfsTask work currently explored in synctools#182 so it becomes the canonical storage-level task object. The storage object should be backed by Entity data from the provider and should define a clear compatibility boundary to the deprecated legacy at.bitfire.ical4android.DmfsTask.

    Scope

    • Land the storage.tasks.DmfsTask API shape
    • Keep behavior-compatible CRUD during the transition
    • Keep the legacy class only as a temporary bridge
    • Document which APIs are storage-level and which are compatibility-only

    Acceptance criteria

    • storage.tasks.DmfsTask is available as the canonical storage task type
    • Its constructor/API shape is stable enough for follow-up refactors to build on
    • Existing task tests still cover the migrated behavior
    • The legacy class is clearly marked as transitional/deprecated

    Issue 2: Introduce task field-builder and field-handler extension points

    Depends on: Issue 1
    Parallel work: unlocks Issues 3-7

    Description

    Introduce task equivalents of the event builder/handler interfaces so DmfsTaskBuilder and DmfsTaskProcessor become orchestration layers instead of monolithic classes. This issue should not intentionally change behavior.

    Scope

    • Add interfaces for task row/sub-row builders
    • Add interfaces for task row/sub-row handlers
    • Wire DmfsTaskBuilder and DmfsTaskProcessor to compose these interfaces
    • Keep the current mapping logic intact, just moved behind extension points

    Acceptance criteria

    • There is a clear task equivalent to the event-side builder/handler abstraction
    • DmfsTaskBuilder no longer needs to own all field logic directly
    • DmfsTaskProcessor no longer needs to own all field logic directly
    • No intentional behavior changes are introduced

    Issue 3: Split task main-row builder into dedicated field builders

    Depends on: Issue 2
    Parallel work: can run in parallel with Issues 4 and 5

    Description

    Extract the non-time, non-property writes from DmfsTaskBuilder.buildTask() into focused builder classes so the main task row is assembled from small, testable components.

    Scope

    • Extract builders for:
      • sync metadata
      • title / description / location / URL
      • GEO
      • organizer
      • priority / classification
      • status
    • Keep the resulting row shape identical to current behavior

    Acceptance criteria

    • DmfsTaskBuilder.buildTask() is reduced to orchestration
    • Each extracted concern has its own builder class
    • Existing or adapted tests still prove field parity

    Issue 4: Split task time and recurrence builder logic

    Depends on: Issue 2
    Parallel work: can run in parallel with Issues 3 and 5

    Description

    Extract all time-related and recurrence-related write logic from DmfsTaskBuilder into dedicated builders and helpers, analogous to the event-side split of start/end/duration/recurrence handling.

    Scope

    • Extract logic for:
      • all-day handling
      • timezone resolution
      • DTSTART
      • DUE
      • DURATION
      • RDATE
      • RRULE
      • EXDATE
    • Extract or introduce shared helper types where needed

    Acceptance criteria

    • Time and recurrence code no longer lives inline in buildTask()
    • Timezone resolution is isolated and reusable
    • Time/recurrence behavior remains compatible with current tests

    Issue 5: Split task property builders for alarms, categories, comments, relations, and unknown properties

    Depends on: Issue 2
    Parallel work: can run in parallel with Issues 3 and 4

    Description

    Replace the insert... methods in DmfsTaskBuilder with dedicated property builder classes, following the pattern already used by event sub-row builders.

    Scope

    • Extract dedicated builders for:
      • alarms
      • categories
      • comments
      • relations
      • unknown properties
    • Keep the current TasksBatchOperation behavior

    Acceptance criteria

    • insertProperties() delegates to dedicated builder classes
    • The builder classes are focused on one property type each
    • Existing property-focused tests remain green after migration

    Issue 6: Split task row-to-Task mapping into dedicated field handlers

    Depends on: Issue 2
    Parallel work: can run in parallel with Issue 7 and partly with Issues 3-5

    Description

    Extract the non-time, non-property reads from DmfsTaskProcessor.populateTask() into focused handler classes so provider-row-to-Task mapping becomes composable and easier to maintain.

    Scope

    • Extract handlers for:
      • UID / sequence
      • title / description / location / URL
      • GEO
      • organizer
      • priority / classification
      • status
    • Keep existing Task output behavior unchanged

    Acceptance criteria

    • populateTask() becomes a small orchestration method
    • Each non-time field group has its own handler class
    • Existing processor tests still validate the mapped fields

    Issue 7: Split task time, recurrence, and property mapping handlers

    Depends on: Issue 2
    Parallel work: can run in parallel with Issue 6

    Description

    Extract the remaining time, recurrence, and property parsing logic from DmfsTaskProcessor into dedicated handlers and helper utilities.

    Scope

    • Extract handlers for:
      • DTSTART
      • DUE
      • DURATION
      • recurrence parsing
      • alarms
      • categories
      • comments
      • relations
      • unknown properties
    • Extract shared timezone/recurrence parsing helpers if needed

    Acceptance criteria

    • DmfsTaskProcessor no longer directly implements all parsing logic
    • Time/recurrence parsing is isolated from unrelated field handling
    • Property handling is delegated to focused handler classes

    Issue 8: Move Task mapping out of storage-level DmfsTask

    Depends on: Issues 3, 4, 5, 6, 7
    Parallel work: none; integration step

    Description

    Once the mapper pieces are split, remove the remaining storage/mapping mixing from storage.tasks.DmfsTask. Storage should deal with provider entities and CRUD, while conversion to/from at.bitfire.ical4android.Task should happen in dedicated mapper composition.

    Scope

    • Remove mapping-heavy behavior from storage-level DmfsTask
    • Move Task conversion behind explicit mapper composition
    • Keep storage CRUD responsibilities in storage classes only

    Acceptance criteria

    • Storage-level DmfsTask no longer owns mixed storage + mapping behavior
    • Task conversion is delegated to explicit mapper composition
    • Callers can use storage APIs without implicitly pulling mapping logic into the storage layer

    Issue 9: Remove deprecated legacy DmfsTask compatibility APIs

    Depends on: Issue 8
    Parallel work: none; cleanup/finalization

    Description

    Remove the temporary compatibility bridge once DAVx5 and tests use the new storage-level and mapper-based APIs.

    Scope

    • Remove deprecated at.bitfire.ical4android.DmfsTask
    • Remove DmfsTaskList.getLegacyTask
    • Remove other compatibility-only task entry points that are no longer needed
    • Update tests/usages to the final APIs

    Acceptance criteria

    • No task code depends on the legacy compatibility bridge anymore
    • The final task API surface matches the intended storage-vs-mapping separation
    • Tests and downstream code use the new APIs only

    Suggested execution order

    1. Meta issue
    2. Issue 1
    3. Issue 2
    4. Issues 3, 4, 5, 6, and 7 in parallel
    5. Issue 8
    6. Issue 9
  5. rfc2822 commented on May 6, 2026

    @rfc2822
    MemberAuthor

    Sounds good to me! I'd however leave the parallelization away and focus on the working main branch after every PR. If we want to use AI for the tasks, the parallelization is not needed anyway because the PRs will be generated quickly and then the bottleneck is the manual verification.

    So I'd:

    • convert the items to real sub-issues (→ 1 PR per sub-issue)
    • try to do every sub-issue in Copilot (with planning mode first)
    • of course always verify that every resulting PR does what we want
  6. 4 remaining items

  7. reopened this on May 8, 2026
  8. assigned and unassigned on May 8, 2026
  9. rfc2822 commented on May 26, 2026

    @rfc2822
    MemberAuthor

    Call needed to get common understanding – what has already been done, what is missing, re-evaluate

    • exact goal / target architecture (class level)
    • steps how to get there
  10. rfc2822 commented on May 26, 2026

    @rfc2822
    MemberAuthor

    Moved to bitfireAT/davx5-ose#2264. We want to analyze the current state / goal again and then create the respective sub-issues in the new issue.

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

Metadata

Metadata

Assignees

Labels

refactoringQuality improvement of existing functionstasksRegarding tasks / everything that's stored in a task app provider

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions