diff --git a/.github/workflows/gradle_notest.yml b/.github/workflows/gradle_notest.yml
new file mode 100644
index 00000000000..935514ca086
--- /dev/null
+++ b/.github/workflows/gradle_notest.yml
@@ -0,0 +1,40 @@
+name: Java Alt CI
+
+on: [push, pull_request]
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ platform: [ubuntu-latest, macos-latest, windows-latest]
+ runs-on: ${{ matrix.platform }}
+
+ steps:
+ - name: Set up repository
+ uses: actions/checkout@v2 # Note: Changed to @v2 for better practices
+
+ - name: Merge to master
+ run: git checkout --progress --force ${{ github.sha }}
+
+ - name: Run repository-wide tests
+ if: runner.os == 'Linux'
+ working-directory: ${{ github.workspace }}/.github
+ run: ./run-checks.sh
+
+ - name: Validate Gradle Wrapper
+ uses: gradle/wrapper-validation-action@v1
+
+ - name: Setup JDK 11
+ uses: actions/setup-java@v2 # Note: Updated to @v2 for better practices
+ with:
+ distribution: 'temurin' # Use Temurin distribution
+ java-version: '11'
+
+ - name: Build with Gradle without running tests
+ run: ./gradlew build -x test # Changed to build without tests
+
+ - name: Upload coverage reports to Codecov
+ if: runner.os == 'Linux'
+ uses: codecov/codecov-action@v3
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
diff --git a/README.md b/README.md
index 13f5c77403f..840d4cdbc1e 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,12 @@
-[![CI Status](https://github.com/se-edu/addressbook-level3/workflows/Java%20CI/badge.svg)](https://github.com/se-edu/addressbook-level3/actions)
+[![CI Status](https://github.com/AY2324S2-CS2103T-T08-1/tp/workflows/Java%20CI/badge.svg)](https://github.com/AY2324S2-CS2103T-T08-1/tp/actions)
-![Ui](docs/images/Ui.png)
+![Ui](docs/images/GUI.png)
-* This is **a sample project for Software Engineering (SE) students**.
- Example usages:
- * as a starting point of a course project (as opposed to writing everything from scratch)
- * as a case study
-* The project simulates an ongoing software project for a desktop application (called _AddressBook_) used for managing contact details.
- * It is **written in OOP fashion**. It provides a **reasonably well-written** code base **bigger** (around 6 KLoC) than what students usually write in beginner-level SE modules, without being overwhelmingly big.
- * It comes with a **reasonable level of user and developer documentation**.
-* It is named `AddressBook Level 3` (`AB3` for short) because it was initially created as a part of a series of `AddressBook` projects (`Level 1`, `Level 2`, `Level 3` ...).
-* For the detailed documentation of this project, see the **[Address Book Product Website](https://se-education.org/addressbook-level3)**.
-* This project is a **part of the se-education.org** initiative. If you would like to contribute code to this project, see [se-education.org](https://se-education.org#https://se-education.org/#contributing) for more info.
+* **ImmuniMate** is a JavaFX application with a GUI, aimed at helping General Practitioners and Healthcare Professionals better keep track of patient Information.
+ Main Features:
+ * Easily create patient profile and update patient information to ImmuniMate
+ * Keep track of infected patients and clusters of information
+ * Search for patients and patient history with a breeze
+* The name `ImmuniMate` is chosen to reflect its purpose of enhancing and safeguarding community immunity.
+* For the detailed documentation and information on ImmuniMate, please visit our **[website](https://ay2324s2-cs2103t-t08-1.github.io/tp/)**.
+* This project is currently being developed by a student team in NUS. Our Source code for the project can be found **[here on github.](https://github.com/AY2324S2-CS2103T-T08-1/tp)**
diff --git a/build.gradle b/build.gradle
index a2951cc709e..face0e9a30a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -66,7 +66,10 @@ dependencies {
}
shadowJar {
- archiveFileName = 'addressbook.jar'
+ archiveFileName = 'immuniMate.jar'
}
+run {
+ enableAssertions = true
+}
defaultTasks 'clean', 'test'
diff --git a/docs/AboutUs.md b/docs/AboutUs.md
index 1c9514e966a..4de87f33bcb 100644
--- a/docs/AboutUs.md
+++ b/docs/AboutUs.md
@@ -3,57 +3,50 @@ layout: page
title: About Us
---
-We are a team based in the [School of Computing, National University of Singapore](http://www.comp.nus.edu.sg).
+We are a NUS based software development team.
-You can reach us at the email `seer[at]comp.nus.edu.sg`
+You can contact us individually through our portfolios
-## Project team
+## ImmuniMate Project Team
-### John Doe
+### Alex Setyawan
-
+
-[[homepage](http://www.comp.nus.edu.sg/~damithch)]
-[[github](https://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
-
-* Role: Project Advisor
-
-### Jane Doe
-
-
-
-[[github](http://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](https://github.com/alex-setyawan)]
+[[portfolio](team/alex-setyawan)]
* Role: Team Lead
-* Responsibilities: UI
+* Responsibilities: Project Manager, Back-end
+
-### Johnny Doe
+### Tan Jovan
-
+
-[[github](http://github.com/johndoe)] [[portfolio](team/johndoe.md)]
+[[homepage](http:/jovantanyk.dev)]
+[[github](https://github.com/jovantanyk)]
+[[portfolio](team/jovantanyk.md)]
* Role: Developer
-* Responsibilities: Data
+* Responsibilities: Back-end, Documentation
+
-### Jean Doe
+### Zhang Lanyu
-
+
-[[github](http://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](http://github.com/laney0808)] [[portfolio](team/laney0808.md)]
* Role: Developer
-* Responsibilities: Dev Ops + Threading
+* Responsibilities: Front-end, Documentation, UI Designer
-### James Doe
+### Natalie Leong
-
+
-[[github](http://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](http://github.com/NatLeong)]
+[[portfolio](team/alex-setyawan)]
* Role: Developer
-* Responsibilities: UI
+* Responsibilities: Front-end, Documentation
diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md
index 1b56bb5d31b..677d833f053 100644
--- a/docs/DeveloperGuide.md
+++ b/docs/DeveloperGuide.md
@@ -7,18 +7,14 @@ title: Developer Guide
--------------------------------------------------------------------------------------------------------------------
-## **Acknowledgements**
-
-* {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well}
-
---------------------------------------------------------------------------------------------------------------------
-
## **Setting up, getting started**
Refer to the guide [_Setting up and getting started_](SettingUp.md).
--------------------------------------------------------------------------------------------------------------------
+
@@ -51,7 +47,7 @@ The bulk of the app's work is done by the following four components:
**How the architecture components interact with each other**
-The *Sequence Diagram* below shows how the components interact with each other for the scenario where the user issues the command `delete 1`.
+The *Sequence Diagram* below shows how the components interact with each other for the scenario where the user issues the command `delete S1234567X`.
![](images/ArchitectureSequenceDiagram.png)
@@ -83,6 +79,8 @@ The `UI` component,
* keeps a reference to the `Logic` component, because the `UI` relies on the `Logic` to execute commands.
* depends on some classes in the `Model` component, as it displays `Person` object residing in the `Model`.
+
+
### Logic component
**API** : [`Logic.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/logic/Logic.java)
@@ -91,7 +89,7 @@ Here's a (partial) class diagram of the `Logic` component:
![](images/LogicClassDiagram.png)
-The sequence diagram below illustrates the interactions within the `Logic` component, taking `execute("delete 1")` API call as an example.
+The sequence diagram below illustrates the interactions within the `Logic` component, taking `execute("delete S1234567X")` API call as an example.
![Interactions Inside the Logic Component for the `delete 1` Command](images/DeleteSequenceDiagram.png)
@@ -100,39 +98,37 @@ The sequence diagram below illustrates the interactions within the `Logic` compo
How the `Logic` component works:
-1. When `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.
-1. This results in a `Command` object (more precisely, an object of one of its subclasses e.g., `DeleteCommand`) which is executed by the `LogicManager`.
-1. The command can communicate with the `Model` when it is executed (e.g. to delete a person).
+1. When `Logic` is called upon to execute a command, it is passed to an `ImmuniMateParser` object which in turn creates a parser that matches the command (e.g., `DeleteCommandParser`) and uses it to parse the command.
+2. This results in a `Command` object (more precisely, an object of one of its subclasses e.g., `DeleteCommand`) which is executed by the `LogicManager`.
+3. The command can communicate with the `Model` when it is executed (e.g. to delete a person).
Note that although this is shown as a single step in the diagram above (for simplicity), in the code it can take several interactions (between the command object and the `Model`) to achieve.
-1. The result of the command execution is encapsulated as a `CommandResult` object which is returned back from `Logic`.
+4. The result of the command execution is encapsulated as a `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:
![](images/ParserClasses.png)
How the parsing works:
-* When called upon to parse a user command, the `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.
-* All `XYZCommandParser` classes (e.g., `AddCommandParser`, `DeleteCommandParser`, ...) inherit from the `Parser` interface so that they can be treated similarly where possible e.g, during testing.
+* When called upon to parse a user command, the `ImmuniMateParser` class creates an `XYZCommandParser` (`XYZ` is a placeholder for the specific command name e.g., `CreateCommandParser`) which uses the other classes shown above to parse the user command and create a `XYZCommand` object (e.g., `CreateCommand`) which the `ImmuniMateParser` returns back as a `Command` object.
+* All `XYZCommandParser` classes (e.g., `CreateCommandParser`, `DeleteCommandParser`, ...) inherit from the `Parser` interface so that they can be treated similarly where possible e.g, during testing.
+
+
### Model component
**API** : [`Model.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/model/Model.java)
-
![](images/ModelClassDiagram.png)
+
![](images/ModelClassDiagram.png)
+
The `Model` component,
-* stores the address book data i.e., all `Person` objects (which are contained in a `UniquePersonList` object).
+* stores the patient data i.e., all `Person` objects (which are contained in a `UniquePersonList` object).
* stores the currently 'selected' `Person` objects (e.g., results of a search query) as a separate _filtered_ list which is exposed to outsiders as an unmodifiable `ObservableList
` 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.
* stores a `UserPref` object that represents the user’s preferences. This is exposed to the outside as a `ReadOnlyUserPref` objects.
* does not depend on any of the other three components (as the `Model` represents data entities of the domain, they should make sense on their own without depending on other components)
-:information_source: **Note:** An alternative (arguably, a more OOP) model is given below. It has a `Tag` list 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.
-
-
![](images/BetterModelClassDiagram.png)
-
-
-
+
### Storage component
@@ -147,101 +143,294 @@ The `Storage` component,
### Common classes
-Classes used by multiple components are in the `seedu.addressbook.commons` package.
+Classes used by multiple components are in the `seedu.address.commons` package.
--------------------------------------------------------------------------------------------------------------------
+
+
## **Implementation**
This section describes some noteworthy details on how certain features are implemented.
-### \[Proposed\] Undo/redo feature
+### List all patients
+#### Implementation
-#### Proposed Implementation
+The `list` feature allows users to view all patients in the system through the `list` command. This patient data is then displayed in the system for the user to have an overview of all patients.
+The `list` command is facilitated by `ListCommand` which extends the `Command` classes, listing all instances in the `Model`.
-The proposed undo/redo mechanism is facilitated by `VersionedAddressBook`. It extends `AddressBook` with an undo/redo history, stored internally as an `addressBookStateList` and `currentStatePointer`. Additionally, it implements the following operations:
+* `ListCommand#execute` is responsible for executing the command and listing all patients in the system.
+* `Model#updateFilteredPersonList()` is called to make the UI display all patients in the system.
-* `VersionedAddressBook#commit()` — Saves the current address book state in its history.
-* `VersionedAddressBook#undo()` — Restores the previous address book state from its history.
-* `VersionedAddressBook#redo()` — Restores a previously undone address book state from its history.
+Step 1. `ListCommand#execute` is called by the `LogicManager`. The `ListCommand` calls `model.updateFilteredPersonList()` to update the filtered list of patients in the system.
-These operations are exposed in the `Model` interface as `Model#commitAddressBook()`, `Model#undoAddressBook()` and `Model#redoAddressBook()` respectively.
+Step 2. `Model#updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS)` is called to update the filtered list such that it shows all patients in the system.
-Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
+Step 3. The `ListCommand` returns the appropriate `CommandResult` to indicate the success of the operation.
-Step 1. The user launches the application for the first time. The `VersionedAddressBook` will be initialized with the initial address book state, and the `currentStatePointer` pointing to that single address book state.
+### Help
+#### Implementation
-![UndoRedoState0](images/UndoRedoState0.png)
+The `help` feature allows users to view the link to User Guide. This command is facilitated by `HelpCommand` which extends the `Command` classes.
-Step 2. The user executes `delete 5` command to delete the 5th person in the address book. The `delete` command calls `Model#commitAddressBook()`, causing the modified state of the address book after the `delete 5` command executes to be saved in the `addressBookStateList`, and the `currentStatePointer` is shifted to the newly inserted address book state.
+* `HelpCommand#execute` is responsible for executing the command and listing the link to the User Guide.
-![UndoRedoState1](images/UndoRedoState1.png)
+Step 1. Parser interprets the user's input and creates a new `HelpCommand` instance.
-Step 3. The user executes `add n/David …` to add a new person. The `add` command also calls `Model#commitAddressBook()`, causing another modified address book state to be saved into the `addressBookStateList`.
+Step 2. `HelpCommand#execute` is called by the `LogicManager`. The `HelpCommand` returns the appropriate `CommandResult`, which signals the UI to display the help window .
-![UndoRedoState2](images/UndoRedoState2.png)
+### Create new patient
+#### Implementation
-:information_source: **Note:** If a command fails its execution, it will not call `Model#commitAddressBook()`, so the address book state will not be saved into the `addressBookStateList`.
+The `create` feature allows users to create a patient by providing input through a command with specific arguments. This patient data is then stored within the system for future reference.
+The `create` command is facilitated by `CreateCommand` and `CreateCommandParser`. They extend the `Command` and `Parser` classes respectively, storing a new instance of `Person` in the `UniquePersonList`.
+* `CreateCommandParser#parse` is responsible for parsing the user input and creating a new `CreateCommand` instance.
+* `CreateCommand#execute` is responsible for executing the command and adding the new patient to the system.
+* `ImmuniMate#addPerson(Person)` is called to add the patient to the internal list of patients.
+* `UniquePersonList#add(Person)` is used to add the new patient to the system.
-
+`ModelManager#addPerson(Person)` is called to add the patient to the system. It calls `ImmuniMate.addPerson(Person)` which calls `UniquePersonList#add(Person)` to add the patient to the internal list of patients.
-Step 4. The user now decides that adding the person was a mistake, and decides to undo that action by executing the `undo` command. The `undo` command will call `Model#undoAddressBook()`, which will shift the `currentStatePointer` once to the left, pointing it to the previous address book state, and restores the address book to that state.
+The command checks for duplicates in the system before adding the new patient.
+* `Person#equals(Object)` is overridden to check if two patients are duplicates.
+* `UniquePersonList#contains(Person)` is used to check if the patient already exists in the system's list of patients.
+* `ImmuniMate#hasPerson(Person)` is used to check if the patient already exists in the system.
+`ModelManager#hasPerson(Person)` is called to check if the patient already exists in the system. It calls `ImmuniMate.hasPerson(Person)` which calls `UniquePersonList#contains(Person)` to check if the patient already exists in the internal list of patients.
-![UndoRedoState3](images/UndoRedoState3.png)
+The creation of `Person` instance also rely on field classes, such as `Name`, `Nric`, `Phone`, `Address`, `DateOfBirth`, `Sex`, and `Status`. Optional field classes include `Email`, `Country`, `DateOfAdmission`, `BloodType`, `Allergies`, `Conditions`, `Symptoms`, and `Diagnosis`.
-:information_source: **Note:** If the `currentStatePointer` is at index 0, pointing to the initial AddressBook state, then there are no previous AddressBook states to restore. The `undo` command uses `Model#canUndoAddressBook()` to check if this is the case. If so, it will return an error to the user rather
-than attempting to perform the undo.
+Step 1. `CreateCommandParser` interprets the user's input, creates instances of fields which matches the input, and creates a new `CreateCommand` instance.
-
+Step 2. The `CreateCommand#execute` is called by the `LogicManager`. The `CreateCommand` checks if the patient already exists in the system by calling `model.hasPerson(person)`.
-The following sequence diagram shows how an undo operation goes through the `Logic` component:
+Step 3. If there is no duplicate, the patient is added to the system by calling `model.addPerson(person)`.
-![UndoSequenceDiagram](images/UndoSequenceDiagram-Logic.png)
+Step 4: After the patient is added, the `CreateCommand` returns the appropriate `CommandResult` to indicate the success of the operation.
-:information_source: **Note:** The lifeline for `UndoCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
+The following sequence diagram shows how a create operation goes through the `Logic` component:
+![CreateState1](images/CreateCommandLogic.png)
+Similarly, the following sequence diagram shows how a create operation goes through the `Model` component:
+![CreateState1](images/CreateCommandModel.png)
-
+### Delete patient
+#### Implementation
-Similarly, how an undo operation goes through the `Model` component is shown below:
+The `delete` feature allows users to delete a patient by providing NRIC through a command. This patient data is then removed from the system.
+The `delete` command is facilitated by `DeleteCommand` and `DeleteCommandParser`. They extend the `Command` and `Parser` classes respectively, removing an instance of `Person` from the `UniquePersonList`.
-![UndoSequenceDiagram](images/UndoSequenceDiagram-Model.png)
+* `DeleteCommandParser#parse` is responsible for parsing the user input and creating a new `DeleteCommand` instance.
+* `DeleteCommand#execute` is responsible for executing the command and removing the patient from the system.
+* `ImmuniMate#removePerson(Person)` is called to remove the patient from the internal list of patients.
+* `UniquePersonList#remove(Person)` is used to remove the patient from the system.
+`ModelManager#deletePerson(Person)` is called to remove the patient from the system. It calls `ImmuniMate.removePerson(Person)` which calls `UniquePersonList#remove(Person)` to remove the patient from the internal list of patients.
+`DeleteCommand` checks if the patient exists in the system before removing the patient.
+* `ModelManager#hasPerson(Person)` is called to check if the patient already exists in the system. It calls `ImmuniMate.hasPerson(Person)` which calls `UniquePersonList#contains(Person)` to check if the patient already exists in the internal list of patients.
-The `redo` command does the opposite — it calls `Model#redoAddressBook()`, which shifts the `currentStatePointer` once to the right, pointing to the previously undone state, and restores the address book to that state.
+Step 1. `DeleteCommandParser` interprets the user's input for NRIC, and creates a new `DeleteCommand` instance.
-:information_source: **Note:** If the `currentStatePointer` is at index `addressBookStateList.size() - 1`, pointing to the latest address book state, then there are no undone AddressBook states to restore. The `redo` command uses `Model#canRedoAddressBook()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.
+Step 2. The `DeleteCommand#execute` is called by the `LogicManager`. The `DeleteCommand` checks if the patient exists in the system by calling `model.hasPerson(person)`.
-
+Step 3. If the patient exists, the patient is removed from the system by calling `model.deletePerson(person)`.
+
+Step 4: After the patient is removed, the `DeleteCommand` returns the appropriate `CommandResult` to indicate the success of the operation.
+
+The following sequence diagram shows how a delete operation goes through the `Logic` and `Model` component:
+![DeleteState1](images/DeleteSequenceDiagram.png)
+
+### Delete patient information
+#### Implementation
+
+The `deleteinfo` command allows users to delete a patient's particular field of information by providing NRIC and the field to be deleted through a command.
+This `deleteinfo` command is facilitated by `DeleteInfoCommand` and `DeleteInfoCommandParser`. They extend the `Command` and `Parser` classes respectively, removing a particular field of information from the `Person` object.
+
+* `DeleteInfoCommandParser#parse` is responsible for parsing the user input and creating a new `DeleteInfoCommand` instance.
+* `DeleteInfoCommand#execute` is responsible for executing the command and removing the field of information from the patient.
+* `Model#getFilteredPersonList()` is called to get the list of patients in the system.
+* `Observablelist#filtered(Predicate)` is called to obtain `Person` object of patient with specified NRIC.
+* `Observablelist#get(int)` is called to obtain `Person` object in the filtered list.
+* `Person#setField` where `Field` refers to whichever field specified to be deleted, is responsible for removing the field of information from the patient.
+ `DeleteInfoCommand` checks if the patient exists in the system before removing the field of information.
+* `ModelManager#hasPerson(Person)` is called to check if the patient already exists in the system. It calls `ImmuniMate.hasPerson(Person)` which calls `UniquePersonList#contains(Person)` to check if the patient already exists in the internal list of patients.
+
+Step 1. `DeleteInfoCommandParser` interprets the user's input for NRIC and the fields to be deleted, and creates a new `DeleteInfoCommand` instance.
+
+Step 2. The `DeleteInfoCommand#execute` is called by the `LogicManager`. The `DeleteInfoCommand` checks if the patient exists in the system by calling `model.hasPerson(person)`.
+
+Step 3. If the patient exists, the `DeleteInfoCommand` calls `model.getFilteredPersonList().filtered().get()` to get the specified patients in the system.
+
+Step 4. `DeleteInfoCommand#execute` check which fields are to be deleted, and remove the field of information using `Person#setField(null)`. Where `Field` is the field to be deleted.
+
+Step 5: After the field of information is removed, the `DeleteInfoCommand` returns the appropriate `CommandResult` to indicate the success of the operation.
+
+The following sequence diagram shows how a `deleteinfo` operation goes through the `Logic` component:
+![DeleteInfoState1](images/DeleteInfoSequenceDiagram.png)
+
+The sequence diagram for how the `deleteinfo` operation goes through the `Model` Component is as the following:
+![DeleteInfoState1](images/DeleteInfoModelDiagram.png)
+
+### Read a patient's information
+#### Implementation
+The `read` feature allows users to read a patient profile by providing NRIC through a command. This patient data is then displayed.
+The `read` command is facilitated by `ReadCommand` and `ReadCommandParser`. They extend the `Command` and `Parser` classes respectively, displaying patient profile from an instance of `Person` from the `UniquePersonList`.
+
+* `ReadCommandParser#parse` is responsible for parsing the user input and creating a new `ReadCommand` instance.
+* `ReadCommand#execute` is responsible for executing the command and displaying the patient profile from the system.
+ `ReadCommand` checks if the patient exists in the system before displaying patient profile.
+* `ModelManager#hasPerson(Person)` is called to check if the patient exists in the system. It calls `ImmuniMate.hasPerson(Person)` which calls `UniquePersonList#contains(Person)` to check if the patient already exists in the internal list of patients.
+* `Model#updateFilteredPersonList(Predicate)` and is called to update the list to be of patient with specified NRIC in the system.
+* `Model#getFilteredPersonList()` is called to get the list of patient with specified NRIC in the system.
+* `Observablelist#get(int)` is called to obtain `Person` object of patient with speicified NRIC.
+
+Step 1. `ReadCommandParser` interprets the user's input for NRIC, and creates a new `ReadCommand` instance.
+
+Step 2. The `ReadCommand#execute` is called by the `LogicManager`. The `ReadCommand` checks if the patient exists in the system by calling `model.hasPerson(person)`.
+
+Step 3. If the patient exists, the patient is obtained from the system by calling `model.updateFilteredPersonList(person)`, followed by calling `model.getFilteredPersonList()` and `Observablelist#get(int)`.
+
+Step 4: After the patient is obtained, the `ReadCommand` formats the patient profile by calling `Messages.format(person)` and returns the appropriate `CommandResult` to indicate the success of the operation.
+
+The following sequence diagram shows how a `read` operation goes through the `Logic` component:
+![ReadState1](images/ReadCommandSequenceDiagram.png)
+
+How a `read` operation goes through the `Model` component is shown below:
+![ReadState2](images/ReadCommandModelDiagram.png)
+
+### Find patient
+#### Implementation
+
+The `find` feature lets users find patients with certain values in various fields, namely `name`, `address` and `condition`.
+After a command with specific arguments as input, the patient list is filtered and the resultant list is shown.
+
+The `find` command is facilitated by `FindCommand` and `FindCommandParser`, extending the `Command` and `Parser` classes respectively.
+* `FindCommandParser#parse` is responsible for parsing the user input and creating a new `FindCommand` instance.
+* `FindCommand#execute` is responsible for executing the command, calling `ModelManager#updateFilteredPersonList(Predicate)` to find patients with the given keywords in the given field.
+
+Step 1. `FindCommandParser` interprets the user's input, determine which field the user wishes to find patients by, and creates a new `FindCommand` instance.
+
+Step 2. The `FindCommand#execute` is called by the `LogicManager`.
+
+Step 3. This in turn calls `model.updateFilteredPersonList(Predicate)`, which identifies patients having any of the keywords in `Predicate` in the given field.
+
+Step 4: The `FindCommand` returns the appropriate `CommandResult` to indicate the success of the operation.
+
+The following sequence diagram shows how a `find` operation goes through the `Logic` and `Model` components:
+![ReadState1](images/FindLogicModelDiagram.png)
+
+### Update patient fields
+#### Implementation
+Given below is an example usage scenario and how the update mechanism behaves at each step.
+
+Step 1. The user launches the application for the first time.
+
+Step 2. The user types `update T0123456A a/35 Bishan Road, #10-40 con/myopia` command to update the address and condition fields in the profile of the person with `Nric` T0123456A in the address book. This calls `immuniMateParser.parseCommand()`, which separates the user input into the command `update` and the rest of the arguments.
+
+Step 3. As the command `update` matches `UpdateCommand.COMMAND_WORD`, `UpdateCommandParser().parse()` is called, taking in the rest of the arguments. Here, the arguments are checked if they are null values, then passed into `ArgumentTokenizer.tokenize()`, where they are separated into `Nric` and other provided fields by finding their respective prefixes, and stored in an `ArgumentMultimap`.
+
+Step 4. Still in `UpdateCommandParser().parse()`, checks are then done to verify the validity of the `Nric` and that no duplicate prefixes are found. A new `UpdatePersonDescriptor` object is then created to store the fields present in `ArgumentMultimap`.
+
+Step 5. At the end of `UpdateCommandParser().parse()`, a new `UpdateCommand` instance is created with the `Nric` and `UpdatePersonDescriptor` as arguments. `UpdateCommand.execute()` is then called, taking in the ImmuniMate `model` as an argument.
+
+Step 6. `model.getFilteredPersonsList()` retrieves the list of `Person`s stored, and a check is done to see if ImmuniMate has a `Person` with the given `Nric`. This `Person` is then retrieved from the list, while a new `Person` object is instantiated, with the `Person` and `UpdatePersonDescriptor` as arguments, representing the retrieved `Person` object with fields updated.
+
+Step 7. `model.setPerson()` then replaces the retrieved `Person` object with the new `Person` object with fields updated, taking in both `Person` objects as arguments. The `model` is then saved into `storage`.
+
+The following sequence diagram shows how an `update` operation goes through the `Logic` components:
+![ReadState1](images/UpdateLogicDiagram.png)
+
+How an `update` operation goes through the `Model` component is shown below:
+![ReadState2](images/UpdateModelDiagram.png)
+
+### Add patient visit
+#### Implementation
+The `addvisit` feature allows users to add a patient visit by providing input through a command with specific arguments. This visit is then stored within the system for future reference.
+The `addvisit` command is facilitated by `AddVisitCommand` and `AddVisitCommandParser`. They extend the `Command` and `Parser` classes respectively, storing a new instance of `Visit` in the `UniqueVisitList`.
+* `AddVisitCommandParser#parse` is responsible for parsing the user input and creating a new `AddVisitCommand` instance.
+* `AddVisitCommand#execute` is responsible for executing the command and adding the new visit to the system.
+* `ImmuniMate#addVisit(Visit)` is called to add the visit to the internal list of visits.
+* `UniquePersonList#add(Visit)` is used to add the new visit to the system.
+ `ModelManager#addVisit(Visit)` is called to add the visit to the system. It calls `ImmuniMate.addVisit(Visit)` which calls `UniqueVisitList#add(Visit)` to add the visit to the internal list of visits.
+ The command checks if the patient exists in the system before adding the new visit of a patient.
+* `Person#equals(Object)` is overridden to check if two patients are the same person.
+* `UniquePersonList#contains(Person)` is used to check if the patient exists in the system's list of patients.
+* `ImmuniMate#hasPerson(Person)` is used to check if the patient exists in the system.
+ `ModelManager#hasPerson(Person)` is called to check if the patient exists in the system. It calls `ImmuniMate.hasPerson(Person)` which calls `UniquePersonList#contains(Person)` to check if the patient exists in the internal list of patients.
+ The command checks for duplicates in the system before adding the new visit.
+* `Visit#equals(Object)` is overridden to check if two visits are duplicates.
+* `UniquePersonList#contains(Visit)` is used to check if the visit already exists in the system's list of visits.
+* `ImmuniMate#hasVisit(Visit)` is used to check if the visit already exists in the system.
+ `ModelManager#hasVisit(Visit)` is called to check if the visit already exists in the system. It calls `ImmuniMate.hasVisit(Visit)` which calls `UniqueVisitList#contains(Visit)` to check if the visit already exists in the internal list of visits.
+
+The creation of `Visit` instance also rely on field classes`NRIC`, `Symptoms`,`Diagnosis`, `Status` and `DateOfVisit`.
+
+Step 1. `AddVisitCommandParser` interprets the user's input, creates instances of fields which matches the input, and creates a new `AddVisitCommand` instance.
+
+Step 2. The `AddVisitCommand#execute` is called by the `LogicManager`. The `AddVisitCommand` checks if the patient already exists in the system by calling `model.hasPerson(person)`.
+
+Step 3. If the patient exists, the `AddVisitCommand` checks if the visit already exists in the system by calling `model.hasVisit(visit)`.
+
+Step 4. If the visit does not exist, the visit is added to the system by calling `model.addVisit(visit)`.
+
+Step 4: After the visit is added, the `AddVisitCommand` returns the appropriate `CommandResult` to indicate the success of the operation.
+
+The following sequence diagram shows how a addvisit operation goes through the `Logic` component:
+![AddVisitState1](images/AddVisitCommandLogic.png)
+Similarly, the following sequence diagram shows how a addvisit operation goes through the `Model` component:
+![addVisitCommandState1](images/AddVisitCommandModel.png)
+
+
+### Check a patient's visit history
+#### Implementation
+The `check` feature allows users to check the visit history of a patient by providing NRIC through a command. This patient visit history is then displayed.
+The `check` command is facilitated by `CheckCommand` and `CheckCommandParser`. They extend the `Command` and `Parser` classes respectively, displaying patient visit history from list of `Visit` from the `UniqueVisitList`.
+
+* `CheckCommandParser#parse` is responsible for parsing the user input and creating a new `CheckCommand` instance.
+* `CheckCommand#execute` is responsible for executing the command and displaying the patient visit history from the system.
+ `CheckCommand` checks if the patient exists in the system before displaying patient visit history.
+* `ModelManager#hasPerson(Person)` is called to check if the patient exists in the system. It calls `ImmuniMate.hasPerson(Person)` which calls `UniquePersonList#contains(Person)` to check if the patient already exists in the internal list of patients.
+* `Model#updateFilteredPersonList(Predicate)` is called to get the list of patient with specified NRIC in the system.
+* `Model#updateFilteredVisitList(Predicate)` is called to get the list of visits with specified NRIC in the system.
+
+Step 1. `CheckCommandParser` interprets the user's input for NRIC, and creates a new `CheckCommand` instance.
+
+Step 2. The `CheckCommand#execute` is called by the `LogicManager`. The `CheckCommand` checks if the patient exists in the system by calling `model.hasPerson(person)`.
+
+Step 3. If the patient exists, the patient is obtained from the system by calling `model.updateFilteredPersonList(pred)`, followed by calling `model.getFilteredPersonList()` and `Observablelist#get(int)`.
+
+Step 4: Patient visit history is obtained from the system by calling `model.updateFilteredVisitList(pred)`, followed by `model.getFilteredVisitList()`.
-Step 5. The user then decides to execute the command `list`. Commands that do not modify the address book, such as `list`, will usually not call `Model#commitAddressBook()`, `Model#undoAddressBook()` or `Model#redoAddressBook()`. Thus, the `addressBookStateList` remains unchanged.
+Step 5: After the patient visit history is obtained, the `CheckCommand` formats the patient visit history by calling `Messages.formatCheck(visit)` and returns the appropriate `CommandResult` to indicate the success of the operation.
-![UndoRedoState4](images/UndoRedoState4.png)
+The following sequence diagram shows how a delete operation goes through the `Logic` component:
+![ReadState1](images/CheckCommandSequenceDiagram.png)
+How a check operation goes through the `Model` component is shown below:
+![ReadState2](images/CheckCommandModelDiagram.png)
-Step 6. The user executes `clear`, which calls `Model#commitAddressBook()`. Since the `currentStatePointer` is not pointing at the end of the `addressBookStateList`, all address book states after the `currentStatePointer` will be purged. Reason: It no longer makes sense to redo the `add n/David …` command. This is the behavior that most modern desktop applications follow.
+### Cluster Identification
+#### Implementation
-![UndoRedoState5](images/UndoRedoState5.png)
+The `cluster` feature tells users if a certain location has a certain number of patients unwell with an illness.
+Provided an integer, location and disease as inputs, it finds unwell patients having an address with the given location as a substring, and diagnosis with the given illness as a substring, and informs the user if the number of those patients is at least that integer.
+The `cluster` command is facilitated by `ClusterCommand` and `ClusterCommandParser`, extending the `Command` and `Parser` classes respectively, storing a new instance of `Person` in the `UniquePersonList`.
-The following activity diagram summarizes what happens when a user executes a new command:
+* `ClusterCommandParser#parse` is responsible for parsing the user input and creating a new `ClusterCommand` instance.
+* `ClusterCommand#execute` is responsible for executing the command and separating the inputs into their categories (cluster size, address and illness). It calls `ModelManager#updateFilteredPersonList(Predicate)` to find patients which satisfy the given criteria.
-
+Step 1. `ClusterCommandParser` interprets the user's input, and separates it into its constituent categories, and creates a new `ClusterCommand` instance.
-#### Design considerations:
+Step 2. The `ClusterCommand#execute` is called by the `LogicManager`.
-**Aspect: How undo & redo executes:**
+Step 3. This in turn calls `model.updateFilteredPersonList(Predicate)`, takes the location and illness keywords in `Predicate`, and finds all the patients which have them as substrings in their addresses and diagnoses respectively.
-* **Alternative 1 (current choice):** Saves the entire address book.
- * Pros: Easy to implement.
- * Cons: May have performance issues in terms of memory usage.
+Step 4. This also calls `model.getFilteredPersonList().size()` to obtain the size of the patient group satisfying the given criteria.
-* **Alternative 2:** Individual command knows how to undo/redo by
- itself.
- * Pros: Will use less memory (e.g. for `delete`, just save the person being deleted).
- * Cons: We must ensure that the implementation of each individual command are correct.
+Step 5: The `ClusterCommand` returns the appropriate `CommandResult` to indicate the success of the operation.
-_{more aspects and alternatives to be added}_
+The following sequence diagram shows how a `cluster` operation goes through the `Logic` and `Model` components:
+![ReadState1](images/ClusterLogicModelDiagram.png)
-### \[Proposed\] Data archiving
+### Exit the app
+#### Implementation
-_{Explain here how the data archiving feature will be implemented}_
--------------------------------------------------------------------------------------------------------------------
@@ -256,80 +445,395 @@ _{Explain here how the data archiving feature will be implemented}_
--------------------------------------------------------------------------------------------------------------------
+
+
## **Appendix: Requirements**
### Product scope
**Target user profile**:
-* has a need to manage a significant number of contacts
+* has a need to manage a significant number of patient information
* prefer desktop apps over other types
* can type fast
* prefers typing to mouse interactions
* is reasonably comfortable using CLI apps
+* works at a gp clinic or similar environments
-**Value proposition**: manage contacts faster than a typical mouse/GUI driven app
+**Value proposition**: As the number of patients a General Practitioner grows, information management might prove complex, especially so for personal data. ImmuniMate offers a way to record comprehensive information about every patient, while ensuring timely updates and avoiding duplications/contradictions. It also seeks to establish links between patient for contact tracing and finding potential infectious clusters.
### User stories
Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*`
-| Priority | As a … | I want to … | So that I can… |
-| -------- | ------------------------------------------ | ------------------------------ | ---------------------------------------------------------------------- |
-| `* * *` | new user | see usage instructions | refer to instructions when I forget how to use the App |
-| `* * *` | user | add a new person | |
-| `* * *` | user | delete a person | remove entries that I no longer need |
-| `* * *` | user | find a person by name | locate details of persons without having to go through the entire list |
-| `* *` | user | hide private contact details | minimize chance of someone else seeing them by accident |
-| `*` | user with many persons in the address book | sort persons by name | locate a person easily |
-
-*{More to be added}*
+| Priority | As a … | I want to … | So that I can… |
+|----------|-------------------|-------------------------------------------------|------------------------------------------------------------------------------|
+| `* * *` | New user | see usage instructions | refer to instructions when I forget how to use the App |
+| `* * *` | Healthcare Worker | create a new patient profile | add new patient to database |
+| `* * *` | Healthcare Worker | delete a patient | remove wrong or obselete patient profile from the database |
+| `* * *` | Healthcare Worker | delete patient's information | remove patient information that is known to be incorrect |
+| `* * *` | Healthcare Worker | read a patient's information by NRIC | locate details of persons without having to go through the entire list |
+| `* * *` | Healthcare Worker | update a person's details | keep the details up to date |
+| `* * *` | Healthcare Worker | find a patient by matching criteria | Find a list of patients from with a certain conditio or address |
+| `* * *` | Healthcare Worker | find a patient by name | find a patient in the situation when their NRIC is not immediately available |
+| `* * *` | Healthcare Worker | record visits made by patients | record the change in health condition of the patients across time |
+| `* *` | Healthcare Worker | highlight contradicting information and entries | minimize the mistakes in entries |
+| `* *` | Healthcare Worker | see the history of visits made by a patient | understand the past health condition of a patient |
+| `* *` | Healthcare Worker | be able to tap different contact methods | make sure important information is sent |
+| `* *` | Healthcare Worker | status of health of a patient | give appropriate treatment |
+| `* *` | Healthcare Worker | see clusters of infected patients | understand which areas are at high risk of infection |
+| `*` | Healthcare Worker | find the person who first spread the disease | better understand the disease |
+| `*` | Healthcare Worker | sort persons by name | locate a person easily |
+| `*` | Healthcare Worker | hide private contact details | minimize chance of someone else seeing them by accident |
+| `*` | Healthcare Worker | be able to resolve duplicate information | correct wrong inputs |
+| `*` | Healthcare Worker | see the close contacts of a patient | see the links between infected patients |
### Use cases
-(For all use cases below, the **System** is the `AddressBook` and the **Actor** is the `user`, unless specified otherwise)
+(For all use cases below, the **IMS** is the `ImmuniMate system` and the **Healthcare Worker** is the `user`, unless specified otherwise)
+
+**Use Case: UC01 - Create Patient Profile**
+
+- **Actor:** Healthcare Worker
+- **Description:** Healthcare worker creates a new patient profile in the IMS.
+- **Preconditions:** Healthcare worker has launched the system.
+- **Guarantees:** New patient profile is successfully created in the IMS.
+- **MSS:**
+ 1. Healthcare worker choose to create a new patient profile.
+ 2. IMS requests the necessary details for the new patient profile (name, NRIC, date of birth, sex, phone number, address, email, country of nationality, date of admission, blood type, allergies).
+ 3. Healthcare worker enters the patient's details.
+ 4. IMS validates the entered data.
+ 5. IMS adds the new patient profile to the database.
+- **Extensions:**
+
+ 3a. IMS detects a conflict in the entered data (user existing).
+
+ 3a1. IMS shows the conflicting existing entry
+ 3a2. IMS requests for the correct data.
+ 3a3. Healthcare Worker enters new data.
+ Steps 3a1-3a3 are repeated until the data entered are correct, or the user cancels the action.
+ Use case resumes from step 4.
+
+ 3b. IMS detects an error in the entered data.
+
+ 3b1. IMS requests for the correct data.
+ 3b2. Healthcare Worker enters new data.
+ Steps 3b1-3b2 are repeated until the data entered are correct.
+ Use case resumes from step 4.
+
+ *a. At any time, Healthcare Worker chooses to cancel creating the patient profile.
+
+ *a1. IMS requests confirmation to cancel.
+ *a2. Healthcare Worker confirms the cancellation.
+ Use case ends.
+
+
+---
+
+**Use Case: UC02 - Read Patient Profile**
+
+- **Actor:** Healthcare Worker
+- **Description:** Healthcare worker reads patient profile in the IMS.
+- **Preconditions:** Healthcare worker has launched the system.
+- **Guarantees:** Existing patient profile in the IMS is successfully displayed.
+- **MSS:**
+ 1. Healthcare worker choose to read a patient profile.
+ 2. IMS requests the necessary detail for reading patient profile (NRIC).
+ 3. Healthcare worker enters the patient's details.
+ 4. IMS validates the entered data.
+ 5. IMS displays the patient profile to the database.
+- **Extensions:**
+
+ 3a. IMS detects an error in the entered data (user does not exist).
+
+ 3a1. IMS shows the conflicting existing entry
+ 3a2. IMS requests for the correct data.
+ 3a3. Healthcare Worker enters new data.
+ Steps 3a1-3a3 are repeated until the data entered are correct, or the user cancels the action.
+ Use case resumes from step 4.
+
+ 3b. IMS detects an error in the entered data (wrong NRIC format).
+
+ 3b1. IMS requests for the correct data.
+ 3b2. Healthcare Worker enters new data.
+ Steps 3b1-3b2 are repeated until the data entered are correct.
+ Use case resumes from step 4.
+
+ *a. At any time, Healthcare Worker chooses to cancel creating the patient profile.
+
+ *a1. IMS requests confirmation to cancel.
+ *a2. Healthcare Worker confirms the cancellation.
+ Use case ends.
+
+
+---
+
+**Use Case: UC03 - Find Patient Information**
+
+- **Actor:** Healthcare Worker
+- **Description:** Healthcare worker searches for specific patient information in the IMS.
+- **Preconditions:** Healthcare worker has launched the system.
+- **Guarantees:** Relevant patient information is displayed for the healthcare worker to view.
+- **Basic Flow:**
+ 1. Healthcare worker chooses to find patient information meeting specified criteria.
+ 2. IMS searches for and displays the relevant patients.
+- **Extensions:**
+ 2a. IMS detects an error in the entered data.
+
+ - 2a1. IMS requests for the correct data.
+ - 2a2. Healthcare Worker enters new data.
+ - Steps 2a1-2a2 are repeated until the data entered are correct. Use case resumes from step 3.
+
+---
+
+**Use Case: UC04 - Update Patient Information**
+
+- **Actor:** Healthcare Worker
+- **Description:** Healthcare worker updates a patient's information in the IMS.
+- **Preconditions:** Healthcare worker has launched the system and has selected the patient whose information needs to be updated.
+- **Guarantees:** Patient's information is successfully updated in the IMS.
+- **Basic Flow:**
+ 1. Healthcare worker chooses to update a certain patient’s certain information.
+ 2. IMS validates the new content.
+ 3. IMS updates the patient's information in the database.
+- **Extensions:**
+
+ 2a. IMS detects an error in the entered data.
-**Use case: Delete a person**
+ 2a1. IMS requests for the correct data.
+ 2a2. Healthcare Worker enters new data.
+ Steps 2a1-2a2 are repeated until the data entered are correct.
+ Use case resumes from step 3.
-**MSS**
-1. User requests to list persons
-2. AddressBook shows a list of persons
-3. User requests to delete a specific person in the list
-4. AddressBook deletes the person
+---
+
+**Use Case: UC05 - Delete Patient Profile**
+
+- **Actor:** Healthcare worker
+- **Description:** Healthcare worker deletes a patient's record from the IMS.
+- **Preconditions:** Healthcare worker has opened the app and has selected the patient whose record needs to be deleted.
+- **Guarantees:** Patient's record is successfully deleted from the IMS.
+- **MSS:**
+ 1. Healthcare worker choose to delete a specified patient’s record.
+ 2. IMS validates the NRIC and deletes the patient's record from the database.
+- **Extensions:**
+
+ 2a. IMS cannot find the patient specified.
+ - 2a1. IMS requests for the correct NRIC.
+ - 2a2. Healthcare worker enters new NRIC.
+ - Steps 2a1-2a2 are repeated until the data entered are correct or Healthcare worker cancels the action. Use case resumes from step 3.
+
+---
+
+**Use Case: UC06 - Delete Patient Information**
+
+- **Actor:** Healthcare Worker
+- **Description:** Healthcare worker deletes specific information from a patient's record in the IMS.
+- **Preconditions:** Healthcare worker has launched the system and has selected the patient whose information needs to be deleted.
+- **Guarantees:** Specified information is successfully deleted from the patient's record in the IMS.
+- **MSS:**
+ 1. Healthcare worker chooses to delete certain fields of a certain patient's profile.
+ 2. IMS validates the information to be deleted and deletes the specified information from the patient's record in the database.
+- **Extensions:**
+
+ 2a. IMS cannot find the patient specified.
+ - 2a1. IMS requests for the correct NRIC.
+ - 2a2. Healthcare worker enters new NRIC.
+ - Steps 2a1-2a2 are repeated until the data entered are correct or Healthcare worker cancels the action. Use case resumes from step 3.
+
+ 2b. IMS cannot find the specified information.
+
+ - 2b1. IMS alerts healthcare worker that the specified information is not found.
+ - 2b2. Healthcare worker enters new field.
+ - Steps 2b1-2b2 are repeated until the data entered are correct or Healthcare worker cancels the action. Use case resumes from step 3.
+
+ 2c. Healthcare worker chooses to delete a mandatory field.
+
+ - 2c1. IMS alerts healthcare worker that mandatory field cannot be deleted.
+ - 2c2. Healthcare worker enters new field.
+ - Steps 2c1-2c2 are repeated until the data entered are correct or Healthcare worker cancels the action. Use case resumes from step 3.
+
+
+---
+
+**Use Case: UC07 - Add Patient Visit**
+
+
+- **Actor:** Healthcare Worker
+- **Description:** Healthcare worker adds a visit record for a patient in the IMS.
+- **Preconditions:** Healthcare worker has launched the system.
+- **Guarantees:** A new visit record is successfully added for the patient in the IMS.
+- **Main Success Scenario (MSS):**
+ 1. Healthcare worker chooses to add a new patient visit.
+ 2. IMS requests the necessary details for the visit (NRIC, date of visit, diagnosis, symptoms, status).
+ 3. Healthcare worker enters the required information for the visit.
+ 4. IMS validates the entered data.
+ 5. IMS adds the visit record to the patient's profile in the database.
+ 6. IMS confirms that the visit has been added successfully.
+ 7. Use case ends.
+
+- **Extensions:**
+
+ 3a. IMS detects an error in the entered data (patient does not exist).
+ - 3a1. IMS notifies Healthcare Worker that the patient does not exist.
+ - 3a2. Healthcare Worker opts to create a new patient profile or re-enters correct data.
+ - Steps 3a1-3a2 are repeated until valid data are entered, or the user cancels the action.
+ - Use case resumes from step 4 if valid data are entered.
+
+ 3b. IMS detects an error in the entered data (e.g., incorrect NRIC format, invalid date of visit).
+ - 3b1. IMS requests for the correct data.
+ - 3b2. Healthcare Worker enters new data.
+ - Steps 3b1-3b2 are repeated until the data entered are correct.
+ - Use case resumes from step 4.
+
+ 3c. IMS detects missing mandatory fields (e.g., NRIC, date of visit).
+ - 3c1. IMS displays an error message indicating which fields are missing.
+ - 3c2. Healthcare Worker provides the missing information.
+ - Steps 3c1-3c2 are repeated until all required data are provided.
+ - Use case resumes from step 4.
+
+ *a. At any time, Healthcare Worker chooses to cancel the addition of the patient visit.
+ - *a1. IMS requests confirmation to cancel.
+ - *a2. Healthcare Worker confirms the cancellation.
+ - Use case ends.
- Use case ends.
+---
+
+**Use Case: UC08 - Check Patient Visit History**
+
+- **Actor:** Healthcare Worker
+- **Description:** Healthcare worker checks patient visit history in the IMS.
+- **Preconditions:** Healthcare worker has launched the system.
+- **Guarantees:** Existing patient visit history in the IMS is successfully displayed.
+- **MSS:**
+ 1. Healthcare worker choose to check a patient visit history.
+ 2. IMS requests the necessary detail for checking patient visit history (NRIC).
+ 3. Healthcare worker enters the patient's details.
+ 4. IMS validates the entered data.
+ 5. IMS displays the patient profile to the database.
+- **Extensions:**
+
+ 3a. IMS detects an error in the entered data (user does not exist).
+
+ 3a1. IMS shows the conflicting existing entry
+ 3a2. IMS requests for the correct data.
+ 3a3. Healthcare Worker enters new data.
+ Steps 3a1-3a3 are repeated until the data entered are correct, or the user cancels the action.
+ Use case resumes from step 4.
-**Extensions**
+ 3b. IMS detects an error in the entered data (wrong NRIC format).
-* 2a. The list is empty.
+ 3b1. IMS requests for the correct data.
+ 3b2. Healthcare Worker enters new data.
+ Steps 3b1-3b2 are repeated until the data entered are correct.
+ Use case resumes from step 4.
+ *a. At any time, Healthcare Worker chooses to cancel creating the patient profile.
+
+ *a1. IMS requests confirmation to cancel.
+ *a2. Healthcare Worker confirms the cancellation.
Use case ends.
-* 3a. The given index is invalid.
+---
- * 3a1. AddressBook shows an error message.
+**Use Case: UC09 - Finding Clusters**
+
+- **Actor:** Healthcare Worker
+- **Description:** Healthcare worker tries to identify disease clusters through data in the ImmuniMate System.
+- **Preconditions:** Healthcare worker has logged into the system.
+- **Guarantees:** There is at least 1 patient profile saved in IMS.
+- **MSS:**
+ 1. Healthcare worker wants to find disease clusters/potential disease clusters.
+ 2. IMS requests Healthcare Worker for relevant details.
+ 3. Healthcare worker enters integer, location and illness.
+ 4. IMS validates the entered data and displays all patients at that location unwell with the illness.
+- **Extensions:**
+
+ 3a. IMS detects an error in the entered data (invalid cluster size).
+
+ * 3a1. IMS shows the conflicting existing entry
+ * 3a2. IMS requests for the correct data.
+ * 3a3. Healthcare Worker enters data with valid cluster size.
+ Steps 3a1-3a3 are repeated until the data entered are correct, or the user cancels the action.
+ Use case resumes from step 4.
+
+ 3b. IMS detects an error in the entered data (empty location).
+
+ * 3b1. IMS requests for the correct data.
+ * 3b2. Healthcare Worker enters data with valid location.
+ Steps 3b1-3b2 are repeated until the data entered are correct.
+ Use case resumes from step 4.
+
+---
+
+**Use Case: UC10 - List all patients**
- Use case resumes at step 2.
+- **Actor:** Healthcare Worker
+- **Description:** Healthcare worker lists all patients in the IMS.
+- **Preconditions:** Healthcare worker has launched the system. The data file is not corrupted.
+- **Guarantees:** Existing patients in the IMS are successfully displayed.
+- **MSS:**
+ 1. Healthcare worker choose to list all patients.
+ 2. IMS displays all patients in the database.
-*{More to be added}*
+---
+**Use Case: UC11 - Access help**
+- **Actor:** Healthcare Worker
+- **Description:** Healthcare worker accesses the help guide in the IMS.
+- **Preconditions:** Healthcare worker has launched the system.
+- **Guarantees:** The help guide is successfully displayed.
+- **MSS:**
+ 1. Healthcare worker chooses to access the help guide.
+ 2. IMS displays the help guide.
### Non-Functional Requirements
1. Should work on any _mainstream OS_ as long as it has Java `11` or above installed.
-2. Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage.
-3. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
-
-*{More to be added}*
+2. Should be able to hold up to 10000 persons without a noticeable sluggishness in performance for typical usage.
+3. Should have high data persistency.
+4. Should work on both 32-bit and 64-bit environments.
+5. Should be easily downloaded from websites/app stores, and need no prior setup besides downloading Java 11.
+6. Should not exceed 100MB in storage space.
+7. Data collection on the app should adhere to the Personal Data Protection Act (PDPA).
+8. Unimplemented fields should be added easily.
+9. Should be convenient to expand storage capacity of the app when needed.
+10. Should use automated testing.
+11. Should respond to queries within 1 second.
+12. Project should adhere to a schedule to deliver new features fortnightly.
+13. Project should aim to solve bugs found in one version by the next version.
+14. Should be usable by doctors/nurses/receptionists with limited guidance.
+15. Should be faster to use by typing queries than using the mouse.
### Glossary
-* **Mainstream OS**: Windows, Linux, Unix, MacOS
-* **Private contact detail**: A contact detail that is not meant to be shared with others
+1. **Name**: The name of the patient. Case-sensitive alphabetical characters with spaces, capped at 2,000,000,000 characters.
+2. **NRIC**: National Registration Identity Card number, follows Singapore NRIC format. 9 characters. First character can be any of S, T, followed by 7 digits, and the last character is an alphabet. NRIC is case-insensitive.
+3. **Date of Birth (DOB)**: The patient's date of birth, in the format `yyyy-MM-dd`.
+4. **Sex**: The biological sex of the patient, limited to `M` or `F`.
+5. **Phone Number**: The contact number of the patient, limited to 8 digits.
+6. **Address**: The home address of the patient. Any text except blank and empty text is accepted.
+7. **Email**: The email address of the patient, follows a valid format: `@.com`. Case-sensitive.
+8. **Country of Nationality**: The country name of the patient's nationality. Any text except blank and empty text is accepted.
+9. **Date of Admission (DOA)**: The date when the patient was admitted for the first visit, in the format `yyyy-MM-dd`.
+10. **Blood Type**: The blood type of the patient. accepts any of `A+`, `A-`, `B+`, `B-`, `AB+`, `AB-`, `O+`, `O-`.
+11. **Allergies**: Any allergies the patient may have. Any text except blank and empty text is accepted.
+12. **Conditions**: Any prior medical conditions of the patient. Any text except blank and empty text is accepted.
+13. **Symptoms**: The latest symptoms experienced by the patient. Any text except blank and empty text is accepted.
+14. **Diagnosis**: The latest diagnosis of the patient's condition. Any text except blank and empty text is accepted.
+15. **Status**: The current health status of the patient, can be `HEALTHY` (green), `PENDING` (yellow), or `UNHEALTHY` (red). `PENDING` means the patient still need upcoming diagnosis to determine the current health status.
+16. **Date of Visit**: The date of the patient's current visit, in the format `yyyy-MM-dd`.
+17. **Fields**: The fields of the patient's information, such as name, status, contact.
+17. **Cluster**: A group of patients who are infected by the same disease.
+18. **Patient Visit**: A record of a patient's one specific visit to the clinic, including the date of visit, symptoms, diagnosis, and status.
+19. **Patient History**: A collection of all the visits by a patient.
+20. **Patient Profile**: A collection of all the information about a patient, including the patient's name, `Nric`, `Phone`, `Address`, `Email`, `Country`.
--------------------------------------------------------------------------------------------------------------------
+
+
## **Appendix: Instructions for manual testing**
Given below are instructions to test the app manually.
@@ -343,40 +847,186 @@ testers are expected to do more *exploratory* testing.
1. Initial launch
- 1. Download the jar file and copy into an empty folder
+ 1.1 Download the jar file and copy into an empty folder.
- 1. Double-click the jar file Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
+ 1.2 Run `java -jar immuniMate.jar` for the jar file Expected: Shows the GUI with a set of sample contacts.
-1. Saving window preferences
+2. Saving window preferences
- 1. Resize the window to an optimum size. Move the window to a different location. Close the window.
+ 2.1 Move the window to a different location. Close the window.
- 1. Re-launch the app by double-clicking the jar file.
+ 2.2 Re-launch the app by running `java -jar ImmuniMate.jar` again.
Expected: The most recent window size and location is retained.
-1. _{ more test cases … }_
+### Adding a person
+
+1. Adding a person while all persons are being shown.
+ 1. Prerequisites:
+ 1. List all persons using the `list` command. Multiple persons in the list.
+ 1. The person with NRIC `S1234567A` is not already created in the system.
+ 1. The person with NRIC `T0234567C` is already created in the system.
+ 1. Test case: `create n/Alice Tan ic/S1234567A dob/1990-01-01 hp/12345678 a/123, Jurong West Ave 6, #08-111 s/F st/PENDING`
+ Expected: A new person is added to the list. The result panel shows the details of the new person.
+ 1. Test case: `create n/Bob Tan ic/T0234567C dob/1990-01-01 hp/12345678 a/123, Jurong West Ave 6, #08-111 s/M st/PENDING`
+ Expected: A new person is not added to the list. The result panel shows an error message, indicating that the person already exists in the system.
+ 1. Test case: `create n/Charlie Tan ic/S1234567A`
+ Expected: A new person is not added to the list. The result panel shows an error message, indicating that the command format is invalid.
+2. Adding a person while only some persons are being shown
+ 1. Prerequisites:
+ 1. Show only 1 person's details using the `find n/alex` command. One person is shown in the list.
+ 1. Test case: `create n/Bob Tan ic/T0234567C dob/1990-01-01 hp/12345678 a/123, Jurong West Ave 6, #08-111 s/M st/PENDING`
+ Expected: A new person is not added to the list. The result panel shows an error message, indicating that the person already exists in the system.
+
+### Reading a person
+1. Reading a person while all persons are being shown.
+ 1. Prerequisites:
+ 1. List all persons using the `list` command. Multiple persons in the list.
+ 1. The person with NRIC `S1234567A` is already created in the system with a `create` command.
+
+ 1. Test case: `read S1234567A`
+ Expected: Details of the read patient shown in result panel. The list panel shows the read person.
+
+ 1. Test case: `read S9876543N`
+ Expected: No person is read. Error details shown.
+
+ 1. Other incorrect read commands to try: `read`, `read 0`, `...` (where the input for NRIC field does not follow format for NRIC)
+ Expected: Similar to previous.
+ 2.
+2. Reading a person while only some persons are being shown
+ 1. Prerequisites:
+ 2. Show only 1 person's details using the `find n/alex` command. One person is shown in the list.
+ 3. The person with NRIC `S1234567A` is already created in the system with a `create` command.
+ 1. Test case: `read S1234567A`
+ Expected: The result panel shows the details of the read person. The list panel shows the read person.
### Deleting a person
1. Deleting a person while all persons are being shown
- 1. Prerequisites: List all persons using the `list` command. Multiple persons in the list.
+ 1. Prerequisites:
+ 1. List all persons using the `list` command. Multiple persons in the list.
+ 1. The person with NRIC `S1234567A` is already created in the system with a `create` command.
- 1. Test case: `delete 1`
- Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated.
+ 1. Test case: `delete S9234568N`
+ Expected: First patient is deleted from the list. Details of the deleted patient shown in the status message. Timestamp in the status bar is updated.
- 1. Test case: `delete 0`
+ 1. Test case: `delete S9876543N`
Expected: No person is deleted. Error details shown in the status message. Status bar remains the same.
- 1. Other incorrect delete commands to try: `delete`, `delete x`, `...` (where x is larger than the list size)
+ 1. Other incorrect delete commands to try: `delete`, `delete 0`, `...` (where the input for NRIC field does not follow format for NRIC)
Expected: Similar to previous.
-
-1. _{ more test cases … }_
-
-### Saving data
-
-1. Dealing with missing/corrupted data files
-
- 1. _{explain how to simulate a missing/corrupted file, and the expected behavior}_
-
-1. _{ more test cases … }_
+2. Deleting a person while only some persons are being shown
+ 1. Prerequisites:
+ 1. Show only 1 person's details using the `find n/alex` command. One person is shown in the list.
+ 1. The person with NRIC `S1234567A` is already created in the system with a `create` command.
+ 1. Test case: `delete S1234567A`
+ Expected: The person is deleted from the list. The result panel shows the details of the deleted person. The list panel shows a full list of patients.
+
+### Updating a person
+1. Updating a existing person's updatable fields
+ 1. Prerequisites:
+ 1. The person with NRIC `S1234567A` is already created in the system with a `create` command.
+ 1. Test case: `update S1234567A a/35 Bishan Road, #10-40 con/myopia`
+ Expected: The person's address is updated to `35 Bishan Road, #10-40` and condition is updated to `myopia`. The result panel shows the updated person's details.
+ 2. Test case: `update S1234567A a/35 Bishan Road, #10-40 con/`
+ Expected: The person's both fields are not updated. The result panel shows an error message, indicating that the argument for condition is invalid.
+ 3. Test case: `update S1234567A`
+ Expected: The person is not updated at all. The result panel shows an error message, indicating that the command format is invalid.
+2. Updating a non-existing person
+ 1. Prerequisites:
+ 1. The person with NRIC `S1234568A` does not exist in the system.
+ 2. Test case: `update S1234568A a/35 Bishan Road, #10-40 con/myopia`
+ Expected: The person is not updated at all. The result panel shows an error message, indicating that the person does not exist in the system.
+3. Updating a person's non-updatable fields
+ 1. Prerequisites:
+ 1. The person with NRIC `S1234567A` is already created in the system with a `create` command.
+ 1. Test case: `update S1234567A a/35 Bishan Road, #10-40 con/myopia ic/S1234568A`
+ Expected: The person's address is updated to `35 Bishan Road, #10-40` and condition is updated to `myopia`. The NRIC is not updated.
+
+### Finding a person
+
+1. Finding a person by name, condition or address
+ 1. Prerequisites:
+ 1. The person with name `Alex Yeoh` exists in the system.
+ 1. The person with condition `diabetes` exists in the system.
+ 1. The person with address `123, Jurong West Ave 6, #08-111` exists in the system.
+ 1. Test case: `find n/Alex Yeoh`
+ Expected: The person with name `Alex Yeoh` is shown in the list. The result panel shows the details of the person.
+ 1. Test case: `find con/diabetes`
+ Expected: The person with condition `diabetes` is shown in the list. The result panel shows the details of the person.
+ 1. Test case: `find a/123, Jurong West Ave 6, #08-111`
+ Expected: The person with address `123, Jurong West Ave 6, #08-111` is shown in the list. The result panel shows the details of the person.
+2. Finding a person by NRIC
+ 1. Test case: `find n/S1234567A`
+ Expected: The person with NRIC `S1234567A` is not shown in the list. The result panel shows an error message, indicating that the command format is invalid.
+
+### Deleting a person's information
+
+1. Deleting a person's optional fields
+ 1. Prerequisites:
+ 1. The person with NRIC `S1234567A` exists in the system.
+ 2. The person with NRIC `S1234568A` does not exist in the system.
+ 1. Test case: `deleteinfo S1234567A a/`
+ Expected: The person's address becomes null. The result panel shows the updated person's details.
+ 1. Test case: `deleteinfo S1234567A a/ con/`
+ Expected: The person's address and condition become null. The result panel shows the updated person's details.
+ 1. Test case: `deleteinfo S1234567A`
+ Expected: The person's information is not deleted. The result panel shows an error message, indicating that the command format is invalid.
+ 1. Test case: `deleteinfo S1234568A e/`
+ Expected: The person's name is not deleted. The result panel shows an error message, indicating that the person does not exist in the system.
+2. Deleting a person's mandatory fields
+ 1. Prerequisites:
+ 1. The person with NRIC `S1234567A` exists in the system.
+ 1. Test case: `deleteinfo S1234567A n/`
+ Expected: The person's name is not deleted. The result panel shows an error message, indicating that the name field cannot be deleted.
+
+### Adding a person's visit
+1. Adding a person's visit while all persons are being shown
+ 1. Prerequisites:
+ 1. List all persons using the `list` command. Multiple persons in the list.
+ 1. The person with NRIC `S1234567A` is already created in the system with a `create` command.
+ 1. The person with NRIC `S9876543N` does not exist in the system.
+ 1. The visit with date `2021-09-01` and with NRIC `S1234567A` is already created in the system.
+ 1. The visit with date `2021-09-03` and with NRIC `S9876543N` does not exist in the system.
+ 1. Test case: `addvisit S1234567A d/2021-09-03 dia/fever sym/cough st/PENDING`
+ Expected: The person's visit is added to the system. The result panel shows the details of the added visit.
+ 1. Test case: `addvisit S9876543N d/2021-09-03 dia/fever sym/cough st/PENDING`
+ Expected: The person's visit is not added. The result panel shows an error message, indicating that the person does not exist in the system.
+ 1. Test case: `addvisit S1234567A d/2021-09-01 dia/fever sym/cough st/PENDING`
+ Expected: The person's visit is not added. The result panel shows an error message, indicating that the visit already exists in the system.
+ 1. Other incorrect addvisit commands to try: `addvisit`, `addvisit 0`, `...` (where the input for NRIC field does not follow format for NRIC)
+ Expected: Similar to previous. The result panel shows an error message, indicating that the command format is invalid.
+
+
+### Checking a person's visit history
+1. Checking a person while all persons are being shown.
+ 1. Prerequisites:
+ 1. List all persons using the `list` command. Multiple persons in the list.
+ 1. The person with NRIC `S1234567A` is already created in the system with a `create` command.
+
+ 1. Test case: `check S1234567A`
+ Expected: Details of the checked person's visit history is shown in the result panel. The list panel shows the checked person.
+
+ 1. Test case: `check S9876543N`
+ Expected: No person is checked. Error details shown.
+
+ 1. Other incorrect read commands to try: `check`, `check 0`, `...` (where the input for NRIC field does not follow format for NRIC)
+ Expected: Similar to previous.
+ 2.
+2. Checking a person while only some persons are being shown
+ 1. Prerequisites:
+ 2. Show only 1 person's details using the `find n/alex` command. One person is shown in the list.
+ 3. The person with NRIC `S1234567A` is already created in the system with a `create` command.
+ 1. Test case: `check S1234567A`
+ Expected: The result panel shows the details of the checked person's visit history. The list panel shows the checked person.
+
+
+
+## Planned enhancements
+**Include FIN as accepted values for field `NRIC`**: The field `NRIC` should accept `F`, `M` and `G` as valid values, as they are valid first characters for foreigners' FIN (foreign identification number).
+
+**Allow `Name` to take special characters**: The field `Name` should be able to accommodate names with special characters such as dashes, slashes, apostrophes etc.
+
+**Limit `Country` to a list of valid countries**: The field `Country` should be limited to a list of countries, to prevent invalid entries.
+
+**Make `Email` case-insensitive**: The field `Email` should be case-insensitive, as emails are not case-sensitive in practice.
diff --git a/docs/UserGuide.md b/docs/UserGuide.md
index 7abd1984218..ab2b6623da7 100644
--- a/docs/UserGuide.md
+++ b/docs/UserGuide.md
@@ -2,40 +2,280 @@
layout: page
title: User Guide
---
+## Introduction
-AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized for use via a Command Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, AB3 can get your contact management tasks done faster than traditional GUI apps.
+Streamline Your Care, Empower Your Patients: Welcome to the Healthcare Information Management Revolution!
+Are you a doctor who has scrambled for a patient's medical information during a crucial consultation?
+Or a clinic receptionist who's gotten frustrated from flipping through stacks of paper notes to recall a patient's phone number?
+Those days are over!
+
+Introducing **ImmuniMate**, our innovative platform designed to revolutionize the way healthcare professionals and staff manage patient information.
+It's your secure, centralized hub where you can access all your patients' medical and personal details – allergies, visit history, medical conditions, you name it – just a few clicks away!
+
+### Who This App is For
+
+ImmuniMate is designed for **healthcare professionals** (doctors, nurses etc.) and **healthcare staff** (clinic receptionist etc.) longing to leverage the efficiencies of the 21st century, who:
+
+* have basic experience in using computers
+* have a computer with sufficient space (~100 MB)
+* are comfortable typing on a regular basis
+* have no serious colour vision deficiencies (can differentiate red, yellow and green)
+
+### Purpose of This Guide
+
+If you ticked all the points above, great!
+This user guide is here as your helping hand, imparting knowledge to unlock the full potential of ImmuniMate.
+You can start with learning to navigate this guide effectively by viewing guidelines on how to use this guide.
+After that, get started with ImmuniMate by following our step-by-step setup instructions, before really getting involved through short tutorials on its comprehensive set of features.
+Get ready to:
+
+* **Enhance Patient Care**: Deliver faster, more informed consultations with easy access to vital information.
+* **Boost Efficiency**: Save precious time by ditching paper records and streamlining your workflow.
+* **Revitalise Patients**: Use organised information about your patients to offer them peronalised medical advice.
+
+Ready to take patient service to the next level?
+Time to ditch those stacks of paper and Excel spreadsheets, and embrace the future of healthcare.
+Let's dive in and explore how ImmuniMate can transform your practice!
+
+-------------------------------------------
+
+
+## Table of Contents
* Table of Contents
{:toc}
--------------------------------------------------------------------------------------------------------------------
+## How to Use This Guide
+
+ImmuniMate's user guide is optimised for ease of navigation, so that you can spend less time on the app, and more time on your patients.
+The table of contents just before this section breaks down the guide into its constituent sections:
+
+1. **How to Use This Guide** (this section)
+ * descriptions on different sections of user guide
+ * glossary on technical terms
+2. **Product Information**
+ * detailed description of product
+ * summary of command and fields
+3. **Quick Start**
+ * system requirements
+ * how to download and get started on the app
+4. **Features**
+ * explains each feature with examples
+ * common usage mistakes
+5. **Frequently Asked Questions**
+6. **Known issues**
+ * descriptions on issues with ImmuniMate that have been spotted, but not fixed
+
+Navigating a complex document can be time-consuming, and we understand.
+That's why we've placed hyperlinks throughout this article (like [this one](#command-summary), to the command summary), so that any information you need is truly at your fingertips.
+
+
+
+### Information Boxes
+
+Before engaging with ImmuniMate, there are some things that are so important that they have to catch your eye.
+That's why we made these nice blue note boxes to capture your attention, to plug gaps in your understanding before proceeding with ImmuniMate.
+
+
+**:information_source: Notes**
+This is what a note box looks like.
+
+
+Sometimes, certain instructions might sound very new or contain too many technical terms, which is why we also positioned a few tip snippets below them in green boxes, so that you'll never have to fret about the intricacies of ImmuniMate.
+
+
+**:bulb: Tip:**
+This is what a tip snippet looks like.
+
+
+Mistakes are inevitable, even in the healthcare industry.
+But we should always strive to minimise them, and we're helping you do just that by informing you of common mistakes that have happened countless times.
+You can view them in red boxes such as this one.
+
+
+
+**:x: Common Mistakes**
+This is what a common mistake box looks like.
+
+
+
+
+
+ImmuniMate comes with an abundant set of features, each of which we have taken great care to explain in great detail.
+Below is the formatting you can expect to see for an explanation of each feature:
+
+### (what this feature does) : `(command word)`
+
+(more specific explanation of feature function)
+
+Format: `(exact usage format with command words and fields)`
+* (format detail 1)
+* (format detail 2)
+* ...
+
+Examples:
+* `(correct use case 1)`
+ * (consequence)
+* `(correct use case 2)`
+ * (consequence)
+* ...
+
+
+
+**:x: Common Mistakes**
+* `wrong use case 1` (reason)
+* `wrong use case 2` (reason)
+* ...
+
+
+
+
+### Glossary
+
+Throughout this guide, there might be some terms that you might not be familiar with, and that's fine.
+Here's a table of some technical terms you'll see further in the guide:
+
+| Term | Definition |
+|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| **Java** | A programming language. Various versions can be downloaded from [here](https://www.oracle.com/sg/java/technologies/downloads/). |
+| **home folder** | The main folder where all app activity can take place and files can be stored |
+| **command terminal** | A text-based interface to your computer.
On Windows, this can be opened by pressing the Windows key, and searching for an app called "Command Prompt".
On MacOS, this can be opened by pressing Command + Space, typing in "terminal", then pressing "Return". |
+| `cd` | A Linux (operating system) command used to navigate to different folders in your command terminal. Stands for "change directory".
Linux tutorials can be found [here](https://ubuntu.com/tutorials/command-line-for-beginners#1-overview). |
+| **GUI** | Short for "Graphical User Interface". The digital interface in which user interact with graphical components, such as icons and buttons. |
+| **CLI** | Short for "Command Line Interface". A software mechanism you use to interact with the application using your keyboard. |
+
+-----------------------------------------------------------------
+
+## Product Information
+
+ImmuniMate is a **desktop application** for healthcare professionals and staff to better store and manage their patients' personal and medical information.
+It is optimised for a single user on a single computer, meaning that after downloading a copy on your computer and using it, your copy cannot be accessed through other computers over the Internet.
+
+ImmuniMate is compatible with **Windows, Linux and MacOS** operating systems, and installation does not require any additional installers.
+It has an eye-catching GUI to capture your attention, but despite that, all interactions with ImmuniMate happen through the command line interface (CLI).
+This means each feature of ImmuniMate is only accessible through typing a command into the command box in its specified format, and pressing "Enter" to get a response.
+
+Here is a graphic on components of the GUI and their functions:
+
+
+
+
+
+The list of commands and their formats are specified below:
+
+### Command summary
+
+| Action | Format | Examples |
+|-------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------|
+| **[Create](#creating-a-patient-profile-create)** | `create a/ [e/Email] [c/Country_of_Nationality] [doa/Date_of_Admission] [bt/Blood type] [al/Allergies] [con/Condition] [sym/Symptom] [d/diagnosis]` | `create ic/S1234567A n/John Doe hp/98765432 a/311, Clementi Ave 2, #02-25 dob/1990-01-01 s/M st/PENDING` |
+| **[Read](#read-specific-patients-read)** | `read ` | `read S1234567A` |
+| **[Update](#updating-a-patient-profile-update)** | `update /` | `update S1234567A hp/91234567 e/jd123@example.com` |
+| **[Find](#finding-patients-by-name-find)** | `find n/ `
`find a/, , , ...`
`find con/, , , ...` | `find n/Alex Bryan Charlie`
`find a/Serangoon, Geylang`
`find con/Covid, Ebola` |
+| **[Delete Patient](#deleting-a-patient-delete)** | `delete ` | `delete S1234567A` |
+| **[Delete Information](#deleting-information-of-a-patient-deleteinfo)** | `deleteinfo ` | `deleteinfo S1234567A e/` |
+| **[Add Visit](#add-patient-visit-to-history-addvisit)** | `addvisit ic/ dov/ sym/ d/ st/` | `addvisit ic/S1234567A dov/2024-01-01 sym/Cough d/Covid st/UNWELL` |
+| **[Check](#check-patient-history-check)** | `check ` | `check S1234567A` |
+| **[Find Cluster](#cluster-finding-cluster)** | `cluster a/ d/` | `cluster 3 a/Serangoon d/dengue` |
+| **[Clear](#clearing-all-entries-clear)** | `clear` | - |
+| **[List](#listing-all-patients-list)** | `list` | - |
+| **[Help](#viewing-help-help)** | `help` | - |
+| **[Exit](#exiting-the-program-exit)** | `exit` | - |
+
+
+
+The list of fields and their formats are specified below:
+
+### Field summary
+
+| Field | Prefix | Format | Mandatory |
+|----------------------------|--------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------|
+| **Name** | `n/` | The name of the patient. Case-insensitive alphanumeric characters and spaces, capped at 2,000,000,000 characters. | Yes |
+| **NRIC** | `ic/` | First character can be either S or T, followed by 7 digits, and the last character is an alphabetical letter, in accordance with Singapore NRIC formats. NRIC is case-insensitive. | Yes |
+| **Phone Number** | `hp/` | 8 digits. | Yes |
+| **Address** | `a/` | Any text. Blank or empty text is not accepted. | Yes |
+| **Date of birth** | `dob/` | `yyyy-MM-dd` format. | Yes |
+| **Sex** | `s/` | `M` or `F`, case-sensitive. | Yes |
+| **Status** | `st/` | `PENDING`, `UNWELL`or `HEALTHY`, case-insensitive. | Yes |
+| **Email** | `e/` | Any valid email address of the form `local-part@domain`, case-sensitive. | No |
+| **Country of nationality** | `c/` | Any text. Blank or empty text is not accepted. | No |
+| **Date of admission** | `doa/` | `yyyy-MM-dd` format. | No |
+| **Blood type** | `bt/` | Any of `A+`, `A-`, `B+`, `B-`, `AB+`, `AB-`, `O+`, `O-` | No |
+| **Allergies** | `al/` | Any text. Blank or empty text is not accepted. | No |
+| **Condition** | `con/` | Any text. Blank or empty text is not accepted. | No |
+| **Symptom** | `sym/` | Any text. Blank or empty text is not accepted. | No |
+| **Diagnosis** | `d/` | Any text. Blank or empty text is not accepted. | No |
+| **Date of visit** | `dov/` | `yyyy-MM-dd` format. | No |
+
+### Error Messages
+
+Sometimes, **you might type in commands in the wrong format**, or fields that don't make sense, and that's fine.
+When that happens, the erroneous command you typed will light up in red, while more details on the nature of the error will be shown in the feedback box, like in the picture below.
+
+![Error Message](images/ErrorMessage.png)
+
+Not to worry, you can just edit that command, or delete it and type in a correct one.
+
+
+
+**:bulb: Tip:**
+Find retyping commands a hassle? Use your 'Up' and 'Down' arrow keys to access your past commands saved in your [Command History](#command-history)!
+
+
+----------------------------------------------------------------
## Quick start
-1. Ensure you have Java `11` or above installed in your Computer.
+1. Ensure you have Java `11` or above installed in your computer.
+
+
+
+ **:bulb: Tip:**
+ Don't worry if you don't have Java 11 installed yet!
+ The Java Development Kit (kind of like an installer) can be downloaded from [here](https://www.oracle.com/sg/java/technologies/downloads/#java11) (screenshot below).
+ Take great care in downloading the one which suits your operating system (Linux, Windows, MacOS etc).
+
+
+ ![Java website](images/JavaWebsite.png)
+
+2. Download the latest `immuniMate.jar` from [our website](https://github.com/AY2324S2-CS2103T-T08-1/tp/releases).
+
+
-1. Download the latest `addressbook.jar` from [here](https://github.com/se-edu/addressbook-level3/releases).
+3. Copy the file to the folder you want to use as the _home folder_ for your ImmuniMate.
-1. Copy the file to the folder you want to use as the _home folder_ for your AddressBook.
+4. Open a command terminal, and `cd` into the folder you put the jar file in.
-1. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar addressbook.jar` command to run the application.
- A GUI similar to the below should appear in a few seconds. Note how the app contains some sample data.
- ![Ui](images/Ui.png)
+
+
+ **:bulb: Tip:**
+ `cd` is a Linux command. New to Linux? You can learn the basics fast from [here](https://ubuntu.com/tutorials/command-line-for-beginners#1-overview).
+
-1. Type the command in the command box and press Enter to execute it. e.g. typing **`help`** and pressing Enter will open the help window.
+5. Type `java -jar immuniMate.jar` and press "Enter" to run the application.
+ A GUI similar to the below should appear in a few seconds. Note how the app contains some sample data. The colored circle on the right of each patient's name is the status indicator. For more information about the status indicator, see [create](#creating-a-patient-profile-create).
+
+ ![Ui](images/GUI.png)
+
+6. Type the command in the command box and press "Enter" to execute it. e.g. typing **`help`** and pressing "Enter" will open the help window.
Some example commands you can try:
* `list` : Lists all contacts.
- * `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` : Adds a contact named `John Doe` to the Address Book.
+ * `create ic/S0123456A n/John Doe hp/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 dob/1990-01-01 s/M st/PENDING` : Adds a patient named `John Doe` to ImmuniMate.
- * `delete 3` : Deletes the 3rd contact shown in the current list.
+ * `delete S0123456A` : Deletes all information of the patient with corresponding NRIC.
- * `clear` : Deletes all contacts.
+ * `clear` : Deletes all patients.
* `exit` : Exits the app.
-1. Refer to the [Features](#features) below for details of each command.
+
+
+ **:bulb: Tip:**
+ Refer to the [Features](#features) section below for details of each command.
+
+
--------------------------------------------------------------------------------------------------------------------
@@ -43,19 +283,19 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo
-**:information_source: Notes about the command format:**
+**:information_source: Notes**
-* Words in `UPPER_CASE` are the parameters to be supplied by the user.
- e.g. in `add n/NAME`, `NAME` is a parameter which can be used as `add n/John Doe`.
+* Words in `UPPERCASE` are the parameters to be supplied by the user.
+ e.g. in `update
/CONTENT`, `CONTENT` is a parameter which can be used as `update S0123456A hp/87654321`.
-* Items in square brackets are optional.
- e.g `n/NAME [t/TAG]` can be used as `n/John Doe t/friend` or as `n/John Doe`.
+* Items in angle brackets are mandatory.
+ e.g. `` must be given.
-* Items with `…` after them can be used multiple times including zero times.
- e.g. `[t/TAG]…` can be used as ` ` (i.e. 0 times), `t/friend`, `t/friend t/family` etc.
+* Items in square brackets are optional.
+ e.g. ` [e/EMAIL]` can be used as `ic/S0123456A e/jd123@example.com` or as `ic/S0123456A`.
* Parameters can be in any order.
- e.g. if the command specifies `n/NAME p/PHONE_NUMBER`, `p/PHONE_NUMBER n/NAME` is also acceptable.
+ e.g. if the command specifies `n/ hp/`, `hp/ n/` is also acceptable.
* Extraneous parameters for commands that do not take in parameters (such as `help`, `list`, `exit` and `clear`) will be ignored.
e.g. if the command specifies `help 123`, it will be interpreted as `help`.
@@ -63,136 +303,416 @@ AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized fo
* If you are using a PDF version of this document, be careful when copying and pasting commands that span multiple lines as space characters surrounding line-breaks may be omitted when copied over to the application.
-### Viewing help : `help`
+
+
+### Viewing help: `help`
-Shows a message explaning how to access the help page.
+**Shows a message explaining how to access the help page.**
-![help message](images/helpMessage.png)
+
Format: `help`
+
-### Adding a person: `add`
+### Listing all patients: `list`
-Adds a person to the address book.
+**Shows all patients in ImmuniMate.**
-Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…`
+Format: `list`
+
+
+
+### Creating a patient profile: `create`
+
+**Creates a patient profile in ImmuniMate.**
+
+Format: `create ic/ n/ hp/ a/ dob/ s/ st/ [e/Email] [c/Country_of_Nationality] [doa/Date_of_Admission] [bt/Blood type] [al/Allergies] [con/Condition] [sym/Symptom] [d/diagnosis]`
+
+* All mandatory fields must be provided. Refer to the [Field Summary](#field-summary) for a list of mandatory and optional fields, and their formats.
+* The unique identifier for each patient is the NRIC. The new NRIC must not already exist in the system.
+* The status of the patient is indicated by a colored circle on the right of the patient's name. The color of the circle corresponds to the status of the patient. The status can be `PENDING` (yellow), `UNWELL`(red) or `HEALTHY`(green).
+
+Examples:
+* `create ic/S1234567A n/John Doe hp/98765432 a/311, Clementi Ave 2, #02-25 dob/1990-01-01 s/M st/PENDING`
+* `create ic/S0123456A hp/87654321 a/311, Clementi Ave 2, #02-25 dob/1990-01-01 s/F st/PENDING e/janed@example.com bt/A+ n/Jane Doe`
+
+![Create Command Result](images/CreateCommandResult.png)
+
+
-
:bulb: **Tip:**
-A person can have any number of tags (including 0)
+**:x: Common Mistakes**
+* `create n/John Doe hp/98765432 a/311, Clementi Ave 2, #02-25 dob/1990-01-01 s/M st/PENDING` (missing NRIC)
+* `create ic/S1234567A n/John Doe hp/98765432 a/311, Clementi Ave 2, #02-25 dob/1990-2-30 s/M st/PENDING` (Wrong date format)
+
+
+### Read specific patients: `read`
+
+**Shows all profile details of patient with corresponding NRIC.**
+
+Format: `read
`
+* The NRIC must follow the correct format specified in [Field Summary](#field-summary).
+
Examples:
-* `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01`
-* `add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal`
+* `read t0234567c`
-### Listing all persons : `list`
+![Read Command Result](images/ReadCommandResult.png)
-Shows a list of all persons in the address book.
+
-Format: `list`
+**:x: Common Mistakes**
+* `read S12345678` (wrong NRIC format)
+
+
+
-### Editing a person : `edit`
+### Updating a patient profile: `update`
-Edits an existing person in the address book.
+**Updates information of a patient with an existing profile in ImmuniMate.**
-Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]…`
+Format: `update /CONTENT`
-* Edits the person at the specified `INDEX`. The index refers to the index number shown in the displayed person list. The index **must be a positive integer** 1, 2, 3, …
-* At least one of the optional fields must be provided.
+* Updates information of the patient with corresponding NRIC.
+* At least one of the fields must be provided.
+* NRIC cannot be updated, all other values can be updated.
* Existing values will be updated to the input values.
-* When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative.
-* You can remove all the person’s tags by typing `t/` without
- specifying any tags after it.
+* Refer to the [Field Summary](#field-summary) for a list of fields and their formats.
+
+
+
+**:bulb: Tip**
+Just finished a consultation with a patient?
+You can update related fields together, like changing the patient's diagnosis to "coronavirus" while changing the status to "UNWELL".
+
Examples:
-* `edit 1 p/91234567 e/johndoe@example.com` Edits the phone number and email address of the 1st person to be `91234567` and `johndoe@example.com` respectively.
-* `edit 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags.
+* `update S1234567A hp/91234567 e/jd123@example.com`
+ * Updates the phone number and email address of the corresponding patient to be `91234567` and `jd123@example.com` respectively.
+* `update S0123456A a/123 Serangoon Road`
+ * Updates the address of the corresponding patient to be `123 Serangoon Road`.
-### Locating persons by name: `find`
+
-Finds persons whose names contain any of the given keywords.
+
-Format: `find KEYWORD [MORE_KEYWORDS]`
+**:x: Common Mistakes**
+* `update S1234567A ic/T1234567A` (NRIC cannot be updated)
+* `update S1234567A` (no field specified)
+
+
+
+
+### Finding patients by name: `find`
+
+**Finds patients whose names contain any of the given keywords.**
+
+Format: `find n/ [NAME] [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 name is searched.
-* Only full words will be matched e.g. `Han` will not match `Hans`
-* Persons matching at least one keyword will be returned (i.e. `OR` search).
- e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang`
+* 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 name field in each patient profile is searched.
+* At least one name must be provided.
+* Only full words will be matched e.g. `Han` will not match `Hans`.
+* Patients matching at least one keyword will be returned (i.e. `OR` search).
+ e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang`.
+* Names can be separated with any number of spaces.
Examples:
-* `find John` returns `john` and `John Doe`
-* `find alex david` returns `Alex Yeoh`, `David Li`
- ![result for 'find alex david'](images/findAlexDavidResult.png)
+* `find n/John`
+ * Returns `John Dolly` and `John Doe`.
+* `find n/alex david`
+ * Returns `Alex Yeoh`, `David Li`.
-### Deleting a person : `delete`
+
-Deletes the specified person from the address book.
+
-Format: `delete INDEX`
+### Finding patients by address: `find`
-* Deletes the person at the specified `INDEX`.
-* The index refers to the index number shown in the displayed person list.
-* The index **must be a positive integer** 1, 2, 3, …
+**Finds patients whose addresses contain any of the given keywords.**
+
+Format: `find a/, [LOCATION], [LOCATION], ...`
+
+* The search is case-insensitive. e.g. `serangoon` will match `Serangoon`.
+* The order of the keywords does matter. e.g. `Clementi Ave` will not match `Ave Clementi`.
+* Only the address field in each patient profile is searched.
+* At least one location must be provided.
+* Partial words will be matched e.g. `Clem` will match `Clementi`.
+* Patients matching at least one keyword will be returned (i.e. `OR` search).
+ e.g. `Clementi, Serangoon` will return patients with address containing `Serangoon` or `Clementi`.
+* Locations must be separated by commas, and whitespaces before and after each location will be ignored.
Examples:
-* `list` followed by `delete 2` deletes the 2nd person in the address book.
-* `find Betsy` followed by `delete 1` deletes the 1st person in the results of the `find` command.
+* `find a/Geylang`
+ * Returns `Alex Yeoh`.
+* `find a/geylang, serangoon, choa chu kang`
+ * Returns `Alex Yeoh`, `Bernice Yu`, `David Li`.
+* `find a/Serangoon`
+ * Returns `Bernice Yu`, `David Li`.
+
+
+
+
+
+### Finding patients by condition: `find`
-### Clearing all entries : `clear`
+**Finds patients whose conditions contain any of the given keywords.**
-Clears all entries from the address book.
+Format: `find con/, [CONDITION], [CONDITION], ...`
+
+* The search is case-insensitive. e.g. `diabetes` will match `Diabetes`.
+* The order of the keywords does matter. e.g. `Stomach Flu` will not match `Flu Stomach`.
+* Only the condition is searched.
+* At least one condition must be provided.
+* Partial words will be matched e.g. `diab` will match `Diabetes`.
+* Patients matching at least one keyword will be returned (i.e. `OR` search).
+ e.g. `Diabetes, Myopia` will return patients with address containing `Diabetes` or `Myopia`.
+* Conditions must be separated by commas, and whitespaces before and after each condition will be ignored.
+
+Examples:
+* `find con/diabetes, high blood pressure`
+
+
+
+
+
+**:x: Common Mistakes**
+* `find ic/S1234567X` (only condition, name and address can be searched with find)
+
+
+
+
+**:bulb: Tip:**
+If you would like to find a person with NRIC, use the `read` command instead.
+
+
+
+
+### Deleting a patient: `delete`
+
+**Deletes the specified patient from ImmuniMate.**
+
+Format: `delete `
+
+* Deletes the profile of the patient with the corresponding NRIC.
+* The NRIC must follow the correct format as specified in [Field Summary](#field-summary).
+
+Examples:
+* `delete S1234567A`
+ * deletes patient uniquely identified by NRIC S1234567A.
+
+
+
+**:x: Common Mistakes**
+* `delete S12345678` (NRIC must be in the correct format)
+* `delete` (NRIC must be provided)
+
+
+
+
+### Deleting information of a patient: `deleteinfo`
+
+**Deletes specified optional information from the specified person from ImmuniMate.**
+
+Format: `deleteinfo [Field] [Field] ...`
+
+* Deletes specified information of the patient with corresponding NRIC.
+* The NRIC must follow the correct format as specified in [Field Summary](#field-summary).
+* Only fields specified as optional in the [Field Summary](#field-summary) can be deleted.
+
+Examples:
+* `deleteinfo S1234567A e/`
+ * Deletes the email of patient uniquely identified by NRIC S1234567A.
+* `deleteinfo S0123456A e/ bt/ c/`
+ * Deletes the email, blood type and country of nationality of patient uniquely identified by NRIC S0123456A.
+
+
+
+**:x: Common Mistakes**
+* `deleteinfo S1234567A abc/` (a valid optional field from the [Field Summary](#field-summary) must be provided)
+* `deleteinfo S1234567A` (a field must be provided)
+* `deleteinfo S1234567A ic/` (mandatory fields cannot be deleted)
+
+
+
+
+**:bulb: Tip:**
+If you would like to change mandatory fields, you can use the `update` command instead.
+
+
+
+
+### Add patient visit to history: `addvisit`
+
+**Adds visit to patient history.**
+
+Format: `addvisit ic/ dov/ sym/ d/ st/`
+
+* NRIC must be that of a patient already in ImmuniMate.
+
+Examples:
+* `addvisit ic/S1234567A dov/2024-01-01 sym/Cough d/Covid st/UNWELL`
+ * Adds a visit to history of patient uniquely identified by NRIC S1234567A. During this visit on 2024-01-01, the patient was having a cough and was diagnosed to be unwell with Covid.
+* `addvisit ic/S0123456A dov/2024-02-02 sym/Fever,Rashes d/possible dengue st/PENDING`
+ * Adds a visit to history of patient uniquely identified by NRIC S0123456A. During this visit on 2024-02-02, the patient had a fever and rashes. The doctor suspects the patient has dengue, but is unable to come to a conclusion, hence the `PENDING` status.
+
+![Add Visit Result](images/AddVisitCommandResult.png)
+
+
+
+**:x: Common Mistakes**
+* `addvisit ic/S7654321X dov/2024-01-01 sym/Cough d/Covid st/` (NRIC must belong to a person existing in the system)
+* `addvisit ic/S1234567A a/#101 Hougang Ave` (fields other than date of visit, symptoms, diagnosis and status cannot be added)
+
+
+
+
+### Check patient history: `check`
+
+**Checks all visits in patient history.**
+
+Format: `check `
+* NRIC must be that of a patient already in ImmuniMate.
+
+Example:
+* `check T0234567C`
+ * Displays all visits in history of patient uniquely identified by NRIC S1234567A.
+
+![Check Command Result](images/CheckCommandResult.png)
+
+
+
+**:x: Common Mistakes**
+* `check S12345678` (NRIC must be in the correct format, and must exist in the system)
+
+
+
+
+### Cluster finding: `cluster`
+
+**Shows whether or not the number of people _unwell_ with the illness given (diagnosis in profile) in the location given is at least the integer given, and lists the people there with the illness.**
+
+Format: `cluster a/ d/`
+
+* The search is case-insensitive. e.g. `serangoon` will match `Serangoon`.
+* Only one location and diagnosis is searched.
+* Location and diagnosis cannot be empty.
+* Cluster size must be between 1 and 2,000,000,000.
+* Partial words will be matched e.g. `Clem` will match `Clementi`, `deng` will match `dengue`.
+
+Example:
+* `cluster 3 a/Serangoon d/dengue`
+ * Shows if there are at least 3 people unwell with dengue in locations with the substring "Serangoon".
+
+![Cluster Command Result](images/ClusterCommandResult.png)
+
+
+
+**:x: Common Mistakes**
+* `cluster 3 a/S d/dengue` (address should be a meaningful word or phrase indicative of a location in Singapore)
+* `cluster 3 a/Serangoon` (diagnosis must be provided)
+* `cluster 3 d/dengue` (diagnosis must be provided)
+* `cluster 0 a/Serangoon d/dengue` (a positive cluster size must be provided)
+* `cluster 30.5 a/Serangoon d/dengue` (an integer cluster sizet must be provided)
+
+
+
+
+### Clearing all entries: `clear`
+
+**Clears all profiles from ImmuniMate.**
Format: `clear`
-### Exiting the program : `exit`
+
-Exits the program.
+### Exiting the program: `exit`
+
+**Exits the program.**
Format: `exit`
+
+
+### Command History
+ImmuniMate allows you to navigate through your previous commands so you can easily reuse them without having to
+retype them entirely. To navigate through the Command History, use the Up Arrow Key to view a previous command, and use the Down
+Arrow Key to view the next command. The Up and Down Arrow Keys can be found on the Arrow Keys.
+
+![Keyboard Arrow Keys](images/KeyboardArrowKeys.png)
+
+
+
+**:information_source: Notes**
+* The Command History only saves **valid commands**, it does not save commands that were unsuccessful.
+* The Command History is **temporary** and **will not be stored in between sessions**. When you close an instance of ImmuniMate, your Command History is cleared.
+
+
+
+
### Saving the data
-AddressBook data are saved in the hard disk automatically after any command that changes the data. There is no need to save manually.
+ImmuniMate data is saved in the hard disk automatically after any command that changes the data. There is no need to save manually.
+
+
### Editing the data file
-AddressBook data are saved automatically as a JSON file `[JAR file location]/data/addressbook.json`. Advanced users are welcome to update data directly by editing that data file.
+ImmuniMate data are saved automatically as a JSON file `[JAR file location]/data/immunimate.json`. Advanced users are welcome to update data directly by editing that data file.
:exclamation: **Caution:**
-If your changes to the data file makes its format invalid, AddressBook will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it.
-Furthermore, certain edits can cause the AddressBook to behave in unexpected ways (e.g., if a value entered is outside of the acceptable range). Therefore, edit the data file only if you are confident that you can update it correctly.
+If your changes to the data file makes its format invalid, ImmuniMate will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it.
+Furthermore, certain edits can cause ImmuniMate to behave in unexpected ways (e.g., if a value entered is outside of the acceptable range). Therefore, edit the data file only if you are confident that you can update it correctly.
-### Archiving data files `[coming in v2.0]`
+
+
+### Update patient's visit in history `[coming in v2.0]`
+- Allows updating of patient's visit in history.
+
+### Automated Infection cluster tracking `[coming in v2.0]`
+- Automatically tracks clusters and stores them in storage.
-_Details coming soon ..._
--------------------------------------------------------------------------------------------------------------------
## FAQ
**Q**: How do I transfer my data to another Computer?
-**A**: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous AddressBook home folder.
+**A**: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous ImmuniMate home folder.
---------------------------------------------------------------------------------------------------------------------
+**Q**: I entered a command and don't want to type it again, how can I go back to it?
+**A**: Use the up and down arrow keys on the keyboard to navigate your Command History. More information is in the Command History section above.
-## Known issues
+**Q**: I added a new Patient Visit to my patient, but it doesn't seem to update the Patient information. Is something wrong?
+**A**: No, this is intended behaviour as we want to afford more flexibility to GPs. Automatically updating the patient field based
+on recent visits might result in accidentally overriding intended data.
-1. **When using multiple screens**, if you move the application to a secondary screen, and later switch to using only the primary screen, the GUI will open off-screen. The remedy is to delete the `preferences.json` file created by the application before running the application again.
+**Q**: My name has dashes, slashes, commas, or apostrophes, I can't input my name in the create command.
+**A**: This is intended behaviour. Our name field aims to adhere to ICA guidelines.
+If your name has any special characters, kindly remove them for compliance. For example, "Lee Chi-Geng, Bryan" can be changed into "Lee Chi Geng Bryan".
+
+**Q**: Help, I can't add multiple patient visits a day!
+**A**: This is intended behaviour. Patients are assumed to only have a single visit a day.
+
+**Q**: Why can I assign multiple patient profiles with the same phone number?
+**A**: This is intended behaviour. We understand there might be some patients (elderly, young children, disabled etc) who might be dependent on their family members or guardians for their day-to-day tasks. These family members and guardians might themselves be patients of the same clinic, hence the flexibility in recording phone numbers.
+**Q**: Why is it when I update a patient's diagnosis, his/her status is not automatically updated to "UNWELL"?
+**A**: This is intended behaviour. We wish to leave it to your expertise to determine when a patient has truly contracted a disease, as there are some ambiguous cases which might not necessitate an "UNWELL" status, such as asymptomatic coronavirus cases.
+
+**Q**: Why is it that when I update a person's field to the exact same content as the current one, no error is shown? Similarly, why is that when I delete a field that originally was not filled, no error message is shown?
+**A**: This is intended behaviour. This operation does not cause error in the system as the content is the same, and we do not want to interrupt your workflow with unnecessary error messages.
--------------------------------------------------------------------------------------------------------------------
-## Command summary
-
-Action | Format, Examples
---------|------------------
-**Add** | `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…`
e.g., `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague`
-**Clear** | `clear`
-**Delete** | `delete INDEX`
e.g., `delete 3`
-**Edit** | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]…`
e.g.,`edit 2 n/James Lee e/jameslee@example.com`
-**Find** | `find KEYWORD [MORE_KEYWORDS]`
e.g., `find James Jake`
-**List** | `list`
-**Help** | `help`
+## Known issues
+
+1. **When using multiple screens**, if you move the application to a secondary screen, and later switch to using only the primary screen, the GUI will open off-screen. The remedy is to delete the `preferences.json` file created by the application before running the application again.
+2. **When using the `cluster` command**, search is purely based on text, which means inputting "ave" will find all unwell patients whose addresses contain "ave", despite the addresses not necessarily being close to one another. We suggest users to input text indicative of location, such as "Hougang".
+3. **The `country` field** does not limit the input to alphabetical characters and is case-insensitive, which may lead to incorrect data entry.
+4. **The `email` field** is case-sensitive, but in practical usage, email is case-insensitive.
+5. **The `NRIC` field** cannot yet take NRIC numbers starting with F, G or M, which might cause inconvenience to a small segment of the Singapore population.
+6. **The ImmuniMate icon** cannot be displayed on Windows systems, instead showing up as a brown square with a person icon. This is simply a cosmetic issue, so it should not pose other technical issues to Windows users.
+7. **The `DateOfBirth`, `DateOfVisit` and `DateOfAdmission` fields** do allow future dates to be added, which might cause inconsistent entry if input is wrong.
diff --git a/docs/_config.yml b/docs/_config.yml
index 6bd245d8f4e..c5d993669f8 100644
--- a/docs/_config.yml
+++ b/docs/_config.yml
@@ -1,4 +1,4 @@
-title: "AB-3"
+title: "ImmuniMate"
theme: minima
header_pages:
@@ -8,7 +8,7 @@ header_pages:
markdown: kramdown
-repository: "se-edu/addressbook-level3"
+repository: "AY2324S2-CS2103T-T08-1/tp"
github_icon: "images/github-icon.png"
plugins:
diff --git a/docs/_sass/minima/_base.scss b/docs/_sass/minima/_base.scss
index 0d3f6e80ced..c0dc0641e3f 100644
--- a/docs/_sass/minima/_base.scss
+++ b/docs/_sass/minima/_base.scss
@@ -288,7 +288,7 @@ table {
text-align: center;
}
.site-header:before {
- content: "AB-3";
+ content: "ImmuniMate";
font-size: 32px;
}
}
diff --git a/docs/diagrams/AddVisitCommandLogic.puml b/docs/diagrams/AddVisitCommandLogic.puml
new file mode 100644
index 00000000000..97d309324cb
--- /dev/null
+++ b/docs/diagrams/AddVisitCommandLogic.puml
@@ -0,0 +1,80 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+box Logic LOGIC_COLOR_T1
+participant ":LogicManager" as LogicManager LOGIC_COLOR
+participant ":ImmuniMateParser" as ImmuniMateParser LOGIC_COLOR
+participant ":AddVisitCommandParser" as AddVisitCommandParser LOGIC_COLOR
+participant "c:AddVisitCommand" as AddVisitCommand LOGIC_COLOR
+participant "r:CommandResult" as CommandResult LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant "m:Model" as Model MODEL_COLOR
+participant "v:Visit" as Visit MODEL_COLOR
+end box
+
+[-> LogicManager : execute("addvisit ...")
+activate LogicManager
+LogicManager -> ImmuniMateParser : parseCommand("addvisit ...")
+activate ImmuniMateParser
+
+create AddVisitCommandParser
+ImmuniMateParser -> AddVisitCommandParser
+activate AddVisitCommandParser
+AddVisitCommandParser --> ImmuniMateParser
+deactivate AddVisitCommandParser
+ImmuniMateParser -> AddVisitCommandParser : parse("...")
+activate AddVisitCommandParser
+
+create Visit
+AddVisitCommandParser -> Visit
+activate Visit
+Visit --> AddVisitCommandParser
+deactivate Visit
+
+create AddVisitCommand
+AddVisitCommandParser -> AddVisitCommand
+activate AddVisitCommand
+AddVisitCommand --> AddVisitCommandParser
+deactivate AddVisitCommand
+
+AddVisitCommandParser --> ImmuniMateParser : c
+deactivate AddVisitCommandParser
+'Hidden arrow to position the destroy marker below the end of the activation bar.
+AddVisitCommandParser -[hidden]-> ImmuniMateParser
+destroy AddVisitCommandParser
+ImmuniMateParser --> LogicManager : c
+deactivate ImmuniMateParser
+
+LogicManager -> AddVisitCommand : execute()
+activate AddVisitCommand
+AddVisitCommand -> Visit : getNric()
+activate Visit
+Visit --> AddVisitCommand : nric
+deactivate Visit
+AddVisitCommand -> Model : hasPerson(...)
+activate Model
+Model --> AddVisitCommand : true
+deactivate Model
+AddVisitCommand -> Model : hasVisit(...)
+activate Model
+Model --> AddVisitCommand : false
+deactivate Model
+AddVisitCommand -> Model : addVisit(v)
+activate Model
+Model --> AddVisitCommand : add visit in the model
+deactivate Model
+
+create CommandResult
+AddVisitCommand -> CommandResult
+activate CommandResult
+CommandResult --> AddVisitCommand
+deactivate
+AddVisitCommand --> LogicManager : r
+deactivate AddVisitCommand
+
+[<--LogicManager : r
+deactivate LogicManager
+@enduml
diff --git a/docs/diagrams/AddVisitCommandModel.puml b/docs/diagrams/AddVisitCommandModel.puml
new file mode 100644
index 00000000000..07fbb2948d4
--- /dev/null
+++ b/docs/diagrams/AddVisitCommandModel.puml
@@ -0,0 +1,119 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+box Logic LOGIC_COLOR_T1
+participant "l:Logic" as Logic LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant ":ModelManager" as ModelManager MODEL_COLOR
+participant ":ImmuniMate" as ImmuniMate MODEL_COLOR
+participant ":UniqueVisitList" as UniqueVisitList MODEL_COLOR
+participant "internalList: ObservableList" as internalList MODEL_COLOR
+participant "p:Person" as p MODEL_COLOR
+participant "v:Visit" as Visit MODEL_COLOR
+end box
+
+[-> Logic : execute()
+activate Logic
+
+create p
+Logic -> p
+activate p
+p --> Logic
+deactivate p
+
+create Visit
+Logic -> Visit
+activate Visit
+Visit --> Logic
+deactivate Visit
+
+Logic -> ModelManager : hasPerson(p)
+activate ModelManager
+
+ModelManager -> ImmuniMate: hasPerson(p)
+activate ImmuniMate
+
+ImmuniMate -> UniqueVisitList : contains(p)
+activate UniqueVisitList
+
+UniqueVisitList -> internalList : stream().anyMatch(p::isSamePerson)
+activate internalList
+
+internalList -> p : isSamePerson()
+activate p
+
+p --> internalList
+deactivate p
+
+internalList --> UniqueVisitList
+deactivate internalList
+
+UniqueVisitList --> ImmuniMate
+deactivate UniqueVisitList
+
+ImmuniMate --> ModelManager
+deactivate ImmuniMate
+
+ModelManager --> Logic
+deactivate ModelManager
+
+Logic -> ModelManager : hasVisit(v)
+activate ModelManager
+
+ModelManager -> ImmuniMate: hasVisit(v)
+activate ImmuniMate
+
+ImmuniMate -> UniqueVisitList : contains(v)
+activate UniqueVisitList
+
+UniqueVisitList -> internalList : stream().anyMatch(v::isSameVisit)
+activate internalList
+
+internalList -> Visit : isSameVisit()
+activate Visit
+
+Visit --> internalList
+deactivate Visit
+
+internalList --> UniqueVisitList
+deactivate internalList
+
+UniqueVisitList --> ImmuniMate
+deactivate UniqueVisitList
+
+ImmuniMate --> ModelManager
+deactivate ImmuniMate
+
+ModelManager --> Logic
+deactivate ModelManager
+
+Logic -> ModelManager : addVisit(v)
+activate ModelManager
+
+ModelManager -> ImmuniMate: addVisit(v)
+activate ImmuniMate
+
+ImmuniMate -> UniqueVisitList : add(v)
+activate UniqueVisitList
+
+UniqueVisitList -> internalList : add(v)
+activate internalList
+
+internalList --> UniqueVisitList
+deactivate internalList
+
+UniqueVisitList --> ImmuniMate
+deactivate UniqueVisitList
+
+ImmuniMate --> ModelManager
+deactivate ImmuniMate
+
+ModelManager --> Logic
+deactivate ModelManager
+
+[<--Logic
+deactivate Logic
+
+@enduml
diff --git a/docs/diagrams/ArchitectureSequenceDiagram.puml b/docs/diagrams/ArchitectureSequenceDiagram.puml
index 48b6cc4333c..a1a42a2832f 100644
--- a/docs/diagrams/ArchitectureSequenceDiagram.puml
+++ b/docs/diagrams/ArchitectureSequenceDiagram.puml
@@ -8,10 +8,10 @@ Participant ":Logic" as logic LOGIC_COLOR
Participant ":Model" as model MODEL_COLOR
Participant ":Storage" as storage STORAGE_COLOR
-user -[USER_COLOR]> ui : "delete 1"
+user -[USER_COLOR]> ui : "delete S1234567X"
activate ui UI_COLOR
-ui -[UI_COLOR]> logic : execute("delete 1")
+ui -[UI_COLOR]> logic : execute("delete S1234567X")
activate logic LOGIC_COLOR
logic -[LOGIC_COLOR]> model : deletePerson(p)
@@ -20,7 +20,7 @@ activate model MODEL_COLOR
model -[MODEL_COLOR]-> logic
deactivate model
-logic -[LOGIC_COLOR]> storage : saveAddressBook(addressBook)
+logic -[LOGIC_COLOR]> storage : saveAddressBook(immuniMate)
activate storage STORAGE_COLOR
storage -[STORAGE_COLOR]> storage : Save to file
diff --git a/docs/diagrams/CheckCommandModelDiagram.puml b/docs/diagrams/CheckCommandModelDiagram.puml
new file mode 100644
index 00000000000..04e620bf78c
--- /dev/null
+++ b/docs/diagrams/CheckCommandModelDiagram.puml
@@ -0,0 +1,65 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+box Logic LOGIC_COLOR_T1
+participant "l:Logic" as CheckCommand LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant ":ModelManager" as ModelManager MODEL_COLOR
+participant ":ImmuniMate" as ImmuniMate MODEL_COLOR
+participant ":UniquePersonList" as UniquePersonList MODEL_COLOR
+participant "internalList: ObservableList" as internalList MODEL_COLOR
+participant "p:Person" as p MODEL_COLOR
+end box
+
+[-> CheckCommand : execute()
+activate CheckCommand
+
+CheckCommand -> ModelManager : hasPerson(p)
+activate ModelManager
+
+ModelManager -> ImmuniMate: hasPerson(p)
+activate ImmuniMate
+
+ImmuniMate --> UniquePersonList : contains(p)
+activate UniquePersonList
+
+UniquePersonList -> internalList : stream().anyMatch(p::isSamePerson)
+activate internalList
+
+internalList -> p : isSamePerson(p)
+activate p
+
+p --> internalList
+deactivate p
+
+internalList --> UniquePersonList
+deactivate internalList
+
+UniquePersonList --> ImmuniMate
+deactivate UniquePersonList
+
+ImmuniMate --> ModelManager
+deactivate ImmuniMate
+
+ModelManager --> CheckCommand
+deactivate ModelManager
+
+CheckCommand -> ModelManager : updateFilteredPersonList(predicate)
+activate ModelManager
+
+ModelManager --> CheckCommand
+deactivate ModelManager
+
+CheckCommand -> ModelManager : updateFilteredVisitList(predicate)
+activate ModelManager
+
+ModelManager --> CheckCommand
+deactivate ModelManager
+
+[<--CheckCommand
+deactivate CheckCommand
+
+@enduml
diff --git a/docs/diagrams/CheckCommandSequenceDiagram.puml b/docs/diagrams/CheckCommandSequenceDiagram.puml
new file mode 100644
index 00000000000..58607180c94
--- /dev/null
+++ b/docs/diagrams/CheckCommandSequenceDiagram.puml
@@ -0,0 +1,94 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+box Logic LOGIC_COLOR_T1
+participant ":LogicManager" as LogicManager LOGIC_COLOR
+participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
+participant ":CheckCommandParser" as CheckCommandParser LOGIC_COLOR
+participant "c:CheckCommand" as CheckCommand LOGIC_COLOR
+participant "r:CommandResult" as CommandResult LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant "m:Model" as Model MODEL_COLOR
+end box
+
+[-> LogicManager : execute("check T0123456A")
+activate LogicManager
+
+LogicManager -> AddressBookParser : parseCommand("check T0123456A")
+activate AddressBookParser
+
+create CheckCommandParser
+AddressBookParser -> CheckCommandParser
+activate CheckCommandParser
+
+CheckCommandParser --> AddressBookParser
+deactivate CheckCommandParser
+
+AddressBookParser -> CheckCommandParser : parse("T0123456A")
+activate CheckCommandParser
+
+create CheckCommand
+CheckCommandParser -> CheckCommand
+activate CheckCommand
+
+CheckCommand --> CheckCommandParser :
+deactivate CheckCommand
+
+CheckCommandParser --> AddressBookParser : c
+deactivate CheckCommandParser
+'Hidden arrow to position the destroy marker below the end of the activation bar.
+CheckCommandParser -[hidden]-> AddressBookParser
+destroy CheckCommandParser
+
+AddressBookParser --> LogicManager : c
+deactivate AddressBookParser
+
+LogicManager -> CheckCommand : execute(m)
+activate CheckCommand
+
+CheckCommand -> Model : hasPerson(...)
+activate Model
+
+Model --> CheckCommand : false
+deactivate Model
+
+CheckCommand -> Model : updateFilteredPersonList(...)
+activate Model
+
+Model --> CheckCommand : updateFilteredPersonList() successful
+deactivate Model
+
+CheckCommand -> Model : getFilteredPersonList()
+activate Model
+
+Model --> CheckCommand : Filtered person list
+deactivate Model
+
+CheckCommand -> Model : updateFilteredVisitList(...)
+activate Model
+
+Model --> CheckCommand : updateFilteredVisitList() successful
+deactivate Model
+
+CheckCommand -> Model : getFilteredVisitList()
+activate Model
+
+Model --> CheckCommand : Filtered visit list
+deactivate Model
+
+create CommandResult
+CheckCommand -> CommandResult
+activate CommandResult
+
+CommandResult --> CheckCommand
+deactivate CommandResult
+
+CheckCommand --> LogicManager : r
+deactivate CheckCommand
+
+[<--LogicManager
+deactivate LogicManager
+@enduml
diff --git a/docs/diagrams/ClusterLogicModelDiagram.puml b/docs/diagrams/ClusterLogicModelDiagram.puml
new file mode 100644
index 00000000000..9f20bfbcf13
--- /dev/null
+++ b/docs/diagrams/ClusterLogicModelDiagram.puml
@@ -0,0 +1,63 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+box Logic LOGIC_COLOR_T1
+participant ":LogicManager" as LogicManager LOGIC_COLOR
+participant ":ImmuniMateParser" as ImmuniMateParser LOGIC_COLOR
+participant ":ClusterCommandParser" as ClusterCommandParser LOGIC_COLOR
+participant "c:ClusterCommand" as ClusterCommand LOGIC_COLOR
+participant "r:CommandResult" as CommandResult LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant "m:Model" as Model MODEL_COLOR
+end box
+
+[-> LogicManager : execute("cluster 50 ...")
+activate LogicManager
+LogicManager -> ImmuniMateParser : parseCommand("cluster 50 ...")
+activate ImmuniMateParser
+
+create ClusterCommandParser
+ImmuniMateParser -> ClusterCommandParser
+activate ClusterCommandParser
+ClusterCommandParser --> ImmuniMateParser
+deactivate ClusterCommandParser
+ImmuniMateParser -> ClusterCommandParser : parse("50 ...")
+activate ClusterCommandParser
+
+create ClusterCommand
+ClusterCommandParser -> ClusterCommand
+activate ClusterCommand
+ClusterCommand --> ClusterCommandParser
+deactivate ClusterCommand
+ClusterCommandParser --> ImmuniMateParser : c
+deactivate ClusterCommandParser
+'Hidden arrow to position the destroy marker below the end of the activation bar.
+ClusterCommandParser -[hidden]-> ImmuniMateParser
+destroy ClusterCommandParser
+ImmuniMateParser --> LogicManager : c
+deactivate ImmuniMateParser
+LogicManager -> ClusterCommand : execute(m)
+activate ClusterCommand
+ClusterCommand -> Model : updateFilteredPersonList(...)
+activate Model
+Model --> ClusterCommand
+deactivate Model
+ClusterCommand -> Model : getFilteredPersonList(...)
+activate Model
+Model --> ClusterCommand
+deactivate Model
+
+create CommandResult
+ClusterCommand -> CommandResult
+activate CommandResult
+CommandResult --> ClusterCommand
+deactivate
+ClusterCommand --> LogicManager : r
+deactivate ClusterCommand
+
+[<--LogicManager : r
+deactivate LogicManager
+@enduml
diff --git a/docs/diagrams/CreateCommandLogic.puml b/docs/diagrams/CreateCommandLogic.puml
new file mode 100644
index 00000000000..86638d4f50e
--- /dev/null
+++ b/docs/diagrams/CreateCommandLogic.puml
@@ -0,0 +1,70 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+box Logic LOGIC_COLOR_T1
+participant ":LogicManager" as LogicManager LOGIC_COLOR
+participant ":ImmuniMateParser" as ImmuniMateParser LOGIC_COLOR
+participant ":CreateCommandParser" as CreateCommandParser LOGIC_COLOR
+participant "c:CreateCommand" as CreateCommand LOGIC_COLOR
+participant "r:CommandResult" as CommandResult LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant "m:Model" as Model MODEL_COLOR
+participant "p:Person" as Person MODEL_COLOR
+end box
+
+[-> LogicManager : execute("create ...")
+activate LogicManager
+LogicManager -> ImmuniMateParser : parseCommand("create ...")
+activate ImmuniMateParser
+
+create CreateCommandParser
+ImmuniMateParser -> CreateCommandParser
+activate CreateCommandParser
+CreateCommandParser --> ImmuniMateParser
+deactivate CreateCommandParser
+ImmuniMateParser -> CreateCommandParser : parse("...")
+activate CreateCommandParser
+
+create Person
+CreateCommandParser -> Person
+activate Person
+Person --> CreateCommandParser
+deactivate Person
+
+create CreateCommand
+CreateCommandParser -> CreateCommand
+activate CreateCommand
+CreateCommand --> CreateCommandParser
+deactivate CreateCommand
+CreateCommandParser --> ImmuniMateParser : c
+deactivate CreateCommandParser
+'Hidden arrow to position the destroy marker below the end of the activation bar.
+CreateCommandParser -[hidden]-> ImmuniMateParser
+destroy CreateCommandParser
+ImmuniMateParser --> LogicManager : c
+deactivate ImmuniMateParser
+LogicManager -> CreateCommand : execute()
+activate CreateCommand
+CreateCommand -> Model : hasPerson(p)
+activate Model
+Model --> CreateCommand : false
+deactivate Model
+CreateCommand -> Model : addPerson(p)
+activate Model
+Model --> CreateCommand : add person in the model
+deactivate Model
+
+create CommandResult
+CreateCommand -> CommandResult
+activate CommandResult
+CommandResult --> CreateCommand
+deactivate
+CreateCommand --> LogicManager : r
+deactivate CreateCommand
+
+[<--LogicManager : r
+deactivate LogicManager
+@enduml
diff --git a/docs/diagrams/CreateCommandModel.puml b/docs/diagrams/CreateCommandModel.puml
new file mode 100644
index 00000000000..edd81b9bde2
--- /dev/null
+++ b/docs/diagrams/CreateCommandModel.puml
@@ -0,0 +1,82 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+box Logic LOGIC_COLOR_T1
+participant "l:Logic" as CreateCommand LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant ":ModelManager" as ModelManager MODEL_COLOR
+participant ":ImmuniMate" as ImmuniMate MODEL_COLOR
+participant ":UniquePersonList" as UniquePersonList MODEL_COLOR
+participant "internalList: ObservableList" as internalList MODEL_COLOR
+participant "p:Person" as p MODEL_COLOR
+end box
+
+[-> CreateCommand : execute()
+activate CreateCommand
+
+create p
+CreateCommand -> p
+activate p
+p --> CreateCommand
+deactivate p
+
+CreateCommand -> ModelManager : hasPerson(p)
+activate ModelManager
+
+ModelManager -> ImmuniMate: hasPerson(p)
+activate ImmuniMate
+
+ImmuniMate -> UniquePersonList : contains(p)
+activate UniquePersonList
+
+UniquePersonList -> internalList : stream().anyMatch(p::isSamePerson)
+activate internalList
+
+internalList -> p : isSamePerson()
+activate p
+
+p --> internalList
+deactivate p
+
+internalList --> UniquePersonList
+deactivate internalList
+
+UniquePersonList --> ImmuniMate
+deactivate UniquePersonList
+
+ImmuniMate --> ModelManager
+deactivate ImmuniMate
+
+ModelManager --> CreateCommand
+deactivate ModelManager
+
+CreateCommand -> ModelManager : addPerson(p)
+activate ModelManager
+
+ModelManager -> ImmuniMate: addPerson(p)
+activate ImmuniMate
+
+ImmuniMate -> UniquePersonList : add(p)
+activate UniquePersonList
+
+UniquePersonList -> internalList : add(p)
+activate internalList
+
+internalList --> UniquePersonList
+deactivate internalList
+
+UniquePersonList --> ImmuniMate
+deactivate UniquePersonList
+
+ImmuniMate --> ModelManager
+deactivate ImmuniMate
+
+ModelManager --> CreateCommand
+deactivate ModelManager
+
+[<--CreateCommand
+deactivate CreateCommand
+
+@enduml
diff --git a/docs/diagrams/DeleteInfoModelDiagram.puml b/docs/diagrams/DeleteInfoModelDiagram.puml
new file mode 100644
index 00000000000..8e5b84ceff1
--- /dev/null
+++ b/docs/diagrams/DeleteInfoModelDiagram.puml
@@ -0,0 +1,74 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+box Logic LOGIC_COLOR_T1
+participant "l:Logic" as CreateCommand LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant ":ModelManager" as ModelManager MODEL_COLOR
+participant ":ImmuniMate" as ImmuniMate MODEL_COLOR
+participant ":UniquePersonList" as UniquePersonList MODEL_COLOR
+participant "internalList: ObservableList" as internalList MODEL_COLOR
+participant "p1:Person" as p1 MODEL_COLOR
+participant "p:Person" as p MODEL_COLOR
+end box
+
+[-> CreateCommand : execute()
+activate CreateCommand
+
+CreateCommand -> ModelManager : getFilteredPersonsList()
+activate ModelManager
+
+ModelManager --> CreateCommand : persons
+deactivate ModelManager
+
+CreateCommand -> ModelManager : hasPerson(...)
+activate ModelManager
+
+ModelManager -> ImmuniMate: hasPerson(p1)
+activate ImmuniMate
+
+ImmuniMate -> UniquePersonList : contains(p1)
+activate UniquePersonList
+
+UniquePersonList -> internalList : stream().anyMatch(p1::isSamePerson)
+activate internalList
+
+internalList -> p1 : isSamePerson(p1)
+activate p1
+
+p1 --> internalList : true
+deactivate p1
+
+internalList --> UniquePersonList : true
+deactivate internalList
+
+UniquePersonList --> ImmuniMate : true
+deactivate UniquePersonList
+
+ImmuniMate --> ModelManager : true
+deactivate ImmuniMate
+
+ModelManager --> CreateCommand : true
+deactivate ModelManager
+
+CreateCommand -> ModelManager : getFilteredPersonList()
+activate ModelManager
+ModelManager --> CreateCommand : internalList
+deactivate ModelManager
+
+CreateCommand -> internalList : filtered().get(0)
+activate internalList
+internalList --> CreateCommand : p
+deactivate internalList
+
+CreateCommand -> p : setEmail(null)
+activate p
+p --> CreateCommand : set email to null
+deactivate p
+
+[<--CreateCommand
+deactivate CreateCommand
+
+@enduml
diff --git a/docs/diagrams/DeleteInfoSequenceDiagram.puml b/docs/diagrams/DeleteInfoSequenceDiagram.puml
new file mode 100644
index 00000000000..d2dbd322ed0
--- /dev/null
+++ b/docs/diagrams/DeleteInfoSequenceDiagram.puml
@@ -0,0 +1,87 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+box Logic LOGIC_COLOR_T1
+participant ":LogicManager" as LogicManager LOGIC_COLOR
+participant ":ImmuniMateParser" as ImmuniMateParser LOGIC_COLOR
+participant ":DeleteInfoCommandParser" as DeleteInfoCommandParser LOGIC_COLOR
+participant "d:DeleteInfoCommand" as DeleteInfoCommand LOGIC_COLOR
+participant "r:CommandResult" as CommandResult LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant "m:Model" as Model MODEL_COLOR
+participant "p:Person" as Person MODEL_COLOR
+end box
+
+[-> LogicManager : execute("deleteinfo S1234567X e/")
+activate LogicManager
+
+LogicManager -> ImmuniMateParser : parseCommand("deleteinfo S1234567X e/")
+activate ImmuniMateParser
+
+create DeleteInfoCommandParser
+ImmuniMateParser -> DeleteInfoCommandParser
+activate DeleteInfoCommandParser
+
+DeleteInfoCommandParser --> ImmuniMateParser
+deactivate DeleteInfoCommandParser
+
+ImmuniMateParser -> DeleteInfoCommandParser : parse("S1234567X e/")
+activate DeleteInfoCommandParser
+
+create DeleteInfoCommand
+DeleteInfoCommandParser -> DeleteInfoCommand
+activate DeleteInfoCommand
+
+DeleteInfoCommand --> DeleteInfoCommandParser :
+deactivate DeleteInfoCommand
+
+DeleteInfoCommandParser --> ImmuniMateParser : d
+deactivate DeleteInfoCommandParser
+'Hidden arrow to position the destroy marker below the end of the activation bar.
+DeleteInfoCommandParser -[hidden]-> ImmuniMateParser
+destroy DeleteInfoCommandParser
+
+ImmuniMateParser --> LogicManager : d
+deactivate ImmuniMateParser
+
+LogicManager -> DeleteInfoCommand : execute(m)
+activate DeleteInfoCommand
+
+DeleteInfoCommand -> Model : getFilteredPersonsList()
+activate Model
+
+Model --> DeleteInfoCommand : persons
+deactivate Model
+
+DeleteInfoCommand -> Model : hasPerson(...)
+activate Model
+
+Model --> DeleteInfoCommand : true
+deactivate Model
+
+DeleteInfoCommand -> Model : getFilteredPersonList().filtered().get(0)
+activate Model
+Model --> DeleteInfoCommand : p
+deactivate Model
+
+DeleteInfoCommand -> Person : setEmail(null)
+activate Person
+Person --> DeleteInfoCommand : set email of specified person to null
+deactivate Person
+
+create CommandResult
+DeleteInfoCommand -> CommandResult
+activate CommandResult
+
+CommandResult --> DeleteInfoCommand
+deactivate CommandResult
+
+DeleteInfoCommand --> LogicManager : r
+deactivate DeleteInfoCommand
+
+[<--LogicManager
+deactivate LogicManager
+@enduml
diff --git a/docs/diagrams/DeleteModelDiagram.puml b/docs/diagrams/DeleteModelDiagram.puml
new file mode 100644
index 00000000000..487a1072cbc
--- /dev/null
+++ b/docs/diagrams/DeleteModelDiagram.puml
@@ -0,0 +1,76 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+box Logic LOGIC_COLOR_T1
+participant "l:Logic" as Logic LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant ":ModelManager" as ModelManager MODEL_COLOR
+participant ":ImmuniMate" as ImmuniMate MODEL_COLOR
+participant ":UniquePersonList" as UniquePersonList MODEL_COLOR
+participant "internalList: ObservableList" as internalList MODEL_COLOR
+participant "p:Person" as p MODEL_COLOR
+end box
+
+[-> Logic : execute()
+activate Logic
+
+Logic -> ModelManager : hasPerson(p)
+activate ModelManager
+
+ModelManager -> ImmuniMate: hasPerson(p)
+activate ImmuniMate
+
+ImmuniMate --> UniquePersonList : contains(p)
+activate UniquePersonList
+
+UniquePersonList -> internalList : stream().anyMatch(p::isSamePerson)
+activate internalList
+
+internalList -> p : isSamePerson(p)
+activate p
+
+p --> internalList
+deactivate p
+
+internalList --> UniquePersonList
+deactivate internalList
+
+UniquePersonList --> ImmuniMate
+deactivate UniquePersonList
+
+ImmuniMate --> ModelManager
+deactivate ImmuniMate
+
+ModelManager --> Logic
+deactivate ModelManager
+
+Logic -> ModelManager : deletePerson(p)
+activate ModelManager
+
+ModelManager -> ImmuniMate: deletePerson(p)
+activate ImmuniMate
+
+ImmuniMate -> UniquePersonList : remove(p)
+activate UniquePersonList
+
+UniquePersonList -> internalList : remove(p)
+activate internalList
+
+internalList --> UniquePersonList
+deactivate internalList
+
+UniquePersonList --> ImmuniMate
+deactivate UniquePersonList
+
+ImmuniMate --> ModelManager
+deactivate ImmuniMate
+
+ModelManager --> Logic
+deactivate ModelManager
+
+[<--Logic
+deactivate Logic
+
+@enduml
diff --git a/docs/diagrams/DeleteSequenceDiagram.puml b/docs/diagrams/DeleteSequenceDiagram.puml
index 5241e79d7da..d8bbded95b4 100644
--- a/docs/diagrams/DeleteSequenceDiagram.puml
+++ b/docs/diagrams/DeleteSequenceDiagram.puml
@@ -4,7 +4,7 @@ skinparam ArrowFontStyle plain
box Logic LOGIC_COLOR_T1
participant ":LogicManager" as LogicManager LOGIC_COLOR
-participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
+participant ":ImmuniMateParser" as ImmuniMateParser LOGIC_COLOR
participant ":DeleteCommandParser" as DeleteCommandParser LOGIC_COLOR
participant "d:DeleteCommand" as DeleteCommand LOGIC_COLOR
participant "r:CommandResult" as CommandResult LOGIC_COLOR
@@ -14,20 +14,20 @@ box Model MODEL_COLOR_T1
participant "m:Model" as Model MODEL_COLOR
end box
-[-> LogicManager : execute("delete 1")
+[-> LogicManager : execute("delete S1234567X")
activate LogicManager
-LogicManager -> AddressBookParser : parseCommand("delete 1")
-activate AddressBookParser
+LogicManager -> ImmuniMateParser : parseCommand("delete S1234567X")
+activate ImmuniMateParser
create DeleteCommandParser
-AddressBookParser -> DeleteCommandParser
+ImmuniMateParser -> DeleteCommandParser
activate DeleteCommandParser
-DeleteCommandParser --> AddressBookParser
+DeleteCommandParser --> ImmuniMateParser
deactivate DeleteCommandParser
-AddressBookParser -> DeleteCommandParser : parse("1")
+ImmuniMateParser -> DeleteCommandParser : parse("S1234567X")
activate DeleteCommandParser
create DeleteCommand
@@ -37,22 +37,25 @@ activate DeleteCommand
DeleteCommand --> DeleteCommandParser :
deactivate DeleteCommand
-DeleteCommandParser --> AddressBookParser : d
+DeleteCommandParser --> ImmuniMateParser : d
deactivate DeleteCommandParser
'Hidden arrow to position the destroy marker below the end of the activation bar.
-DeleteCommandParser -[hidden]-> AddressBookParser
+DeleteCommandParser -[hidden]-> ImmuniMateParser
destroy DeleteCommandParser
-AddressBookParser --> LogicManager : d
-deactivate AddressBookParser
+ImmuniMateParser --> LogicManager : d
+deactivate ImmuniMateParser
LogicManager -> DeleteCommand : execute(m)
activate DeleteCommand
-DeleteCommand -> Model : deletePerson(1)
+DeleteCommand -> Model : hasPerson(...)
activate Model
-
-Model --> DeleteCommand
+Model --> DeleteCommand : true
+deactivate Model
+DeleteCommand -> Model : deletePerson(...)
+activate Model
+Model --> DeleteCommand : delete specified person
deactivate Model
create CommandResult
diff --git a/docs/diagrams/FindLogicModelDiagram.puml b/docs/diagrams/FindLogicModelDiagram.puml
new file mode 100644
index 00000000000..b4a0b230803
--- /dev/null
+++ b/docs/diagrams/FindLogicModelDiagram.puml
@@ -0,0 +1,59 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+box Logic LOGIC_COLOR_T1
+participant ":LogicManager" as LogicManager LOGIC_COLOR
+participant ":ImmuniMateParser" as ImmuniMateParser LOGIC_COLOR
+participant ":FindCommandParser" as FindCommandParser LOGIC_COLOR
+participant "f:FindCommand" as FindCommand LOGIC_COLOR
+participant "r:CommandResult" as CommandResult LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant "m:Model" as Model MODEL_COLOR
+end box
+
+[-> LogicManager : execute("find ...")
+activate LogicManager
+LogicManager -> ImmuniMateParser : parseCommand("find ...")
+activate ImmuniMateParser
+
+create FindCommandParser
+ImmuniMateParser -> FindCommandParser
+activate FindCommandParser
+FindCommandParser --> ImmuniMateParser
+deactivate FindCommandParser
+ImmuniMateParser -> FindCommandParser : parse("...")
+activate FindCommandParser
+
+create FindCommand
+FindCommandParser -> FindCommand
+activate FindCommand
+FindCommand --> FindCommandParser
+deactivate FindCommand
+FindCommandParser --> ImmuniMateParser : f
+deactivate FindCommandParser
+'Hidden arrow to position the destroy marker below the end of the activation bar.
+FindCommandParser -[hidden]-> ImmuniMateParser
+destroy FindCommandParser
+ImmuniMateParser --> LogicManager : f
+deactivate ImmuniMateParser
+LogicManager -> FindCommand : execute(m)
+activate FindCommand
+FindCommand -> Model : updateFilteredPersonList(...)
+activate Model
+Model --> FindCommand
+deactivate Model
+
+create CommandResult
+FindCommand -> CommandResult
+activate CommandResult
+CommandResult --> FindCommand
+deactivate
+FindCommand --> LogicManager : r
+deactivate FindCommand
+
+[<--LogicManager : r
+deactivate LogicManager
+@enduml
diff --git a/docs/diagrams/ModelClassDiagram.puml b/docs/diagrams/ModelClassDiagram.puml
index 0de5673070d..e65d736d024 100644
--- a/docs/diagrams/ModelClassDiagram.puml
+++ b/docs/diagrams/ModelClassDiagram.puml
@@ -5,20 +5,33 @@ skinparam arrowColor MODEL_COLOR
skinparam classBackgroundColor MODEL_COLOR
Package Model as ModelPackage <>{
-Class "<>\nReadOnlyAddressBook" as ReadOnlyAddressBook
+Class "<>\nReadOnlyImmuniMate" as ReadOnlyImmuniMate
Class "<>\nReadOnlyUserPrefs" as ReadOnlyUserPrefs
Class "<>\nModel" as Model
-Class AddressBook
+Class ImmuniMate
Class ModelManager
Class UserPrefs
-
Class UniquePersonList
+Class UniqueVisitList
Class Person
Class Address
-Class Email
Class Name
Class Phone
-Class Tag
+Class Nric
+Class DateOfBirth
+Class Sex
+Class Status
+Class Email
+Class Country
+Class Allergies
+Class BloodType
+Class Condition
+Class DateOfAdmission
+Class Diagnosis
+Class Symptom
+Class Visit
+Class DateOfVisit
+
Class I #FFFFFF
}
@@ -26,29 +39,54 @@ Class I #FFFFFF
Class HiddenOutside #FFFFFF
HiddenOutside ..> Model
-AddressBook .up.|> ReadOnlyAddressBook
+ImmuniMate .up.|> ReadOnlyImmuniMate
ModelManager .up.|> Model
Model .right.> ReadOnlyUserPrefs
-Model .left.> ReadOnlyAddressBook
-ModelManager -left-> "1" AddressBook
+Model .left.> ReadOnlyImmuniMate
+ModelManager -left-> "1" ImmuniMate
ModelManager -right-> "1" UserPrefs
UserPrefs .up.|> ReadOnlyUserPrefs
-AddressBook *--> "1" UniquePersonList
+ImmuniMate *--> "1" UniquePersonList
+ImmuniMate *--> "1" UniqueVisitList
UniquePersonList --> "~* all" Person
-Person *--> Name
-Person *--> Phone
-Person *--> Email
-Person *--> Address
-Person *--> "*" Tag
+UniqueVisitList --> "~* all" Visit
+Person *--> "1" Nric
+Person *--> "1" Name
+Person *--> "1" Phone
+Person *--> "1" Address
+Person *--> "1" DateOfBirth
+Person *--> "1" Sex
+Person *--> "1" Status
+
+Person *--> "0..1" Email
+Person *--> "0..1" Country
+Person *--> "0..1" Allergies
+Person *--> "0..1" BloodType
+Person *--> "0..1" Condition
+Person *--> "0..1" DateOfAdmission
+Person *--> "0..1" Diagnosis
+Person *--> "0..1" Symptom
+
+Visit *--> "1" DateOfVisit
+Visit *--> "1" Nric
+Visit *--> "1" Diagnosis
+Visit *--> "1" Symptom
+Visit *--> "1" Status
+
Person -[hidden]up--> I
UniquePersonList -[hidden]right-> I
+Nric -[hidden]right-> Name
Name -[hidden]right-> Phone
Phone -[hidden]right-> Address
-Address -[hidden]right-> Email
+Address -[hidden]right-> DateOfBirth
+DateOfBirth -[hidden]right-> Sex
+Sex -[hidden]right-> Status
ModelManager --> "~* filtered" Person
+ModelManager --> "~* filtered" Visit
@enduml
+
diff --git a/docs/diagrams/ParserClasses.puml b/docs/diagrams/ParserClasses.puml
index ce4c5ce8c8d..2080e0b626f 100644
--- a/docs/diagrams/ParserClasses.puml
+++ b/docs/diagrams/ParserClasses.puml
@@ -9,7 +9,7 @@ Class XYZCommand
package "Parser classes"{
Class "<>\nParser" as Parser
-Class AddressBookParser
+Class ImmuniMateParser
Class XYZCommandParser
Class CliSyntax
Class ParserUtil
@@ -19,12 +19,12 @@ Class Prefix
}
Class HiddenOutside #FFFFFF
-HiddenOutside ..> AddressBookParser
+HiddenOutside ..> ImmuniMateParser
-AddressBookParser .down.> XYZCommandParser: <>
+ImmuniMateParser .down.> XYZCommandParser: <>
XYZCommandParser ..> XYZCommand : <>
-AddressBookParser ..> Command : <