PROJECT: NurseTraverse


I am a Year 2 Computer Science student at the National University of Singapore. I enjoy learning new technologies and software tools as well as helping out in any project that is interesting, challenging, and can have a positive impact in any community. Here you can find my contributions to one of my projects.

Overview

NurseTraverse is a desktop application designed to help community nurses manage all the data they may need, including visit management, appointment scheduling, and importing and exporting of patient data. The user interacts with the app using a CLI (Command Line Interface) enhanced with an autocomplete functionality and ability to undo and redo commands. The app has a GUI created with JavaFX and is written in Java. NurseTraverse is built by me and 4 other students.

Summary of contributions

Lists all appointments nurses have scheduled, including reference to patient details, appointment start and end date and time, frequency with which the appointment recurs (if it does), and additional description details associated with the appointment.

  • Major enhancement: added the ability to manage appointments

    • What it does: allows the user to schedule and manage appointments with their patients. The user can add, edit, delete their appointments, Preceding undo commands can be reversed by using the redo command.

    • Justification: This feature improves the product significantly because tracking the appointments associated with different patients is a must-have for every community nurse so that they can organize their schedule before paying visits to the patients.
      This feature has been identified as a required feature in user story #7.

    • Highlights:

      • This enhancement adds a new feature to the app. Lot of groundwork to be done in terms of setting up the AppointmentBook, converting AppointmentBook data to JSON for storage, adding it to be tracked by the ModelManager when the app is running, etc.

      • The feature adds new commands for listing appointments scheduled, finding specific appointments by patient name, adding, deleting, and editing appointments, where the appointments can be recurring or non-recurring. It affects any appointment-related commands to be added in the future.

      • Particularly challenging was implementing recurring appointments and prevention of clashing appointments alongside each other, since appointments that are added may clash with future date and time of a recurring appointment. Many design alternatives had to be considered before it was decided to recur appointments until they did not clash with any appointments in the existing list of appointments.

      • Moreover, since this feature takes into account the association from the Appointments to the Patient class, it affected existing patient commands' behaviour (for instance, deleting or editing of patients accordingly result in deleting and editing the appointments associated with this patient).
        Handling and implementing this association while trying to minimise the coupling as much as possible was challenging and required an in-depth analysis of design alternatives.

    • Credits: No code or ideas were borrowed or adapted from outside applications, nor were any third-party libraries used. Only referenced, used, and modified code within Address Book 3.

  • Minor enhancements:

    • Added appointment card and appointment list in a separate tab for easy user visibility.

    • Improved date time printing such that the date times are viewed as, for example, Sun, 1st Dec 2019, 18:00 instead of 01-12-2019 1800.

  • Code contributed: Code contributed can be found in the following link (there are filters on the landing page to view the code contributed as functional or tests) here. For a more specific breakdown, my PRs reference the following issues (v1.2 #65, v1.3 #97, v1.4 #64)

  • Other contributions:

    • Project management:

      • Opened user stories issues

    • Documentation:

      • Pointed out various issues in the early stages of designing the User Guide for the app: #42.

      • Updated About Us and Contact Us Pages: #38.

      • Opened draft PPPs for everyone, as well as updated (and made more specific) the app’s information in the PPPs: #38.

    • Community:

      • PRs reviewed (with non-trivial review comments or reviewed to approve): #73, #80, #104, #194

      • Contributed to forum discussions (in Pull Requests(s) #42 and offline/Telegram discussions)

    • Tools:

      • Set up team repo and organization.

Contributions to the User Guide

Given below are some of the sections I contributed to the User Guide for V1.4 of the product. They showcase my ability to write documentation targeting end-users.

Appointments

Appointments

As a community nurse, you will often schedule appointments with your patients before visiting them, as well as keep track of these appointments you make with your patients. You can use the application to manage and keep track of these appointments. This section describes the features that will allow you to manage your appointments.

Listing All Appointments: appt-list

You can see a list of all appointments in the app by typing appt-list.

In the list displayed, each appointment will have an index number which can then be used for other features that require you to select an appointment by index e.g. appt-delete. Take note that an appointment will be given the same index regardless of other display commands such as appt-find.

The appointment list is sorted in increasing order of start date time of the appointments, i.e it shows the earlier scheduled appointments followed by the later ones.

Format: appt-list

Finding Appointment(s): appt-find

You can find appointments by patient name by typing any keyword of your choice following appt-find.

In the list displayed, each appointment will have an index number which can then be used for other features that require you to select an appointment by index e.g. appt-delete. Take note that an appointment will be given the same index regardless of other display commands such as appt-list or if different parameters are used.

Format: appt-find [PATIENT_NAME]

  • 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

  • Only the patient name is searched for in the list of appointments.

  • Partial words will be matched (e.g. John will return John Smith and John Kim if both have appointments in the appointment list).

Examples:

  • appt-find James
    Lists all appointments of that particular patient James

Adding an Appointment: appt-add

You can add an appointment to the list of all appointments by using appt-add.

Format: appt-add p/PATIENT_INDEX sdt/START_DATE_TIME edt/END_DATE_TIME [desc/DESCRIPTION] [ryr/RECUR_YEARS] [rmon/RECUR_MONTHS] [rweek/RECUR_WEEKS] [rday/RECUR_DAYS] [rhr/RECUR_HOURS] [rmin/RECUR_MINUTES]

  • START_DATE_TIME and END_DATE_TIME expect inputs in the format dd-MM-yyyy HHmm with dd, MM, yyyy, HH, and mm all as numerical numbers (HHmm being in 24-hour time), and the end date time should be equal to or after the start date time. Also, both start and end date times must be past the system’s local date time.

  • RECUR_YEARS, RECUR_MONTHS, RECUR_WEEKS, RECUR_DAYS, RECUR_HOURS, RECUR_MINUTES each must be a positive integer 1, 2, 3, …​

  • An appointment can recur by any amount of each of the frequencies: years, months, weeks, days, hours, and minutes. If you wish for an appointment to only recur by years and months, just typing ryr/[RECUR_YEARS] and `rmon/[RECUR_MONTHS] in any order is sufficient.

  • The appointment added cannot have the same identity as an existing appointment. Its identity is defined by START_DATE_TIME, END_DATE_TIME, patient it is associated with through the PATIENT_INDEX, and the frequency as defined by RECUR_YEARS, RECUR_MONTHS, etc.

  • The appointment added cannot clash in timing with any other existing appointment, i.e. their start and end date times must not overlap in any way.

Examples:

  • appt-add p/1 sdt/24-12-2019 1200 edt/24-12-2019 1400 desc/Medical checkup

  • appt-add p/2 sdt/09-12-2019 1300 edt/09-12-2019 1330 ryr/1 rmon/3

Editing an Appointment: appt-edit

You can edit an existing appointment in the app using appt-edit.

Format: appt-edit INDEX [sdt/START_DATE_TIME] [edt/END_DATE_TIME] [p/PATIENT_INDEX] [desc/DESCRIPTION] [ryr/RECUR_YEARS] [rmon/RECUR_MONTHS] [rweek/RECUR_WEEKS] [rday/RECUR_DAYS] [rhr/RECUR_HOURS] [rmin/RECUR_MINUTES]

  • Edits the appointment at the specified INDEX.

  • The index refers to the index number shown in the list of appointments displayed by appt-list or appt-find.

  • 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 recurring frequencies (years, months, etc.), the existing frequencies of the appointment will be kept unless overwritten by i.e adding of frequencies is cumulative.

  • You can make the appointment not recurring by setting all the necessary recurring frequencies to 0. For example, if an appointment recurs every year, then specify a 0 frequency as ryr/0 to make the appointment non-recurring.

  • You cannot change individual fields of the patient (i.e. patient name, phone number, etc.) using the appt-edit command. Refer to pat-edit under [Patient] for more on this.

Examples:

  • appt-list
    appt-edit 1 sdt/05-12-2019 1900 edt/05-12-2019 2000
    Edits the start date time and end date time of the 1st person in the entire appointment’s list to be 05-12-2019 1900 and 05-12-2019 2000 respectively.

  • appt-edit 2 p/3 ryr/1
    Edits the second appointment to be associated with the third patient in the patient list. Also edits the appointment to recur by 1 year.

Deleting an Appointment: appt-delete

You can delete an appointment by index using appt-delete.

Format: appt-delete INDEX

  • Deletes the appointment at the specified INDEX.

  • The index refers to the index number shown in the list of appointments displayed by appt-list or appt-find.

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

  • If the appointment referred to by the INDEX is a recurring appointment, deleting this appointment will automatically recur the appointment (i.e. get the next start and end date time) and add it to the appointment list. If you wish to remove a recurring appointment permanently from the appointment list, refer to [Deleting an Appointment Permanently].

Examples:

Assuming the first appointment in the list is a recurring appointment, and the second is a non-recurring one.

  • appt-delete 2
    Deletes the 2nd appointment in the displayed appointment list.

  • appt-delete 1
    Deletes the 1st appointment in the displayed appointment list. Recurs the appointment and adds the new appointment with the next start and end date time to the appointment list.

Deleting an Appointment permanently: appt-delete-permanent

You can delete an appointment permanently by index using appt-delete-permanent.

You can use this command on both recurring and non-recurring appointments, but its use is more suited for recurring appointments since appt-delete and appt-delete-permanent work in the same way for non-recurring appointments.

Format: appt-delete-permanent INDEX

  • Deletes the appointment permanently at the specified INDEX.

  • The index refers to the index number shown in the list of appointments displayed by appt-list or appt-find.

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

  • For recurring appointments, unlike in the case of appt-delete, now the recurring appointment referred to by the INDEX is removed from the appointment list permanently and not recurred.

Examples:

Assuming the first appointment in the list is a recurring appointment, and the second is a non-recurring one.

  • appt-list
    appt-delete-permanent 2
    Deletes the 2nd appointment in the displayed appointment list permanently.

  • appt-delete-permanent 1
    Deletes the 1st appointment in the displayed appointment list permanently.

Contributions to the Developer Guide

Given below are some of the 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.

Implementation Overview

The appointments management feature is facilitated primarily by the AppointmentBook, a class that implements the ReadOnlyAppointmentBook interface and wraps around all appointments data of the app. This is a new book (different from the PatientBook) that is now required by the ModelManager class for instantiation along with UserPrefs and PatientBook. The AppointmentBook is, therefore, a field in the ModelManager class. The AppointmentBook has appointments, which is a UniqueAppointmentList, as a private field that holds all appointments currently in the AppointmentBook as a unique list. This list is modified from certain method calls in the ModelManager class.

Model

The main operations in the AppointmentBook are exposed to in the Model interface. Model implements the following operations to accommodate for the inclusion of the AppointmentBook and its related methods:

  • Model#setStagedAppointmentBook(ReadOnlyAppointmentBook appointmentBook) — Replaces appointment book in the Model with data from the ReadOnlyAppointmentBook appointmentBook passed in as argument.

  • Model#replaceStagedAppointmentBook(List<Appointment> appointments) — Replaces all appointments in appointment book with new appointments from the list.

  • Model#getStagedAppointmentBook() — Returns the current AppointmentBook.

  • Model#hasAppointment(Appointment appointment) — Returns true if an appointment with the same identity as the appointment passed in as argument exists in the appointment list.

  • Model#hasClashingAppointment(Appointment appointment) — Returns true if any appointment in the appointment list has clashing time with the appointment passed in as argument.

  • Model#deleteAppointment(Appointment target) — Deletes the given appointment. If the the target appointment is recurring, then the appointment is recurred and the next one is added to the appointment list.

  • Model#deleteRecurringAppointment(Appointment target) — Deletes the given recurring or non-recurring appointment permanently.

  • Model#deleteAppointments(Patient target, Index targetIndex) — Deletes all appointments associated with the target patient.

  • Model#addAppointment(Appointment appointment) — Adds the given appointment. The appointment passed in as argument must not already exist in the appointment list.

  • Model#setAppointment(Appointment target, Appointment editedAppointment) — Replaces the given appointment target with editedAppointment. target must exist in the appointment list. The appointment identity of editedAppointment must not be the same as another existing appointment in the appointment list.

  • Model#setAppointments(Patient patientToEdit, Patient editedPatient) — Replaces all appointments' patients that equal patientToEdit with editedPatient.

  • Model#ObservableList<Appointment> getStagedAppointmentList() — Returns an unmodifiable view of the entire appointment list.

  • Model#FilteredList<Appointment> getFilteredAppointmentList() — Returns an unmodifiable view of the filtered appointment list.

  • Model#void updateFilteredAppointmentList(Predicate<Appointment> predicate) — Updates the filter of the filtered appointment list to filter by the given predicate.

Model Design Considerations

Aspect: Where to wrap all appointments data in
  • Alternative 1 (current choice): Create AppointmentBook to wrap around all appointments and add it as a field of ModelManager.

    • Pros:

      • Splitting the AddressBook into PatientBook and AppointmentBook clearly demarcates the handling of patients and appointments separately.

      • When there are changes made to the appointments, only the AppointmentBook is modified, i.e. there is no need to, for example, refresh the data for patients.

    • Cons:

      • Overhead of more methods in the Model needed separately for the changes made in the AppointmentBook.

      • Major refactoring was needed in many classes and tests since there were changes to the constructor and fields of the ModelManager.

  • Alternative 2: Modify the original AddressBook to have two unique lists as fields within it, one for patients and one for appointments.

    • Pros:

      • The number of extra methods added to the Model could have been reduced since some methods may do the same operation on both appointment and patient lists.

    • Cons:

      • Principle of separation of concerns may be violated.

      • Optimization might be compromised, since methods intended to operate only on the specific patient or appointment lists might operate on the whole AddressBook unnecessarily.

Use Case

Appointment Management is used when the user wants to schedule an appointment with the patient. There are 6 actions that a user can perform:

AppointmentManagementUseCase

Perhaps the most complex workflow is when a user deletes a recurring appointment. In doing so, as indicated in the Use Case diagram above, the appointment is first deleted from the list of appointments. The appointment is then recurred to get the next appointment (i.e. with the next start and end date time), and added to the list of appointments by directly calling the AppointmentBook#addRecurringAppointment method. Assuming the first appointment in the appointment list is recurring. The following sequence diagrams show the object interactions for user command appt-delete 1:

AppointmentManagementSequenceDiagram

Figure: Delete Appointment Sequence Diagram

AppointmentManagementSequenceDiagramRef

Figure: Reference - delete appointment, recur, and add the recurred appointment