Refer to the guide Setting up and getting started.
The Architecture Diagram below explains the high-level design of the DocTrack application.
Given below is a quick overview of main components and how they interact with each other.
Main (consisting of classes Main and MainApp) is in charge of the app launch and shut down.
The bulk of the app's work is done by the following four components:
UI: The UI of DocTrack.Logic: The command executor.Model: Holds the data of DocTrack in memory.Storage: Reads data from, and writes data to, the hard disk.Commons represents a collection of classes used by multiple other components.
The Sequence Diagram below shows how the components interact with each other, for the scenario where the user enters the command delete person 1.
Each of the four main components (also shown in the diagram above),
interface with the same name as the Component.{Component Name}Manager class (which follows the
corresponding API interface mentioned in the previous point).For example, the Logic component defines its API in the Logic.java interface and implements its functionality using the LogicManager.java class which follows the Logic interface. Other components interact with a given component through its interface rather than the concrete class (reason: to prevent outside component's being coupled to the implementation of a component), as illustrated in the (partial) class diagram below.
The sections below give more details of each component.
The API of this component is specified in Ui.java
The UI consists of a MainWindow that is made up of parts e.g.CommandBox, ResultDisplay, PersonListPanel, AppointmentListPanel, StatusBarFooter etc. All these, including the MainWindow, inherit from the abstract UiPart class which captures the commonalities between classes that represent parts of the visible GUI.
The UI component uses the JavaFx UI framework. The layout of these UI parts are defined in matching .fxml files that are in the src/main/resources/view folder. For example, the layout of the MainWindow is specified in MainWindow.fxml
The UI component,
Logic component.Model data so that the UI can be updated with the modified data.Logic component, because the UI relies on the Logic to execute commands.Model component, as it displays Person or Appointment object residing in the Model.API : Logic.java
Here's a (partial) class diagram of the Logic component:
The sequence diagram below illustrates the interactions within the Logic component, taking execute("delete 1") API call as an example.
Note: The lifeline for 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:
Logic is called upon to execute a command, it is passed to an AddressBookParser object which in turn creates a parser that matches the command (e.g., DeleteCommandParser) and uses it to parse the command.Command object (more precisely, an object of one of its subclasses e.g., DeleteCommand) which is executed by the LogicManager.Model when it is executed (e.g. to delete a person).Model) to achieve.CommandResult object which is returned back from Logic.Here are the other classes in Logic (omitted from the class diagram above) that are used for parsing a user command:
How the parsing works:
AddressBookParser class creates an XYZCommandParser (XYZ is a placeholder for the specific command name e.g., AddCommandParser) which uses the other classes shown above to parse the user command and create a XYZCommand object (e.g., AddCommand) which the AddressBookParser returns back as a Command object.XYZCommandParser classes (e.g., AddCommandParser, DeleteCommandParser, ...) inherit from the Parser interface so that they can be treated similarly where possible e.g, during testing.API : Model.java
The Model component,
Person objects:
PersonDescriptor objectPersonDescriptor object with a personId in the Person class.Person objects (which are contained in a UniquePersonList object).Person objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiable ObservableList<Person> that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change.Appointment objects:
AppointmentDescriptor objectAppointmentDescriptor object with a Person and appointmentId in the Appointment class.Appointment objects (which are contained in a UniqueAppointmentList object).Appointment objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiable ObservableList<Appointment> 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.UserPref object that represents the user’s preferences. This is exposed to the outside as a ReadOnlyUserPref objects.Model represents data entities of the domain, they should make sense on their own without depending on other components)Note: An alternative (arguably, a more OOP) model is given below. It has a Tag list (the
UniqueTagList) 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. Similarly, the Appointment objects are shown as such too.
API : Storage.java
Storage component can save patient data, appointment data, and user preference data in JSON format, and read them back into corresponding objects.Storage interface inherits from AddressBookStorage, AppointmentBookStorage and UserPrefStorage, which means it can be treated as either one (if only the functionality of only one is needed).JsonAddressBookStorage which inherits from interface AddressBookStorage.JsonSerializableAddressBook which consists of JsonAdaptedPerson and
JsonAdaptedTag which embodies the actual data of the individual patient and their dataJsonAppointmentBookStorage which inherits from interface AppointmentBookStorage.JsonSerializableAppointmentBook which consists of JsonAdaptedAppointment which
embodies the actual data of appointments and appointment detailsUserPrefsStorage interface and saved as JsonUserPrefsStorageStorage component depends on some classes in the Model component (because the Storage component's job is to save/retrieve objects that belong to the Model)Classes used by multiple components are in the seedu.address.commons package.
The activity diagram shows the general sequence of steps when a user interacts with DocTrack.
CommandBox.AddressBookParser parses the command.Command object. Else, an error is displayed.Command object is executed.UI displays the result of the command execution to the user.Entity commands include add, delete, find, clear, edit, and list commands.
xyzCommand can be addCommand, deleteCommand, findCommand, clearCommand, editCommand, or listCommand.The sequence diagram shows how an entity command is executed:
Note: The lifeline for xyzCommandParser should end at the destroy marker (X) but due to a limitation
of PlantUML, the lifeline continues till the end of diagram.
Note: There are two entities, Person and Appointment.
FindEntityCommand refers to FindPersonCommand and FindAppointmentCommand.AddEntityCommand refers to AddPersonCommand and AddAppointmentCommand.Step 1. The user types an xyz command input in the CommandBox, followed by the type of entity,
person or appt. This is followed by appropriate arguments and prefixes.
Step 2. The input is passed to the LogicManager. LogicManager then calls the
AddressBookParser::parseCommand method to parse the input.
Step 3. The AddressBookParser parses the input and creates an xyzCommandParser object, which is
returned to the AddressBookParser.
Step 4. The AddressBookParser calls the
xyzCommandParser::parse method to parse the arguments.
Step 5. The xyzCommandParser creates an xyzCommand object, which is returned to the LogicManager.
Step 6. The LogicManager calls the xyzCommand : execute method, which creates a CommandResult
Object.
Step 7. The CommandResult object is returned to the LogicManager.
Aspect: Whether to implement entity commands as separate commands or through an abstract base command
AddPersonCommand, AddAppointmentCommand, DeletePersonCommand,DeleteAppointmentCommand) inherit from.
Aspect: What constitutes duplicate person that should not be added or edited into the AddressBook
Aspect: What constitutes duplicate appointment that should not be added or edited into the AppointmentBook
Aspect: Whether appointment fields should be optional
Sickness and Medicine fields are optional.
Aspect: What input should be valid for fields Sickness and Medicine
Aspect: Whether delete person and clear person should remove appointments too
personId of the deleted person(s).
personId of that person.
personId. However, the user might forget to do so.Aspect: What value to use for indicating entity
Aspect: Whether to check if the personId associated with edited appointment corresponds to an existing person in the AddressBook
edit appt command, check if the new personId
exists in the AddressBook.
edit appt command does not check if the new personId exists in the AddressBook.
Aspect: How to implement the find person and find appt commands that allow finding by multiple criteria
Aspect: How to combine multiple prefixes when executing the find commands
Aspect: Whether to implement case sensitivity in matching for search terms
Tip:
To add a new predicate, navigate the corresponding entity folder in the model package. There, you can create a new class that implements Predicate<Entity>. Ensure that this method has a test method which defines the specific condition for a predicate.
General commands include the exit and help commands.
The sequence diagram shows how a general command (ExitCommand or HelpCommand) is executed:
Step 1. The user types an xyz command (exit or help) in the CommandBox, which is then passed to the LogicManager.
Step 2. The LogicManager calls the AddressBookParser::parseCommand method to parse the xyz command.
Step 3. The AddressBookParser creates an XYZCommand object, which is returned to the
LogicManager. The XYZCommand object can be an ExitCommand or a HelpCommand.
Step 4. The LogicManager calls the XYZCommand::execute method, which creates a new CommandResult
object.
Step 5. The CommandResult object is returned to the LogicManager.
When a user types an exit command, the DocTrack application will exit.
When a user types a help command, the DocTrack application will display a HelpWindow.
Aspect: How to display help information:
Aspect: Save patient and appointment data in
data/addressbook.json and appointment data in data/appointmentbook.json.
data/addressbook.json Note:
For Appointment, the fields Sickness and Medicine are optional. Hence, if Sickness or Medicine
is not specified, it would be represented as "null", in the appointmentbook.json file.
Aspect: When the data is updated in the .json file
Aspect: How to parse the commands
Context: The commands (other than the general) have the command format: COMMAND ENTITY_TYPE ENTITY_ARGS
ENTITY_TYPE and ENTITY_ARGS separately.
Aspect: Command format (with or without prefixes)
Aspect: The use of ArgumentMultimap across different entities
ArgumentMultimap for all entities.
ArgumentMultimap for each entity.
Aspect: How to show appointment and person lists
Context: There are two entity types (appointment and person) being managed in DocTrack.
add appt
or edit appt commands, which may need information about personId.list appt or list person command.
Aspect: Color Scheme
Target user profile:
Value proposition:
Priorities: High * * * (must have), Medium * * (nice to have) , Low * (unlikely to have)
| Priority | As a … | I want to … | So that I can… |
|---|---|---|---|
* * * | doctor | add appointments | find them in the future for reference |
* * * | doctor | schedule a new patient appointment | ensure that the patient is properly booked for consultation |
* * * | doctor | remove an appointment that is no longer needed | free up time slots for other patients and avoid scheduling conflicts |
* * * | doctor | view all upcoming appointments for better planning | organize my day effectively and ensure no appointments are missed |
* * * | administrative staff | manage patient contact information | easily communicate with patients |
* * * | administrative staff | update patient details | maintain accurate records |
* * * | administrative staff | get details on a specific patient's appointments | keep track of the patient |
* * * | administrative staff | store all patients information | retrieve them in the future |
* * * | nurse | track appointments | get ready to serve patients |
* * | doctor | access appointment history | understand patient visit patterns |
* * | doctor | categorize patients by conditions or treatments | easily track patient groups |
* * | doctor | find free slots in the appointments | find gaps for appointments or holidays |
* * | administrative staff | get details on appointments for the day | keep track of the day's appointments |
* * | doctor | shift appointments to a different time | change appointments based on holidays, etc. |
* * | administrative staff | schedule follow-up appointments | keep track of patients' appointments |
* * | doctor | add mood status to appointment details | keep track of patient health each time we meet |
* * | doctor | sort patients by closest future appointment date | see which patient to see next |
* * | doctor | find duplicate errors within the system | not have erroneous appointments |
* * | doctor | organize appointments | arrange my schedule accordingly |
* * | doctor | set holidays/free days | disallow appointments during certain dates |
* * | doctor | categorise patients based on certain factors | easily track patients with certain statuses |
* * | doctor | add list of allergies for a certain patient | not prescribe them stuff that will kill them |
* | doctor | view patient's medical history | make informed treatment decisions |
* | doctor | access test results for patients | review and discuss results with patients |
* | doctor | set reminders for specific patient actions | ensure follow-up on important tasks |
* | doctor | retrieve medical certificates of patients | gather patient information quickly |
* | doctor | record the medications given to patients | keep track of personal medication records of patients |
* | administrative staff | search for patient files by name or ID | quickly retrieve specific records |
* | administrative staff | check prescription assigned by the doctor | print out prescription for patient |
* | doctor | search up medicine to prescribe | give prescription to patient |
* | doctor | add notes to patient files | reference them during future visits |
* | doctor | change the time frame for receiving reminders | receive reminders more frequently or less frequently |
* | doctor | add guardian/parental contacts to patient | contact patient indirectly |
* | doctor | update patient status | keep track of patient's condition |
* | doctor | copy treatments | duplicate medication plans for similar patients |
* | doctor | receive reminders on upcoming appointments | prepare for them |
* | doctor | retrieve specific treatment information | treat them appropriately |
* | doctor | generate an automated document for a patient | give it to them as reference |
For all use cases below, unless specified otherwise,
DocTrack applicationuserMSS
User requests to add a patient.
DocTrack adds the patient.
Use case ends.
Extensions
1a. User enters invalid parameters.
1a1. DocTrack shows an error message.
Use case resumes at step 1.
1b. User enters a patient that already exists.
1b1. DocTrack shows an error message.
Use case resumes at step 1.
MSS
DocTrack shows a list of patients (UC04).
User requests to edit a specific patient in the list with new details.
DocTrack updates the patient with the new details.
Use case ends.
Extensions
2a. The given index is invalid.
2a1. DocTrack shows an error message.
Use case resumes at step 2.
2b. The new patient details are invalid.
2b1. DocTrack shows an error message.
Use case resumes at step 2.
MSS
DocTrack shows a list of patients (UC04).
User requests to delete a specific patient in the list.
DocTrack deletes the patient.
Use case ends.
Extensions
2a. The given index is invalid.
2a1. DocTrack shows an error message.
Use case resumes at step 2.
MSS
User requests to list all patients.
DocTrack shows a list of patients.
Use case ends.
Extensions
2a. The list is empty.
Use case ends.
MSS
User requests to find a patient by name.
DocTrack shows the patient details.
Use case ends.
Extensions
1a. User enters invalid parameters.
1a1. DocTrack shows an error message.
Use case resumes at step 1.
2a. The patient is not found.
Use case ends.
MSS
User requests to clear all patients.
DocTrack clears all patients.
Use case ends.
MSS
User requests to add an appointment.
DocTrack adds the appointment.
Use case ends.
Extensions
1a. User enters invalid parameters.
1a1. DocTrack shows an error message.
Use case resumes at step 1.
1b. User enters an appointment with the same date and time.
1b1. DocTrack shows an error message.
Use case resumes at step 1.
MSS
DocTrack shows a list of appointments (UC10).
User requests to edit a specific appointment in the list with new details.
DocTrack updates the appointment with the new details.
Use case ends.
Extensions
2a. The given index is invalid.
2a1. DocTrack shows an error message.
Use case resumes at step 2.
2b. The new appointment details are invalid.
2b1. DocTrack shows an error message.
Use case resumes at step 2.
MSS
DocTrack shows a list of appointments (UC10).
User requests to delete a specific appointment in the list.
DocTrack deletes the appointment.
Use case ends.
Extensions
2a. The given index is invalid.
2a1. DocTrack shows an error message.
Use case resumes at step 1.
MSS
User requests to list all appointments.
DocTrack shows a list of appointments.
Use case ends.
Extensions
2a. The list is empty.
Use case ends.
MSS
User requests to find an appointment by patient name or date.
DocTrack shows the appointment details.
Use case ends.
Extensions
1a. User enters invalid parameters.
1a1. DocTrack shows an error message.
Use case resumes at step 1.
2a. The appointment is not found.
Use case ends.
MSS
User requests to clear all appointments.
DocTrack clears all appointments.
Use case ends.
17 or above installed.Given below are instructions to test the app manually.
Note: These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing.
Initial launch
java -jar DocTrack.jar Saving window preferences
java -jar DocTrack.jar.add person n/Elmo p/98765432 e/elmo@sesa.me a/Sesame Street st/recovering t/insurancelist person.delete person 1delete person -1delete, delete x, ... (where x is larger than the list size)edit person 1 p/90909090find person n/Elmon persons".n refers to the amount of people with names containing "elmo".clear personadd appt ty/Check up d/2024-10-16 12:30 i/1 s/Common Cold m/Paracetamollist appt.delete appt 1delete appt -1 delete, delete x, ... (where x is larger than the list size)edit appt 1 ty/Health Checkupfind appt n/[NAME]x appointments".x refers to the amount of appointment for people with names containing "elmo".clear appt../data and delete the .json files.../data and edit the .json file, adding a random / at the end.Team size: 5
Unknown Command, which is
not informative.sortUnknown Command. Did you mean: list, find, clear, add, edit, delete, exit, or help?2023-02-29 for an appointment date.Invalid date: 2023 is not a leap year, so February 29 is not valid.2023-03-32 for an appointment date.Invalid date: The day is out of range for the month.edit commands utilising INDEX as a field, when users input an index larger than the
list size of Person or Appointment, the application does not check for the validity of the index.edit person 100000Invalid index! Please enter a valid index within the list size.2024-05-12 25:61 returns an error message that says "Invalid date-time format," which is unclear since the format is correct.... d/2024-05-12 25:61Invalid time format. Please enter a valid time between 00:00 and 23:59.person with a new name, his/her appointments still refer to the old name.EditPersonCommand, also edit any appointments with this patient to point to the new Person object.edit person 1 n/Jonathan.appointment, such that the sickness or medicine field is null, the GUI invalidates this input even though these fields are optional.edit appt 1 s/ m/25:00, it would be helpful if the error message shows that invalid format for time has been provided. This would provide more information for those who
may be unfamiliar with 24-hour time format.edit appt 3 d/2024-12-05 25:00Model classModel class.Model class. Reference frames can be included to show the interactions with the Model class for different commands.
Our project presented a higher level of complexity compared to AB3. Our project involved handling multiple entity types, mainly persons and appointments, whereas AB3 manages only a single entity. This increased the requirements for command processing as each entity type has additional attributes and methods.
Patient attribute to the Appointment class.personId and appointmentId attribute to the Person and Appointment classes respectively.Our project involved substantial effort in several key areas:
Our project successfully expanded AB3’s functionality, enabling the application to manage patients and appointments. Despite the challenges, our final solution provides a user-friendly interface and coherent command structure. Additionally, the design allows for potential future expansion to include other entity types without extensive restructuring, making the system both flexible and scalable.