layout | title |
---|---|
page |
Developer Guide |
Thank you for your interest in the developing of Notor! This is an open-source project aimed at helping mentors take quick, efficient notes to facillitate effective and efficient mentoring of many mentees. The design principles scaffolding Notor are as follows.
- Efficient UX for the User:
- You shouldn't have to wait for Notor; it should simply run -- quickly and without hassle.
- Look for how you can make the process faster, more streamlined, or more effective for our clients: mentors.
- CLI-first
- We target fast-typers who are comfortable taking notes on their computer.
In particular, we tackle the needs of mentor professors, who tend to be busy and are assigned mentees they are unlikely to personally know or even contact often outside of the mentor relationship. Key features of Notor which scaffold this are:
- Powerful Organisation which is up to the user to manage many mentees
- Group mentees, and place groups into subgroups for greater control
- Add tags to mentees and sort by tags to easily identify meta-data
- Archive contacts you're no longer speaking to
- A clean note-taking system
- designed so that they can take notes concurrently with meeting the mentee so no information is forgotten
This project is a further iteration of the AddressBook-Level 3 ( AB-3) project. All features we have are in addition to those already present in AB-3. Removed features may or may not be listed as well.
- Table of Contents {:toc}
Refer to the guide Setting up and getting started.
- Command structure: The order in which parameters and command words must be written in order for the command to be correctly parsed
- Dummy data: Sample data used in testing or example data present on first launch of application
- Group: A container containing
Person
objects with shared traits that is created by the user - Key power features: Essential features that will be used often when running the software application
- Mainstream OS: Windows, Linux, Unix, MacOS
- Metadata: Personal data about a
Person
object - Note: A general description of each
Person
to record their activities, with last edit timestamp attached - Pin: Fixing a
Person
to the top of the current list ofPerson
objects or aGroup
- Subgroup: A child of a
Group
used to store multiple persons based on a more specific category thanGroup
. A ** Subgroup** can be created by specifying the parent group of the Subgroup. A person in a Subgroup is automatically in the parentGroup
as well - Tag: A string descriptor attached to
Group
objects orPerson
objects - Ungrouped: Used to describe a
Person
object with no grouping
The Architecture of our iteration is built upon AB-3. Please refer to the AB-3 Architecture section for the general Architectural design of the app. Only changes will be listed here.
Due to the addition of many new commands and refactoring of the command structure, we have amended the classes related to managing commands.
Parser
now takes in genericT extends Command
since we have multiple types of commands, each with their own unique parserExecutor
instances are created by eachCommand
class, which then handle the actual execution of commands and returning ofCommandResult
- Commands now come in 3 general types,
PersonCommand
,GroupCommand
andCommand
PersonCommand
operates onPerson
objectsGroupCommand
operates onGroup
objectsCommand
operates without either aPerson
orGroup
object
Parser
andExecutor
classes come in the same 3 categories asCommand
classesNotorParser
now parses both thecommandWord
andsubCommandWord
for user commandscommandWord
refers to eitherPerson
,Group
or one of the object agnostic commandssubCommandWord
refers to an operation that can be carried out on aPerson
orGroup
, such asfind
ortag
New Workflow for Adding Commands:
- Create a
XYZCommand
class that extends eitherPersonCommand
,GroupCommand
or simplyimplements Command
. - Create a
XYZCommandParser
class that extends the same type ofParser
as theCommand
above is. - Add the new
XYZCommandParser
to theparse()
method inNotorParser
. - Create a
XYZCommandExecutor
class that extends the same type ofExecutor
as theCommand
from step 1. - Implement all required methods and ensure all fields used by the methods are present.
Notor allows you to search for groups and people, and both searches have slightly different requirements.
Lets break down what happens to call a person comamnd.
(placeholder API for now, will update to our own link later when implemented.)
**
API** : Model.java
-
Person
does not contain theAddress
field anymore. -
Person
contains a newNote
field,SuperGroup
field andSubGroup
field. -
Person
does not contain direct reference toSuperGroup
andSubGroup
but strings of SuperGroup and for display purposes. -
This UML diagram is the current class structure implemented.
Here is the better class structure to be implemented:
Trie
allows tags to be autocompleted as commands are entered.- Storing
String
objects in aTrie
in Notor allows all tags to only get created once instead of once per object. - Storing tags as
String
objects in a trie is simpler than a dedicatedTag
class.
(placeholder API for now, will update to our own link later when implemented.)
**
API** : Storage.java
The Storage
component,
- now includes a new
Archive
Storage component Archive
allows users to temporarily removePerson
s from their Address Book
**
API** : Trie.java
- Allows grouping and autocompletion of
Tag
andCommand
objects. - Supports addition and deletion of items.
- Supports finding of first item.
- Supports finding of first item that contains specified keyword.
This section describes some noteworthy details on how certain features are implemented.
The proposed undo/redo mechanism is facilitated by VersionedNotor
. It extends Notor
with an undo/redo
history, stored internally as an NotorStateList
and currentStatePointer
. Additionally, it implements the
following operations:
VersionedNotor#commit()
— Saves the current address book state in its history.VersionedNotor#undo()
— Restores the previous address book state from its history.VersionedNotor#redo()
— Restores a previously undone address book state from its history.
These operations are exposed in the Model
interface as Model#commitNotor()
, Model#undoNotor()
and Model#redoNotor()
respectively.
Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
Step 1. The user launches the application for the first time. The VersionedNotor
will be initialized with the
initial address book state, and the currentStatePointer
pointing to that single address book state.
Step 2. The user executes delete 5
command to delete the 5th person in the address book. The delete
command
calls Model#commitNotor()
, causing the modified state of the address book after the delete 5
command executes
to be saved in the NotorStateList
, and the currentStatePointer
is shifted to the newly inserted address book
state.
Step 3. The user executes add n/David …
to add a new person. The add
command also calls Model#commitNotor()
, causing another modified address book state to be saved into the NotorStateList
.
Step 4. The user now decides that adding the person was a mistake, and decides to undo that action by executing
the undo
command. The undo
command will call Model#undoNotor()
, which will shift the currentStatePointer
once to the left, pointing it to the previous address book state, and restores the address book to that state.
The following sequence diagram shows how the undo operation works:
The redo
command does the opposite — it calls Model#redoNotor()
, which shifts the currentStatePointer
once
to the right, pointing to the previously undone state, and restores the address book to that state.
Step 5. The user then decides to execute the command list
. Commands that do not modify the address book, such
as list
, will usually not call Model#commitNotor()
, Model#undoNotor()
or Model#redoNotor()
.
Thus, the NotorStateList
remains unchanged.
Step 6. The user executes clear
, which calls Model#commitNotor()
. Since the currentStatePointer
is not
pointing at the end of the NotorStateList
, all address book states after the currentStatePointer
will be
purged. Reason: It no longer makes sense to redo the add n/David …
command. This is the behavior that most modern
desktop applications follow.
The following activity diagram summarizes what happens when a user executes a new command:
Aspect: How undo & redo executes:
-
Alternative 1 (current choice): Saves the entire address book.
- Pros: Easy to implement.
- Cons: May have performance issues in terms of memory usage.
-
Alternative 2: Individual command knows how to undo/redo by itself.
- Pros: Will use less memory (e.g. for
delete
, just save the person being deleted). - Cons: We must ensure that the implementation of each individual command are correct.
- Pros: Will use less memory (e.g. for
{more aspects and alternatives to be added}
{Explain here how the data archiving feature will be implemented}
Target user profile: mentor professors
- has a need to manage a significant number of contacts
- prefer desktop apps over other types
- can type fast
- prefers typing to mouse interactions
- is reasonably comfortable using CLI apps
- has groups of contacts that have different needs
Value proposition: manage contacts faster than a typical mouse/GUI driven app
Priorities:
- High - must have
- Medium - nice to have
- Low - unlikely to have
- Default - already implemented)
As a … | I want to … | So that I can … | Priority | Status | When? |
---|---|---|---|---|---|
on the go user | add notes without wifi or internet access | use the app anywhere | Default | Iteration 1.2 | |
new user | have dummy data | see what my entries look like | Default | Iteration 1.2 | |
new user | remove all dummy entries easily | start doing work quickly | Medium | Iteration 1.2 | |
general user, new user | see a simple UI which shows essential features immediately and hides away advanced features till you need them | slowly learn the features | High | Iteration 1.2 | |
general user, mentor professor, module professor | take notes with timestamps | see my notes chronologically | High | Iteration 1.2 | |
general user, mentor professor, module professor | edit the groups or tags of a student | High | Iteration 1.2 | ||
mentor professor | group the students based on the mentoring subjects | tag or comment on each group separately | High | Iteration 1.2 | |
general user, mentor professor, module professor | have easy-to-remember commands for inputting information | High | Iteration 1.2 | ||
general user | delete groups/subgroups | High | Not started | Iteration 1.2 | |
experienced user, general user | add tags cumulatively | not retype my old tags | High | Not started | Iteration 1.2 |
new user | see clear error messages that explains how to enter the correct command | learn the right syntax from my errors | High | Not started | Iteration 1.2b |
experienced user, general user, mentor professor, module professor | edit previous notes I have taken | High | Iteration 1.2b | ||
mentor professor, module professor, new user | have an easily accessible help page | High | Iteration 1.2b | ||
experienced user, general user, mentor professor, module professor, new user, on the go user | search by tag/category | find students based on tag/category | High | Not started | Iteration 1.2b |
general user, mentor professor, module professor | have notes attached to categories | save notes relevant to a whole group | Medium | Iteration 1.2b | |
general user | create general notes | take down any thoughts I have on the fly | Medium | Not started | Iteration 1.2b |
new user | see a confirmation message if I choose to delete something | avoid accidental deletions | Medium | Iteration 1.2b | |
experienced user, mentor professor, module professor | specify the kinds of data attached to contacts which is viewable from the front page | only see information that I need | Nice To Have | Iteration 1.3 | |
general user | display all of the user information in an easy to reference format | read large amounts of information at once easily | Medium | Iteration 1.3 | |
mentor professor, module professor | initialise the contacts for many students at once | add similar students by batch | Medium | Iteration 1.3 | |
mentor professor | see the last time I contacted a student | know if I need to check up on them | Medium | Iteration 1.3 | |
new user | get prompted for the arguments. | learn the command structure | Medium | Iteration 1.3 | |
experienced user | pin users I need to access regularly | see commonly accessed users easily | Low | Iteration 1.3b | |
experienced user | see personal metadata such as number of high-priority students & number of contacts | determine my own usage | Low | Iteration 1.3b | |
new user | see a short tutorial | get familiar with key features | Low | Not started | Iteration 1.3b |
general user | see a list of recently looked up people | quickly add on thoughts on the people I've just seen | Medium | Iteration 1.3b | |
mentor professor, module professor | hide groups | ignore groups no longer relevant to me | Low | Iteration 1.3b | |
general user, mentor professor, module professor, on the go user | export the data to PDF & CSV / Excel | reference the information in another format | Low | Iteration 1.3b | |
experienced user | sort by complete inclusion of terms rather than matching any term | narrow down my search results easily | Low | Not started | Iteration 1.3b |
general user | create general reminders | remind myself of tasks I need to do for my mentees/students | Low | Not started | Iteration 1.3b |
experienced user, module professor | set my own command aliases | use my own commands when I am used to them | Low | Delay | |
experienced user, mentor professor, module professor | use shorter commands | save time | Medium | Delay |
(For all use cases below, the System is the Notor
and the Actor is the user
, unless specified
otherwise)
Use case: Add a note to a person
MSS
-
User requests to add a note to the person
-
Notor shows a list of persons
-
User requests to add a note to a specific person in the list
-
Notor opens up a pop up dialogue for the user to type the note for the person
-
User requests to save the note to the person
-
Notor stores the book to the person
-
Notor saves the note to storage
Use case ends.
Extensions
-
2a. The list is empty. Use case ends.
-
3a. The given index is invalid.
- 3a1. Notor shows an error message. Use case resumes at step 2.
Use case: User types a command
MSS
-
User starts typing a command in Notor
-
Notor shows possible commands starting with what user has typed
-
User presses tab to select the right command
-
User presses enter to execute the selected command
-
Notor runs command (UC1)
Use case ends.
Extensions
- 2a. The typed string is not in any command.
- 2a1. Notor displays no commands. Use case resumes at step 1.
- Should work on any mainstream OS as long as it has Java
11
or above installed. - Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage.
- 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.
- Installing a new update shall not in any way, modify or erase existing data and value from the previous version, and the new update should be compatible with the data produced earlier within the system.
- Should be able to store notes in English language, and provisions shall be made to support all languages.
- The system should be able to handle notes with at most 1000 lines without any noticeable decrease in performance, so that users can keep extensive notes on their mentees.
- The user should not lose any data if the system exits prematurely.
- The system should be able to reply to the prompt or command from the user within 3 seconds.
- The system should be intuitive to use for a mentor professor.
- Should ensure personal data privacy and security of data access.
- Software testing will require the use of automated testing. The test will be deleted after successful implementation of the software system.
Given below are instructions to test the app manually.
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
-
-
Saving window preferences
-
Resize the window to an optimum 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 is retained.
-
-
{ more test cases … }
-
Deleting a person while all persons are being shown
-
Prerequisites: List all persons using the
list
command. Multiple persons in the list. -
Test case:
delete 1
Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated. -
Test case:
delete 0
Expected: No person is deleted. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
delete
,delete x
,...
(where x is larger than the list size)
Expected: Similar to previous.
-
-
{ more test cases … }
-
Dealing with missing/corrupted data files
- {explain how to simulate a missing/corrupted file, and the expected behavior}
-
{ more test cases … }