PROJECT: Heart²

This portfolio aims to document my contributions to the project Heart².

1. Overview

Heart² is a desktop wedding application for wedding planners to efficiently manage their clients and vendors. Heart² allows wedding planners to quickly find suitable clients and vendors by automatically matching them together based on the vendors' services and the client’s requirements. The user primarily interacts with Heart² through a CLI, and it has a GUI created with JavaFX. Heart² is written in Java, with about 10 kLoC.

2. Summary of contributions

2.1. Major enhancement 1:

Enabled support for two different types of contacts, clients and vendors, in Heart².

  • What it does:

Allows the user to be work with two different types of contacts using Heart².

  • Justification:

Heart² is made for wedding planners to efficiently manage their clients and vendors, two of their key stakeholders. Therefore, we chose to model the contacts in Heart² after clients and vendors.

  • Highlights:

    1. This enhancement serves a foundation of many features in Heart², including: add, delete, update, view, list, addservice and automatch.

    2. In Heart², the users are presented with two separated lists. However, in Heart², there is only one contact list for both clients and vendors. Filters are constantly applied to this contact list as commands are entered so as to maintain the illusion of a distinct list to the user.

    3. This enhancement required extensive refactoring of the codebase as the inherited, legacy code only supported a single contact. Heart² currently supports two types of contacts, and can easily be extended to support even more types of contacts with this enhancement.

2.2. Major enhancement 2:

Implemented unique IDs for contacts.

  • What it does:

Allows the user to refer to contacts by their unique IDs.

  • Justification:

The inherited implementation from AddressBook (Level 4) had users use the contact’s relative position in the currently shown list to refer to that contact. For our users to make use of their time most efficiently, we chose to have our users be able to refer to contacts using IDs, as opposed to the previous implementation.

In the previous, inherited implementation from AddressBook (Level 4), the user must ensure that the current list shown in the UI contains the contact and check the contact’s relative position on the list. With unique IDs for contacts, the context of the commands do not change, and this allows our users to know quickly the context of their commands and thus execute any command at any point of time in Heart².

With this unique ID system, our users are able to simplify and improve their workflow on Heart²,

  • Highlights:

    1. This enhancement serves as another foundation of many features in Heart², including: delete, update, view, addservice and automatch.

    2. Together with the contact type, it allows Heart² to be able to offer a very simple and intuitive command syntax.

      Commands pertaining to a contact type start with the contact type (client or vendor). More specific commands pertaining to a specific contact have the unique ID appended to the contact type.

2.3. Minor enhancement 1:

Updated the main parser that parses all commands entered by the user.

  • What it does:

Implements the command syntax enabled by the two previously mentioned enhancements.

  • Highlights:

    1. This enhancement although minor proved to be quite a challenge, because commands differ in their components.

      For example, help consists of just a word, client list consists of two words, vendor#3 delete consists of 2 words and the unique ID, and lastly client#1 update n/Wai Lun consists of 2 words, the unique ID and the parameters for the command.

      It required some research on regular expressions in Java and tinkering in JShell. In the end, only a single parser is used to parse and identify all of Heart² commands when they are entered by the user.

2.4. Minor enhancement 2:

Extended the add, delete, update and view commands in Heart².

  • What it does:

Gives functionality to the mentioned commands.

  • Highlights:

    1. This enhancement makes use of and relies on all three enhancements mentioned above.

    2. The text feedback to the user is customised based on the command entered by the user. Due to having two possibilities (client and vendor) for these commands, and in order avoid "hard-coding" every possible text feedback to the user, these text feedback use Java’s string formatting feature.

      With this, the text feedback can be easily extended for even more contact types if we choose to add more contact types in the future.

2.5. Code contributed:

As of 12 November 2018, I have contributed over 40 pull requests on Heart²'s GitHub.

The following pull requests are some examples of my code contribution, both functional and test code, to the Heart² project.

My full code contribution to Heart² can be viewed here.

2.6. Other contributions:

  1. Helped solve bug fixes in Heart².

  2. Helped with checking all documents for spelling and grammar mistakes.

  3. As of 12 November 2018:

    1. Reviewed 21 pull requests on Heart²'s Github.

    2. Raised 21 issues on Heart²'s Github.

  4. Restructured and generalised the commands regarding client and vendor in the user guide for a better reading experience.

  5. Participated actively in discussions regarding Heart² and its features.

3. Contributions to the User Guide

Given below are sections I contributed to the User Guide.

3.1. Working with a specific contact

Contacts in Heart² are assigned a unique ID each for you to refer to the contact at any point of time when using Heart².

Commands pertaining to one specific contact have an additional unique ID appended to the back of client or vendor.
These IDs are persistent for one session. Each restart of Heart reassigns IDs to contacts, effectively accounting for deleted contacts and compacting the IDs of your contacts.
IDs can be similar for client and vendor. However, since the contact type and ID come hand in hand, the contacts are still effectively unique!

3.1.1. Viewing a contact: view

You can view detailed information about a specific contact using its unique ID. This information will be displayed on the right panel in Heart².

view shows you all the information regarding the specific client, which includes the name, phone number, email address, tags, residential (client) or office (vendor) address and services requested (client) or offered (vendor).
Any command following view will hide the information shown before on the panel on the right.

Format: <CONTACT_TYPE>#<ID> view

exampleimage

client#3 view

exampleimage

vendor#3 view

Clicking on the contact panels on the left of Heart²'s GUI corresponds to a view command for that contact!

3.1.2. Deleting a contact: delete

You can also delete a contact from Heart², by specifying its unique ID.

Format: <CONTACT_TYPE>#<ID> delete

exampleimage

client#123 delete

exampleimage

vendor#123 delete

You can undo and redo deleting a contact!

3.1.3. Updating a contact: update

You can also update a contact’s particulars, again by specifying its unique ID, followed by the updated fields.

Format: <CONTACT_TYPE>#<ID> update [n/FULL_NAME] [p/PHONE_NUMBER] [e/EMAIL_ADDRESS] [a/HOME_ADDRESS] [t/TAG]…​

You cannot update a contact to another contact that already exists in the application. Two contacts are considered duplicates if they are the same type (either both clients or both vendors), possess the same name, and either the same phone number or the same email address.
When editing tags, adding of tags is not cumulative and existing tags of the contact will be removed.
You can remove all tags for a contact by updating the contact with t/ (without specifying any tags after it)!

exampleimage

client#123 update n/Jane Doe e/janedoe@gmail.com

exampleimage

vendor#123 update n/Bob Vans e/bobvans@gmail.com

You can undo and redo updating a contact!

4. Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide.

4.1. Unique ID feature

Heart² assigns a unique ID to every client and vendor when they are added into Heart². This ID is unique within their contact type, meaning that a client and a vendor may have the same ID, but since this ID comes hand in hand with the contact type, they are effectively unique. These IDs are last for a single session, and Heart² reassigns the IDs at the start of the next session.

4.1.1. Current Implementation

Both the Client and Vendor class have a public static running counter starting from 1. When a client or vendor is created, it is assigned that number, before incrementing it by 1. The contact then has this ID for this session, and the user can use this ID, coupled with the contact type to always refer to this particular contact.

This unique ID is used by many other commands, namely: add, delete, update, view, addservice, automatch. It allows for these commands to be executed at any point in Heart², with always the same context.

4.1.2. Design Considerations

Aspect: How should we refer to contacts in Heart²?
  • Alternative 1: Use the legacy implementation, which is to use the relative position of the contact in the list.

    • Pros: No change is required, as it is the legacy implementation.

    • Cons: Users have to navigate to a list that shows that contact, and the relative position of that contact may keep changing throughout a session.

  • Alternative 2 (current choice):

    • Pros: Users are able to refer back to a particular contact at any time, without requiring the current list shown to contain that contact. Also, this ID will never change during a session, so the user can confidently use the ID knowing that it will always refer to that contact.

    • Cons: Users still have to remember this unique ID to refer back to the contact. It might be hard to remember the ID.

After much consideration, we decided to go with option 2. Heart² is built for speed, and we would like to give our users flexibility to execute any command within Heart² at any time. We believe that this can give users more control and power over their work using Heart², and therefore we chose to implement this unique ID system.

However, we also do realise that users might find it hard to remember the unique ID assigned to the contact. While users can quickly look at a recent contact using the command history, a possibly quality-of-life improvement would be to implement a mnemonic unique identifier.

4.2. Add contact feature

Heart² requires users to explicitly specify whether the contact to be added is a client or a vendor in the command.

  • client add n/Wai Lun p/90463327 e/wailun@u.nus.edu a/PGP House

  • vendor add n/Lun Wai p/72336409 e/lunwai@u.nus.edu a/RVRC

The above commands add a client and a vendor, together with the details provided, respectively.

This differentiation between client and vendor facilitates many other features of Heart². It complements the unique ID feature earlier to ensure that a client and a vendor with the same ID are still differentiable due to the contact type.

Adding of duplicate contacts are not allowed in Heart².

A contact is considered a duplicate if they are of the same contact type and have the same name and have either the same phone number or email address.

4.2.1. Current Implementation

Both Client and Vendor classes inherit from an abstract Contact class. When adding a contact, either a new Client or a Vendor object is instantiated. Both Client and Vendor objects are added to a list of generic type Contact.

In order to differentiate them, there is an abstract method Contact#getType() that Client and Vendor implement differently. Client objects return a ContactType.CLIENT enum while Vendor objects return a ContactType.VENDOR enum.

When adding a contact, the parser first distinguishes whether it is an addition of a client or vendor. The correct ContactType enum is then passed to AddCommandParser. The AddCommandParser parses the argument to create the appropriate contact, and creates the appropriate AddCommand.

This AddCommand is passed back to the LogicManager, and the method execute() is called. The contact is then added to the model.

Below is the sequence diagram of a client add command.

AddClientSequenceDiagram

4.2.2. Design Considerations

Aspect: How should we store Client and Vendor objects in Heart²?
  • Alternative 1 (current choice): Client and Vendor objects are stored in a more general Contact list.

    • Pros: Easy to implement by tweak the inherited legacy list slightly.

    • Cons: Cannot tell immediately if an element in the Contact list is a Client or Vendor. This might take a longer time to display lists, due to having to filter them every time.

  • Alternative 2: Hold Client and Vendor objects differently in two different lists.

    • Pros: Able to get Client or Vendor immediately without having to go through the entire Contact list as in alternative 1.

    • Cons: Difficult and extremely tedious to implement.

Aspect: How restrictive should the definition of a duplicate contact be?
  • Alternative 1: It should be regardless of contact type, meaning a client and a vendor cannot have the same name and either the same phone number or email.

    • Pros: No additional implementation required. The legacy implementation already supports this.

    • Cons: Less flexibility for our users. A client cannot be a vendor possibly.

  • Alternative 2 (current choice): A client and a vendor can have similar fields, meaining a client and a vendor can possibly have the same name, phone number and/or email.

    • Pros: More flexibility for our users. A client can be a vendor too, which is possible in the real world.

    • Cons: Additional implementation to have.