PROJECT: docX
This portfolio aims to document my contribution to the project docX.
Overview
docX is a desktop clinic data management application used to maintain clinic’s database. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC.
Summary of contributions
-
Major enhancement: added the ability to find relevant and available doctors based on specialisation and the desired date and time
-
What it does: Allows the user to find doctors whose specialisation matches the input and are available at the desired date and time for an appointment.
-
Justification: This feature improves the product significantly because the user can now find available doctor(s) that match(es) the required specialisation with just one command, instead of the traditional method, where the user has to scroll through the list of doctors to find them manually. This would save the user a huge amount of time and resources spent on finding the right doctor for the patient and would result in reduced manhours of the front desk.
-
Highlights: This enhancement required an in-depth analysis of design alternatives. The implementation too was challenging as it required access to another class' information (Appointment list under ModelManager) and temporary changes made to the Appointment Filtered List under Model Manager during implementation. Additionally, the filtering of the doctors' list can only be done with one predicate, which means the list will always be filtered from the full original list. Hence, I had to create 3 different predicates to filter the doctor list to get the relevant doctors to check against the appointment list, then filter the doctor list again based on the above results.
-
-
Minor enhancement: making searching of doctors by keywords more convenient with the usage of just 1 command.
-
What it does: Allows the user to find doctors whose fields matches the keyword(s) inputted.
-
Justification: This feature allows the user to intuitively use the same command word for different functions.
list-d
now can be used to list the full original list of doctors andlist-d 10
will list doctors whose field(s) contains '10'. Hence, the user just needs to remember 1 command word for listing and searching of the doctors. This is particularly useful because a receptionist new to our application will be able to get used to the application as soon as possible, which is our objective of this application - to make the jobs of receptionist faster and easier. -
Highlights: This enhancement although minor, proved to be a challenge because the parser for this command has to accept any number of keywords (0 to infinitely many). As the parser must be prepared to take in null arguments and many arguments, there had to be checks to ensure the right results is shown to the user.
-
-
Code contributed: Find my code contributed here.
-
Other contributions:
-
Enhancements to existing features:
-
Allowing the display of doctors' information on the browser panel. (Pull request #178)
-
Wrote additional tests for existing features to increase coverage by 8%. (Pull requests #198, #202, #205)
-
Change Patient and Doctor to inherit from Person class (OOP)
-
Structured the initial User Guide for the team (Pull request #99, #66, #65)
-
-
Community: As of 15 April 2019,
-
Pull Requests (PRs) on docX's GitHub > 30
-
PRs reviewed with non-trivial review comments = 3 (#212, #113, #93)
-
Issues raised on docX's GitHub = 5
-
Reported bugs and suggestions for other teams in the class (examples: 1, 2, 3)
-
-
Contributions to the User Guide
Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users. |
Adding a doctor: add-d
Adds a doctor to docX
Format: add-d n/NAME g/GENDER y/YEAR_OF_EXPERIENCE p/PHONE_NUMBER s/SPECIALISATION
Examples:
-
add-d n/John Doe g/M y/5 p/98765432 s/acupuncture s/general
-
add-d n/Betsy Crowe g/f p/81234567 y/22 s/surgery
Listing all doctors : list-d
Shows a list of all doctors in docX.
Format: list-d
Selecting a doctor : select-d
Selects an existing doctor in docX to display all the information about this doctor in the browser panel.
Format: select-d INDEX
Examples:
-
select-d 1
Selects the doctor with ID of '1'. -
select-d 5
Selects the doctor with ID of '5'.
Editing a doctor : edit-d
Edits an existing doctor in docX.
Format: edit-d INDEX [n/NAME] [g/GENDER] [y/YEAR_OF_EXPERIENCE] [p/PHONE] [s/SPECIALISATION]
Examples:
-
edit-d 1 p/91234567
Edits the phone number of the doctor with ID of '1' to be91234567
. -
edit-d 2 s/acupuncture s/general
Edits the specialisations of the doctor with ID of '2' to beacupuncture
and 'general'.
Locating doctor by keywords: list-d
Finds doctor(s) whose names contain any of the given keywords.
Format: list-d [KEYWORD] [KEYWORD]
Examples:
-
list-d John
Returnsjohn
andJohn Doe
-
list-d 1
Returns doctor with doctor ID of1
, phone number containing1
or year of specialisation containing1
.
Deleting an existing doctor : delete-d
Deletes the specified doctor from docX.
Format: delete-d INDEX
Examples:
-
list-d
delete-d 1
Deletes the doctor with ID of '1' in docX. -
delete-d 2
Deletes the doctor with ID of '2' in docX.
Finding a doctor for appointment : match-d
Lists the doctors whose specialisations match and are free for an appointment at the stated date and time.
Format: match-d s/SPECIALISATION d/DESIRED_DATE_OF_APPT t/DESIRED_START_TIME_OF_APPT
Examples:
-
match-d s/acupuncture d/2019-06-02 t/10:00
Lists the doctors who has the specialisation ofacupuncture
and is free on 2nd June 2019 at 10am. -
match-d s/general d/2019-10-04 t/15:00
Lists the doctors who has the specialisation ofgeneral
and is free on 4th October 2019 at 3pm.
Contributions to the Developer Guide
Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. |
UI component
API : Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, PersonListPanel
, StatusBarFooter
, BrowserPanel
etc. All these, including the MainWindow
, inherit from the abstract UiPart
class.
The UI
component uses 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.
CRUD of Doctors
Doctor is one of the two valid types of Persons to be stored in the docX record. The following features are implemented or will be implemented for doctors of docX:
-
Add doctor
add-d
-
List all doctors and search for doctors by keywords
list-d
-
Edit existing doctors
edit-d
-
Select a doctor to display the full details
select-d
-
Delete existing doctors
delete-d
-
Finding relevant and available doctors for upcoming appointments
match-d
Add Doctor feature
Implementation
When a user executes add-d n/John Doe g/M p/98765432 y/3 s/'acupuncture
Step1. LogicManager calls parseCommand("add-d") in docXParser.
Step2. Based on the COMMAND_WORD, docXParser builds a new AddDoctorCommandParser() and calls function parse(arguments) of AddDoctorCommandParser.
Step3. AddDoctorCommandParser parses the argument and get doctor’s name, gender, year of experience, phone and his/her specialisations. AddDoctorCommandParser calls constructors of Name, Year, Gender, Phone, Specialisation and then calls the constructor of Doctor. Then, AddDoctorCommandParser calls AddDoctorCommand(Doctor).
Step4. LogicManager calls execute() of AddDoctorCommand.
Step5. execute() calls hasDoctor() of Model. If doctor does not exist, call addDoctor() of Model.
Design Considerations
Aspect 1: Definition of 'duplicates' in Doctor List of docX.
Alternative 1 (current choice): Phone number that is the same as any existing doctors would be deemed as a duplicated doctor. * Pros: It is intuitive for our users that a doctor can have the same name, same specialisations, but should have different numbers, as in the real world. * Cons: -
Alternative 2: Name and phone number that is the same as any existing doctors would be deemed as a duplicated doctor. * Pros: No additional implementation required. * Cons: Less flexibility for our users. Not intuitive as anyone can have the same name, but should have different numbers, as in the real world.
List Doctor feature
Implementation
Given below is the Sequence Diagram for interactions within the Logic
component for the execute("list-d")
API call.
When a user executes list-doctor acupu
Step1. LogicManager calls parseCommand("list-d") in docXParser.
Step2. Based on the COMMAND_WORD, docXParser builds a new ListDoctorCommandParser() and calls function parse(arguments) of ListDoctorCommandParser.
Step3. ListDoctorCommandParser parses the argument. If no argument is present, then ListDoctorCommandParser calls ListDoctorCommand(). If there are argument(s) present, DoctorContainsKeywordsPredicate("acupu") will be created. Then, ListDoctorCommandParser calls ListDoctorCommand(DoctorContainsKeywordsPredicate).
Step4. LogicManager calls execute() of ListDoctorCommand.
Step5. execute() checks if the DoctorContainsPredicate equals to null. If it equals to null, it calls updateFilteredDoctorList() of Model to show all doctors. If it is not null, it calls updateFilteredDoctorList() of ModelManager.
Step6. test(Doctor) of DoctorContainsKeywordsPredicate will be called. It will check if any of the field matches "acupu" in full or part. If it matches, the doctor will be shown.
Design Considerations
Aspect 1: Substring matching or full-word matching
-
Alternative 1 (current choice): Substring matching of keyword inputted.
-
Pros: Users will be able to view a wider list of doctors after filtering as any phrase that contains the input will be shown. Even when there are accidental typing mistakes, (eg. "genera" instead of "general") substring matching will eliminate the possibility of results being omitted due to human error.
-
Cons: When the search is too general, irrelevant results may be shown. For example, when the user input "s", almost all doctors with 's' in any of its fields will be shown.
-
-
Alternative 2: Full-word matching of keyword inputted.
-
Pros: Ensure that only doctors with fields that matches the user’s input exactly will be returned. This will greatly reduce irrelevant results being shown.
-
Cons: Any accidental mistakes made in typing will not be condoned by the system, and may result in relevant results being omitted due to human error.
-
Aspect 2: Categorised or non-categorised keywords
-
Alternative 1 (current choice): Substring matching for all fields in Doctor.
-
Pros: Users will be able to view a wider list of doctors after filtering as doctors with any of the fields containing the keyword(s) will be shown.
-
Cons: Users will not be able to specify the field he/she wants to check, even when he/she knows which field to look into. This may result in irrelevant results being shown, where the doctor(s) of irrelevant fields that matches the user’s input will be shown.
-
-
Alternative 2: Substring matching for specific fields stated in Doctor.
-
Pros: Users will be able to view the most accurate results from the search. For example, if the user wants to search for "Ong" under the Name field only, he/she can specify in the search and narrow down to the relevant results.
-
Cons: Too restrictive if the user is not able to identify the specific field to check or if the user wants to check multiple fields.
-
Edit Doctor feature
When a user executes edit-d 1 n/Betty Veronica
Step1. LogicManager calls parseCommand("edit-d") in docXParser.
Step2. Based on the COMMAND_WORD, docXParser builds a new EditDoctorCommandParser() and calls function parse(arguments) of EditDoctorCommandParser.
Step3. EditDoctorCommandParser parses the argument and get the relative index of the doctor to be changed and the respective field(s) to be changed. It will call EditDoctorDescriptor() and change the field(s) accordingly. Then, EditDoctorCommandParser calls EditDoctorCommand(index, EditDoctorDescriptor).
Step4. LogicManager calls execute() of EditDoctorCommand.
Step5. execute() calls getFilteredDoctorList() of ModelManager and gets the doctor to be edited. After creating the edited doctor, EditDoctorCommand calls setDoctor(DoctorToEdit, EditedDoctor) of ModelManager.
Select Doctor feature
Implementation
When a user executes select-d 1
Step1. LogicManager calls parseCommand("select-d") in docXParser.
Step2. Based on the COMMAND_WORD, docXParser builds a new SelectDoctorCommandParser() and calls function parse("1") of SelectDoctorCommandParser.
Step3. SelectDoctorCommandParser parses the argument and get the relative index of the doctor to be selected. Then SelectDoctorCommandParser calls SelectDoctorCommand(index).
Step4. LogicManager calls execute() of SelectDoctorCommand.
Step5. execute() calls getFilteredDoctorList() of ModelManager and gets the doctor to be selected. SelectDoctorCommand calls setSelectedDoctor(selectedDoctor) and calls DOCTOR_BROWSER to be showed in the browser panel in the UI with the CommandResult.
Delete Doctor feature
Implementation
When a user executes delete-d 1
Step1. LogicManager calls parseCommand("delete-d") in docXParser.
Step2. Based on the COMMAND_WORD, docXParser builds a new DeleteDoctorCommandParser() and call function parse("1") of DeleteDoctorCommandParser.
Step3. DeleteDoctorCommandParser parses the argument and get the relative index of the doctor to be deleted. Then, DeleteDoctorCommandParser calls DeleteDoctorCommand(index).
Step4. LogicManager calls execute() of DeleteDoctorCommand.
Step5. execute() calls getFilteredDoctorList() of ModelManager and gets the doctor to be deleted. DeleteDoctorCommand calls deleteDoctor(doctorToDelete) of ModelManager.
Doctor Match feature
Implementation
When a user executes match-d s/general d/2019-06-20 t/09:00
Step1. LogicManager calls parseCommand("match-d") in docXParser.
Step2. Based on the COMMAND_WORD, docXParser builds a new DoctorMatchCommandParser() and call function parse(arguments) of DoctorMatchCommandParser.
Step3. DoctorMatchCommandParser parses the argument and get the desired specialisation, date and time of the appointment. DoctorMatchCommandParser calls constructors of Specialisation, AppointmentDate, AppointmentTime and then calls the constructor of DoctorMatch. Then, DoctorSpecialisationMatchesPredicate(DoctorMatch) will be created.
Step4. Then, DoctorMatchCommandParser calls DoctorMatchCommand(DoctorSpecialisationMatchesPredicate).
Step5. execute() calls updateFilteredDoctorList(DoctorSpecialisationMatchesPredicate) of ModelManager to filter the list of doctors whose specialisation matches the user’s input.
Step6. Then, execute() will call the constructor of DoctorsMatch with the filtered list of doctors, the desired appointment date and time. AppointmentContainsDoctorPredicate(DoctorsMatch) will be created. execute() calls updateAppointmentList(AppointmentContainsDoctorPredicate) of ModelManager to filter the list of appointments who are occupied during the desired date and time of appointment.
Step7. Then, execute() will get the filtered list of appointments and the desired specialisation. DoctorHasAppointmentPredicate will be created. execute() calls updateFilteredDoctorList(DoctorHasAppointmentPredicate) to filter the list of doctors whose specialisation matches and are available on the date and timing inputted.
Design Considerations
Aspect 1: Use user’s input of the doctor’s specialisation or use patient’s tags to auto-match.
-
Alternative 1: Using patient’s tags
-
Pros: Users only have to input the patient’s ID, and the command will generate available doctors who are suitable (according to specialisation match) and available at the date and time.
-
Cons: Restrictions on creation of patients' tags and doctors' specialisations, as there must be a back-end check that categorises the tags under specified specialisations, which results in tags and specialisations having to be in ENUM form and added prior to usage of the application.
-
-
Alternative 2 (current choice): Using user’s inputs to match with doctor’s specialisation(s).
-
Pros: Users have the flexibility and autonomy to input the specialisation to check with the doctors' specialisations. Our users are mostly clinic receptionists, who have the ability and knowledge to decide the type of doctor the patient should consult.
-
Cons: Any accidental errors in typing or someone new on the job may not be able to identify the correct doctors for the patient based on his/her illness.
-