This project was built from scratch by the UniTasker team. The following third-party libraries and references were consulted during development:
This section describes the design and implementation of the key components of UniTasker. UML diagrams are provided for highlighted classes and interaction flows

The Architecture Diagram given above explains the high-level design of the App
Main components of the architecture
UniTasker is in charge of the app launch and shut down
The bulk of the app’s work is done by the following components:
How the architecture components interact with each other:

AppContainer component

The AppContainer consists of the following:
CategoryList categories – stores all categories and their associated tasks (todos, deadlines, events)Calendar calendar – Manages the mapping of dates to tasks with date information (deadlines and events)Storage storage – handles saving and loading of data from local filesCourseParser courseParser – processes and handles course-related commandsThe AppContainer component,
Storage component

The Storage component consists of the following:
String todoFilePath - path to the local file storing todo tasksString deadlineFilePath - path to the local file storing deadline tasksString eventFilePath - path to the local file storing event tasksString SETTINGS_FILE - path to the file storing application settings (daily task limit, end year)The Storage component,
UI component

The UI package consists of the following classes:
GeneralUi – central utility class providing shared print helpers (bordered output, welcome screen, reminders) used by all other UI classesErrorUi – handles all error and warning messages shown to the userCategoryUi – handles output for category-related actions (add, delete, list)DeadlineUi – handles output for deadline-related actions (add, delete)EventUi – handles output for event-related actions (add, delete, recurring events)TaskUi – handles output for todo-related actions (mark, priority, sort, reorder, find)LimitUi – handles output for limit and course result messagesCommandHelp – provides formatted help text for all command modes and topicsThe UI package,
Command component
The Command component handles the execution of user commands. Each supported command is represented by a separate command class implementing the common Command interface.
The component consists of:
CommandParser, which maps raw user input to a concrete command objectCommand, which defines the common execute(AppContainer container) methodAddCommand, DeleteCommand, and so on.CommandSupport, which provides shared helper methods such as data saving and category index retrievalNote: For most commands, the category index is expected to be at a fixed position (third element)
in the input array. This design allows the use of a shared helper method in CommandSupport to
consistently extract the category index.
How the Command component works:
UniTaskerCommandParserCommandParser returns the appropriate Command objectexecute(container) is calledAppContainerStorageUIThe figure below illustrates the high-level structure of CategoryList within the AppContainer.

CategoryList consists of a collection of Category objects. Each Category contains three task lists:
TodoListDeadlineListEventListThese task lists store their corresponding task types:
TodoList stores Todo objectsDeadlineList stores Deadline objectsEventList stores Event objectsAll task types inherit from the abstract Task class, while the three task list types inherit from the abstract TaskList class.
The CategoryList class:
AppContainerThis design allows related tasks to be grouped under a category, making it easier for users
to organize work by module or context. It also improves maintainability by centralizing
task management logic within CategoryList and Category.
The delete marked command allows users to remove all completed tasks in a single command.

The sequence diagram above shows how the delete marked command is handled by DeleteCommand.
delete marked command.DeleteCommand retrieves the CategoryList from the AppContainer.DeleteCommand calls deleteMarkedTasks() on CategoryList.CategoryList iterates through all Category objects it stores.Category, deleteMarkedTasks() is called.Category then removes marked tasks from all three task lists:
TodoListDeadlineListEventListUI.Storage.This feature demonstrates that CategoryList acts as the central access point for all categories and their associated task lists.
By delegating the deletion process through CategoryList and Category:
TodoList, DeadlineList, and EventList directlyThis design improves modularity and keeps command logic simple, while allowing CategoryList to coordinate operations affecting all three task lists.
The figure below illustrates the relationship between Deadline class and the following classes: Task, Timed, Calendar, DateUtils, DeadlineList, TaskList.

The Deadline class consists of the following members:
logger - private logger instance used for fin-grained diagnostic logging on object creationby stores the due date and time (LocalDateTime) by which the task must be completedDeadline (description, by) - constructor that initializes the task with a description and deadline, delegating to the parent TaskparseDateTime(input) – static helper that delegates to DateUtils to parse a date/time string into a LocalDateTimegetBy() – returns the raw deadline date/timegetDate() – satisfies the Timed interface by delegating to getBy(), enabling calendar and sorting integrationstoFileFormat() – serialises the task into pipe-delimited storage format (D, done, description, datetime)toString() – produces a human-readable representation prefixed with [D]The Deadline class,
Task to inherit description and completion state, adding only the by field to keep deadline-specific logic self-containedTimed interface so that Calendar can register and sort Deadline objects polymorphically without depending on the concrete typeDateUtils, ensuring consistent validation and formatting rules are applied uniformly across task typesThe event commands manages one-time occurrences and automated recurring schedules, utilising a mapping layer to ensure UI actions correctly modify the underlying data.
Note: The relationship between Event class with EventList, Tasked, Timed, Calendar, DateUtils and TaskList classes is similar to the relationship between Deadline class and the classes mentioned above under the Deadline Class Diagram section.
Workflow for Add Event command
add event <categoryIndex> <description> /from <startDateTime> /to <endDateTime>add recurring <categoryIndex> <description> /from <day> <time> /to <day> <time> /(date or month) <dateOrMonth>AddCommand is created.AddCommand calls CategoryList functions to add events.EventList add(Event) is calledEventList addRecurringWeeklyEvent(event, calendar, date, months) is called to generate and group weekly events.EventList, persisted by Storage, and reflected in the CalendarSequence Diagram for add event command

Workflow for List Event command
The list command is a prerequisite for deletion and modification as it synchronises the user’s view with the underlying data coordinates.
User enters a command such as list event, list recurring, or list event /all.
Input is parsed by the CommandParser, which creates a ListCommand object.
ListCommand calls CategoryList.getAllEvents(showAll,showNormalEventsOnly) with flags determining the view (e.g., collapsed vs. expanded).
Mapping Generation: As the CategoryList iterates through categories and events to build the display string, it simultaneously populates the activeDisplayMap.
Each displayed line is assigned a UI Index, which is mapped to an EventReference containing the (categoryIndex, eventIndex).
The formatted string is sent to GeneralUi for display, and the currentView is updated to allow subsequent delete or edit commands to reference the correct map.
Sequence Diagram for list event command

Workflow for Delete Event command
delete event <categoryIndex> <uiIndex> which is parsed by CommandParser class to
create a DeleteCommand objectDeleteCommand under ‘event’ uiIndex is parsed and used as an index in the list of EventReference objects to
get the particular EventReference objectEventReference.categoryIndex and EventReference.eventIndex.Storage class and Calendar objectNote:
list event must be called before delete event <categoryIndex> <uiIndex> to populate the map correctlydelete occurrence <categoryIndex> <uiIndex> and delete recurring <categoryIndex> <uiIndex> works the same
except for deleting multiple events at once (all events in recurring group) for delete recurring <categoryIndex> <uiIndex>Sequence Diagram for delete event <categoryIndex> <uiIndex> command

Key Design Considerations
The following architectural choices ensure that UniTasker remains efficient, extensible, and user-friendly despite the complexity of time-based data.
1. UI-to-Data Mapping
To maintain a clean user interface, UniTasker utilises a translation layer that bridges the gap between the “collapsed” UI view and the detailed data model:
EventReference Tracking: Each UI entry is backed by an EventReference storing the (categoryIndex, eventIndex). This acts as a direct pointer to the actual data object in the EventListActiveDisplayMap: This Map<Integer,List<EventReference>> map (where the key is the category index and the value is a list of EventReference objects) is populated during list commands. It ensures that when a user inputs a UI index (e.g., delete event 1 5), the command resolves to the exact physical index in the backend.Example:
list event /all
| categoryIndex | uiIndex | EventReference (categoryIndex, eventIndex) | Description |
|---|---|---|---|
| 0 | 1 | (0,0) | consultation |
| 0 | 2 | (0,1) | CS2113 tutorial |
| 0 | 3 | (0,2) | meeting |
| 0 | 4 | (0,3) | CS2113 lecture |
| 0 | 5 | (0,4) | CS2113 tutorial |
| 0 | 6 | (0,5) | CS2113 lecture |
| 1 | 1 | (1,0) | yoga lesson |
| 1 | 2 | (1,1) | yoga lesson |
list event
| categoryIndex | uiIndex | EventReference (categoryIndex, eventIndex) | Description |
|---|---|---|---|
| 0 | 1 | (0,0) | consultation |
| 0 | 2 | (0,1) | CS2113 tutorial |
| 0 | 3 | (0,2) | meeting |
| 0 | 4 | (0,3) | CS2113 lecture |
| 1 | 1 | (1,0) | yoga lesson |
list recurring
| categoryIndex | uiIndex | EventReference (categoryIndex, eventIndex) | Description |
|---|---|---|---|
| 0 | 1 | (0,1) | CS2113 tutorial |
| 0 | 2 | (0,3) | CS2113 lecture |
| 1 | 1 | (1,0) | yoga lesson |
2. Polymorphism and Time-Based Tasks
UniTasker treats deadlines and events differently from todos to enable advanced scheduling features:
Calendar class to store and query deadlines and events polymorphically. This enables range queries (e.g., “show all tasks this week”) without the Calendar needing to know the specific task type.Calendar uses a TreeMap<LocalDate, List<Task>>. This structure provides O(log n) lookup times for specific dates and efficient range-based sub-maps, avoiding the need to iterate through the entire global task list.DateUtils encapsulates three DateTimeFormatter constants, to store deadlines and events in different formats.3. System Integrity and Hierarchy
CategoryList acts as a central task management hub, interfacing with multiple specialized task lists (TodoList, DeadlineList, EventList) to maintain separation of concernsDeadlineList and EventList extends the generic TaskList, inheriting add/delete/mark/contains operations.There are two main types of validations for task.
The following figures explains how tasks are validated based on Time and Occurrence.
DateUtils.parse()
DateUtils is used as a Time Validator.
The sequence diagram below illustrates how a date string entered by the user is parsed, validated, and return as a LocalDateTime. This flow is triggered whenever a timed task, a deadline or event, is added. Recurring events will be illustrated in a different diagram as it does not follow numerical convention.
Example: Add deadline 1 Homework /by 31-12-2025 1800 or Add event 1 Homework /from 31-12-2025 1800 /to 01-01-2026
Note: The command in the diagram has been generalized as a date since DateUtils validates dates only

Parsing Flow Summary:
Implementation Note - isLoading Flag
The isLoading parameter is set to true when DateUtils.parse() is called from the storage layer (file loading), and false during user input. This allows tasks saved in a previous session to be restored if their dates have now passed, while preventing the user form directly scheduling past tasks interactively.
TaskValidator
TaskValidator ensures that there is a unique occurrence of a given task with no overlaps.
Before any task (Todo, Deadline, Event) is added to the system, the AddCommand invokes three sequential validation passes via TaskValidator. These checks ensure that no Task have the same name, workload per day does not exceed set limit and there is no overlap in events. The diagram below shows the full interaction.

Parsing Flow Summary
The Course Tracker feature allows students to manage their courses and track their assessment scores and weightages.
Course Class Diagram

The following sequence diagram shows how a course add command is executed:

Key Design Considerations
CourseParser is kept separate from CommandParser to isolate course-specific parsing logicCourseManager acts as the single point of access for all course operationsCourseStorage is a separate class from the main Storage class, handling course data persistence in its own file (courses.txt) using a different block-based formatweightedScore = (scoreObtained / maxScore) * weightageThe undo feature allows users to reverse the most recent course command that modified data.
The following sequence diagram shows how an undo command is executed:

The following class diagram shows the structure of the undo feature:

Key Design Considerations
UniTasker maintains a Stack<Command> to track undoable commandsCommand interface exposes default undo() and isUndoable() methods so existing commands are unaffectedadd, delete, add-assessment)Current Limitation
Undo is currently supported for course commands only. Other commands such as add todo,
add deadline and add event are not undoable. This is a known limitation planned as a future enhancement.
UniTasker is designed for university students who need to manage multiple courses, assignments, deadlines, and personal tasks simultaneously. These users often:
University students often struggle to keep track of tasks and course assessments across different platforms such as learning portals, calendars and notes. This fragmented approach leads to missed deadlines, poor prioritization, and unnecessary stress.
UniTasker provides a centralized task management solution that consolidates todos, deadlines, events and course information into a single platform. Through a simple command-line interface, it allows students to efficiently organize, update, and review their tasks and assessments. This helps students to stay on top of their workload and focus on completing their academic responsibilities.
| Version | As a … | I want to … | So that I can … |
|---|---|---|---|
| v1.0 | University Student | create categories for each of my courses | organise my tasks by module |
| v1.0 | University Student | view a specific category | focus on tasks related to a single course |
| v1.0 | University Student | assign priority levels to todos in a category | identify important todos easily |
| v1.0 | University Student | sort todos within a category by priority | focus on high-priority todos first |
| v1.0 | University Student | track all tasks with a due date | keep track of all my deadlines |
| v1.0 | University Student | arrange tasks which occur or are due within a certain time period | prioritise tasks that are due earlier |
| v1.0 | University Student | delete all deadlines within a category | quickly remove deadlines in a category |
| v1.0 | University Student | have my deadlines sorted by earliest date | easily identify earliest due deadline |
| v1.0 | University Student | track all tasks with a start date and time and end date and time | keep track of all my events |
| v1.0 | University Student | have my events sorted by earliest date | easily identify events that happen earliest |
| v1.0 | University Student | track all recurring tasks with a start date and time and end date and time | keep track of all my recurring events |
| v1.0 | University Student | add a course | keep track of all the modules I am taking |
| v1.0 | University Student | delete a course | remove modules I am no longer taking |
| v1.0 | University Student | list all courses | see an overview of all my modules |
| v1.0 | University Student | add assessments to a course | track the components that make up the grades |
| v1.0 | University Student | delete an assessment from a course | remove an incorrect or irrelevant assessment from the tracker |
| v1.0 | University Student | view all assessments within a course | understand how my course grading is structured |
| v1.0 | University Student | record my score for an assessment | keep track of my performance in each assessment |
| v2.0 | University Student | delete all marked tasks | quickly clean up completed work across categories |
| v2.0 | University Student | bulk mark and unmark tasks | quickly update the status of multiple tasks at once |
| v2.0 | University Student | search for tasks across all categories | quickly find relevant tasks |
| v2.0 | University Student | customize the maximum tasks permitted per day | schedule my tasks without burning myself out |
| v2.0 | University Student | customize the year of my schedule | plan beyond my acedemic years |
| v2.0 | University Student | customise the duration to add a certain recurring event | adjust it based on the event |
| v2.0 | University Student | have reminders for events and deadlines coming soon | plan my time accordingly to complete them |
| v2.0 | University Student | have different views of events | so that it is clearer to distinguish different type of events |
| v2.0 | University Student | undo my last course action | reverse accidental changes to the course tracker |
17 or above installed.The following steps can be used to manually test category and todo management in UniTasker.
Launch the application.
Add a category:
add category School
Add todos to the category:
add todo 1 finish tutorial
add todo 1 reply email /p 5
add todo 1 submit assignment /p 4
Verify that the category and todos are added correctly:
list category
list category 1
list todo
Mark todos:
mark todo 1 1
mark todo 1 1 2 3
Unmark todos:
unmark todo 1 1 2
Verify the status changes:
list category 1
Set priority for a todo:
priority todo 1 1 3
Sort todos by priority:
sort todo 1
Verify sorting:
list category 1
Reorder todos:
reorder todo 1 1 2
Reorder categories (at least two categories required):
add category Work
reorder category 1 2
Verify reordered results:
list category
Delete a specific todo:
delete todo 2 1
Delete all todos in a category:
delete todo 2 all
Add more todos for further testing:
add todo 1 task one
add todo 1 task two
Mark multiple todos:
mark todo 1 1 2
Delete all marked tasks:
delete marked
Verify that only unmarked tasks remain:
list category 1
Search for tasks:
find tutorial
Verify that only matching tasks are displayed.
Delete a category:
delete category 1
Verify final state:
list category
add deadline 1 Homework /by 23-05-2026 2245
add deadline 1 Project /by 24-05-2026
add deadline 1 Revision /by 23-05-2026 1200mark deadline 1 1 mark deadline 1 2 3list deadlineunmark deadline 1 1unmark deadline 1 2 3list deadlinelist range 23-05-2026 25-05-2026 /deadlinedelete deadline 1 1delete deadline 1 alllist deadlinelist limitlimit year 2040limit task 10list limitexitjava -jar UniTasker.jarlist limit or check welcome message stating current limitsadd event 1 consultation /from 20-05-2026 1800 /to 20-05-2026 1900
add event 1 meeting /from 20-05-2026 2000 /to 20-05-2026
add event 1 workshop /from 21-05-2026 0800 /to 21-05-2026 1000mark event 1 1 mark event 1 2 3list eventunmark event 1 1unmark event 1 2 3list eventlist range 19-05-2026 25-05-2026 /eventdelete event 1 1delete event 1 alllist eventadd recurring 1 CS2113 lecture /from Friday 1600 /to Friday 1800
add recurring 1 CS2113 tutorial /from Thursday 1400 /to Thursday 1500 /date 24-05-2026
add recurring 1 CG2023 lecture /from Tuesday 1600 /to Tuesday 1800 /month 2list event → then list occurrence 1 1 → then mark occurrence 1 1 mark occurrence 1 2 3list event → then list occurrence 1 1unmark occurrence 1 1unmark occurrence 1 2 3list event → then list occurrence 1 1list recurring → then delete recurring 1 1list recurringlist event → then list occurrence 1 1 → then delete occurrence 1 1list event → then list occurrence 1 1delete event 1 alladd recurring 1 CS2113 lecture /from Friday 1600 /to Friday 1800add event 1 consultation /from 20-05-2026 1800 /to 20-05-2026 1900list eventlist event /normallist event /allcourse add CS2113
course add-assessment CS2113 /n Finals /w 40 /ms 100
course score CS2113 /n Finals /s 85
course view CS2113
course delete CS2113
undo with no prior course commands
course add CS2113 then undo
course add-assessment CS2113 /n Finals /w 40 /ms 100 then undo