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 and list-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,

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

  • A doctor must have at least 1 specialisation.

  • Year of specialisation should be within 0 to 100.

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

  • There has to be an initial select-d INDEX command executed, before the user can use the mouse to click on the other doctors to display their information.

  • Selects the doctor at the specified INDEX. The index refers to the relative ID of the doctor. The index must be a positive integer 1, 2, 3, …​

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]

  • Edits the doctor at the specified INDEX. The index refers to the relative ID of the doctor. The index must be a positive integer 1, 2, 3, …​

  • At least one of the optional fields must be provided.

  • Existing values will be updated to the input values.

  • When editing specialisation, the existing specialisations of the doctor will be removed i.e adding of specialisation(s) is not cumulative.

Examples:

  • edit-d 1 p/91234567
    Edits the phone number of the doctor with ID of '1' to be 91234567.

  • edit-d 2 s/acupuncture s/general
    Edits the specialisations of the doctor with ID of '2' to be acupuncture and 'general'.

Locating doctor by keywords: list-d

Finds doctor(s) whose names contain any of the given keywords.
Format: list-d [KEYWORD] [KEYWORD]

  • The search is case insensitive. e.g hans will match Hans

  • The order of the keywords does not matter. e.g. Hans Bo will match Bo Hans

  • Partial or full words will be matched e.g. Han will match Hanry and Han

  • Doctors matching at least one keyword will be returned (i.e. OR search). e.g. Hans Bo will return Hans Gruber, Bo Yang

  • If no keywords are given, you will list all the existing doctors in docX. (Section 3.12)

Examples:

  • list-d John
    Returns john and John Doe

  • list-d 1
    Returns doctor with doctor ID of 1, phone number containing 1 or year of specialisation containing 1.

Deleting an existing doctor : delete-d

Deletes the specified doctor from docX.
Format: delete-d INDEX

  • Deletes the doctor of the specified INDEX.

  • The index refers to the relative ID of the doctor.

  • The index must be a positive integer 1, 2, 3, …​

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

  • Search can only be done with 1 specialisation.

  • Only full words are matched. e.g. acupun will not match acupuncture

  • DESIRED_DATE_OF_APPT is in the format YYYY-MM-DD.

  • DESIRED_START_TIME_OF_APPT is in the 24-hour format as HH:mm.

Examples:

  • match-d s/acupuncture d/2019-06-02 t/10:00
    Lists the doctors who has the specialisation of acupuncture 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 of general 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

UiClassDiagram edited
Figure 1. Structure of the 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.

ListDoctorCreationSequenceDiagram
Figure 2. The Sequence Diagram of the creation of the list doctor command.
ListDoctorExecutionSequenceDiagram
Figure 3. The Sequence Diagram of the execution of the list doctor command.

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.