PROJECT: WatchOver


Overview

WatchOver is a gamified desktop task manager.

Summary of contributions

  • Major enhancement: Time and completion dependency

    • What it does: Users can add and remove dependencies between tasks: to ensure that the right tasks are completed in order and to know the earliest due date among all tasks that are directly or indirectly dependent on a given task is displayed for that given task (an effective due date)

    • Justification: Some tasks have complicated dependencies with other tasks hence the user would want to ensure that he or she completes the tasks in the right order. A useful information to have when deciding how to prioritise tasks is not just to look at the due date of a task but also the earliest due date among all tasks that directly or indirectly dependent on the task.

    • Highlights:

      • There were significant design choices that needed to be made to specify dependencies given that tasks are immutable. (i.e. Assume that there are two tasks, task A and task B, where task A is dependent on task B. If I was to edit task B, task A has to be recreated as the dependencies on task A has to reflect the dependency to the new task B object)

      • Dependency feature is strongly linked to edit, delete, complete commands

  • Code contributed: [Project Code Dashboard] [Github Commits]

  • Other contributions:

    • Minor Enhancements:

      • Minor Enhancement 1: Time-based status update (between IN PROGRESS and OVERDUE)

      • Minor Enhancement 2: Topological sort (topoorder command)

    • Bugs found in other team’s code: Bugs not due to inaccurate documentation are listed here. Some are relatively major and difficult to find. CS2103-AY1819S1-W17-4 [#195:Non-unique tasks] [#241: Files with changed names]

    • Project Management:

      • Coordinated releases v1.1 - v1.4 (4 releases) on GitHub

      • Product Manager Role

        • Coordinated and facilitated meetings one to two times a week

        • Ensures that deadlines are completed on-time

      • Created and maintained all project boards

    • Enhancements to existing features:

      • Enhanced the GUI by allowing it to display time until completion, dependencies [PR #219]

      • Did a significant amount of initial refactoring for the team: [PR 41, 47, 48, 50, 51, 54, 66]

    • Community:

      • Reported bug on module website [Module webpage GH issue 2,3]

      • PRs reviews : [PR 76, 95, 154, 67, 213, 241]

    • Tools:

      • Maintained a Github plugin (TravisCI) in team repo #60

Contributions to the User Guide

Given below are sections I contributed to the User Guide.

Adding/Removing a dependency to a Task: dependency

Adds/removes a dependency of a task dependent to the task dependee.
For a given scenario where task A is dependent on task B, task A is defined as the dependant task while task B is defined as the dependee task.
The dependency is added if it already exists and removed if it does not exist.

Format: dependency INDEX_DEPENDANT INDEX_DEPENDEE

+Example: dependency 1 2

-Example: dependency 1 dependency a b

There are several cases when a dependency cannot be created:

1) The dependency introduces a cyclic dependency

A cyclic dependency is defined as a dependency path from a task back to the task itself.

CyclicDependency

In the diagram above, an additional dependency from Task A to Task C will introduce a cycle and hence will be rejected by the Task Manager.

2) The dependency is added from a COMPLETED task to an IN-PROGRESS or OVERDUE task

The dependency will violate the notion of a completed task as tasks can only be completed if all the tasks that it depends on are completed.

Listing Tasks by topological order: topoorder

Shows a list of uncompleted tasks by their topological order in the CLI window.

A topological order defines a possible valid sequence of tasks to tackle given existing task dependency constraints. Dependencies to completed tasks are deemed as fulfilled and is not a "constraint".

Example:

  • topoorder

Topological order is a linear ordering of vertices such that for every vertex u to vertex v, u comes before v in the ordering. (Source: wikipedia)

In the context of our application, it is a linear ordering of Task s such that if Task A is dependent to Task B, B comes before A in the ordering.

TopologicalOrdering

Diagram of a possible dependency graph

A topological order of this graph is: [A, B, C]

Adding a Task: add

Adds a task to the task manager.
Format:

add n/TASK_NAME t/DUE_DATE p/PRIORITY_VALUE [d/detailed description] [l/LABEL]

Date Format: dd-MM-yy or dd-MM-yy HHmm or dd-MM-yyyy or dd-MM-yyyy HHmm. A missing HHmm field will cause time to be interpreted as the start of the day, i.e 00:00.

+Example:
add n/complete milestone t/14-09-19 p/99 d/a detailed description l/CS2103
add n/complete milestone t/14-09-19 1320 p/9 d/a detailed description l/CS2103

-Example: add n/complete milestone t/2018/09/14 p/important add n/complete milestone t/14-09-19 p/-4

Duplicated tasks are not allowed in the task manager. Duplicated tasks are defined as tasks with the same name and due date or tasks with the same name and priority value.

Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide.

Sections excluded: topological order command manual testing, dependency related manual testing, extra details about implementation of dependency

Effective Due Date

Current Implementation

Effective Due Date (EDD) is a derived field in the UI. It is the earliest due date among all tasks directly or indirectly dependent on the task, including the task itself.

Steps to find effective due date of task A:

  1. Prune completed tasks and dependencies to COMPLETED tasks from the DependencyGraph

  2. Invert the dependencies in the DependencyGraph (to allow graph traversal in the opposite direction)

EffectiveDueDateImplementation1

Diagram for effective due date implementation

  1. Perform a depth first search from Task A to find earliest effective due date among all children (i.e. B)

    1. Task C’s effective due date will be 1-3-19 [No children]

    2. Task B’s effective due date will be 1-1-19 [C: 1-3-19, B’s due date is earlier than EDD of C]

    3. Task A’s effective due date will be 1-1-19 [B: 1-1-19, B’s EDD is earlier than A’s due date]

Note: comparison of due date with EDDs of children in square brackets

EffectiveDueDateImplementation2

Table for effective due date implementation

Command Component

Command is refactored to be implemented using a template method pattern. The rationale is that there are shared codes and invariants among all the executions of the command classes such as the method to update the status of tasks to overdue if their due date is past current time.

The common patterns in execution are implemented in the execute function of the command class which is declared final. Concrete implementations of each execute function is implemented in the executePrimitive function of each subclass of command. The implementation for executePrimitive fill the "variant" portion of the model template. Note that execute primitive is implemented as an abstract method in command.

CommandComponentClassDiagram

Simplified class diagram for the command component

Dependency Feature Modelling

Current Implementation

The dependencies of a task is modelled by an embedded Dependencies object in the task. This object represents dependencies with a hashset that contains the hashcodes of the tasks that the task is dependent upon.

The dependencies between tasks are added or removed using the dependency command. If a given task A is dependent on a given task B, task A is the dependant task while task B is the dependee task.

When deleting a task, all dependencies to the deleted task will be removed. When editing a task, all dependencies to the edited task will be updated with the hashcode of the new edited task.

DependencyActivityDiagram

Activity diagram for the dependency command (dependencies are toggled using the command)

Design Considerations

Aspect: Modelling a dependency
  • Alternative 1(current choice): Dependencies specified by unique hashcodes of tasks

    • Pros: When a task dependency is updated, the updating of tasks do not propagate . (Refer to alternative 2)
      The hashcodes are generated without a task’s dependencies. Hence, when updating a given task A, tasks dependent to task A do not need to be recreated as the hashcode of the new task A is the same hashcode as the old task A.

    • Cons: Some functions such as UI display require details of the dependee tasks. Additional computation required to find reference of the dependee task from its hashcode.

  • Alternative 2: Dependencies specified by (references to) the Task objects themselves

    • Pros: Easy reference the task object.

    • Cons: Introduces unnecessary complications.
      1)Tasks are immutable. Whenever a task dependency is added or removed a new task is created. All tasks dependent to the updated task have to have their dependencies updated. Consequently, all tasks that are dependent to the the tasks dependent to the original task have to have their dependencies updated as well.
      2)[Assumption: In storage, task dependencies are specified by hashcodes of task] When retrieving data from storage, the parser needs to first load the dependencies as a set of hashcodes before transforming the hashcodes to references to tasks only when all tasks are instantiated from storage.

Modelling Dependency Checks

Current Implementation

The DependencyGraph is the graph representing the dependencies between the task objects. A graph model needs to be created so useful functions can be implemented such as cyclic check, topological sort, or a depth first search of the graph.

ShowTopologicalOrderCommandSequenceDiagram

Sequence Diagram of the Show Topological Order Command (DependencyGraph on the right hand side of diagram)

DependencyGraph is instantiated whenever it is needed. Transformations such as inverting the graph or pruning COMPLETED tasks from graph.

Design Considerations

Aspect: Real-time graph or graph instantiated on function call.
  • Alternative 1(current choice): Graph is only instantiated when needed.

    • Pros:
      1) Graph does not have to be maintained at every relevant command
      2) Graph can be transformed (pruning/inverting) without worrying about modifying the original dependencies object

    • Cons: Slight increase in latency, but mitigated by the fact that a typical user won’t have an extremely large amount of tasks.

  • Alternative 2: Graph created on start-up and maintained during run-time

    • Pros: Slightly faster speed for dependency related commands

    • Cons: Upkeep of graph is complex to implement especially with the immutable nature of the Tasks

Design Considerations
Aspect: Implementing the check on whether a task is overdue
  • Alternative 1 (current choice): Run a check before the execution of every command

    • Pros: From a user experience perspective, the user should not expect there to be a commit to state every time a task is overdue. i.e. An undo command should never undo an overdue. Simple implementation prevents race conditions (refer to cons of alternative 2).

    • Cons: If a user does not input a command, the task state will not be updated. (Mitigated by the fact that the number of commands that a person uses likely occurs at a higher rate than the number of tasks itself).

  • Alternative 2: Run a cron job that checks at a regular interval if the task is overdue

    • Pros: The overdue state of the task is current

    • Cons: Potential race condition and might introduce latency to the application.

Effective Due Date field

  1. Showcasing Effective due date field

Effective due date is a field in the UI that updates according to command changes. Effective due date can be seen by selecting the task on task panel with the mouse or by entering the command select x, where x is the index of the task.

  1. Prerequisites:

EffectiveDueDate1

Diagram of Due Dates and Effective Due Dates after pre-requisites are fulfilled

  1. Clear task manager with clear

  2. Add Task A using add n/A t/1-2-19 p/5 d/blank

  3. Add Task B using add n/B t/1-1-19 p/5 d/blank

  4. Add Task C using add n/C t/1-3-19 p/5 d/blank

EffectiveDueDate2

Diagram of Due Dates and Effective Due Dates for test case 1

  1. Test case 1: dependency 2 1, select 1 or click on Task A
    Expected: Dependency added between task B and task A. Effective due date of A now specifies 1-1-19. Number of dependencies field on the task card updated.

EffectiveDueDate3

Diagram of Due Dates and Effective Due Dates for test case 2

  1. Test case 2: dependency 2 1 + dependency 3 2 + select 3 or click on task C
    Expected: No change to effective due date. Number of dependencies field on the task card updated.