PROJECT: The Real App


Overview

The Real App is an enhanced desktop address book designed primarily for real estate agents. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC.

Summary of contributions

  • Major Enhancement: Added the ability to archive/unarchive contacts

    • Related commands: archive, archivelist, archiveselect, archiveclear, unarchive

    • What it does:

      • Allows the user to archive existing contacts which are deleted from the main working contact book, but kept as storage which can be displayed, or even unarchived when needed in the future.

    • Justification:

      • This feature improves the product significantly because users who want to remove their contacts can remove them from their main contact book without permanently deleting them.

      • They can keep these contacts in a separate archive storage in case of future need, and these archived contacts can be restored back into the main contact book when needed.

    • Highlights:

      • This enhancement affects almost all existing commands and new commands to be added in future. Each command has be to defined whether the main address book list or the archive list is displayed before and/or after the execution of the command.

      • It required an in-depth analysis of design alternatives.

      • The implementation too was challenging as it required modifications to existing commands, especially the undo/redo commands.

    • Credits:

      • Existing implementation of the AddressBook storage in AddressBook-Level4 was used to create the ArchiveBook storage.

  • Minor Enhancements:

    • Added a Google Maps query in the browser panel that allows the user to view the location of a selected contact’s address on Google Maps.

    • Refined the selection of contacts across all features.

  • Code contributed: [Project Code Dashboard]

  • Other contributions:

    • Project management:

      • Managed releases v1.1 - v1.4 (4 releases) on GitHub

      • Tracked issues and milestones on GitHub

    • Enhancements to existing features:

      • Updated the GUI color scheme: #86

      • Wrote tests for new and existing features to increase coverage from 79% to 86% (Pull requests #144, #147, #149)

    • Documentation:

      • Ported all commands (basic form) and the command summary into the User Guide: #16, #23, #34

      • Ported all User Stories and Use Cases into the Developer Guide: #16, #17, #23, #34

      • Set up 'About Us', 'Contact Us' and 'README': #3, #15

    • Community:

      • Reported bugs and suggestions for other teams in the class (examples: 1, 2, 3)

Contributions to the User Guide

Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users. The following only contains an abbreviated version of the archive and select related features. Refer to the full User Guide for more details.

Archiving a contact : archive

Moves the specified contact from the main contact book to the archive book.
Archived contacts can only be accessed through the archivelist command.
Format: archive INDEX

Archived contacts cannot be pinned, deleted individually or displayed in a sorted list.
Unarchive a contact before performing those commands.

  • Main contact list must be displayed prior to archiving.

  • Archives the contact at the specified INDEX.

  • The index refers to the index number shown in the displayed contact list.

  • The index must be a positive integer 1, 2, 3, …​

Examples:

  • list
    archive 2
    Archives the 2nd contact in the contact book.

  • search James
    archive 1
    Archives the 1st contact in the results of the search command.

  • search seller
    archive 3
    Archives the 3rd contact in the results of the search command.

Screenshots for 1st example:

  • Enter list:

archive screenshot 1
  • Main contact list is successfully displayed:

archive screenshot 2
  • Enter archive 2:

archive screenshot 3
  • The 2nd contact, Bernard Chan, in the main contact list has been successfully archived:

archive screenshot 4

Listing all archived contacts : archivelist

Lists all the contacts in the archive book, in their archived chronological order.
Format: archivelist

Screenshots (following the 1st example of archive) :

  • Enter archivelist:

archive screenshot 5
  • The archive list is successfully displayed (and the contact archived, Bernard Chan, can be found!):

archive screenshot 6

Selecting an archived contact : archiveselect

Selects the archived contact identified by the index number used in the displayed archive list.
Format: archiveselect INDEX

  • Archive list must be displayed prior to this.

  • Selects the contact at the specified INDEX and displays the address location of the associated property on the Google Maps™ browser window panel.

  • The index refers to the index number shown in the displayed contact list.

  • The index must be a positive integer 1, 2, 3, …​

Go to Displaying location on Google Maps™ for more details on the Google Maps™ display.

Examples:

  • archivelist
    archiveselect 2
    Selects the 2nd contact in the archive book.

Selecting a contact : select

Selects the contact identified by the index number used in the displayed contact list.
Format: select INDEX

  • Selects the contact at the specified INDEX and displays the address location of the associated property (if applicable) on the Google Maps™ browser window panel.

  • The index refers to the index number shown in the displayed contact list.

  • The index must be a positive integer 1, 2, 3, …​

Go to Displaying location on Google Maps™ for more details on the Google Maps™ display.

Examples:

  • list
    select 2
    Selects the 2nd contact in the contact book.

  • search James
    select 1
    Selects the 1st contact in the results of the search command.

  • search seller
    select 3
    Selects the 3rd contact in the results of the search command.

Displaying location on Google Maps™

Double-clicking the contact will also select the contact and display the address location of the associated property on the Google Maps™ browser window panel.

  • As of v1.4,

    • Google Maps™ will search for the location of any address provided. If it is an invalid address that cannot be found on Google Maps™, Google Maps™ will simply return that the location cannot be found, just like in the browser version.

    • Once the map location is displayed, you will be able to input to the Google Maps™ search bar. Click the command box again to resume typing and entering of commands.

The screenshot below shows how selecting a contact using any of the select commands will work:

select screenshot

Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. The following only shows extracts of the User Stories and Use Cases related to the features I implemented. I also added Instructions for Manual Testing in Appendix F. Refer to the full Developer Guide for more details.

Archive features

Current Implementation

This section explains the implementation of all archive related features.

To implement the archive features, an archiveBook is created in the Model and Storage to facilitate the archiving of contacts. The archiveBook implements the AddressBook class in the Model since it works similarly, and has its own ArchiveBookStorage class in the Storage to facilitate the storage of a separate data file.

Archive/Unarchive

The following sequence diagram shows how the archive command operation works:

ArchiveSequenceDiagram

The unarchive command does the opposite — it calls addPerson(p) of the versionedAddressBook and removePerson(p) of the versionedArchiveBook instead.

Archive List

The archivelist command displays the list of persons in the archiveBook. This has to be carefully implemented to work hand-in-hand with the list of persons in the addressBook, as well as the list command.

More importantly, to have a separate archive list that can be swapped back and forth with the main list in the UI display requires careful designs and implementations in the Logic and Ui components.

Archive Select

The archiveselect command is implemented the same as 'select'.

When unarchive is performed on a person that has been selected by archiveselect, archiveselect is set to be null, so no person will be selected.

Archive Clear

The archiveclear command is implemented the same as clear where a new empty archiveBook is created by calling Model#setArchiveBook(new AddressBook()).

Select feature

Current Implementation

The select feature requires careful implementation:

  • As there are 3 separate lists (main contact list, archive list, pin list) that can be selected from, having a unique command for each list (i.e. select, archiveselect, pinselect) ensures that the person is selected from the correct list.

  • Only at most 1 person can be selected at any point in time from each list.

    • However, having 3 separate lists means that there will be overlapping selections which will cause errors in the Ui component in displaying the browser panel.

    • To avoid overlapping of selections from each of the select commands, previous selections from another list are set to null.

  • Adding and editing a person will select that person.

  • Deleting, archiving and unarchiving a selected contact will set the selection to null.

  • Changing lists will set the selected person in the list that is swapped away to be set to null.

  • Selection of a pinned person will remain regardless of which of the two lists are displayed.

Appendix A: User Stories

Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *

Priority As a …​ I want to …​ So that I can…​

* * *

clean user

archive contacts when I currently do not need them

keep contacts for later use

* * *

efficient user

see the list of contacts which I have archived

check which contacts I have in my archive

* * *

real estate agent

unarchive contacts

retrieve contacts which I need again

Appendix B: Use Cases

(For all use cases below, the System is the TheRealApp and the Actor is the User, unless specified otherwise)

Use case: Archive contact

MSS

  1. User requests to list contacts.

  2. TheRealApp shows a list of contacts.

  3. User requests to archive a specific contact in the list.

  4. TheRealApp archives the contact.

    Use case ends.

Extensions

  • 2a. The contact list is empty.

    Use case ends.

  • 3a. The given index is invalid.

    • 3a1. TheRealApp shows an error message.

      Use case resumes at step 3.

Use case: Display archived contact list

MSS

  1. User requests to list archived contacts.

  2. TheRealApp shows a list of archived contacts.

    Use case ends.

Extensions

  • 1a. The archived contact list is empty.

    Use case ends.

Use case: Select archived contact

MSS

  1. User requests to select an archived contact.

  2. TheRealApp selects the contact and shows the information of the archived contact.

    Use case ends.

Extensions

  • 1a. The given index is invalid.

    • 1a1. TheRealApp shows an error message.

      Use case resumes at step 1.

  • 1b. The list displayed is invalid.

    • 1b1. TheRealApp shows an error message.

    • 1b2. User requests for the valid list.

    • 1b3. TheRealApp displays the requested list.

      Use case resumes at step 1.

Use case: Search for archived contact

MSS

  1. User requests to search for an archived contact by entering keyword(s).

  2. TheRealApp shows a list of archived contacts with information containing the keywords(s).

    Use case ends.

Extensions

  • 1a. The keyword(s) is invalid.

    • 1a1. The RealApp shows an error message.

      Use case resumes from step 1.

  • 1b. The list displayed is invalid.

    • 1b1. TheRealApp shows an error message.

    • 1b2. User requests for the valid list.

    • 1b3. TheRealApp displays the requested list.

      Use case resumes at step 1.

Use case: Unarchive contact

MSS

  1. User requests to list archived contacts.

  2. TheRealApp shows a list of archived contacts.

  3. User requests to unarchive a specific contact in the archived list.

  4. TheRealApp unarchives the contact.

    Use case ends.

Extensions

  • 2a. The archived contact list is empty.

    Use case ends.

  • 3a. The given index is invalid.

    • 3a1. TheRealApp shows an error message.

      Use case resumes at step 3.

Use case: Clear archived contact list

MSS

  1. User requests to clear the archived contact list.

  2. TheRealApp clears the entire archived contact list.

    Use case ends.

    • 1a. The list displayed is invalid.

      • 1a1. TheRealApp shows an error message.

      • 1a2. User requests for the valid list.

      • 1a3. TheRealApp displays the requested list.

        Use case resumes at step 1.

PROJECT: PowerPointLabs