From b7d12fdf05db34451e5f80f6da2f6f8a283b8453 Mon Sep 17 00:00:00 2001 From: Kappaccinoh Date: Mon, 15 Apr 2024 23:20:21 +0800 Subject: [PATCH 1/2] add query DG documentation --- docs/DeveloperGuide.md | 144 ++---------------- ...yPatientCommandExecuteSequenceDiagram.puml | 2 +- ...ryPatientCommandExecuteSequenceDiagram.png | Bin 21728 -> 23121 bytes 3 files changed, 16 insertions(+), 130 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 3ce1d0883eb..77373f530ad 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -377,8 +377,6 @@ Alternative implementation for consideration 2. This will centralise the behaviours, and reduce the amount of code needed to perform the edit function. 3. A further extension is to do so with all other overlapping functionalities, such as `add` or `delete`, however we leave that possibility for future discussion and refinement. - - ### Delete `Appointment` Deletes an `Appointment` entry by indicating their `Index`. This command is implemented through the `DeleteAppointmentCommand` class which extend the `Command` class. @@ -414,139 +412,27 @@ Alternative implementation for consideration 2. This will centralise the behaviours, and reduce the amount of code needed to perform the delete function. 3. A further extension is to do so with all other overlapping functionalities, such as `add` or `edit`, however we leave that possibility for future discussion and refinement. -### Find `Person` -Queries a `Person` entry, either `Doctor` or `Patient` by indicating their name or a substring of their name. -This command is implemented through the `FindCommand` class which extends the `Command` class. - -The `find` command is able to take in multiple parameters (at least one), each of these parameters are read as strings, and act as separate queries. This is a feature of the `find` command, to have the capability of parsing both parameters as a short-hand feature. -Example, the command `find hans doe` is equivalent of returning the logical 'or' result of `find hans` and `find doe`. - -* Step 1. User enters a `find` command. -* Step 2. The `AddressBookParser` will call `parseCommand` on the user's input string and return an instance of `findCommandParser`. -* Step 3. The `parse` command in `FindCommandParser` checks if at least one parameter is present. - * If the field is missing, a `ParseException` is thrown, and the UI displays an error message. - -The activity diagram below demonstrates this error handling process in more detail. - - - -* Step 4. The `parse` command in `FindCommandParser` returns an instance of `FindCommand`. -* Step 5. The `LogicManager` calls the `execute` method in `FindCommand`. -* Step 6. The `execute` method in `FindCommand` executes and calls `updateFilteredPersonList` in model with the `NameContainsKeywordsPredicate` to get a filtered list of person entries of the entered keyword(s), both `patient` and `doctor` entries can be displayed. -* Step 7. A Success message gets printed onto the results display to notify user and the list of matching results is produced. - -The sequence diagram below closely describes the interaction between the various components during the execution of the `FindCommand`. - - - -Alternative implementations considered -1. The following sections describes the behaviour of querying `doctor` and `patient` entries by separate commands by all of the entry's fields, both following a very similar logic to how the `find` command is implemented. We might consider using flags to be more precise with our searches, (e.g a -doctor or -patient flag to indicate we wish to search for only `doctor` and `patient` entries respectively) so as to avoid the need to create additional commands. However, we felt that this approach overloaded the `find` method too much, and overcomplicated the `find` command's usage. -2. Even if the `find` command was to be overloaded with flags, we foresaw that the creation of distinct commands to fit the flags parsed by the `find` command was unavoidable. As such, it was prudent to start with the implementation of the distinct commands first (as described in the following sections, each tied to a specific command), and leave the overloading of the `find` command as a later increment. - - -### Query `doctor` -Queries a `doctor` entry by indicating the exact string, or substring of any of a `doctor`'s fields - name, nric, phone number and date of birth (as displayed on the UI. e.g 30 January 2023). -This command is implemented through the `QueryDoctorCommand` class which extends the `Command` class. - -Similar to the `find` command, the `doctor` query command is able to take in multiple parameters (at least one), each of these parameters are read as strings, and act as separate queries, with the result returned being the logical 'or' result of applying a `doctor` query to each parameter separately. - -* Step 1. User enters a `doctor` command. -* Step 2. The `AddressBookParser` will call `parseCommand` on the user's input string and return an instance of `QueryDoctorCommandParser`. -* Step 3. The `parse` command in `QueryDoctorCommandParser` checks if at least one parameter is present. - * If the field is missing, a `ParseException` is thrown, and the UI displays an error message. - -The activity diagram below demonstrates this error handling process in more detail. - - - -* Step 4. The `parse` command in `QueryDoctorCommandParser` returns an instance of `QueryDoctorCommand`. -* Step 5. The `LogicManager` calls the `execute` method in `QueryDoctorCommand`. -* Step 6. The `execute` method in `QueryDoctorCommand` executes and calls `updateFilteredPersonList` in model with the `DoctorContainsKeywordsPredicate` to get a filtered list of only `Doctor` entries of the entered keywords(s). -* Step 7. Success message gets printed onto the results display to notify user and the list of matching results is produced. - - -Why is this implemented this way? -1. The backend execution of the `doctor` command and the `find` command are very similar, however the choice to separate the two query commands is justified due to the expansion of fields in the `doctor` query, conceptually making them distinct commands. -2. Furthermore, there is an additional check to check if an entry is of type `doctor` that is not present in the `find` command. - - -### Query `patient` -Queries a `patient` entry by indicating the exact string, or substring of any of a `patient`'s fields - name, nric, phone number and date of birth (as displayed on the UI. e.g 30 January 2023). -This command is implemented through the `QueryPatientCommand` class which extends the `Command` class. - -Similar to the `find` command, the `patient` query command is able to take in multiple parameters (at least one), each of these parameters are read as strings, and act as separate queries, with the result returned being the logical 'or' result of applying a `patient` query to each parameter separately. +### Querying Entities in MediCLI `patient`, `doctor`, `appointment` +This section describes the general sequence for commands that query entities. MediCLI has 5 different commands that serve this function: `find`, `patient`, `doctor`, `apptforpatient` and `apptfordoctor`. +Although this section describes only the `patient` command, each of the other commands, while lined with different predicates and have different requirements for their parameters, possess as similar implementation. Hence, the flow of method calls between classes are generally similar, and all 5 commands with query entities are described together in one section. -* Step 1. User enters a `patient` command. -* Step 2. The `AddressBookParser` will call `parseCommand` on the user's input string and return an instance of `QueryPatientCommandParser`. -* Step 3. The `parse` command in `QueryPatientCommandParser` checks if at least one parameter is present. - * If the field is missing, a `ParseException` is thrown, and the UI displays an error message. +* Step 1. The `execute()` method is called in an instance of `QueryPatientCommand`. +* Step 2. The instance of `QueryPatientCommand` calls the `updateFilteredPersonList()` method with the `PatientContainsKeywordsPredicate` in an instance of the `Model` class, which filters out entries and returns only patients that match the keywords entered. Note that the other commands listed here will have their respective `predicate` requirements and implementations. +* Step 3. Control is passed to an instance of the `Logger` class, which calls the method `log()` to log a "Success" message. +* Step 4. The instance of `QueryPatientCommand` calls the constructor method of the `CommandResult` class, which returns the final result. +* Step 5. Control is returned to the caller with the final result. -The activity diagram below demonstrates this error handling process in more detail. - - - -* Step 4. The `parse` command in `QueryPatientCommandParser` returns an instance of `QueryPatientCommand`. -* Step 5. The `LogicManager` calls the `execute` method in `QueryPatientCommand`. -* Step 6. The `execute` method in `QueryPatientCommand` executes and calls `updateFilteredPersonList` in model with the `PatientContainsKeywordsPredicate` to get a filtered list of only `Patient` entries of the entered keywords(s). -* Step 7. Success message gets printed onto the results display to notify user and the list of matching results is produced. - - -Why is this implemented this way? -1. The backend execution of the `patient` command and the `find` command are very similar, however the choice to separate the two query commands is justified due to the expansion of fields in the `patient` query, conceptually making them distinct commands. -2. Furthermore, there is an additional check to check if an entry is of type `patient` that is not present in the `find` command. - - -### Query `apptfordoctor` -Queries an `appointment` entry that has the associated `doctor`'s `Nric`, by indicating the exact `Nric` of the doctor as the search parameter. -This command is implemented through the `apptfordoctor` class which extends the `Command` class. - -The `apptfordoctor` command takes in multiple parameters (at least one), and each of these parameters are read as strings (not case-sensitive, i.e S1234567A is equivalent to s1234567a), and returns the logical 'or' result of applying the `apptfordoctor` command to each parameter separately. **Note that no errors will not be thrown if the inputted `Nric`(s) are not of the appropriate form** (i.e Begins with one of S, T, G, F, or M, followed by 7 numerical digits, then ended by an alphabetical letter), but rather the expected return result is that no queries will be found. - -* Step 1. User enters an `QueryDoctorAppointment` command. -* Step 2. The `AddressBookParser` will call `parseCommand` on the user's input string and return an instance of `QueryDoctorAppointmentCommandParser`. -* Step 3. The `parse` command in `QueryDoctorAppointmentCommandParser` checks if at least one parameter is present. - * If the field is missing, a `ParseException` is thrown, and the UI displays an error message. - -The activity diagram below demonstrates this error handling process in more detail. - - - -* Step 4. The `parse` command in `QueryDoctorAppointmentCommandParser` returns an instance of `QueryDoctorAppointmentCommand`. -* Step 5. The `LogicManager` calls the `execute` method in `QueryDoctorAppointmentCommand`. -* Step 6. The `execute` method in `QueryDoctorAppointmentCommand` executes and calls `updateFilteredAppointmentList` in model with the `AppointmentContainsDoctorPredicate` to get a filtered list of appointment entries with the entered keyword(s), only those `appointment`(s) that have the associated `doctor`'s `Nric` entries are be displayed. -* Step 7. Success message gets printed onto the results display to notify user and the list of matching results is produced. +The sequence diagram below describes the interaction between the various components during the `execute` method of the `patient` command, which uses the `QueryPatientCommand` on the backend. + Why is this implemented this way? -1. This command closely resembles the `find` command, but can be seen as a stricter version as the results queried do not include substring searches. Therefore, it is justified to separate this command from the `find` command as two distinct commands with distinct `commandParsers`. -2. The rationale behind excluding substring searches for `appointment`(s) is that if a hospital clerk is searching for a specific `doctor`'s scheduled `appointment`(s), the hospital clerk already has the `doctor`'s unique `Nric` and hence including substring querying is irrelevant. - - -### Query `apptforpatient` - -Queries an `appointment` entry that has the associated `patient`'s `Nric`, by indicating the exact `Nric` of the patient as the search parameter. -This command is implemented through the `apptforpatient` class which extends the `Command` class. +1. All query command closely resembles the structure of the `find` command. Each of the commands here have either stricter (i.e have stricter parameter requirements e.g `apptforpatient` and `apptfordoctor`) or looser (i.e searching for more fields e.g `patient` and `doctor`) predicates, but all generally have the same flow of control between the `Command`, `Logger` and `Model` classes. +2. Conceptually, each of the 5 commands listed here are searching for different entities, and are hence split into separate commands despite having very similar structures. -The `apptforpatient` command takes in multiple parameters (at least one), and each of these parameters are read as strings (not case-sensitive, i.e S1234567A is equivalent to s1234567a), and returns the logical 'or' result of applying the `apptforpatient` command to each parameter separately. **Note that no errors will not be thrown if the inputted `Nric`(s) are not of the appropriate form** (i.e Begins with one of S, T, G, F, or M, followed by 7 numerical digits, then ended by an alphabetical letter), but rather the expected return result is that no queries will be found. - -* Step 1. User enters an `QueryPatientAppointment` command. -* Step 2. The `AddressBookParser` will call `parseCommand` on the user's input string and return an instance of `QueryPatientAppointmentCommandParser`. -* Step 3. The `parse` command in `QueryPatientAppointmentCommandParser` checks if at least one parameter is present. - * If the field is missing, a `ParseException` is thrown, and the UI displays an error message. - -The activity diagram below demonstrates this error handling process in more detail. - - - -* Step 4. The `parse` command in `QueryPatientAppointmentCommandParser` returns an instance of `QueryPatientAppointmentCommand`. -* Step 5. The `LogicManager` calls the `execute` method in `QueryPatientAppointmentCommand`. -* Step 6. The `execute` method in `QueryPatientAppointmentCommand` executes and calls `updateFilteredAppointmentList` in model with the `AppointmentContainsPatientPredicate` to get a filtered list of appointment entries with the entered keyword(s), only those `appointment`(s) that have the associated `patient`'s `Nric` entries are be displayed. -* Step 7. Success message gets printed onto the results display to notify user and the list of matching results is produced. - - -Why is this implemented this way? -1. This command closely resembles the `find` command, but can be seen as a stricter version as the results queried do not include substring searches. Therefore, it is justified to separate this command from the `find` command as two distinct commands with distinct `commandParsers`. -2. The rationale behind excluding substring searches for `appointment`(s) is that if a hospital clerk is searching for a specific `patient`'s scheduled `appointment`(s), the hospital clerk already has the `patient`'s unique `Nric` and hence including substring querying is irrelevant. +Alternative implementations considered +1. The behaviour of `patient` and `doctor`, `apptforpatient` and `apptfordoctor` have similar requirements in terms of parameters, with the main difference being either `patient` or `doctor` typed classes. We might consider combining each pair into one command, and using flags to distinguish the desired class (e.g a -doctor or -patient flag to indicate we wish to search for only `doctor` and `patient` entries respectively) so as to avoid the need to create additional commands. However, we felt that at the time of implementation, separating the commands would be a cleaner strategy, and combining methods might overcomplicate the implementation. +2. Even if we did proceed with combining, the combined command was to be overloaded with flags, we foresaw that the creation of distinct commands to fit the flags parsed were unavoidable. As such, it was prudent to start with the implementation of the distinct commands first, and leave the possibility of combining as a later increment. ### \[Proposed\] Undo/redo feature diff --git a/docs/diagrams/QueryPatientCommandExecuteSequenceDiagram.puml b/docs/diagrams/QueryPatientCommandExecuteSequenceDiagram.puml index ebbcf887114..42129318192 100644 --- a/docs/diagrams/QueryPatientCommandExecuteSequenceDiagram.puml +++ b/docs/diagrams/QueryPatientCommandExecuteSequenceDiagram.puml @@ -18,7 +18,7 @@ end box [-> QueryPatientCommand : execute() activate QueryPatientCommand -QueryPatientCommand -> Model : updateFilteredPersonList(predicate) +QueryPatientCommand -> Model : updateFilteredPersonList(PatientContainsKeywordsPredicate) activate Model Model --> QueryPatientCommand diff --git a/docs/images/QueryPatientCommandExecuteSequenceDiagram.png b/docs/images/QueryPatientCommandExecuteSequenceDiagram.png index b983749177dcc71f49eb69550f3574336ce87b7f..e6c2e4701e4c36ce4f7806ceb520363a218f800a 100644 GIT binary patch literal 23121 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 xX=wo)D|9L`^KCNY|9_P0e{tF??JJ8K+Z9 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 From 20e35279564c02d5e246c071a083deb8d783e274 Mon Sep 17 00:00:00 2001 From: Kappaccinoh Date: Mon, 15 Apr 2024 23:25:09 +0800 Subject: [PATCH 2/2] fix spelling errors --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 77373f530ad..2e65da95dc8 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -414,7 +414,7 @@ Alternative implementation for consideration ### Querying Entities in MediCLI `patient`, `doctor`, `appointment` This section describes the general sequence for commands that query entities. MediCLI has 5 different commands that serve this function: `find`, `patient`, `doctor`, `apptforpatient` and `apptfordoctor`. -Although this section describes only the `patient` command, each of the other commands, while lined with different predicates and have different requirements for their parameters, possess as similar implementation. Hence, the flow of method calls between classes are generally similar, and all 5 commands with query entities are described together in one section. +Although this section describes only the `patient` command, each of the other commands, while lined with different predicates and have different requirements for their parameters, possesses similar implementation. Hence, the flow of method calls between classes are generally similar, and all 5 commands that query entities are described here together in one section. * Step 1. The `execute()` method is called in an instance of `QueryPatientCommand`. * Step 2. The instance of `QueryPatientCommand` calls the `updateFilteredPersonList()` method with the `PatientContainsKeywordsPredicate` in an instance of the `Model` class, which filters out entries and returns only patients that match the keywords entered. Note that the other commands listed here will have their respective `predicate` requirements and implementations.