This project is based on the AddressBook-Level3 project created by the SE-EDU initiative.
This project also utilised CoPilot and ChatGPT to assist in the development and documentation process.
Jayne - I had ChatGPT's assistance for HelpCommand code, documentation and UI edits done by me.
Jia Hui - I used the assistance of Github CoPilot for most of my code. I also used the assistance of ChatGPT mainly for documentation, UI edits for my code.
Drustan - I had Github CoPilot's assistance for most of the code attributed to me. Including but not limited to functional code, test code, github workflow files, and documentation.
Charmaine - I had the assistance of ChatGPT for some of my functional code (other than AddNote Command which was referenced from the tutorial for Remark Command). I mainly had assistance for test code, documentation and UI edits done by me.
Refer to the guide Setting up and getting started.
lightbulb Useful Tip:
.puml files used to create diagrams in this document are in the docs/diagrams folder in our code repository.
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.
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 delete S0123456A.
Each of the four main components (also shown in the diagram above),
interface with the same name as the Component.{Component Name}Manager class (which follows the corresponding API interface 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.
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. All these, including the MainWindow, 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,
Logic component.Model data so that the UI can be updated with the modified data.Logic component, because the UI relies on the Logic to execute commands.Model component, as it displays Person object residing in the Model.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 S0123456A") API call as an example.
Note: The lifeline for DeleteCommandParser and DeleteCommand 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:
Logic is called upon to execute a command, it is passed to an AddressBookParser object which in turn creates a parser that matches the command (e.g., DeleteCommandParser) and uses it to parse the command.Command object (more precisely, an object of one of its subclasses e.g., DeleteCommand) which is executed by the LogicManager.Model when it is executed (e.g. to delete a person).Model).CommandResult object which is returned back from Logic.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:
AddressBookParser class creates an XYZCommandParser (XYZ is a placeholder for the specific command name e.g., AddCommandParser) which uses the other classes shown above to parse the user command and create a XYZCommand object (e.g., AddCommand) which the AddressBookParser returns back as a Command object.XYZCommandParser classes (e.g., AddCommandParser, DeleteCommandParser, ...) inherit from the Parser interface so that they can be treated similarly where possible e.g, during testing.API : Model.java
The Model component,
Person objects (which are contained in a UniquePersonList object).Person objects (e.g. results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiable ObservableList<Person> 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 changes.UserPref object that represents the user’s preferences. This is exposed to the outside as a ReadOnlyUserPref object.Model represents data entities of the domain, they should make sense on their own without depending on other components).API : Storage.java
The Storage component,
AddressBookStorage and UserPrefStorage, which means it can be treated as either one (if only the functionality of only one is needed).Model component (because the Storage component's job is to save/retrieve objects that belong to the Model).Classes used by multiple components are in the seedu.addressbook.commons package.
This section describes some noteworthy details on how certain features are implemented.
The add feature is implemented using the AddCommand class. The AddCommand object takes in a Person object.
Person object is created if the following conditions are satisfied:
Person in ClinicMateThe add mechanism is facilitated by AddressBook. It implements Model#addPerson(Person p)which allows users to add patients’ contacts
and relevant patient information into ClinicMate. These operations are exposed in the Model interface as Model#addPerson(Person p).
Apart from that, the feature also includes the following operation in Model, which implements the Model interface:
Model#hasPerson(Person person): Checks if the Person to be added is already an existing Person profile in ClinicMateGiven below is an example usage scenario and how the add mechanism behaves at each step.
Step 1. The user launches the application for the first time. ClinicMate will be initialized with the initial address book state.
Step 2. The user executes add n\John Doe p\12345678 e\john@mail.com i\T0123456A ag\12 s\M a\John street, block 123, #01-01 to add the person in the address book with the unique IC number T0123456A.
The add command calls Model#addPerson(Person p), causing the modified state of the address book after the add n\John Doe … command executes to be saved.
Note: If a command fails its execution, it will not call Model#addPerson(Person p), so the address book state will not be saved.
The following sequence diagram illustrates how the add command works and goes through the Logic and Model components.
Note: The lifeline for AddCommandParser and AddCommand should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The following activity diagram summarizes what happens when a user executes a new add command:
Aspect: How to add:
Alternative 1 (current choice): Requires all the relevant fields (e.g. name, phone, email, IC number, age, sex, address).
Alternative 2: Allow users to add patients by adding fields as and when is needed (i.e. not make all the fields compulsory).
Aspect: Display of new contact when command is successful:
Aspect: Display of error message when command is unsuccessful:
The addnote mechanism is facilitated by AddressBook. It implements AddressBook#setPerson(Person target, Person editedPerson) which allow users to add/replace patients’ notes in the addressbook.
These operations are exposed in the Model interface:
Model#getPersonIfExists: Checks if the Person with the predicate existsModel#setPerson: Changes the note parameter of the target PersonModel#isPersonDisplayed: Checks if the Person has their notes displayed in the patient notes panelModel#setDisplayedNote: If Model#isPersonDisplayed returns true, the notes displayed will be updatedGiven below is an example usage scenario and how the addnote mechanism behaves at each step.
Step 1. The user launches the application. The AddressBook will be initialized with the initial address book state.
Step 2. The user executes addnote T0123456A n\Covid to add a note to the person in ClinicMate with the unique IC number T0123456A.
The addnote command calls Model#setPerson(Person target, Person editedPerson), causing the modified state of ClinicMate after the addnote T0123456A n\Covid command executes to be saved.
Note: If a command fails its execution, it will not call Model#setPerson(Person target, Person editedPerson), so the address book state will not be saved.
The following sequence diagram shows how an addnote operation goes through the Logic component:
Note: The lifeline for AddNoteCommandParser and AddNoteCommand should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The following activity diagram summarizes what happens when a user executes a new addnote command:
Aspect: How to add or replace:
Alternative 1 (Current Choice): Have a flag (-replace) to allow users to replace the whole note section of specified patient.
This is an extension of the normal addnote command where new notes are appended to the existing note itself.
Alternative 2: Allow users to only add notes to patients.
Aspect: Display of new note when command is successful:
Aspect: Display of error message when command is unsuccessful:
The find mechanism is facilitated by ModelManager. It implements ModelManager#updateFilteredPersonList(Predicate predicate)
which allow users to find patients in ClinicMate.
These operations are exposed in the Model interface as Model#updateFilteredPersonList(Predicate predicate).
The predicate argument takes in a IdentityCardNumberMatchesPredicate to filter the list of patients.
Given below is an example usage scenario and how the find mechanism behaves at each step.
Step 1. The user launches the application. The AddressBook will be initialized with the initial address book state.
Step 2. The user executes find S0123456A to find the person in the address book with the unique IC number S0123456A. The find command calls Model#updateFilteredPersonList(Predicate predicate),
causing the modified state of the address book after the find S0123456A command executes to be displayed.
Note: If a command fails its execution, it will not call Model#updateFilteredPersonList(Predicate predicate), so the address book state will not be displayed.
The following sequence diagram shows how a find operation goes through the Logic component:
Note: The lifeline for FindCommand and FindCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The following activity diagram summarizes what happens when a user executes a new command:
Aspect: Filtering patients
Alternative 1 (Current Choice): Requires users to input a full and valid IC number
Alternative 2: Match all relevant patients' profiles even if the user enters a partial IC number
Aspect: Display of filtered list when command is successful:
Aspect: Display of error message when command is unsuccessful:
The delete mechanism is facilitated by Addressbook. It implements Addressbook#removePerson(Person key) which allow users to delete patients in the addressbook.
These operations are exposed in the Model interface as Model#getPersonIfExists(Predicate predicate) and Model#deletePerson(Person target).
Given below is an example usage scenario and how the delete mechanism behaves at each step.
Step 1. The user launches the application. The AddressBook will be initialized with the initial address book state.
Step 2. The user executes delete S0123456A to delete the person in the address book with the unique IC number S0123456A.
The delete command calls Model#deletePerson(Person target), causing the modified state of the address book after the delete S0123456A command executes to be saved.
Note: If a command fails its execution, it will not call Model#deletePerson(Person target), so the address book state will not be saved.
The following sequence diagram shows how a delete operation goes through the Logic component:
Note: The lifeline for DeleteCommandParser and DeleteCommand should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The following activity diagram summarizes what happens when a user executes a new command:
Aspect: Display of updated person list when command is successful:
Aspect: Display of error message when command is unsuccessful:
The edit mechanism is facilitated by AddressBook. It implements AddressBook#setPerson(Person target, Person editedPerson) which allow users to edit patient’s details in the addressbook.
These operations are exposed in the Model interface as Model#setPerson(Person target, Person editedPerson).
The edit feature has the following operations in ModelManager which implements the Model interface:
Model#getPersonIfExists(predicate) : Returns the specified Person if they exist in the list.
Model#setPerson: Replaces the given Person target with editedPerson. Target must exist in the address book. The identity of editedPerson must not be the same as another existing person in the address book.
Model#hasPerson: Returns true if the address book contains the person in question.
Model#updateFilteredPersonList: Updates the filter of the filtered person list to filter by the given predicate.
Given below is an example usage scenario and how the edit mechanism behaves at each step.
Step 1. The user launches the application. The AddressBook will be initialized with the initial address book state.
Step 2. The user executes edit T0123456A … to edit details of the person in the address book with the unique IC number T0123456A. The edit command calls Model#setPerson(Person target, Person editedPerson), causing the modified state of the address book after the edit T0123456A … command executes to be saved.
Note: If a command fails its execution, it will not call Model#setPerson(Person target, Person editedPerson), so the address book state will not be saved.
The following sequence diagram shows how an edit operation goes through the Logic component:
Note: The lifeline for EditCommand and EditCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The following activity diagram summarizes what happens when a user executes a new command:
Aspect: Display of updated information when command is successful:
Aspect: Display of error message when command is unsuccessful:
The show mechanism is facilitated by ModelManager. It implements
ModelManager#getPersonIfExists(predicate) : Returns the specified Person if they exist in the list.ModelManager#setDisplayNote(Person person) : Which allows users to display
the notes of selected contacts on the NoteDisplay.ModelManager#clear() : Which clears the notes in NoteDislay.The ShowCommandParser parses the user input and implements ShowCommand#createClearCommand() if input is an empty string, else,
it implements ShowCommand#createShowCommad(IdentityCardNumberMatchesPredicate icPredicate).
Given below is an example usage scenario and how the show mechanism behaves at each step.
Step 1: The user launches the application. The AddressBook will be initialized with the initial address book state.
Step 2:
Scenario 1: The user executes show T0123456A ... to show the notes of the person in the address book with the unique IC number of T0123456A.
The show command calls ModelManager#getPersonIfExists(predicate) to check if the specific person exists in the addressbook.
ModelManager#setDisplayNote(Person person) is then called, causing the modified state of the address book after the show T0123456A ... command executes to be displayed.
Scenario 2: The user executes show to clear the notes of the person in patient notes panel of the address book.
The show command calls ModelManager#clear(), causing the modified state of the address book after the show command executes to be displayed.
The following sequence diagram illustrates how a show operation goes through the Logic component and sets the patient notes panel.
Note: The lifeline for ShowCommandParser and ShowCommand should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The following activity diagram summarizes what happens when a user executes a show command:
Aspect: How to show the notes of patient on patient notes panel.
Alternative 1 (Current Choice): Show patient's notes in one command using IC_NUMBER.
Pros: Users are able to view specific user's notes.
Cons: Only allow for one parameter which is IC_NUMBER.
Alternative 2: Only show the patient notes which was last searched for.
Pros: Easy to implement.
Cons: Brings inconvenience to users if they only want to view a specific user's notes.
Aspect: How to clear the notes of patient on patient notes display.
Alternative 1 (Current Choice): Clears patient's notes on patient notes display using one command.
Pros: Easy to implement. Users do not need to remember so many commands.
Cons: The command might not be intuitive.
Alternative 2: Clears patient's notes on patient notes display with another command.
Pros: The command is more intuitive.
Cons: Users are required to know an extra command, which reduces usability of application.
The NoteDisplay allows the users to view the notes of the selected patient in the patient list. All notes are displayed in the Person Card.
NoteDisplay inherits UIPart and is used to display the notes section of the patient details. More details of the class implementation can be seen in the class diagram below.
NoteDisplay has a private field noteDisplay which is of type TextArea. The NoteDisplay has a method called setNoteToUser which takes in a Note and changes the noteDisplay through its settext method.
The notes will then be displayed in a section which is a FXML VBox.
Aspect: How the notes of the patient are displayed
Alternative 1 (Current Choice): Display the notes of the patients in a separate panel.
Pros: The information of patient is more well organised. It allows users to have a more comprehensive view of their patient notes.
Cons: One additional command is needed to view the notes of the patients.
Alternative 2: Display the notes of the patients in the PersonCard with the rest of the details.
Pros: The user does not need to enter an extra command to view the notes of the patients.
Cons: It is very difficult to view the notes of the individual patient as there is too much information displayed on the PersonCard.
Target user profile:
Value proposition: Quick and easy management of patient contacts, including important patient information.
Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *
| Priority | As a … | I want to … | So that I can… |
|---|---|---|---|
* * * | user | add a new patient | manage patient information for that new patient |
* * * | organised user | easily delete unnecessary data to reduce clutter in ClinicMate | maintain a clean and organised patient database |
* * * | user | add notes associated to each patient (including past diagnosis etc.) | easily follow up on necessary actions and understand the patient better |
* * * | user | exit ClinicMate quickly | conclude my session at the end of the day and ensure that ClinicMate is not running in the background |
* * | user | remove notes associated to each patient | remove irrelevant information and keep my notes up to date |
* * | user managing many patients | filter the data based on ic number | view the information quickly without searching through the whole list |
* * | careless user | edit patient information | keep accurate records of my patients |
* * | new user | see usage instructions | refer to instructions when I have difficulty using ClinicMate |
* * | new user | clear all sample data | insert my own patient information into ClinicMate |
* * | new user | see ClinicMate populated with sample data | see how ClinicMate looks like when it is in use |
* | user | show individual patient information | focus on the patient's details during consultations |
* | creative user | be able to change the theme of ClinicMate | personalise the apperance of the user interface based on my preferences |
* | new user | be able to export patient data | analyse health trends of a patient over time |
edit Note:
For all use cases below, the System is the ClinicMate and the Actor is the user, unless specified otherwise
Use case: UC01 - Add a person
MSS
User requests to list patients.
ClinicMate shows a list of patients.
User requests to add a specific patient to the list.
ClinicMate adds the patient.
Use case ends.
Extensions
2a. The list is empty.
Use case ends.
3a. The given command format is wrong.
3a1. ClinicMate shows an error message.
Use case resumes at step 2.
4a. There is an existing user in the database.
4a1. ClinicMate shows an error message.
Use case resumes at step 2.
Use case: UC02 - Add notes for a person
MSS
User requests to list patients.
ClinicMate shows a list of patients.
User requests to add notes for a specific patient in the list.
ClinicMate adds notes for the patient.
Use case ends.
Extensions
2a. The list is empty.
Use case ends.
3a. The given command format is wrong → handled similarly to UC01 3a.
4a. The given IC_NUMBER is invalid.
4a1. ClinicMate shows an error message.
Use case resumes at step 2.
Use case: UC03 - Delete a person
MSS
User requests to list patients.
ClinicMate shows a list of patients.
User requests to delete a specific patient in the list.
ClinicMate deletes the patient.
Use case ends.
Extensions
2a. The list is empty.
Use case ends.
3a. The given command format is wrong → handled similarly to UC01 3a.
4a. The given IC_NUMBER is invalid → handled similarly to UC02 4a.
Use case: UC04 - Find a person
MSS
User requests to list patients.
ClinicMate shows a list of patients.
User requests to find a specific patient in the list.
ClinicMate finds the patient.
Use case ends.
Extensions
2a. The list is empty.
Use case ends.
3a. The given command format is wrong → handled similarly to UC01 3a.
4a. The given IC_NUMBER is invalid → handled similarly to UC02 4a.
Use case: UC05 - Edit a person
MSS
User requests to list patients.
ClinicMate shows a list of patients.
User requests to edit a specific patient in the list.
ClinicMate edits the patient.
Use case ends.
Extensions
2a. The list is empty.
Use case ends.
3a. The given command format is wrong → handled similarly to UC01 3a.
4a. The given IC_NUMBER is invalid → handled similarly to UC02 4a.
Use case: UC06 - Show a person
MSS
User requests to list patients.
ClinicMate shows a list of patients.
User requests to show a specific patient in the list.
ClinicMate shows the patient.
Use case ends.
Extensions
2a. The list is empty.
Use case ends.
3a. The given command format is wrong → handled similarly to UC01 3a.
4a. The given IC_NUMBER is invalid → handled similarly to UC02 4a.
Use case: UC07 - Clear all patients
MSS
User requests to list patients.
ClinicMate shows a list of patients.
User requests to clear all patients from the full list of patients.
ClinicMate clear all patients in the list.
Use case ends.
Extensions
2a. The list is empty.
Use case ends.
3a. The given command format is wrong → handled similarly to UC01 3a.
Use case: UC08 - Exit the program
MSS
User requests to exit the program.
ClinicMate exits.
Use case ends.
Extensions
Use case: UC09 - View help
MSS
User requests for help to use ClinicMate.
ClinicMate shows a help window with a link to the user guide.
Use case ends.
Extensions
11 or above installed.edit Note:
Some definitions have been omitted as they have already been defined in the user guide.
Potential Issues With Current Feature
Existing Person class has all fields: name, age, sex, ic, phone, email and address. However, users might not require all of these fields.
User A might not require the phone field while User B might require all fields, including those that ClinicMate has yet to implement.
Hence, it is important that ClinicMate allows for users to customize the fields they require to make it less restrictive and allow for flexibility.
Proposed Enhancements
Before users initialize their own version of ClinicMate, they will be able to choose the fields from a whole range of fields which we offer. The fields could also be made optional depending on user's choice. Their application will thus be initialized with user's very own fields which they require.
Examples
Person class with only name, age, sex, and ic.Person class with only name, age, sex, ic and phone with the phone field optional.add n\John Doe p\12345678 i\T0123456A ag\12 s\M a\311, Clementi Ave 2, #02-25 will be allowed.add n\John Doe e\johndoe@mail.com i\T0123456A ag\12 s\M a\311, Clementi Ave 2, #02-25 will be allowed.add n\John Doe i\T0123456A ag\12 s\M a\311, Clementi Ave 2, #02-25 will be allowed.Potential Issues With Current Feature
Currently, the find command only allows users to find patient details using their IC_NUMBER. This could be inconvenient and troublesome
at times as users are required to type out the full IC_NUMBER. A single wrong character thus requires the user to re-look at the whole string of
IC_NUMBER again in order to identify their mistakes.
Proposed Enhancements
In light of this issue, we would be working on our application to provide an update to the find command
to allow users to find contacts using different fields such as name, age, email etc. They will be case-insensitive to allow for better search results.
Examples
John returns contact with name of John Doe and corresponding IC_NUMBER of T0123456Ajohndoe@mail.com returns contact with email of johndoe@mail.com and corresponding IC_NUMBER of T0123456APotential Issues With Current Feature
Users have given us the feedback that the notes in our patient notes panel does not update with the use of other commands.
For instance, if our notes panel currently already has John's notes reflected on it, using the addnote command to add a note of another contact who is not John will not cause the
notes panel to update accordingly. John's notes will still exist on the notes panel despite executing the addnote command to edit the note of another person.
This could bring inconvenience to the user as users will not be able to view a contact's notes immediately upon using other commands.
They would then have to go through the hassle of typing the show command to allow the new contact's note to be displayed on the notes panel.
Proposed Enhancements
In order to make it more convenient for the users, we will enhance all of our commands such that the notes of the contact involved in the last executed command will have his/her notes replace the current notes in the notes panel. We will also allow users to know whose note they are viewing, by displaying the patient's name or IC number.
Examples
IC_NUMBER of T1234567C,
executing addnote T0123456A n\diabetes, will cause the notes panel to update to the notes of user with IC_NUMBER of T0123456AIC_NUMBER of T1234567C,
executing edit T0123456A p\12345678, will cause the notes panel to update to the notes of user with IC_NUMBER of T0123456APotential Issues With Current Feature
Currently, ClinicMate only supports English and does not support other languages such as Chinese, Japanese, Arabic etc. This restricts the usability of
users who does not use English. In another scenario where a patient's name might not be in English, the user will also not be able to perform most commands such as add, edit etc.
Proposed Enhancements
We will be allowing more languages to be supported in ClinicMate
Examples
add n\ジョン p\12345678 e\johndoe@mail.com i\T0123456A ag\12 s\M a\311, Clementi Ave 2, #02-25 will be allowed.edit n\ジョン p\12345678 will be allowed.Potential Issues With Current Feature
While most of the error messages are specific, there are some instances where the error messages are too general. For instance,
currently, the edit command does not check the existence of IC_NUMBER upon entering an edit command with an empty field.
For instance, entering edit S1234567P in the event that the contact with the IC_NUMBER of S1234567P does not exist returns an error message
of at least one field to edit must be provided. However, the error message should be that the IC_NUMBER provided does
not exist as the existence of the IC_NUMBER should be checked first. This is a problem as users might go on to provide a field for a non-existing contact, thus returning them another error message.
Proposed Enhancements
We will add more specific conditionals to verify the validity of parsed inputs in the various Parser classes.
Examples
edit S1234567P should return the error message the IC_NUMBER provided does not exist.edit S1234567P e\ should return the error message email field should not be blank.Potential Issues With Current Feature
Currently, our phone number field only allows for one number. However, since ClinicMate is targeted at doctors working at the GP clinics with their contacts being patients, it
is only natural for the phone number field to allow for multiple numbers. Reason being that a patient might have a caregiver or is required to contact his/her
family members. Therefore, restricting the phone to only one is very restrictive and could bring about inconvenience.
Proposed Enhancements
We will allow for the addition of multiple numbers under the phone field through the add command.
Examples
add n\John Doe p\12345678 e\johndoe@mail.com i\T0123456A ag\12 s\M a\311, Clementi Ave 2, #02-25 will cause the phone number 12345678 to be added for user T0123456Aadd n\John Doe p\12345678, 09876544, 99999999 e\johndoe@mail.com i\T0123456A ag\12 s\M a\311, Clementi Ave 2, #02-25 will cause the phone numbers 12345678, 09876544, 99999999 to be added for user T0123456APotential Issues With Current Feature
Existing features require the users to manually enter the age of contacts. For example, add n\John Doe p\12345678 e\johndoe@mail.com i\T0123456A ag\12 s\M a\311, Clementi Ave 2, #02-25.
However, it is very cumbersome for users to edit the age of their contact individually through the edit command.
Proposed Enhancements
In order to save the time of our users, we will be adding in a new field called DOB which is Date of Birth in the form of DD/MM/YYYY.
age of the contacts will thus be derived from their DOB with reference to the current year which we are in. Hence, streamlining the contact management process.
Examples
Given that we are in the year 2024, the patient with the DOB of
10/10/2003 will be at the age of 2112/12/1990 will be at the age of 34Potential Issues With Current Feature
Firstly, our current addnote command only allows users to add a new note, which will be appended to the previous one. However,
there might be many instances in which the users need to edit or delete specific notes. Disallowing this will make adding notes quite frustrating at times.
Secondly, each of the contacts in the patient list panel has a notes section which cannot be hidden and will appear in the UI. Users might not want to see all the notes for each contact as it might be very long and distracting.
Lastly, there is a lack of organisation for the notes and users might want to categorize their notes into different sections.
Proposed Enhancements
Convert the way notes are stored to use a doubly linked list. This will allow for the independent updating and manipulation of separate notes, while still maintaining the chronological effect of notes being appended.
Examples
Since this is a work in progress, please do stay tuned for any updates to see how these could be implemented. We thank you for your patience.
Given below are instructions to test ClinicMate manually.
edit Note:
These instructions only provide a starting point for testers to work on;
testers are expected to do more exploratory testing.
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.
Adding a person while all persons are being shown
Prerequisites: List all persons using the list command. Multiple persons will be shown in the list.
Test case: add n\John Doe p\12345678 e\JohnDoe@mail.com i\T0123456A ag\12 s\M a\311, Clementi Ave 2, #02-25
Expected: New contact with the unique IC number T0123456A is added to the list. Details of the new contact shown in the status message.
Test case: add T0123A
Expected: No person is added. Error details shown in the status message. Status bar remains the same.
Other incorrect add commands to try: add, add n\, ...
Expected: Similar to previous.
Deleting a person while all persons are being shown
Prerequisites: List all persons using the list command. Multiple persons will be shown in the list.
Test case: delete T0123456A
Expected: The contact with the unique IC number T0123456A is deleted from the list. Details of the deleted contact shown in the status message.
Test case: delete T0123A
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 the IC number which does not exist in the list)
Expected: Similar to previous.
Adding a note to a person while all persons are being shown
Prerequisites: List all persons using the list command. Multiple persons will be shown in the list.
Test case: addnote T0123456A n\Diabetes
Expected: The note Diabetes will be added to contact with the unique IC number T0123456A. Successful note update message will be shown in the status message.
Test case: addnote T0123A
Expected: No note is added. Error details shown in the status message. Status bar remains the same.
Other incorrect addnote commands to try: addnote, addnote x, ... (where x is the IC number which does not exist in the list)
Expected: Similar to previous.
Finding a person while all persons are being shown
Prerequisites: List all persons using the list command. Multiple persons will be shown in the list.
Test case: find T0123456A
Expected: The contact with the unique IC number T0123456A will be displayed in the list. Details of person found will be shown in the status message.
Test case: find T0123A
Expected: No contact is found. Error details shown in the status message. Status bar remains the same.
Other incorrect find commands to try: find, find x, ... (where x is the IC number which does not exist in the list)
Expected: Similar to previous.
Editing a person while all persons are being shown
Prerequisites: List all persons using the list command. Multiple persons will be shown in the list.
Test case: edit T0123456A p\91234567 e\johndoe@example.com
Expected: The contact with the unique IC number T0123456A will be edited in the list. Updated details of person found will be shown in the status message.
Test case: edit T0123A
Expected: No contact is edited. Error details shown in the status message. Status bar remains the same.
Other incorrect find commands to try: edit, edit x, ... (where x is the IC number which does not exist in the list)
Expected: Similar to previous.
Showing the note of a person while all persons are being shown
Prerequisites: List all persons using the list command. Multiple persons will be shown in the list.
Test case: show T0123456A
Expected: The note of the contact with the unique IC number T0123456A will be shown in the patient notes panel. Successful show message will be shown in the status message.
Test case: show
Expected: The notes in the patient notes panel will be removed. Successful notes cleared message will be shown in the status message.
Test case: show T0123
Expected: If patient notes panel is previously empty, no note will be shown; If the patient notes panel already has a note, the note of the specified IC_NUMBER will not be shown.
Error details shown in the status message.
Other incorrect find commands to try: show x, ... (where x is the IC number which does not exist in the list)
Expected: Similar to previous.
New classes were added which enhanced ClinicMate's Features. Below are some examples of the new classes added:
Model classes: IdentityCardNumber, Sex, Note
Command classes: show, addnote
We ensured that these new classes follow the code quality standard strictly and practiced defensive programming. A couple of test cases were also crafted in order to ensure that the new classes function as expected and meet the specified requirements. These test cases cover various scenarios and edge cases to validate the robustness and reliability of the code.
Other than making changes to the existing commands by adding in more parameters, we put in significant effort to make sure the edited commands fits the features of ClinicMate.
For instance, the find command will allow users to find contact details with their IC, and more importantly, the user's notes will also appear on the patient notes panel.
This allowed for a more comprehensive view of contact's notes which is an important field that GPs will require. Hence, much effort was placed into enhancing existing features to improve usability of ClinicMate.
Rather than the dark theme which ClinicMate originally had, we chose to go with a lighter theme and a bigger font size in order to improve readability of ClinicMate.
Effort was put in by us to learn different JavaFX markup elements such as the ScrollPane and SplitPanel in order to allow for a wider and better view of patient details in ClinicMate.
The team definitely had a rough start during the beginning of the team project since most of the team were new to the GitHub workflow. The process of picking up the workflow was rocky, as we had difficulties understanding how issues, pull request and merging of branches worked. Merge conflict hindered the efficiency of our teamwork. However, after much help and guidance within the team, everyone in the team became more familiar with the workflow, which enhanced our collaboration.
The team also faced difficulties in keeping track of the deliverables every week and during every iteration. We were not sure of the requirements that we needed to fulfill. Therefore, the team came together weekly to meet in order to better understand the deliverables needed and also to split the workload, increasing the productivity of the team.
To make our app look nicer and easier to understand, we had a tough time dealing with JavaFX features as we were newly introduced to it. Changing how things look on the screen was tricky because we needed to see it visually. Despite the challenge, we kept working on improving how our app looked and felt for users.
The hardest challenge in which the team faced was to perform edits to the initial code which was provided to us. The large codebase required a very long time to understand and digest. This was made even more tough as we only started working on the code in the second half of the semester with limited time. However, through clarifying each other's doubts and questions, we were able to comprehend and made edits to the code eventually.
Throughout the module, the team has gained much experience both in technical and soft skills. We definitely made significant improvements to our product through self-research, teamwork and support from each other. We got accustomed to the GitHub workflow, made use of JavaFX to implement our UI and most importantly, we developed a CLI application that adheres to rigorous code quality standards, ensuring readability and maintainability at the same time. The team definitely had many takeaways from this module.