Developer Guide
- Acknowledgements
- Setting up, getting started
- Design
- Implementation
- Documentation, logging, testing, configuration, dev-ops
- Appendix: Requirements
- Appendix: Instructions for manual testing
- Appendix: Planned Enhancements
Acknowledgements
- This project is based on the AddressBook-Level3 project created by the SE-EDU initiative.
- Libraries used: JavaFX, Jackson, JUnit5
Setting up, getting started
Refer to the guide Setting up and getting started.
Design

.puml
files used to create diagrams in this document docs/diagrams
folder. Refer to the PlantUML Tutorial at se-edu/guides to learn how to create and edit diagrams.
Architecture
The Architecture Diagram given above explains the high-level design of the App.
Given below is a quick overview of main components and how they interact with each other.
Main components of the architecture
Main
(consisting of classes Main
and MainApp
) is in charge of the app launch and shut down.
- At app launch, it initializes the other components in the correct sequence, and connects them up with each other.
- At shut down, it shuts down the other components and invokes cleanup methods where necessary.
The bulk of the app’s work is done by the following four components:
-
UI
: The UI of the App. -
Logic
: The command executor. -
Model
: Holds the data of the App in memory. -
Storage
: Reads data from, and writes data to, the hard disk.
Commons
represents a collection of classes used by multiple other components.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command student delete 1
.
Each of the four main components (also shown in the diagram above),
- defines its API in an
interface
with the same name as the Component. - implements its functionality using a concrete
{Component Name}Manager
class (which follows the corresponding APIinterface
mentioned in the previous point.
For example, the Logic
component defines its API in the Logic.java
interface and implements its functionality using the LogicManager.java
class which follows the Logic
interface. Other components interact with a given component through its interface rather than the concrete class (reason: to prevent outside component’s being coupled to the implementation of a component), as illustrated in the (partial) class diagram below.
The sections below give more details of each component.
UI component
The API of this component is specified in Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, PersonListPanel
, StatusBarFooter
etc. The classes PersonListPanel
, SessionListPanel
, and AttendanceRecordListPanel
inherit from the abstract ListPanel
class which captures the commonalities of a panel in the GUI that displays a list of items. Each item in the list is represented as a card (e.g. SessionCard
). All these, including the MainWindow
and ListPanel
, inherit from the abstract UiPart
class which captures the commonalities between classes that represent parts of the visible GUI.
The UI
component uses the JavaFx UI framework. The layout of these UI parts are defined in matching .fxml
files that are in the src/main/resources/view
folder. For example, the layout of the MainWindow
is specified in MainWindow.fxml
The UI
component,
- executes user commands using the
Logic
component. - listens for changes to
Model
data so that the UI can be updated with the modified data. - keeps a reference to the
Logic
component, because theUI
relies on theLogic
to execute commands. - depends on some classes in the
Model
component, as it displaysPerson
,Session
, andAttendanceRecord
objects residing in theModel
.
Logic component
API : Logic.java
Here’s a (partial) class diagram of the Logic
component:
The sequence diagram below illustrates the interactions within the Logic
component, taking execute("delete 1")
API call as an example.

StudentCommandParser
and DeleteStudentCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline continues till the end of diagram.
How the Logic
component works:
- When
Logic
is called upon to execute a command, it is passed to anAddressBookParser
object which in turn creates a parser that matches the command (e.g.,DeleteStudentCommandParser
) and uses it to parse the command. - This results in a
Command
object (more precisely, an object of one of its subclasses e.g.,DeleteStudentCommand
) which is executed by theLogicManager
. - The command can communicate with the
Model
when it is executed (e.g. to delete a person).
Note that although this is shown as a single step in the diagram above (for simplicity), in the code it can take several interactions (between the command object and theModel
) to achieve. - The result of the command execution is encapsulated as a
CommandResult
object which is returned back fromLogic
.
Here are the other classes in Logic
(omitted from the class diagram above) that are used for parsing a user command:
How the parsing works:
- When called upon to parse a user command, the
AddressBookParser
class creates anXYZCommandParser
(XYZ
is a placeholder for the specific command name e.g.,StudentCommandParser
) which can then create more parsers as required (e.g.,AddStudentCommandParser
) and use the other classes shown above to parse the user command and create aXYZCommand
object (e.g.,AddStudentCommand
) which theAddressBookParser
returns back as aCommand
object. - All
XYZCommandParser
classes (e.g.,StudentCommandParser
,AddStudentCommandParser
,DeleteStudentCommandParser
, …) inherit from theParser
interface so that they can be treated similarly where possible e.g, during testing.
Model component
API : Model.java
The Model
component,
- stores the address book data i.e., all
Person
,Session
, andAttendanceRecord
objects (which are contained inUniquePersonList
,UniqueSessionList
andUniqueAttendanceRecordList
objects respectively), as well as the IDs of the nextPerson
orSession
to be added. - stores the currently filtered
Person
andSession
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<Person>
andObservableList<Session>
that can be ‘observed’ e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. - stores a
UserPref
object that represents the user’s preferences. This is exposed to the outside as aReadOnlyUserPref
objects. - does not depend on any of the other three components (as the
Model
represents data entities of the domain, they should make sense on their own without depending on other components)
Storage component
API : Storage.java
The Storage
component,
- can save both address book data and user preference data in JSON format, and read them back into corresponding objects.
- inherits from both
AddressBookStorage
andUserPrefStorage
, which means it can be treated as either one (if only the functionality of only one is needed). - depends on some classes in the
Model
component (because theStorage
component’s job is to save/retrieve objects that belong to theModel
)
Common classes
Classes used by multiple components are in the tutorly.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Undo feature
There are several ways to build an undo feature. One way is to keep a stack of AddressBook
s in memory. Each time a change is made to the AddressBook
, push a copy of the current AddressBook
onto the stack. When the user requests an undo, pop the top AddressBook
from the stack and set it as the current AddressBook
. This is a straightforward and relatively less error-prone way to implement undo. However, it has the following drawbacks:
- It requires a lot of memory to store multiple copies of the
AddressBook
object. - It is not efficient to copy the entire
AddressBook
object every time a change is made.
Our implementation
We build upon this idea, but instead of keeping a stack of AddressBook
s, we keep a stack of Command
s. Each time a change is made to the AddressBook
, we push the reverse of the command that made the change onto the stack. When the user requests an undo, we pop the top Command
from the stack and execute it. This way, we do not need to keep multiple copies of the AddressBook
object in memory. This is more efficient in terms of memory usage and performance.
Each Command
defines its reverse operation during execution. When building the CommandResult
, the Command
also specifies the reverse command to be executed when the user requests an undo. This is kept track of by LogicManager
, which maintains a stack of Command
s. When the undo command is executed, LogicManager
pops the top Command
from the stack and executes it. The Command
then executes its reverse operation on the Model
to revert the changes made by the original command.
The following sequence diagram shows how an undo operation goes through the Logic
component, when used to undo a student addition.

AddStudentCommand
, UndoCommand
, and DeleteStudentCommand
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline continues till the end of diagram.
Documentation, logging, testing, configuration, dev-ops
Appendix: Requirements
Product scope
Target user profile:
- private tutor
- need to track large number of students’ details and sessions
- prefer desktop apps over other types
- can type fast
- prefers typing to mouse interactions
- is reasonably comfortable using CLI apps
Value proposition: tracks and manages students’ details faster than a typical mouse/GUI driven app, reducing manual effort and ensuring better organization.
User stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
new user | see usage instructions | refer to instructions when I forget how to use the app |
* * * |
user | add a new student with basic details | begin tracking their progress |
* * * |
user | record additional student details | recall other information about the student |
* * * |
user with many students | search a student by name or phone number | quickly find their details before a session without going through the entire list |
* * * |
user | edit student records | update student details when they change |
* * * |
long-time user | delete old student records | stop tracking students that I no longer teach |
* * * |
user | record student attendance | track my student’s participation |
* * |
potential user | see the app populated with sample data initially | easily visualise how it will look like in real use |
* * |
user ready to start using the app | delete all sample data | start fresh with my actual students |
* * |
user | log lesson feedback | keep track of progress of a student in the session |
* * |
user | create custom tags for students | categorise them based on needs |
* |
user with many students | sort students by any field | locate a student easily |
* |
user | filter students by custom tags | see all students with particular needs |
* |
expert user | bulk-edit lesson notes or assignments | save time by updating multiple records at once |
* |
user teaching multiple subjects | customise tracking fields for different subjects | tailor my records to different teaching needs |
* |
user teaching group classes | create group sessions with multiple students | track their progress collectively as a class |
* |
user | generate a progress report for a student | share updates with parents |
* |
user | receive a weekly summary of my sessions | review my workload |
* |
user | set reminder for upcoming sessions | remember upcoming lessons |
* |
user | view reminders for upcoming sessions | plan my schedule |
* |
user | hide private contact details | minimise chance of someone else seeing them by accident |
Use Cases
(For all use cases below, the System is Tutorly
, and the Actor is the tutor
, unless specified otherwise.)
Use case: Add a student record
MSS
- Tutor requests to add a new student with the required details (Name, Phone, Email, Address, Tag, Memo).
- Tutorly validates the input.
-
Tutorly adds the student profile to the database and confirms success.
Use case ends.
Extensions
- 1a. Tutor does not provide all compulsory fields.
- 1a1. Tutorly prompts for the missing information.
- 1a2. Tutor enters the all the required details
- Use case resumes at step 2.
- 2a. Tutor provides invalid input for any field.
- 2a1. Tutorly displays an appropriate error message.
- 2a2. Tutor corrects the input.
- Use case resumes at step 2.
- 2b. The student already exists (Same Name).
- 2b1. Tutorly displays an error message indicating the student already exists.
- Use case ends.
Use case: Search for a student record
MSS
- Tutor requests to search for a student by entering a query.
- Tutorly validates the search query.
-
Tutorly retrieves and displays matching student profiles.
Use case ends.
Extensions
- 3a. No students match the search query.
- 3a1. Tutorly responds that no students match the search query.
- Use case ends.
Use case: Update a student record
MSS
- Tutor requests to update a student record by providing the student’s Identifier and updated details. (e.g., Name, Phone, Email, Address, Tag, Memo).
- Tutorly validates the input.
-
Tutorly updates the student profile and confirms success.
Use case ends.
Extensions
- 1a. Tutor does not provide any update parameters.
- 1a1. Tutorly displays an error message indicating that there must be at least one update parameter.
- Use case ends.
- 2a. The student Identifier does not exist.
- 2a1. Tutorly responds that the student does not exist.
- Use case ends.
- 2c. Tutor provides invalid input for any field.
- 2c1. Tutorly displays an appropriate error message.
- 2c2. Tutor corrects the input.
- Use case resumes at step 2.
Use case: Delete a student record
MSS
- Tutor requests to delete a student record by providing the student’s Identifier.
- Tutorly validates the request and performs the action.
-
Tutorly confirms the success of the operation.
Use case ends.
Extensions
- 2a. The student Identifier does not exist.
- 2a1. Tutorly displays an error message indicating the student does not exist.
- Use case ends.
Use case: Add a Session
MSS
- Tutor requests to add a new session with the required details (Timeslot, Subject).
- Tutorly validates the input.
-
Tutorly adds the session to the database and confirms success.
Use case ends.
Extensions
- 1a. Tutor does not provide all required fields.
- 1a1. Tutorly prompts for the missing information.
- Use case resumes at step 2.
- 2a. Tutor provides invalid input for any field.
- 2a1. Tutorly displays an appropriate error message.
- 2a2. Tutor corrects the input.
- Use case resumes at step 2.
- 2b. The timeslot overlaps with another existing session.
- 2b1. Tutorly displays an error message indicating the timeslot overlaps with an existing session.
- Use case ends.
Use case: Enrol a student to a session
MSS
- Tutor requests to enrol a new student to an existing session by providing the student’s identifier and Session ID.
- Tutorly validates the input.
-
Tutorly adds the student profile to the session and confirms success.
Use case ends.
Extensions
- 1a. Tutor does not provide all required fields.
- 1a1. Tutorly prompts for the missing information.
- 1a2. Tutor corrects the input.
- Use case resumes at step 2.
- 2a. Tutor provides invalid input for any field.
- 2a1. Tutorly displays an appropriate error message.
- 2a2. Tutor corrects the input.
- Use case resumes at step 2.
–
Use case: Mark attendance for a tutoring session
MSS
- Tutor requests to mark a session as attended by providing the student’s identifier, Session ID, and attendance status.
- Tutorly validates the input.
- Tutorly logs the attendance.
-
Tutorly confirms success.
Use case ends.
Extensions
- 2a. The student identifier does not exist.
- 2a1. Tutorly displays an error message showing the student identifier does not exist.
- Use case ends.
- 2b. The Session ID does not exist.
- 2b1. Tutorly displays an error message showing the session ID does not exist.
- Use case ends.
- 2c. The student is not enrolled in the session.
- 2c1. Tutorly displays an error message indicating the student is not enrolled in the session.
- Use case ends.
Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java
17
or above installed. - Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage, ensuring that typical operations (such as loading, searching, and editing records) complete within 3 seconds.
- The graphical user interface shall be easy to use such that a new user can complete primary workflows (e.g., adding a record or searching for a student) within 5 minutes of first use.
- A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
- The codebase should be modular and well-documented, allowing for easier updates or the integration of future features. At least 90% of the codebase shall have inline or external documentation, and modules must have well-defined interfaces.
- The source code should be open source and shall be released under an approved open source license (e.g., MIT, Apache 2.0) and published in a publicly accessible repository with minimal entry barriers.
Glossary
- Tutor: An educator who uses Tutorly to manage student details, schedule sessions, log lesson notes, and track attendance.
- Student Record / Student Profile: The digital record for each student stored in Tutorly.
- Session: A scheduled tutoring meeting or lesson.
- Lesson: The content delivered during a session.
Appendix: Instructions for manual testing
Launch and Shutdown
-
Initial Launch
- Download the jar file and copy it into an empty folder.
- Double-click the jar file.
- Expected: Shows the GUI with a set of sample students. The window size may not be optimal.
-
Saving Window Preferences
- Resize the window to an optimal size. Move the window to a different location. Close the window.
- Re-launch the app by double-clicking the jar file.
- Expected: The most recent window size and location are retained.
Saving Data
-
Dealing with Missing Data Files
- Simulate a missing file by renaming or deleting the data file.
- Launch the application.
- Expected: Application should handle the error gracefully, by creating a new data file containing the sample data once any command is successfully executed. (For student/session add commands, it will also include the added student/session.)
-
Dealing with Corrupted Data Files
- Simulate a corrupted file by modifying the data file to be unreadable.
- Launch the application.
- Expected: Application should clear the corrupted data file and create a empty data file once any command is successfully executed.
Adding a Student
-
Adding a New Student
- Test case: Add a new student with valid details.
student add n/John Doe
- Expected: Student is added successfully, and a confirmation message is shown.
- Test case: Add a new student with invalid details (e.g., missing required fields
student add p/12345678
).- Expected: Error message is shown, prompting for correct input.
- Test case: Add a new student with valid details.
Deleting a Student
-
Deleting a Student
Prerequisite: The student must exist in the list.
- Test case:
student delete 1
- Expected: Student with id 1 is deleted from the list. Details of the deleted students are shown.
- Test case:
student delete 0
- Expected: No student is deleted. Error details are shown in the status message.
- Other incorrect delete commands to try:
student delete
,student delete x
(where x is a number that is larger than the list size)- Expected: Similar to previous.
- Test case:
Searching for a Student
-
Search for a Student
- Test case: Search for a student by name.
student search n/John
- Expected: A message “x students listed!” is shown. Matching student profiles are displayed. (x is the number of students matching the search query. If no matches are found, x = 0. If multiple matches are found, x > 1. If only one match is found, x = 1. The list of students is filtered to show only those matching the search query.)
- Test case: Search with a query that has no matches.
student search n/NonExistent
- Expected: “0 students listed!” message is shown.
- Test case: Search for a student by name.
Editing a Student
-
Editing a Student
- Test case: Edit a student’s details with valid input.
student edit 1 n/John Smith
- Expected: Student details are updated successfully, and a confirmation message is shown.
- Test case: Edit a student’s details with invalid input.
student edit x n/John Smith
(x is a number larger than the list size)- Expected: Error message “Student not found!” is shown.
- Test case: Edit a student’s details with missing required fields.
student edit 1 n/
- Expected: Error message is shown, prompting for correct input.
- Test case: Edit a student’s details with valid input.
Adding a Session
-
Adding a Session
- Test case: Add a new session with valid details.
session add t/30 Mar 2025 11:30-13:30 sub/Math
- Expected: Session is added successfully, and a confirmation message is shown.
- Test case: Add a new session with invalid details (e.g., missing required fields).
session add
- Expected: Error message is shown, prompting for correct input.
- Test case: Add a new session with overlapping timeslots.
session add t/30 Mar 2025 11:30-13:30 sub/Science
(Suppose there is a session whose time slot has overlapped with the new session’s time slot.)- Expected: Error message is shown, indicating the timeslot overlaps with an existing session.
- Test case: Add a new session with valid details.
Marking Attendance for a Session
-
Marking attendance for a session
Prerequisite: The session and student must exist and the student must be enrolled in the session.
- Test case: Mark a session with valid input.
session mark 1 ses/1
- Expected: Attendance is marked successfully, and a confirmation message is shown.
- Test case: Mark a session as completed with invalid input (e.g., invalid session id).
session mark 1 ses/x
(x is a number larger than the list size)- Expected: Error message is shown, prompting for correct input.
- Test case: Mark a session which the student is not enrolled in.
session mark 1 ses/2
- Expected: Error message is shown, indicating the student is not enrolled in the session.
- Test case: Mark a session with valid input.
Adding Feedback
-
Adding feedback for a session
Prerequisite: The session and student must exist and the student must be enrolled in the session.
- Test case: Add feedback with valid input.
session feedback 1 ses/1 f/Great session!
- Expected: Feedback is added successfully, and a confirmation message is shown.
- Test case: Add feedback with invalid input (e.g., missing required fields).
session feedback
- Expected: Error message is shown, prompting for correct input.
- Test case: Add feedback for a session which the student is not enrolled in.
session feedback 1 ses/2 f/Great session!
(Suppose student 1 is not enrolled in session 2)- Expected: Error message is shown, indicating the student is not enrolled in the session.
- Test case: Add feedback with valid input.
Undo Feature
-
Undo Operations
- Test case: Perform an action (e.g., add a student), then undo the action.
- Expected: The action is undone, and the previous state is restored. There is also a confirmation message shown.
- Test case: Perform an action (e.g., add a student), then undo the action.
Error Handling
-
Invalid Commands
- Test case: Enter an invalid command.
- Expected: Error message is shown, indicating the command is not recognized/unknown.
- Test case: Enter an invalid command.
-
System Errors
- Test case: Simulate a system error (e.g., by corrupting a data file).
- Expected: Application handles the error gracefully, removing or replacing the corrupted data file
- Test case: Simulate a system error (e.g., by corrupting a data file).
These instructions provide a starting point for testers to work on; testers are expected to do more exploratory testing.
Appendix: Planned Enhancements
- Enhance undo functionality for the add command to allow for rollback of assigned IDs.
- Improve the output display to seamlessly present long messages without requiring scrolling.
- Refine cell selection behavior in the UI to reduce flickering and improve responsiveness.
- Optimize the list view so it dynamically adjusts its height in response to changes in the filtered item count.
- Enhance the UI focus management to ensure that the correct item is consistently highlighted.
- Add support for multiple students of the same name.
- A
redo
command to undo anundo
command. - Improved
search
command forstudent
andsession
with other fields including tags and date/time range with control over matching any or all fields. -
class
management commands that handle adding of multiple sessions and mass enrolling/marking of attendance for students. - Viewing sessions each student is enrolled in via the
students
tab.