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 JsonUserPrefsStorage
Storage
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
applicationuser
MSS
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/insurance
list person
.delete person 1
delete person -1
delete
, delete x
, ...
(where x is larger than the list size)edit person 1 p/90909090
find person n/Elmo
n
persons".n
refers to the amount of people with names containing "elmo".clear person
add appt ty/Check up d/2024-10-16 12:30 i/1 s/Common Cold m/Paracetamol
list appt
.delete appt 1
delete appt -1
delete
, delete x
, ...
(where x is larger than the list size)edit appt 1 ty/Health Checkup
find 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.sort
Unknown 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 100000
Invalid 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:61
Invalid 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:00
Model
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.