Developer Guide
- Acknowledgements
- Setting up, getting started
- Documentation, logging, testing, configuration, dev-ops
- Design
- Implementation
-
Appendix: Requirements
- Product Scope
- User stories
-
Use cases
- Use Case: Add a New Contact
- Use Case: Edit a Contact
- Use Case: Delete a Contact
- Use Case: Add Emergency Contacts
- Use Case: Delete an Emergency Contact
- Use Case: Find Contacts By Patient Name
- Use Case: Find Contacts By Doctor Name
- Use Case: Archive Contacts
- Use Case: List Archive Files
- Use Case: Load Archived Contacts
- Use Case: Delete Archive File
- Use Case: Undo Last Command
- Use Case: Redo Last Undone Command
- Non-Functional Requirements (NFRs)
- Glossary
- Appendix: Planned Enhancements
- Appendix: Instructions for manual testing
- Appendix: Effort
Acknowledgements
- This project is based on the AddressBook-Level3 project created by the SE-EDU initiative.
- Libraries used: JavaFX, Jackson, JUnit5
- The undo and redo features were inspired by the proposed implementation found in AB3’s Developer Guide.
- The icons used were taken from Flaticon.
Setting up, getting started
Refer to the guide Setting up and getting started.
Documentation, logging, testing, configuration, dev-ops
Design
.puml
files used to create diagrams in this document can be found in the 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 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. 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:
- 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
object 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.
DeleteCommandParser
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.,DeleteCommandParser
) and uses it to parse the command. - This results in a
Command
object (more precisely, an object of one of its subclasses e.g.,DeleteCommand
) 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.,AddCommandParser
) which uses the other classes shown above to parse the user command and create aXYZCommand
object (e.g.,AddCommand
) which theAddressBookParser
returns back as aCommand
object. - All
XYZCommandParser
classes (e.g.,AddCommandParser
,DeleteCommandParser
, …) 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
objects (which are contained in aUniquePersonList
object). - stores the currently ‘selected’
Person
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<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 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)
Tag
list in the AddressBook
, which Person
references. This allows AddressBook
to only require one Tag
object per unique tag, instead of each Person
needing their own Tag
objects.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 seedu.address.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Add feature
Implementation
The image below shows the class diagram of a Person object and its related class attributes.
The Person object is made up of several attributes:
-
Name
: The name of the patient. -
Phone
: The phone number of the patient. -
Email
: The email of the patient. -
Address
: The address of the patient. -
Doctor
: The doctor assigned to the patient. -
Emergency Contact
: A list of emergency contacts of the patient. -
Tags
: Additional information about the patient.
The Doctor object is also made up of attributes:
-
Doctor Name
: The name and title of the doctor. -
Phone
: The phone number of the doctor. -
Email
: The email of the doctor.
The Emergency Contact object is also made up of attributes:
-
Name
: The name of the emergency contact. -
Phone
: The phone number of the emergency contact. -
Relationship
: The relationship of the emergency contact to the patient.
Feature details
- MedConnect will verify that the parameters supplied by the user follow a set of relevant restrictions for the respective parameters.
- If any invalid parameter is provided, an error will be thrown, informing the user which parameter violates the restrictions. The format for the valid input for that parameter will be displayed to the user.
- If all parameters are valid, a new
Person
entry will be created and stored in theVersionedAddressBook
.
Design Considerations:
Aspect: The required input of parameters:
-
Alternative 1 (current choice): Make all parameters compulsory, except Tags.
- Pros: Will not have missing data when it is needed in an emergency.
- Cons: Add Command is lengthy to type out, might be hard to remember the syntax.
-
Alternative 2: Make only a few specific parameters compulsory.
- Pros: Patient registration will be faster.
- Cons: If user forgets to update missing details, during an emergency there might not be an emergency contact to call.
We opted for Alternative 1 to make almost all parameters compulsory as the autocomplete feature we implemented will aid users in typing out the Add Command.
Undo/redo feature
Implementation
The proposed undo/redo mechanism is facilitated by VersionedAddressBook
. It extends AddressBook
with an undo/redo history, stored internally as an addressBookStateList
and currentStatePointer
. Additionally, it implements the following operations:
-
VersionedAddressBook#commit()
— Saves the current address book state in its history. -
VersionedAddressBook#undo()
— Restores the previous address book state from its history. -
VersionedAddressBook#redo()
— Restores a previously undone address book state from its history.
These operations are exposed in the Model
interface as Model#commitAddressBook()
, Model#undoAddressBook()
and Model#redoAddressBook()
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 VersionedAddressBook
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#commitAddressBook()
, causing the modified state of the address book after the delete 5
command executes to be saved in the addressBookStateList
, 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#commitAddressBook()
, causing another modified address book state to be saved into the addressBookStateList
.
Model#commitAddressBook()
, so the address book state will not be saved into the addressBookStateList
.
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#undoAddressBook()
, 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.
currentStatePointer
is at index 0, pointing to the initial AddressBook state, then there are no previous AddressBook states to restore. The undo
command uses Model#canUndoAddressBook()
to check if this is the case. If so, it will return an error to the user rather
than attempting to perform the undo.
The following sequence diagram shows how an undo operation goes through the Logic
component:
UndoCommand
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Similarly, how an undo operation goes through the Model
component is shown below:
The redo
command does the opposite — it calls Model#redoAddressBook()
, which shifts the currentStatePointer
once to the right, pointing to the previously undone state, and restores the address book to that state.
currentStatePointer
is at index addressBookStateList.size() - 1
, pointing to the latest address book state, then there are no undone AddressBook states to restore. The redo
command uses Model#canRedoAddressBook()
to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.
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#commitAddressBook()
, Model#undoAddressBook()
or Model#redoAddressBook()
. Thus, the addressBookStateList
remains unchanged.
Step 6. The user executes clear
, which calls Model#commitAddressBook()
. Since the currentStatePointer
is not pointing at the end of the addressBookStateList
, 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:
Design considerations:
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
Data archiving
Implementation
The archive functionality in MedConnect is facilitated by the ModelManager
class. It handles the archiving, listing, loading, and deleting of archived contact data. The ModelManager
interacts with the Filename
class and FileUtil
components to manage the archive files in the archive directory.
For example, the sequence diagram below illustrates the interactions within the ModelManager
component when the archive
command is executed.
- The
ArchiveCommand
archives the current address book data by calling thearchiveAddressBook
method in theModelManager
component. - The
ModelManager
creates the archive directory if it does not exist. - The
ModelManager
saves the current address book data to a JSON file in the archive directory with the specified file name.
Appendix: Requirements
Product Scope
Target User Profile
- User Role: Healthcare Administrator
- Workplace: Elderly care home for dementia patients
-
Responsibilities:
- Manage and update contact details for patients, doctors, and next-of-kin.
- Respond quickly to emergency situations by accessing relevant contacts.
- Maintain communication efficiency with minimal manual processes.
-
Key Characteristics:
- Handles large volumes of contact data on a daily basis.
- Prefers using desktop applications over mobile or web-based alternatives.
- Skilled at typing and prefers keyboard shortcuts over mouse interactions for speed.
- Comfortable with using command-line interfaces (CLI) for fast data entry and retrieval.
Value Proposition
MedConnect offers a streamlined contact management system tailored for healthcare administrators. Its key features include:
- Efficient Lookup and Update: Quickly find and update contact information for patients, their emergency contacts, and healthcare staff.
- Time-Sensitive Operations: When every second counts, MedConnect ensures that administrators can contact the right person immediately.
- Command-Line First: Optimized for users who prefer CLI, allowing for rapid data entry and navigation without reliance on graphical interfaces.
- Comprehensive Contact Database: Centralizes all relevant contact details, reducing the need for multiple systems and improving response times in emergencies.
User stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Beginner User Stories
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
new user | have sample data to work with | understand how to use the application |
* * * |
healthcare administrator | add new doctors and patients | easily reach out to them when needed |
* * * |
healthcare administrator | update contact details | ensure all contact information is accurate and current |
* * * |
healthcare administrator | delete outdated patient contacts | ensure all information is relevant and current |
* * * |
healthcare administrator | view all contacts in the address book | have a comprehensive overview of all patients, doctors, and emergency contacts |
* * * |
healthcare administrator | view patient emergency contact details | notify next-of-kin during urgent medical events |
* * * |
healthcare administrator | add emergency contacts for patients | quickly reach out to next-of-kin during medical emergencies |
* * * |
healthcare administrator | assign doctors to patients | easily track which doctor is responsible for each patient |
* * |
healthcare administrator | search contacts by name or assigned doctor | quickly find and connect with the right person in high-pressure situations |
* * |
healthcare administrator | add multiple emergency contacts for each person | reach different emergency contacts when one is uncontactable |
Intermediate User Stories
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * |
healthcare administrator | filter contacts by their doctor | view a consolidated list of all the patients a doctor is responsible for |
* * |
healthcare administrator | sort patients by their admission time | provide appropriate care to longer-term patients |
* * |
healthcare administrator | tag important notes to patients | remember special considerations about certain patients |
* * |
healthcare administrator | archive outdated contacts | maintain a clean and relevant contact list without losing historical records |
* * |
healthcare administrator | load backup archived data | restore a backup copy in case of data corruption or user error |
* * |
healthcare administrator | delete archived data | free up storage space and remove unnecessary or outdated contact information |
* * |
healthcare administrator | view a list of all archived data | keep track of the archived data for reference or auditing purposes |
* * |
healthcare administrator | undo the last operation | recover from accidental deletions or modifications |
* * |
healthcare administrator | redo the last undone operation | reverse an undo operation if it was done in error |
Advanced User Stories
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * |
healthcare administrator | import contact data in bulk | keep the database up-to-date without manual entry |
* * |
healthcare administrator | export contact information | provide it to others or have a backup in case of system failures |
Use cases
Not all commands use cases are included as commands, such as clear
and exit
are self-explanatory.
(For all use cases below, the System is the AddressBook
and the Actor is the user
, unless specified otherwise)
Use Case: Add a New Contact
System: MedConnect
Actor: Healthcare Administrator
Main Success Scenario (MSS):
- User requests to add a new patient contact.
- MedConnect prompts the user to enter patient details:
- Name
- Phone Number
- Address
- Doctor Name
- Doctor Phone Number
- Doctor Email
- Emergency Contact Name
- Emergency Contact Phone Number
- Emergency Contact Relationship to Patient
- Tag(s) [Optional]
- User enters the required details.
- MedConnect validates the provided information.
- MedConnect successfully adds the new contact to the address book.
-
MedConnect confirms that the contact was added successfully.
Use case ends.
Extensions:
3a. The entered details are invalid (e.g., phone number contains letters).
- 3a1. MedConnect informs the user of the invalid details.
-
3a2. User corrects the invalid details and resubmits.
Use case resumes from step 4.
3b. Some required fields are missing.
- 3b1. MedConnect prompts the user to complete the missing fields.
-
3b2. User provides the missing information.
Use case resumes from step 4.
3c. There are duplicate fields provided (e.g., 2 name fields).
- 3c1. MedConnect informs the user of the duplicate field(s).
-
3c2. User removes the duplicate parameters and resubmits.
Use case resumes from step 4.
6a. The contact already exists in the system (e.g., duplicate phone number).
-
6a1. MedConnect notifies the user of the duplicate entry.
Use case ends.
Use Case: Edit a Contact
System: MedConnect
Actor: Healthcare Administrator
Main Success Scenario (MSS):
- User requests to list all contacts.
- MedConnect retrieves and shows a list of all contacts.
- User requests to edit a patient’s details.
- MedConnect prompts the user to enter the following details:
- Index of the patient to be edited
- New data of the field(s) to be edited
- MedConnect validates the provided information.
- MedConnect successfully edits the contact with the new data.
-
MedConnect confirms that the contact was edited successfully.
Use case ends.
Extensions:
2a. The patient list is empty.
- Use case ends.
4a. The given index is invalid (e.g., out of range).
-
4a1. MedConnect informs the user of the invalid index.
Use case resumes from step 3.
4b. The entered details are invalid (e.g., phone number contains letters).
- 4b1. MedConnect informs the user of the invalid details.
-
4b2. User corrects the invalid details and resubmits.
Use case resumes from step 5.
Use Case: Delete a Contact
System: MedConnect
Actor: Healthcare Administrator
Main Success Scenario (MSS):
- User requests to list all contacts.
- MedConnect retrieves and shows a list of all contacts.
- User requests to delete a specific contact by its index.
-
MedConnect removes the contact from the database.
Use case ends.
Extensions:
2a. The contact list is empty.
- Use case ends.
3a. The given index is invalid (e.g., out of range).
-
3a1. MedConnect informs the user of the invalid index.
Use case resumes from step 2.
Use Case: Add Emergency Contacts
System: MedConnect
Actor: Healthcare Administrator
Main Success Scenario (MSS):
- User requests to list all contacts.
- MedConnect retrives and shows a list of all contacts.
- User requests to add a new emergency contact to a patient.
- MedConnect prompts the user to enter the following details:
- Index of the patient
- Emergency Contact Name
- Emergency Contact Phone Number
- Emergency Contact Relationship to Patient
- User enters the required details.
-
MedConnect adds the emergency contact to the patient’s details.
Use case ends.
Extensions:
2a. The contact list is empty.
- Use case ends.
5a. The index given is out of range.
-
5a1. MedConnect informs the user of the invalid index.
Use case resumes from step 3.
5b. The emergency contact already exists under the patient. (e.g., duplicate phone number).
-
5b1. MedConnect notifies the user that the emergency contact already exists.
Use case ends.
5c. The emergency contact relationship provided is invalid.
- 5c1. MedConnect informs the user of possible relationship types.
-
5c2. User corrects the invalid relationship type and resubmits.
Use case resumes from step 6.
Use Case: Delete an Emergency Contact
System: MedConnect
Actor: Healthcare Administrator
Main Success Scenario (MSS):
- User requests to list all contacts.
- MedConnect retrieves and shows a list of all contacts.
- User requests to delete a specific emergency contact of a patient by its index.
-
MedConnect removes the emergency contact from the database.
Use case ends.
Extensions:
2a. The contact list is empty.
- Use case ends.
3a. The given index is invalid (e.g., out of range).
-
3a1. MedConnect informs the user of the invalid index.
Use case resumes from step 2.
3b. The specified patient only has 1 emergency contact.
-
3b1. MedConnect informs the user that they cannot delete a patient’s only emergency contact.
Use case ends.
Use Case: Find Contacts By Patient Name
System: MedConnect
Actor: Healthcare Administrator
Main Success Scenario (MSS):
- User requests to find a patient by their name.
- MedConnect prompts the user to provide a name to search for.
- User provides a name.
-
MedConnect returns a list of patients who matches the provided name.
Use case ends.
Extensions:
3a. User provides a blank name.
-
3a1. MedConnect notifies the user to provide a name.
Use case resumes from step 3.
4a. There are no patients who match the provided name.
-
4a1. MedConnect returns a list of 0 patients.
Use case ends.
Use Case: Find Contacts By Doctor Name
System: MedConnect
Actor: Healthcare Administrator
Main Success Scenario (MSS):
- User requests to find a patient by their assigned doctor’s name.
- MedConnect prompts the user to provide a name to search for.
- User provides a name.
-
MedConnect returns a list of patients whose assigned doctor matches the provided name.
Use case ends.
Extensions:
3a. User provides a blank name.
-
3a1. MedConnect notifies the user to provide a name.
Use case resumes from step 3.
4a. There are no patients whose doctor matches the provided name.
-
4a1. MedConnect returns a list of 0 patients.
Use case ends.
Use Case: Archive Contacts
System: MedConnect
Actor: Healthcare Administrator
Main Success Scenario (MSS):
- User requests to archive the address book with a description.
-
MedConnect confirms that the contact data has been successfully archived.
Use case ends.
Extensions:
1a. The given description is invalid.
- 1a1. MedConnect informs the user of the invalid description.
-
1a2. User corrects the invalid description and resubmits.
Use case resumes from step 2.
Use Case: List Archive Files
System: MedConnect
Actor: Healthcare Administrator
Main Success Scenario (MSS):
- User requests to list all archived data files in the archive folder.
-
MedConnect returns a list of all the archived data files in the archive folder.
Use case ends.
Use Case: Load Archived Contacts
System: MedConnect
Actor: Healthcare Administrator
Main Success Scenario (MSS):
- User requests to load an archive file.
- MedConnect prompts the user to provide the file name of an archive file in the archives folder.
- User enters a file name.
- MedConnect validates the file name and checks for a matching file.
-
MedConnect loads the archived contacts from the file into the address book.
Use case ends.
Extensions:
3a. The given file name is invalid.
- 3a1. MedConnect notifies the user that the file name contains invalid characters.
-
3a2. User corrects the file name and resubmits.
Use case resumes from step 4.
3b. The given file name does not match any existing file.
- 3b1. MedConnect notifies the user that a file with the given file name is not found.
-
3b2. User enters the file name of an existing file in the archives folder and resubmits.
Use case resumes from step 4.
Use Case: Delete Archive File
System: MedConnect
Actor: Healthcare Administrator
Main Success Scenario (MSS):
- User requests to delete an archive file.
- MedConnect prompts the user to provide the file name of an archive file in the archives folder.
- User enters a file name.
- MedConnect validates the file name and checks for a matching file.
-
MedConnect deletes the archive file.
Use case ends.
Extensions:
3a. The given file name is invalid.
- 3a1. MedConnect notifies the user that the file name contains invalid characters.
-
3a2. User corrects the file name and resubmits.
Use case resumes from step 4.
4a. The given file name does not match any existing file.
- 4a1. MedConnect notifies the user that a file with the given file name is not found.
-
4a2. User enters the file name of an existing file in the archives folder and resubmits.
Use case resumes from step 4.
Use Case: Undo Last Command
System: MedConnect
Actor: Healthcare Administrator
Main Success Scenario (MSS):
- User performs an command that modifies the address book (e.g., adds or deletes a contact).
- User requests to undo the last command.
-
MedConnect reverts to the state before the last command.
Use case ends.
Extensions:
2a. There is no previous command to undo.
-
2a1. MedConnect informs the user that there are no actions to undo.
Use case ends.
Use Case: Redo Last Undone Command
System: MedConnect
Actor: Healthcare Administrator
Main Success Scenario (MSS):
- User performs an undo command.
- User requests to redo the last undone action.
- MedConnect restores the previously undone action.
Use case ends.
Extensions:
2a. There is no undone command to redo.
-
2a1. MedConnect informs the user that there are no actions to redo.
Use case ends.
2b. User makes a new change after an undo command.
-
2b1. MedConnect restores the undo command that the user most recently executed.
Use case ends.
Non-Functional Requirements (NFRs)
1. Performance Requirements:
-
Responsiveness: The system should respond to user commands (e.g., adding, updating, or viewing contacts) within 2 seconds for typical operations under normal usage conditions (i.e., up to 1000 contacts in the database).
-
Scalability: MedConnect should support operations with up to 5000 contacts without performance degradation. Basic operations such as retrieving or adding contacts should not exceed a response time of 3 seconds under this load.
2. Reliability and Availability:
-
System Uptime: MedConnect must be available for use at least 99% of the time, especially during hospital operating hours (24/7 access). Regular maintenance should be scheduled during off-peak times.
-
Disaster Recovery and Backup: Contact data must be backed up daily to prevent data loss. The system should be able to recover from backup within 2 hours of a failure.
3. Usability Requirements:
-
Typing Efficiency: The system should be optimized for keyboard-only interactions. A user familiar with the system should be able to complete key operations (e.g., adding a new contact, viewing emergency contacts) in less than 30 seconds using only the keyboard.
-
Error Handling and Feedback: The system must provide immediate feedback (within 1 second) when an error occurs, such as invalid input or missing fields. The user should be able to correct errors without restarting the operation.
4. Data and Storage Requirements:
-
Human-Editable File Format: Contact information should be stored in a human-readable and editable format (e.g.,
.json
or.csv
) so that administrators can manually access and modify data if needed. -
Data Integrity: The system must ensure that no data is lost or corrupted during common operations (e.g., adding, updating, or deleting contacts). Transaction-like behavior must be implemented to ensure all data operations either succeed fully or fail without partially corrupting data.
5. Compatibility and Portability:
- Cross-Platform Support: MedConnect must be compatible with mainstream operating systems (Windows, macOS, Linux) and function seamlessly on systems with Java 17 or higher installed.
6. Maintainability and Extensibility:
-
Modular Design: The system must be designed with a modular structure, allowing future extensions such as additional data fields or user roles without requiring significant rework.
-
Testability: MedConnect must be easily testable, with automated tests that can cover at least 70% of the codebase. Each core feature (e.g., adding a contact, deleting outdated contacts) should have dedicated test cases. —
Glossary
-
Mainstream OS: Windows, Linux, Unix, MacOS
-
MedConnect: A healthcare application designed to help healthcare administrators manage patient and staff contact information efficiently.
-
Healthcare Administrator: The primary user of MedConnect, responsible for managing patient and staff contact details in a healthcare environment. They ensure that the contact information is up-to-date for communication during critical situations.
-
Emergency Contact: The designated person or persons to be notified in case of a patient emergency, usually including details such as their name, phone number, and relationship to the patient.
-
Primary Contact Method: The main communication method for a person in the system, typically used for emergency situations.
-
Command-Line Interface (CLI): A method of interacting with MedConnect through typed text commands, allowing fast input for users who prefer typing over graphical interfaces.
-
Mainstream Operating Systems: Common operating systems on which MedConnect can run, including Windows, macOS, and Linux.
-
Encryption: The process of encoding sensitive data, such as patient information, to protect it from unauthorized access.
-
Java 17: The version of Java required to run MedConnect, which ensures compatibility and performance across different operating systems.
-
Human-Editable File: A data file format (e.g.,
.json
or.csv
) that can be easily accessed and modified by healthcare administrators without needing special software. -
System Uptime: The percentage of time that MedConnect is available and operational, measured as part of reliability goals.
-
Backup: The process of creating copies of MedConnect’s data to ensure it can be restored in the event of data loss or system failure.
-
Test Coverage: The percentage of the system’s code that is covered by automated tests, ensuring that key features and functionality are reliably tested.
Appendix: Planned Enhancements
Team size: 4
The current version of MedConnect has its flaws so here are our plans for future enhancements to improve future versions of MedConnect.
Optimisations to handle large number of contacts
Currently, depending on the limitations of the PC hardware that MedConnect is running on, a large number of contacts may cause an OutOfMemory error. Our planned enhancement is to optimise the data storage and retrieval process to handle a larger number of contacts without causing performance issues or memory errors, or implement a pagination feature to display contacts in smaller batches. We plan to also implement an import and export feature to allow users to import and export contacts in bulk to avoid the need to manually enter each contact.
Duplicate detection
Currently, MedConnect’s duplicate person detection only works within each class. There is no duplicate person detection between a patient and a doctor. In reality, there should likely not be a case where a patient is also a doctor. We plan to implement duplicate person detection across classes to prevent or display a warning message to prevent a person from being added as both a patient and a doctor, for instance, in the future.
Whitespaces in names
Currently, MedConnect is able to remove leading and trailing whitespaces from names. However, the functionality to remove whitespaces in between words in a name is not yet implemented. We plan to implement this in the future to prevent users from entering names with excessive whitespaces between words in the future as it may reduce readability.
Handling long fields
Currently, MedConnect does not handle long fields well. For example, if a user enters a long name, the name may be cut off in the GUI. Our planned enhancement is to implement a feature that allows users to view the full details of each field by hovering over the field in the GUI or clicking to expand the details for the field in the card. This will allow users to view the full field (e.g. full name) should the field be too long to be displayed in the GUI.
Multiple Language Support
Currently, MedConnect is only available for usage in English. We recognise that our target users may not be able to read English proficiently or require non-English inputs (e.g. Chinese names). Our planned enhancement is to translate MedConnect into other languages, such as Chinese, Malay and Tamil to accommodate for healthcare administrators who are more fluent in these languages and require such languages to be supported in the application.
Emergency Contact UI
Currently, clicking on a emergency contact card of a patient in the GUI, followed by clicking the same patient card results in the emergency contact card being unselected. This behavior is not ideal for users who select the card to focus on viewing the correct contact in the list. Our planned enhancement is to update the behaviour of selecting the patient card so that it will not refresh the user’s selection upon clicking it.
Autocomplete field suggestion
Currently, due to difficulties with parsing, the autocomplete feature does not suggest square brackets for optional fields, such as in the Edit command. Users would have to refer to the User Guide or error message to know which fields are optional. We plan to add the square brackets to clearly indicate optional parameters in the autocomplete feature in future iterations of MedConnect to minimise the need for users to continuously reference the User Guide.
Autocomplete dynamic parsing
Currently, the autocomplete feature does not dynamically parse the user’s input for each parameter as it is entered to provide the next suggestion. For example, the autocomplete feature would not function ideally if users enter a whitespace after command prefixes (e.g., add n/ John
would continue to suggest add n/ John (n/NAME)
). This also limits us to keep to the specified default order of parameters. We plan to implement dynamic parsing in the autocomplete feature to provide more accurate suggestions based on the user’s input in future iterations of MedConnect, particularly for optional parameters. This would also improve the user experience by allowing us to carry out input validation for each parameter and provide feedback to the user in real-time without the need to submit the command.
Appendix: Instructions for manual testing
Given below are instructions to test the app manually.
Launch and shutdown
-
Initial launch
-
Download the latest jar file here and copy into an empty folder.
-
Open a terminal window and
cd
into the same folder. -
Enter
java -jar medconnect.jar
into the terminal. Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum but it is resizable.
-
-
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.
-
-
Shutdown
There are multiple ways to exit the application:
-
Use the
exit
command. -
Click
File
in the top left corner, thenExit
in the dropdown menu. -
Click the red ‘X’ of the application window.
-
Use the keyboard shortcut
Alt + F4
.
-
Adding a patient
- Adding a patient while any number of patients are being shown.
Note: Due to the long length of valid
add
commands, the usage ofxx/PARAMETER...
will refer to all remaining compulsory parameters that have not been mentioned for that test case, with valid inputs for the respective parameters.
Prerequisites: List all patients using thelist
command. Patients are sorted by the time they were added to MedConnect.Test case input Expected behaviour Expected message add n/Ryan p/98765432 xx/PARAMETER...
A new patient Ryan is added to the bottom of the patient list. New person added: [PERSON DETAILS] add n/Ryan n/Daniel p/98765432 xx/PARAMETER...
Error message is shown. Multiple values specified for the following single-valued field(s): n/ add n/Ryan
Error message is shown. Invalid command format! [CORRECT COMMAND FORMAT] add
Error message is shown. Invalid command format! [CORRECT COMMAND FORMAT] add n/
Error message is shown Invalid command format! [CORRECT COMMAND FORMAT] add p/???
Error message is shown Invalid command format! [CORRECT COMMAND FORMAT] add n/John+Doe xx/PARAMETER...
Error message is shown Names should not be blank and should only contain alphanumeric characters, spaces or the following special characters: - . ( ) @ / ‘ add p/98@1532 xx/PARAMETER...
Error message is shown Phone numbers should only contain numbers, and it should be at least 3 digits long add ecrs/knight xx/PARAMETER...
Error message is shown Relationship type should be Parent, Child, Sibling, Spouse, Grandparent or Relative or their gendered variants
Editing a patient
- Editing a patient while any number of patients are being shown.
Prerequisites: List all patients using the
list
command. Patients are sorted by the time they were added to MedConnect.Test case input Expected behaviour Expected message edit 1 n/Ryan p/98765432 e/ryan@hotmail.com
The name, phone and email of the first patient in the list is edited to the new values provided as arguments Edited person: [PERSON DETAILS] edit 1
Error message is shown. At least one field to edit must be provided. edit 1 n/
Error message is shown. Names should not be blank and should only contain alphanumeric characters, spaces or the following special characters: - . ( ) @ / ‘ edit 1 n/John p/
Error message is shown. Phone numbers should only contain numbers, and it should be at least 3 digits long edit
Error message is shown Invalid command format! [CORRECT COMMAND FORMAT] edit 2 ecname/John Doe
Error message is shown At least one emergency contact index to edit must be provided. edit 2 ec/2
Error message is shown At least one emergency contact field to edit must be provided. edit 1 ec/x ecname/Heather ecphone/5137985 ecrs/Sibling
(x > number of emergency contacts)Error message is shown Index is not a non-zero unsigned integer. edit x n/Heather
(x > number of contacts)Error message is shown The person index provided is invalid
Deleting a patient
-
Deleting a patient while all patients are being shown
Prerequisites:
1. List all patients using thelist
command.
2. Multiple persons in the list.Test case input Expected behaviour Expected message delete 1
First contact is deleted from the list. Deleted Person: [PERSON DETAILS] delete 1 ec/1
The first emergency contact of the first contact in the list is deleted. Deleted emergency contact: [PERSON DETAILS] delete 0
Error message is shown. Invalid command format! [CORRECT COMMAND FORMAT] delete 2 ec/0
Error message is shown. Index is not a non-zero unsigned integer. delete ec/1
Error message is shown Invalid command format! [CORRECT COMMAND FORMAT] delete ec/x
(x > number of emergency contacts)Error message is shown The emergency contact index provided is invalid delete x
(x > number of contacts)Error message is shown The person index provided is invalid
-
Deleting a patient while a filtered list is being shown
Prerequisites: The patient list is filtered using thefind
orfinddoc
command.Test case input Expected behaviour Expected message delete 1
First contact is deleted from the list. Deleted Person: [PERSON DETAILS] delete 1 ec/1
The first emergency contact of the first contact in the list is deleted. Deleted emergency contact: [PERSON DETAILS] delete 0
Error message is shown. Invalid command format! [CORRECT COMMAND FORMAT] delete 2 ec/0
Error message is shown. Index is not a non-zero unsigned integer. delete ec/1
Error message is shown Invalid command format! [CORRECT COMMAND FORMAT] delete ec/x
(x > number of emergency contacts)Error message is shown The emergency contact index provided is invalid delete x
(x > number of contacts)Error message is shown The person index provided is invalid
Adding an emergency contact to a patient
- Editing a patient while any number of patients are being shown.
Prerequisites: List all patients using the
list
command. Patients are sorted by the time they were added to MedConnect.Test case input Expected behaviour Expected message addec 1 ecname/Sarah Lim ecphone/91234567 ecrs/Granddaughter
The name, phone and email of the first patient in the list is edited to the new values provided as arguments Added emergency contact: [PERSON DETAILS] addec 1
Error message is shown. Invalid command format! [CORRECT COMMAND FORMAT] addec ecname/Sarah Lim ecphone/91234567 ecrs/Granddaughter
Error message is shown. Invalid command format! [CORRECT COMMAND FORMAT] addec 1 ecname/Sarah Lim ecphone/91234567
Error message is shown. Invalid command format! [CORRECT COMMAND FORMAT] addec 1 ecname/Sarah Lim ecphone/91234567 ecrs/Neighbor
Error message is shown Relationship type should be Parent, Child, Sibling, Spouse, Grandparent or Relative or their gendered variants addec 2 ecname/D%#P! ecphone/91234567 ecrs/Son
Error message is shown Names should not be blank and should only contain alphanumeric characters, spaces or the following special characters: - . ( ) @ / ‘ addec x ecname/Heather ecphone/5137985 ecrs/Sibling
(x > number of contacts)Error message is shown Invalid command format! [CORRECT COMMAND FORMAT]
Saving data
- Dealing with missing/corrupted data files
1. _{explain how to simulate a missing/corrupted file, and the expected behavior}_
- { more test cases … }
Appendix: Effort
Developing MedConnect as a brownfield project from the upgrading of AB3 was challenging for us as a team of relatively junior software engineers who did not have much experience in a software engineering project. For some of our team members, the only prior software engineering experience we had was our Orbital project.
Initially, we faced many challenges in managing the Git workflow of creating issues, creating branches, merging branches and pull requests. This was because the process was new to most of the group and we carefully took the time to learn the proper workflow and avoid merge conflicts.
Another challenge we faced was implementing the autocomplete feature. Since MedConnect was directed to be used by fast typists, we brainstormed the idea of having an autocomplete feature to greatly benefit them. However, this idea was quite foreign to all of us and we took a great deal of time in figuring out how to tackle this problem. In due time, we managed to figure out a solution as a team and it is now implemented in the current version of MedConnect.
Finally, for the undo and redo feature, we adapted the proposed implementation provided in the developer guide of AB3. This greatly reduced the effort required for these features as there are many ways to implement them. A more complex solution would be for each command to have its own respective undo and redo implementation. However, we followed the proposed implementation of saving the AddressBook in states and having a pointer that points to the current state. The pointer would move between states upon execution of the undo and redo commands.
Overall, we faced many challenges as a team that we had to overcome over a short runway. We managed to stay afloat and tackle these challenges through constant communication and good teamwork between team members, helping each other out swiftly and decisively.