---
layout: page
title: Developer Guide
---
* Table of Contents
{:toc}
--------------------------------------------------------------------------------------------------------------------
## **Setting up, getting started**
Refer to the guide [_Setting up and getting started_](SettingUp.md).
--------------------------------------------------------------------------------------------------------------------
## **Design**
### Architecture
<img src="images/ArchitectureDiagram.png" width="450" />
The ***Architecture Diagram*** given above explains the high-level design of the App. Given below is a quick overview of each component.
<div markdown="span" class="alert alert-primary">
:bulb: **Tip:** The `.puml` files used to create diagrams in this document can be found in the [diagrams](https://github.com/se-edu/addressbook-level3/tree/master/docs/diagrams/) folder. Refer to the [_PlantUML Tutorial_ at se-edu/guides](https://se-education.org/guides/tutorials/plantUml.html) to learn how to create and edit diagrams.
</div>
**`Main`** has two classes called [`Main`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/Main.java) and [`MainApp`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/MainApp.java). It is responsible for,
* At app launch: Initializes the components in the correct sequence, and connects them up with each other.
* At shut down: Shuts down the components and invokes cleanup methods where necessary.
[**`Commons`**](#common-classes) represents a collection of classes used by multiple other components.
The rest of the App consists of four components.
* [**`UI`**](#ui-component): The UI of the App.
* [**`Logic`**](#logic-component): The command executor.
* [**`Model`**](#model-component): Holds the data of the App in memory.
* [**`Storage`**](#storage-component): Reads data from, and writes data to, the hard disk.
Each of the four components,
* defines its *API* in an `interface` with the same name as the Component.
* exposes its functionality using a concrete `{Component Name}Manager` class (which implements the corresponding API `interface` mentioned in the previous point.
For example, the `Logic` component (see the class diagram given below) defines its API in the `Logic.java` interface and exposes its functionality using the `LogicManager.java` class which implements the `Logic` interface.

**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`.
<img src="images/ArchitectureSequenceDiagram.png" width="574" />
The sections below give more details of each component.
### UI component

**API** :
[`Ui.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/Ui.java)
The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `PersonListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class.
The `UI` component uses JavaFx UI framework. The layout of these UI parts are defined in matching `.fxml` files that are in the `src/main/resources/view` folder. For example, the layout of the [`MainWindow`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/MainWindow.java) is specified in [`MainWindow.fxml`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/resources/view/MainWindow.fxml)
The `UI` component,
* Executes user commands using the `Logic` component.
* Listens for changes to `Model` data so that the UI can be updated with the modified data.
### Logic component

**API** :
[`Logic.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/logic/Logic.java)
1. `Logic` uses the `AddressBookParser` class to parse the user command.
1. This results in a `Command` object which is executed by the `LogicManager`.
1. The command execution can affect the `Model` (e.g. adding a person).
1. The result of the command execution is encapsulated as a `CommandResult` object which is passed back to the `Ui`.
1. In addition, the `CommandResult` object can also instruct the `Ui` to perform certain actions, such as displaying help to the user.
Given below is the Sequence Diagram for interactions within the `Logic` component for the `execute("delete 1")` API call.

<div markdown="span" class="alert alert-info">:information_source: **Note:** The lifeline for `DeleteCommandParser` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
</div>
### Model component

**API** : [`Model.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/model/Model.java)
The `Model`,
* stores a `UserPref` object that represents the user’s preferences.
* stores the address book data.
* exposes an unmodifiable `ObservableList<Person>` that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change.
* does not depend on any of the other three components.
<div markdown="span" class="alert alert-info">: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` object.<br>

</div>
### Storage component

**API** : [`Storage.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/storage/Storage.java)
The `Storage` component,
* can save `UserPref` objects in json format and read it back.
* can save the address book data in json format and read it back.
### Common classes
Classes used by multiple components are in the `seedu.addressbook.commons` package.
--------------------------------------------------------------------------------------------------------------------
## **Implementation**
This section describes some noteworthy details on how certain features are implemented.
### \[Proposed\] Undo/redo feature
#### Proposed Implementation
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:
* `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.
These operations are exposed in the `Model` interface as `Model#commitAddressBook()`, `Model#undoAddressBook()` and `Model#redoAddressBook()` respectively.
Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
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.

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.

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`.

<div markdown="span" class="alert alert-info">: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`.
</div>
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.

<div markdown="span" class="alert alert-info">: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.
</div>
The following sequence diagram shows how the undo operation works:

<div markdown="span" class="alert alert-info">: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.
</div>
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.
<div markdown="span" class="alert alert-info">: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.
</div>
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 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.

The following activity diagram summarizes what happens when a user executes a new command:

#### Design consideration:
##### Aspect: How undo & redo executes
* **Alternative 1 (current choice):** Saves the entire address book.
* Pros: Easy to implement.
* Cons: May have performance issues in terms of memory usage.
* **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.
_{more aspects and alternatives to be added}_
### \[Proposed\] Data archiving
_{Explain here how the data archiving feature will be implemented}_
--------------------------------------------------------------------------------------------------------------------
## **Documentation, logging, testing, configuration, dev-ops**
* [Documentation guide](Documentation.md)
* [Testing guide](Testing.md)
* [Logging guide](Logging.md)
* [Configuration guide](Configuration.md)
* [DevOps guide](DevOps.md)
--------------------------------------------------------------------------------------------------------------------
## **Appendix: Requirements**
### Product scope
**Target user profile**:
Nina works as a housing service management officer for a Residential College* (in NUS). She is the sole manager of the office. She:
* has to manage a large number of residents and rooms (> 600)
* needs to efficiently assign rooms to residents
* handles room allocation exercise every semester
* needs to track room issues reported by students during the semester
* needs to update the issue lifecycle (reported => maintenance ongoing => fixed/closed)
* prefers typing over interacting via GUI
**Value proposition**: manage residents, rooms, and allocations faster than a typical GUI app.
### 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 if I forget how to use the app |
| `* * *` | confused user | have a help command | learn how to use the application |
| `* * *` | user | add a new person | |
| `* * *` | user | add issues | |
| `* * *` | user | see a list of pending tasks sorted by deadline | prioritise which to do |
| `* * *` | user | search for tasks | |
| `* * *` | user | close issues | focus on open issues |
| `* * *` | user | update issues | |
| `* * *` | user | remove issues | |
| `* * *` | user | add residents | |
| `* * *` | user | search for residents | |
| `* * *` | user | update resident details | ensure their information is up to date |
| `* * *` | user | remove residents | |
| `* * *` | user | add new rooms | |
| `* * *` | user | see a list of rooms with their statuses | know which rooms are available |
| `* * *` | user | search for rooms | |
| `* * *` | user | update room details | |
| `* * *` | user | remove rooms | |
| `* *` | user | see both available rooms and unassigned residents side by side | easily match residents to rooms |
| `* *` | careless user | undo previous commands | easily fix any errors I might make |
| `* *` | careless user | redo previous commands | easily fix an erroneous undo |
| `* * *` | user | allocate a resident to a room | |
| `* * *` | user | deallocate a resident from a room | |
## Use cases
(For all use cases below, the **System** is the `SunRez` and the **Actor** is the `user`, unless specified otherwise. All Use Cases are prefixed with `UC` followed by a 3 digit code)
### UC-001 Add a resident
**MSS**
1. User requests to add a specific resident to the list.
2. SunRez adds the resident and saves the changes.
Use case ends.
**Extensions**
* 1a. The resident's details are incorrectly formatted (e.g phone number/email/year format does not conform, OR room number is invalid).
* 1a1. SunRez displays an error stating which field is incorrectly formatted and requests the user to try again after fixing the stated error.
Use case ends.
* 1b. The resident's phone number or email are in use by an existing resident.
* 1b1. SunRez displays an error stating which field is already in use and requests the user to try again after fixing the stated error.
Use case ends.
* 2a. Sunrez encounters an error while saving the content.
* 2a1. SunRez shows an error message and requests the user to try their command again.
Use case ends.
### UC-002 List all residents
**MSS**
1. User requests to list residents.
2. SunRez shows a list of residents.
Use case ends.
**Extensions**
* 2a. The list is empty.
Use case ends.
### UC-003 Find residents
**MSS**
1. User searches for a resident by keywords.
2. SunRez shows a list of residents whose name contain any of the keywords.
Use case ends.
**Extensions**
* 2a. There are no residents matching the keywords.
* 2a1. An empty list is displayed.
Use case ends.
### UC-004 Edit a resident record
**MSS**
1. User requests to list residents.
2. SunRez shows a list of residents.
3. User requests to edit a specific resident based on the index from the list displayed in step 2.
4. SunRez edits the residents and saves the changes.
Use case ends.
**Extensions**
* 2a. The list of residents is empty.
Use case ends.
* 3a. The resident's details are invalid (e.g phone number/email/dob format does not conform, OR room number is invalid).
* 3a1. SunRez shows an error message stating which field is incorrectly formatted and requests the user to try again.
Use case resumes at step 2.
### UC-005 Delete a resident
**MSS**
1. User requests to list residents.
2. SunRez shows a list of residents.
3. User requests to delete a specific resident based on the index from the list displayed in step 2.
4. SunRez deletes the specified resident and saves the changes.
Use case ends.
**Extensions**
* 2a. The list of residents is empty.
Use case ends.
* 3a. The specified resident does not exist.
* SunRez shows an error message.
Use case resumes at step 2.
### UC-006 Add a room
**MSS**
1. User requests to add a specific room to the list.
2. SunRez adds the room and saves the changes.
Use case ends.
**Extensions**
* 1a. The room's details are invalid (e.g room number format is not valid).
* 1a1. SunRez shows an error stating which field is incorrectly formatted and requests the user to try again after fixing the stated error.
Use case ends.
### UC-007 List all rooms
Similar to *UC-002 List all residents*, just replace residents with rooms.
### UC-008 Find rooms
Similar to *UC-003 Find residents*, just replace resident with room.
### UC-009 Edit a room record
**MSS**
1. User requests to list rooms.
2. SunRez shows a list of rooms.
3. User requests to edit a specific room based on the index from the list displayed in step 2.
4. SunRez edits the room and saves the changes.
Use case ends.
**Extensions**
* 2a. The list of rooms is empty.
Use case ends.
* 3a. The room's details are invalid (e.g room number format is not valid).
* 3a1. SunRez shows an error message stating which field is incorrectly formatted and requests the user to try again.
Use case resumes at step 2.
### UC-010 Delete a room
Similar to *UC-005 Delete a resident*, just replace resident with room.
### UC-011 Add an open issue
**MSS**
1. User requests to add a specific open issue to the list.
2. SunRez adds the issue and saves the changes.
Use case ends.
**Extensions**
* 1a. The issue's details are invalid (e.g invalid room number).
* 1a1. SunRez shows an error stating which field is incorrectly formatted and requests the user to try again after fixing the stated error.
Use case ends.
### UC-012 List all issues
Similar to *UC-002 List all residents*, just replace residents with issues.
### UC-013 Find issues
Similar to *UC-003 Find residents*, just replace residents with issues.
### UC-014 Edit an issue record
**MSS**
1. User requests to list issues.
2. SunRez shows a list of issues.
3. User requests to edit a specific issue based on the index from the list displayed in step 2.
4. SunRez edits the issue and saves the changes.
Use case ends.
**Extensions**
* 2a. The list of issue is empty.
Use case ends.
* 3a. The issue's details are invalid (e.g invalid room number).
* 3a1. SunRez shows an error message stating which field is incorrectly formatted and requests the user to try again.
Use case resumes at step 2.
### UC-015 Close an issue
**MSS**
1. User requests to list issues.
2. SunRez shows a list of issues.
3. User requests to mark a specific issue as closed based on the index from the list displayed in step 2.
4. SunRez marks the issue as closed and saves the changes.
Use case ends.
**Extensions**
* 2a. The list is empty.
Use case ends.
* 3a. The given index is invalid.
* 3a1. SunRez shows an error message.
Use case resumes at step 2.
### UC-016 Delete an issue
Similar to *UC-005 Delete a resident*, just replace resident with issue.
### UC-017 Undo Previous Command
**MSS**
1. User requests to undo previous command.
2. Previous command is undone and SunRez's state is reverted to before that command.
Use case ends.
**Extensions**
* 1a. There are no previous commands that change state.
* 1a1 SunRez shows an error message.
Use case ends.
### UC-018 Redo Previous Command
**MSS**
1. User requests to redo previously undone command.
2. Previous undone command is redone and SunRez's state is updated accordingly.
Use case ends.
**Extensions**
* 1a. There are no previously undone commands.
* 1a1 SunRez shows an error message.
Use case ends.
### UC-019 Allocate a Room
**MSS**
1. User requests to list unassigned residents and unallocated rooms.
2. SunRez displays unassigned residents and unallocated rooms side-by-side.
3. User requests to allocate a room to a resident.
4. SunRez allocates the room and saves the changes.
**Extensions**
* 2a. There are no unassigned residents or unassigned.
Use case ends.
* 3a. The given index is invalid.
* 3a1. SunRez shows an error message.
Use case resumes at step 2.
### UC-020 Deallocate a Room
**MSS**
1. User requests to list room allocations.
2. SunRez displays rooms, each with its corresponding allocated resident.
3. User requests to deallocate a room based on the index from the list displayed in step 2.
4. SunRez deallocates the room and saves the changes.
**Extensions**
* 2a. There are no unassigned residents or unassigned.
Use case ends.
* 3a. The given index is invalid.
* 3a1. SunRez shows an error message.
Use case resumes at step 2.
## 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 records (residents, rooms and issues) 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.
4. A user should be able to learn the basic commands within half an hour of initial usage.
5. Should work without the internet.
6. Should be a highly portable to enable transfer between different computers with different OS.
7. Executable program should occupy less than 20MB on the computer.
8. Should not require an installer.
9. The data should not be stored in a Database Management System (DBMS).
10. Should not depend on any remote server.
*{More to be added}*
### Glossary
* **Mainstream OS**: Windows, Linux, Unix, OS-X
* **Residential College (RC)**: A university residence for students that offers a 2-year program at NUS
* **NUS**: The National University of Singapore
* **Resident**: A university student staying in the Residential College
* **Issue**: A maintenance problem that concerns the condition of a room
--------------------------------------------------------------------------------------------------------------------
## **Appendix: Instructions for manual testing**
Given below are instructions to test the app manually.
<div markdown="span" class="alert alert-info">:information_source: **Note:** These instructions only provide a starting point for testers to work on;
testers are expected to do more *exploratory* testing.
</div>
### Launch and shutdown
1. Initial launch
1. Download the jar file and copy into an empty folder
2. Double-click the jar file Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
2. Saving window preferences
1. Resize the window to an optimum size. Move the window to a different location. Close the window.
2. Re-launch the app by double-clicking the jar file.<br>
Expected: The most recent window size and location is retained.
3. _{ 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}_
2. _{ more test cases … }_